Adaptation GWBasic en PureBasic

Sujets variés concernant le développement en PureBasic
Mesa
Messages : 1097
Inscription : mer. 14/sept./2011 16:59

Re: Adaptation GWBasic en PureBasic

Message par Mesa »

Comme les ports série n'utilisent en générale que des octets non signés (.a), il est préférables autant que possible de n'utiliser que des .a et éviter les strings, et autres. C'est une précaution.
De plus en utilisant les strings, certains caractères, comme le caractère 0, ne seront pas affichés.

Éviter d'utiliser debug pendant une réception/émission de données, c'est préférable aussi.

Je n'ai pas pu debugger ce code, mais c'est dans l'esprit de ce que je ferais :

Code : Tout sélectionner

;VOIR ICI ---->http://www.purebasic.fr/english/viewtopic.php?f=12&t=46481

Procedure EmissionCom(NumeroBoitier.i)
  Protected c.a
  
  If IsSerialPort(#PortSerie) = 0
    Debug "le port série n'est pas initialisé"
    ProcedureReturn 1 
  Else 
    *Envoi=AllocateMemory(4) 
    *Reponse=AllocateMemory(14) ; prévoir le tampon avant la reception de la réponse
    
    Debug NumeroBoitier
    texte$= boitier(NumeroBoitier) ; il faudrait éviter les strings au cas où...
    Debug texte$
    For i=0 To 3
      c=Mid(texte$,i+1,1)
      PokeA(*Envoi+i, c)
    Next i
    Resultat = WriteSerialPortData(#PortSerie,*Envoi,4)
    If resultat=0
      Debug "erreur envoi"
    Else
      Debug " envoi ok"
    EndIf
    
  EndIf
  
  ;####################################
  ;# RECEVOIR ECHO #
  ;####################################
  
  Repeat 
    compteur=compteur+1
    Resultat = AvailableSerialPortInput(#SerialPort)      ; Check for available data in input buffer 
    If Resultat  <>0
      Delay(50)  ; "Attendre..." Give modem a chance to respond  
      While Resultat
        ;Cette fonction bloquera l'éxécution du programme jusqu'à l'arrivée des données.  
        ReadSerialPortData(#SerialPort, *Reponse, Resultat) ; Read the data in the input buffer into memory 
        ;Text$ = PeekS(*Reponse, Resultat) 
        ;Msg$ + Text$   
        Resultat = AvailableSerialPortInput(#SerialPort) 
      Wend 
      Break  
    EndIf 
    Delay(500)  ; Let system do other things 
    If compteur >2000 ; quitter si trop long
      Debug "trop long..."
      Break
    EndIf
    
  ForEver  
  
  Debug "echo"
  echo$=""
  For i = 0 To 3
    echo$=echo$+PeekA(*Reponse+i)
  Next i
  Debug echo$
  
  Debug "adresse du boitier 1 : Chr(128)+Chr(27)+Chr(4) "
  Dim adr1(3)
  For i = 4 To 6
    c=PeekA(*Reponse+i)
    adr1(i-4)=c
    Debug c 
  Next i
  
  
  Debug "datas du boitier 1 : 6c "
  Dim data1(6)
  For i = 7 To 12
    c=PeekA(*Reponse+i)
    data1(i-7)=c
    Debug c 
  Next i
  
  Debug "checksum du boitier 1 : 1c "
  checksum=PeekA(*Reponse+13)
  Debug data1$ 
  
  ProcedureReturn 0
EndProcedure

M.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Adaptation GWBasic en PureBasic

Message par djes »

Comme mesa, il faut se méfier des string, le chr(0) étant considéré comme fin de chaîne par pb. Petit truc pour déboguer sans debug, utiliser messagerequester()...
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Adaptation GWBasic en PureBasic

Message par Marc56 »

Hello,

Voilà un truc qui marche, enfin dans mon contexte :oops:

Note: Je ne comprend pas pourquoi j'ai du mettre deux fois de suite OpenSerialPort (?), mais ce fut le seul moyen :? (j'ai travaillé en mode Shadock: pomper/essayer jusqu'à ce qu'il se passe quelque-chose :mrgreen: ) (si quelqu'un peut m'expliquer pourquoi ça marche?) 8O

Il faut aussi penser aux temporisations: sans le délai de 2 sec avant avant AvailableSerial, ça ne marche pas.

J'ai fait une boucle sur 28 octets pour avoir à coup sûr la séquence de 14
(j'ai programmé une carte Arduino pour qu'elle émette en boucle ta séquence)

Code : Tout sélectionner

ShowDebugOutput()

Port$ = "COM4"

Com_ID = OpenSerialPort(0, Port$, 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
Debug "Com_ID = " + Str(Com_ID)

Com_ID = OpenSerialPort(0, Port$, 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024)
Delay(2000)

While AvailableSerialPortInput(Com_ID) > 0 And i < 28
	i + 1
	Delay(100)
	If ReadSerialPortData(Com_ID, @Buffer, 1) ; Read Byte
		Debug Buffer
	EndIf
Wend


CloseSerialPort(Com_ID)

Debug "End"
End
Pour tester, j'ai utilisé une carte Arduino, sur laquelle j'ai uploadé ce minuscule programme

Code : Tout sélectionner

/* Send Serial
*
*/

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.write(192);
  Serial.write(27);
  Serial.write(4);
  Serial.write(95);
  Serial.write(22);
  Serial.write(18);
  Serial.write(0);
  Serial.write(54);
  Serial.write(0);
  Serial.write(195);
  delay(1000);
}
Arduino, serial.write http://arduino.cc/en/Serial/write

Pas sûr que ça corresponde exactement à ce que tu cherches, mais ça te donne une base de réflexion :wink: :idea:

Ma console de debug affiche:

Com_ID = 208
195
192
27
4
95
22
18
0
54
0
195

192
27
4
95
22
18
0
54
0
195
192
27
4
95
22
18
0
End

On voit donc bien passer la séquence, y compris les 0

Dans tous les cas, je commence par tester avec un terminal série (tera term etc), si ça marche là et pas dans le programme c'est souvent une question de temporisation (ou plus bête des vitesses différentes entre les deux interfaces séries) 8O

PureBasic 5.31 x86 sur Windows 8.1
Arduino UNO connecté sur COM4 (over USB)

:wink:
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Adaptation GWBasic en PureBasic

Message par djes »

Le buffer, non déclaré, est automatiquement un .i, donc tu n'as de problèmes avec les CHR(0), puisque ce n'est pas une chaîne (.s)
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Adaptation GWBasic en PureBasic

Message par Marc56 »

Y'a un truc (enfin plusieurs) qui va pas du tout dans mon exemple, oubliez 8O :? :oops:
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Adaptation GWBasic en PureBasic

Message par Marc56 »

Marc56 a écrit :Y'a un truc (enfin plusieurs) qui va pas du tout dans mon exemple, oubliez 8O :? :oops:
Ah, non, c'est bon :D

Je trouvais bizarre que la carte m'envoie toujours la même séquence en commençant bien au début quelque soit l'état du buffer, mais j'avais oublié que les cartes Arduino ont une caractéristiques: elle se réinitialisent chaque fois qu'il y a une connexion sur leur port série, donc le programme recommençait au début à chaque fois

192, 27, 4 etc

:wink:
PureDev
Messages : 31
Inscription : sam. 25/janv./2014 9:42

Re: Adaptation GWBasic en PureBasic

Message par PureDev »

Tous mes remerciements aux différents contributeurs à ce forum. Je rentre du site industriel. Les essais de communication ont donné les résultats attendus. Je remercie tout particulièrement MESA qui m'a mis sur la bonne voie et djes qui m'a définitivement convaincu.

Le programme de MESA a éffectivement un bog mineur (déclaration de variable) facile à corriger.

Effectivement il ne fallait pas utiliser des .s (string) mais des .a (ascii) pour recevoir des données pouvant valoir 0.



Bonne fêtes de fin d'année, et encore merci.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Adaptation GWBasic en PureBasic

Message par djes »

Ca fait plaisir, merci de nous avoir tenus au courant :)
Mesa
Messages : 1097
Inscription : mer. 14/sept./2011 16:59

Re: Adaptation GWBasic en PureBasic

Message par Mesa »

Oui, ça fait toujours plaisir :D

Une dernière petite chose, quand on utilise allocatememory dans une procedure, il faut prévoir un freememory aussi afin d'éviter les fuites de mémoires qui peuvent faire planter le programme après un certain temps d'utilisation, pour tracer les fuites, on active le purificateur dans les options du compilateur.

Mesa.
PureDev
Messages : 31
Inscription : sam. 25/janv./2014 9:42

Re: Adaptation GWBasic en PureBasic

Message par PureDev »

Bonjour Mesa,
A vrai dire je ne comprend pas les fuites de mémoire auxquelles tu fais référence.
Je vais néanmoins placer un FreeMemory à la sortie de la procédure comme tu le suggères.
Actuellement le programme se comporte correctement sans cette instruction.
Il est vrai que mes tests durent une heure ou deux. Mis en situation, le programme doit "tourner" 20 heures par jour, et même 24/24.
Alors prudence.
Répondre