Domotique avec Panoramic : Arduino, commande des GPIO
2 participants
Auteur
Message
Marc
Nombre de messages : 2466 Age : 63 Localisation : TOURS (37) Date d'inscription : 17/03/2014
Sujet: Domotique avec Panoramic : Arduino, commande des GPIO Mer 28 Juil 2021 - 16:19
Bonjour à tous !
Le thème abordé est le pilotage de plusieurs sorties GPIO de l'Arduino UNO depuis Panoramic.
Pour cette démonstration, j’ai utilisé :
- 1 x Arduino UNO - 1 x câble USB - 12 x LED rouges et/ou vertes - 12 x résistances 330 ohms 1/4W - 1 x platine de prototypage (breadboard) - Fils de câblage
Une LED en série avec une résistance de 330 ohms est reliée d’un coté à chaque GPIO de l’Arduino et de l’autre coté à la broche GND.
Pour pouvoir envoyer un ordre différent à chaque GPIO, il va falloir définir un protocole de communication. Ce protocole doit indiquer quel GPIO est ciblé en plus de l’information de l’état (haut ou bas) qu’il doit prendre.
Les GPIO disponibles sur la version UNO de l’Arduino sont les broches numérotées de 2 à 13. Le broches 0 et 1 sont réservées à la transmission série utilisée par Panoramic entre autres.
Comme exemple de protocole, j’ai choisi d’envoyer une trame composée de trois octets.
- Le premier octet indiquera le numéro de GPIO ciblé, de 2 à 13 ; - Le deuxième octet sera la valeur à affecter au GPIO, "0" pour éteindre la LED ou "1" pour l'allumer ; - Le troisième octet sera un octet de contrôle pour indiquer la fin de la trame.
Pour ce troisième octet, il ne sera pas possible d’utiliser un simple "Retour Chariot" (CR en abrégé, valeur Hexadécimale 0D) qui correspond à la valeur décimale 13 : il y aurait confusion avec le GPIO 13.
De même, il ne sera pas possible d’utiliser un "Line Feed" (LF en abrégé, 0A en hexa) qui correspondrait au GPIO 10.
Comme valeur de troisième octet, j’utiliserai "255" en décimal (FF en hexadécimal).
Exemple d’une trame :
Je souhaite allumer une LED connectée au GPIO 13. La trame en hexadécimal sera « OD 01 FF ».
Décomposition de cette trame : - Premier octet : 0D => GPIO 13 - Deuxième octet : 01 => mise à l’état « Haut » - Troisième octet : FF => Fin de la trame.
Ceci n’est qu’un exemple de protocole de communication. Il ne saurait être la panacée à toutes les configurations possibles. C’est à vous d’en créer un qui "colle" avec votre projet.
Dans le cadre de cette démonstration, voici un code-exemple à téléverser dans l’Arduino pour pouvoir utiliser plusieurs GPIO :
Code:
const int LED1 = 2; //La LED1 est connectée à la broche 2 const int LED2 = 3; //La LED2 est connectée à la broche 3 const int LED3 = 4; //La LED3 est connectée à la broche 4 const int LED4 = 5; //La LED4 est connectée à la broche 5 const int LED5 = 6; //La LED5 est connectée à la broche 6 const int LED6 = 7; //La LED6 est connectée à la broche 7 const int LED7 = 8; //La LED7 est connectée à la broche 8 const int LED8 = 9; //La LED8 est connectée à la broche 9 const int LED9 = 10; //La LED9 est connectée à la broche 10 const int LED10 = 11; //La LED10 est connectée à la broche 11 const int LED11 = 12; //La LED11 est connectée à la broche 12 const int LED12 = 13; //La LED12 est connectée à la broche 13
int numeroGpio; // Variable indiquant le numéro de GPIO ciblé String trameRecu; // Trame reçue du port série
void setup() { Serial.begin(9600); // Initialisation du port série avec sa vitesse en bauds pinMode(LED1, OUTPUT); // La broche 2 (LED1) est configurée en "sortie" pinMode(LED2, OUTPUT); // La broche 3 (LED2) est configurée en "sortie" pinMode(LED3, OUTPUT); // La broche 4 (LED3) est configurée en "sortie" pinMode(LED4, OUTPUT); // La broche 5 (LED4) est configurée en "sortie" pinMode(LED5, OUTPUT); // La broche 6 (LED5) est configurée en "sortie" pinMode(LED6, OUTPUT); // La broche 7 (LED6) est configurée en "sortie" pinMode(LED7, OUTPUT); // La broche 8 (LED7) est configurée en "sortie" pinMode(LED8, OUTPUT); // La broche 9 (LED8) est configurée en "sortie" pinMode(LED9, OUTPUT); // La broche 10 (LED9) est configurée en "sortie" pinMode(LED10, OUTPUT); // La broche 11 (LED10) est configurée en "sortie" pinMode(LED11, OUTPUT); // La broche 12 (LED11) est configurée en "sortie" pinMode(LED12, OUTPUT); // La broche 13 (LED12) est configurée en "sortie" }
void loop() { if (Serial.available()) { trameRecu = Serial.readStringUntil(255); // Lecture trame série reçue et mémorisation dans la variable "data" numeroGpio = trameRecu[0]; // Le premier octet de la trame reçue est mémorisé dans la variable "numeroGpio"
if (trameRecu[1] == 1) // Si le deuxième octet de la trame est un "1" digitalWrite(numeroGpio,HIGH); else digitalWrite(numeroGpio,LOW); } }
Fonctionnement:
Sous Panoramic, vous pouvez utiliser soit le programme PANORAMIC Terminal RS232, soit un programme personnel.
1) Avec Panoramic Terminal RS232.
Après avoir téléversé le programme dans l’Arduino, fermez l’IDE Arduino. Laissez votre Arduino connecté au port USB de l’ordinateur. Exécutez le programme PANORAMIC Terminal RS232.
Dans la zone Port COM, sélectionnez le numéro de port COM utilisé par votre Arduino dans votre ordinateur. Réglez les paramètres du port à 9600 bauds, 8bits, sans parité et 1 bit de stop puis cliquez sur le bouton tout à droite pour ouvrir le port COM. Le bouton passe au vert.
Dans la zone Ligne de commande RS232, sélectionnez le format Hexa, Sans suffixe.
Exemple pour allumer la LED reliée au GPIO n° 5. D’après le protocole défini ci-dessus, tapez la trame 05 01 FF puis cliquez sur Envoyer. La LED concernée s’allume.
Pour éteindre cette même LED, tapez 05 00 FF puis cliquez sur Envoyer.
2) Avec un programme Panoramic personnel.
Voici un exemple d'interface graphique et son code-source :
Code:
' Panoramic => Arduino UNO ' Logiciel de démonstration ' Commande en tout ou rien des GPIO 2 à 13 ' Marc - juillet 2021
dim portCom%, i%
label onOffSerial, choixPortCom, action, redim0
dessinerInterfaceUtilisateur()
end
action: select number_click case 12 if checked(12) = 0 serial_write 60,chr$(2)+chr$(1)+chr$(255) color 42,0,255,0 else serial_write 60,chr$(2)+chr$(0)+chr$(255) color 42,127,127,127 end_if
case 13 if checked(13) = 0 serial_write 60,chr$(3)+chr$(1)+chr$(255) color 43,0,255,0 else serial_write 60,chr$(3)+chr$(0)+chr$(255) color 43,127,127,127 end_if
case 14 if checked(14) = 0 serial_write 60,chr$(4)+chr$(1)+chr$(255) color 44,0,255,0 else serial_write 60,chr$(4)+chr$(0)+chr$(255) color 44,127,127,127 end_if
case 15 if checked(15) = 0 serial_write 60,chr$(5)+chr$(1)+chr$(255) color 45,0,255,0 else serial_write 60,chr$(5)+chr$(0)+chr$(255) color 45,127,127,127 end_if
case 16 if checked(16) = 0 serial_write 60,chr$(6)+chr$(1)+chr$(255) color 46,0,255,0 else serial_write 60,chr$(6)+chr$(0)+chr$(255) color 46,127,127,127 end_if
case 17 if checked(17) = 0 serial_write 60,chr$(7)+chr$(1)+chr$(255) color 47,0,255,0 else serial_write 60,chr$(7)+chr$(0)+chr$(255) color 47,127,127,127 end_if
case 18 if checked(18) = 0 serial_write 60,chr$(8)+chr$(1)+chr$(255) color 48,0,255,0 else serial_write 60,chr$(8)+chr$(0)+chr$(255) color 48,127,127,127 end_if
case 19 if checked(19) = 0 serial_write 60,chr$(9)+chr$(1)+chr$(255) color 49,0,255,0 else serial_write 60,chr$(9)+chr$(0)+chr$(255) color 49,127,127,127 end_if
case 20 if checked(20) = 0 serial_write 60,chr$(10)+chr$(1)+chr$(255) color 50,0,255,0 else serial_write 60,chr$(10)+chr$(0)+chr$(255) color 50,127,127,127 end_if
case 21 if checked(21) = 0 serial_write 60,chr$(11)+chr$(1)+chr$(255) color 51,0,255,0 else serial_write 60,chr$(11)+chr$(0)+chr$(255) color 51,127,127,127 end_if
case 22 if checked(22) = 0 serial_write 60,chr$(12)+chr$(1)+chr$(255) color 52,0,255,0 else serial_write 60,chr$(12)+chr$(0)+chr$(255) color 52,127,127,127 end_if
case 23 if checked(23) = 0 serial_write 60,chr$(13)+chr$(1)+chr$(255) color 53,0,255,0 else serial_write 60,chr$(13)+chr$(0)+chr$(255) color 53,127,127,127 end_if
end_select return
choixPortCom: portCom% = item_index(2) if serial_port_exists(portCom%) = 0 if message_warning_ok("COM"+str$(portCom%) + " : Liaison série inexistante !") < 2 inactive 3 :' interrupteur on/off Serial return end_if end_if active 3 :' interrupteur on/off Serial return
onOffSerial: if checked(3) = 0 inactive 2 initialisationLiaisonSerie() serial_open 60 for i% = 12 to 23 active i% next i% else serial_close 60 active 2 for i% = 12 to 23 inactive i% next i% end_if return
sub initialisationLiaisonSerie() if object_exists(60) = 0 serial 60 end_if serial_port 60,portCom% serial_baudrate 60,9600 serial_databits 60,8 serial_parity 60,0 serial_stopbits 60,1 end_sub
sub dessinerInterfaceUtilisateur() width 0,width(0) - width_client(0) + 1010 height 0,height(0) - height_client(0) + 180 left 0,(screen_x - width(0)) / 2 top 0,(screen_y - height(0)) / 2 on_resize 0,redim0 caption 0,"PANORAMIC --> Arduino UNO Commande des GPIO" creerModuleSerial() creerModuleInterrupteursGpio() end_sub
sub creerModuleSerial() dim_local n%
command_target_is 0
container 1 width 1,100 height 1,150 left 1,15 top 1,15 caption 1,"Serial"
command_target_is 1
combo 2 parent 2,1 width 2,70 top 2,30 left 2,15 for n% = 1 to 255 item_add 2,"COM" + str$(n%) next n% on_change 2,choixPortCom
switch1 3 parent 3,1 width 3,50 top 3,70 left 3,25 caption 3,"Off|On" on_click 3,onOffSerial inactive 3 end_sub
sub creerModuleInterrupteursGpio() dim_local n%,e%,numeroGpio% command_target_is 0
container 10 width 10,865 height 10,150 top 10,15 left 10,130 caption 10,"GPIO"
' dessiner les interrupteurs de commande des GPIO numeroGpio% = 2 e% = 23
for n% = 12 to 23 switch1 n% parent n%,10 width n%,50 top n%,70 left n%,e% caption n%,str$(numeroGpio%)+": Off|"+str$(numeroGpio%)+": On" on_click n%, action inactive n% e% = e% + 70 numeroGpio% = numeroGpio% + 1 next n%
' dessiner LEDs au dessus des interrupteurs de commande GPIO e% = 36 for n% = 42 to 53 led1 n% parent n%,10 top n%,28 left n%,e% color n%,127,127,127 e% = e% + 70 next n% end_sub