Marc
Nombre de messages : 2397 Age : 63 Localisation : TOURS (37) Date d'inscription : 17/03/2014
| Sujet: Interface de commande RS485/Modbus Mar 25 Mai 2021 - 15:39 | |
| Bonjour à tous ! Dans la cadre du développement de la partie RS485/Modbus pour Panoramic, je vous propose ce petit utilitaire qui vous permettra de tester et piloter un périphérique Modbus à partir de votre ordinateur. Il vous apportera également une aide à la programmation sous Panoramic. Vous pourrez visualiser le trafic entrant et sortant du port COM. Le calcul et l’ajout du CRC est automatique. - Code:
-
' Interface de commande MODBUS RTU ' Marc - mai 2021 - https://panoramic.1fr1.net/ dim portCom%(255), baudrate%(12), nbBits%(4), parity%(3), bitstop(3) dim indexPortCom%, indexBaudRate%, indexNbBits%, indexParity%, indexBitStop% dim comN%(255) dim etatPort%, debug% dim repertoire$
label enregistrer, choixPortCom, choixBaudrate, choixNbBits, choixParity, choixBitstop label autoDetect, ouvrirFermerPort, envoyerTrame, reception, redim0, copiePanoramic label effacerCRC16
data 110,300,600,1200,2400,4800,9600,14400,19200,38400,57600,115200 data 5,6,7,8 data 0,1,2 data 1,1.5,2
debug% = 0
initConstantes() interfaceUtilisateur()
if debug% = 1 form 999 print_target_is 999 end_if
end
ouvrirFermerPort: if etatPort% = 1 etatPort% = 0 color 14,255,0,0 serial_close 50 active 2 active 4 active 6 active 8 active 10 active 12 active 13 caption 14,"Port COM" + chr$(13) + "fermé" else if serial_port_exists(portCom%(indexPortCom%)) = 0 if message_error_ok("Le port COM" + str$(portCom%(indexPortCom%)) + " n'est pas disponible !") < 2 return end_if end_if etatPort% = 1 if debug% = 1 cls print "port COM: " + str$(portCom%(indexPortCom%)) print "BaudRate: " + str$(baudRate%(indexBaudRate%)) print "Nb Bits: " + str$(nbBits%(indexNbBits%)) print "Parity: " + str$(parity%(indexParity%)) print "Bits Stop: " + str$(bitStop(indexBitStop%)) end_if inactive 2 inactive 4 inactive 6 inactive 8 inactive 10 inactive 12 inactive 13 serial_port 50,portCom%(indexPortCom%) serial_baudrate 50,baudRate%(indexBaudRate%) serial_databits 50,nbBits%(indexNbBits%) serial_parity 50,parity%(indexParity%) serial_stopbits 50,bitStop(indexBitStop%) color 14,0,255,0 caption 14,"Port COM" + chr$(13) + "ouvert" serial_open 50 on_receive 50,reception end_if return
sub interfaceUtilisateur() width 0,width(0) - width_client(0) + 570 height 0,height(0) - height_client(0) + 411 top 0,(screen_y - height(0)) / 2 left 0,(screen_x - width(0)) / 2 caption 0,"PANORAMIC Modbus RTU" on_resize 0,redim0 application_title "PANORAMIC Modbus RTU" modulePortCom() chargerFichierPreferences() moduleSaisieTrame() moduleAffichageVariable() logo() end_sub
sub moduleSaisieTrame() container 20 top 20,90 left 20,10 width 20,550 height 20,310 caption 20," Trame ModBus RTU " edit 21 parent 21,20 top 21,21 left 21,15 width 21,455 font_size 21,10 on_change 21,effacerCRC16
button 22 parent 22,20 top 22,20 left 22,483 width 22,52 height 22,23 caption 22,"Envoyer" on_click 22,envoyerTrame memo 23 parent 23,20 top 23,70 width 23,455 left 23,15 height 23,150 bar_vertical 23 font_size 23,10 memo 24 parent 24,20 top 24,245 width 24,455 left 24,15 height 24,50
alpha 25 parent 25,20 top 25,56 left 25,18 caption 25,"Trafic port série :" alpha 26 parent 26,20 top 26,231 left 26,18 caption 26,"Trame au format Panoramic :" button 27 parent 27,20 top 27,260 left 27,483 width 27,52 height 27,23 caption 27,"Copier" on_click 27,copiePanoramic alpha 28 parent 28,20 top 28,75 left 28,489 caption 28,"CRC-16" edit 29 parent 29,20 top 29,90 left 29,483 width 29,52 end_sub
sub moduleAffichageVariable() panel 40 top 40,150 left 40,165 width 40,260 height 40,160
container 45 parent 45,40 width 45,240 height 45,140 top 45,10 left 45,10 caption 45," Auto Detect " alpha 41 parent 41,45 left 41,45 top 41,20
alpha 42 parent 42,45 left 42,71 top 42,49
alpha 43 parent 43,45 left 43,40 top 43,67 alpha 44 parent 44,45 top 44,105 left 44,96 hide 40 end_sub
envoyerTrame: inactive 22 inactive 21 traitementTrame() active 21 active 22 return
sub traitementTrame() dim_local crc, crc16$, i%, j%, c$, p%, pFort$, pFaible$, t$, tr$, trameComplete$, trameSerie$, trameMemo$, tramePanoramic$ tr$ = text$(21)
' suppression des espaces dans la trame hexadécimale for p% = 1 to len(tr$) c$ = mid$(tr$,p%,1) if c$ <> " " t$ = t$ + c$ end_if next p%
' vérification de la trame hexadécimale if mod(len(t$),2) = 0 for p% = 1 to len(t$) c$ = mid$(t$,p%,1) if instr("0123456789ABCDEFabcdef",c$) = 0 message "Le caractère ''" + c$ + "'' : n'est pas une valeur hexadécimale !" exit_sub end_if next p% else message "Le nombre de charactères doit être pair." exit_sub end_if
t$ = upper$(t$)
' calcul du crc16 p% = 1 crc = hex("FFFF") for i% = len(t$) to 1 step -2 c$ = mid$(t$,p%,2) crc = bin_xor(crc,hex(c$)) p% = P% + 2 for j% = 0 to 7 if bin_and(crc,hex("0001")) = 1 crc = bin_xor(int(crc/2),hex("A001")) else crc = int(crc/2) end_if next j% next i%
' inversion des 2 octets (little-endian) crc16$ = hex$(crc)
while len(crc16$) < 4 crc16$ = "0" + crc16$ end_while
pFort$ = left$(crc16$,2) pFaible$ = right$(crc16$,2) crc16$ = pFaible$ + pFort$
trameComplete$ = t$ + crc16$ ' affichage du CRC16 dans l'EDIT 29 text 29," " + pFaible$ + " " + pFort$ ' affichage dans le memo de la trame complete envoyée trameMemo$ = "" p% = 1 for i% = 1 to len(trameComplete$) step 2 c$ = mid$(trameComplete$,p%,2) trameMemo$ = trameMemo$ + c$ + " " p% = p% + 2 next i% if etatPort% = 1 item_add 23,"Trame envoyée vers le port COM" + str$(portCom%(indexPortCom%)) + " à " + time$ +" :" item_add 23,trameMemo$ item_add 23,"" else item_add 23,"Port COM fermé, trame non envoyée à " + time$ + " :" item_add 23,trameMemo$ item_add 23,"" end_if ' affichage dans le memo Panoramic de la trame complete à envoyer tramePanoramic$ = "" clear 24 p% = 1 for i% = 1 to len(trameComplete$) step 2 c$ = mid$(trameComplete$,p%,2) tramePanoramic$ = tramePanoramic$ + "chr$(" + str$(hex(c$)) + ")+" p% = p% + 2 next i% tramePanoramic$ = left$(tramePanoramic$,len(tramePanoramic$) - 1) item_add 24,tramePanoramic$ ' mise en forme pour transfert via le port COM trameSerie$ = "" p% = 1 for i% = 1 to len(trameComplete$) step 2 c$ = mid$(trameComplete$,p%,2) trameSerie$ = trameSerie$ + chr$(hex(c$)) p% = p% + 2 next i% if etatPort% = 1 serial_write 50,trameSerie$ end_if end_sub
reception: TrameReception() return
sub TrameReception() dim_local trameRecept$, trameReceptMemo$, i%, char$, c%, h$ trameRecept$ = serial_read$(50)
for i% = 1 to len(trameRecept$) char$ = mid$(trameRecept$,i%,1) c% = asc(char$) h$ = hex$(c%) if len(h$) = 1 h$ = "0" + h$ end_if trameReceptMemo$ = trameReceptMemo$ + h$ + " " next i%
item_add 23,"Trame reçue depuis le port COM" + str$(portCom%(indexPortCom%)) + " à " + time$ +" :" item_add 23,trameReceptMemo$ item_add 23,"" end_sub
sub modulePortCom() dim_local n% container 1 top 1,10 left 1,10 width 1,550 height 1,75 caption 1," Port COM "
button 2 parent 2,1 top 2,30 left 2,10 width 2,35 height 2,20 caption 2,"Auto" on_click 2,autoDetect
alpha 3 parent 3,1 top 3,15 left 3,58 caption 3,"Port" combo 4 parent 4,1 width 4,75 top 4,30 left 4,55 for n% = 1 to 255 item_add 4,"COM" + str$(n%) next n% on_change 4,choixPortCom alpha 5 parent 5,1 top 5,15 left 5,141 caption 5,"BaudRate" combo 6 parent 6,1 top 6,30 left 6,138 width 6,75 item_add 6,"110" item_add 6,"300" item_add 6,"600" item_add 6,"1200" item_add 6,"2400" item_add 6,"4800" item_add 6,"9600" item_add 6,"14400" item_add 6,"19200" item_add 6,"38400" item_add 6,"57600" item_add 6,"115200" on_change 6,choixBaudRate alpha 7 parent 7,1 top 7,15 left 7,223 caption 7,"Bits" combo 8 parent 8,1 top 8,30 left 8,220 width 8,40 item_add 8,"5" item_add 8,"6" item_add 8,"7" item_add 8,"8" on_change 8,choixNbBits alpha 9 parent 9,1 top 9,15 left 9,271 caption 9,"Parité" combo 10 parent 10,1 top 10,30 left 10,268 width 10,75 item_add 10,"Aucune" item_add 10,"Impaire" item_add 10,"Paire" on_change 10,choixParity alpha 11 parent 11,1 top 11,15 left 11,353 caption 11,"Stop Bits" combo 12 parent 12,1 top 12,30 left 12,350 width 12,50 item_add 12,"1" item_add 12,"1.5" item_add 12,"2" on_change 12,choixBitStop button 13 parent 13,1 top 13,30 left 13,410 width 13,20 height 13,20 caption 13,"M" hint 13,"Enregistrer les paramètres" on_click 13,enregistrer button_picture 14 parent 14,1 left 14,445 top 14,20 width 14,90 height 14,40 color 14,255,0,0 caption 14,"Port COM" + chr$(13) + "Fermé" on_click 14,ouvrirFermerPort end_sub
effacerCRC16: text 29,"" return
sub chargerFichierPreferences() if file_exists(repertoire$ + "pmrt.cfg") = 1 file_open_read 31,repertoire$ + "pmrt.cfg" IndexPortCom% = file_readln$(31) indexBaudrate% = file_readln$(31) indexNbBits% = file_readln$(31) indexParity% = file_readln$(31) indexBitStop% = file_readln$(31) file_close 31 else ' valeurs par défaut IndexPortCom% = 8 :' COM8 indexBaudrate% = 7 :' 9600 bauds indexNbBits% = 4 :' 8 bits indexParity% = 1 :' Aucune indexBitstop% = 1 :' 1 bit end_if item_select 4,indexPortCom% item_select 6,indexBaudrate% item_select 8,indexNbBits% item_select 10,indexParity% item_select 12,indexBitStop% end_sub
choixPortCom: indexPortCom% = item_index(4) return
choixBaudrate: indexBaudRate% = item_index(6) return
choixNbBits: indexNbBits% = item_index(8) return
choixParity: indexParity% = item_index(10) return
choixBitstop: indexbitStop% = item_index(12) return
sub initConstantes() dim_local n% repertoire$ = dir_current$ + "" serial 50 for n% = 1 to 255 portCom%(n%) = n% next n%
for n% = 1 to 12 read baudRate%(n%) next n% for n% = 1 to 4 read nbBits%(n%) next n% for n% = 1 to 3 read parity%(n%) next n% for n% = 1 to 3 read bitStop(n%) next n% end_sub
autoDetect: scanPortCom() return
copiePanoramic: clipboard_string_copy text$(24) return
sub scanPortCom() dim_local key%, n%, pass%, quitter% inactive 0 pass% = 1 indexPortCom% = 0 text 4,""
caption 41,"Initialisation en cours..." left 41,64 top 41,45
caption 42," Patientez SVP !" left 42,81 top 42,90 caption 43,"" caption 44,"" show 40 display
' cartographie des ports COM existants for n% = 1 to 255 comN%(n%) = 0 if serial_port_exists(n%) = 1 comN%(n%) = 1 end_if next n% caption 41,"Connectez votre clé USB/RS485 !" left 41,40 top 41,30
caption 42,"Recherche en cours..." left 42,71 top 42,55
caption 43,"" left 43,40 top 43,80 caption 43,"Interrogation du port COM1/255"
caption 44,"Passe " + str$(pass%) + "/5" top 44,105 left 44,96 display
' recherche modification d'un port com while pass% < 6 for n% = 1 to 255 caption 43,"Interrogation du port COM" + str$(n%) + "/255" display pause 20 if serial_port_exists(n%) = 1 if comN%(n%) = 0 comN%(n%) = 1 indexPortCom% = n% text 4,"COM" + STR$(n%) item_select 4,indexPortCom% hide 40 active 0 exit_while end_if else if comN%(n%) = 1 comN%(n%) = 0 end_if end_if next n% pause 20 pass% = pass% + 1 caption 44,"Passe " + str$(pass%) + "/5" display ' après 5 scans sans succès, sortie du mode auto if pass% = 6 hide 40 message "Clé USB/RS485 non trouvée !" active 0 exit_while end_if
end_while end_sub
sub logo() picture 35 parent 35,20 width 35,42 height 35,42 top 35,166 left 35,488 color 35,255,255,255 2d_target_is 35 ' cadre 2d_pen_color 160,160,160 2d_rectangle 0,0,42,42 ' cercles rouges 2d_pen_width 2 2d_pen_color 255,0,0 2d_circle 21,21,17 2d_circle 21,21,13 ' lettre P 2d_pen_width 1 2d_pen_color 35,35,145 2d_fill_color 35,35,145 2d_rectangle 17,15,20,28 2d_line 15,15,26,15 2d_line 16,16,27,16 2d_line 23,17,28,17 2d_line 24,18,28,18 2d_line 24,19,28,19 2d_line 23,20,28,20 2d_line 20,21,27,21 2d_line 20,22,26,22 2d_line 16,26,21,26 2d_line 15,27,23,27 end_sub
redim0: width 0,width(0) - width_client(0) + 570 height 0,height(0) - height_client(0) + 411 return
enregistrer: FILE_OPEN_WRITE 30,repertoire$ + "pmrt.cfg" FILE_WRITELN 30,indexPortCom% FILE_WRITELN 30,indexBaudrate% FILE_WRITELN 30,indexNbBits% FILE_WRITELN 30,indexParity% FILE_WRITELN 30,indexBitStop% FILE_CLOSE 30 return Au téléchargement : - Le mode d’emploi : https://mon-partage.fr/f/uFuxJbJe/- L’exécutable : https://mon-partage.fr/f/UJzgtipI/- Le code-source : https://mon-partage.fr/f/KkbdWyOQ/En cas de liens morts, retrouvez ces trois fichiers dans mon WebDAV, dans le dossier "Domotique Electronique avec PANORAMIC". EDIT du 26/05/2021 : mise à jour du code
Dernière édition par Marc le Mer 22 Sep 2021 - 14:46, édité 2 fois | |
|