Bonjour à vous 2
voici quelques modifications à apporter au programme Processing
je vais essayer de les expliquer et je pense qu'ensuite @JP les choses seront plus simples pour vous
dans PERSO_10-2-1
il faut déclarer une variable globale qui va représenter notre port série de discussion avec l'arduino. On met donc au débutil faut ensuite trouver le bon port. Généralement un Arduino va toujours se déclarer au même endroit, donc on peut câbler cela en dur dans le setup et donc on ajoute dans le setup()
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 // LE PORT SERIE import processing.serial.*; Serial arduinoSerial; // The serial portla première commande affiche dans la console de processing tous les ports séries détectés. Sur mon mac avec mon Arduino Mega branché ça affiche
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 // List all the available serial ports: printArray(Serial.list()); // Open whatever port is the one you're using - here Serial.list()[1] arduinoSerial = new Serial(this, Serial.list()[1], 115200);
[0] "/dev/cu.Bluetooth-Incoming-Port"
[1] "/dev/cu.usbmodem1401"
[2] "/dev/tty.Bluetooth-Incoming-Port"
[3] "/dev/tty.usbmodem1401"
et je sais que mon MEGA est sur "/dev/cu.usbmodem1401" qui est l'entrée N° 1 donc dans le code à la ligne suivante j'écris en dur quelle entrée de la liste choisir, ici la 1et j'ouvre la connexion à 115200 bauds.
Code : Sélectionner tout - Visualiser dans une fenêtre à part arduinoSerial = new Serial(this, Serial.list()[1], 115200);
Pour tester ce qu'il se passe, on va charger dans l'arduino un petit programme tout simple qui renvoie sur la ligne série ce qu'il reçoit. une sorte d'echo. Installez donc ceci dans votre Arduino Mega:ATTENTION DE NE PAS OUVRIR LA CONSOLE ARDUINO (car sinon le programme processing ne va pas pouvoir s'y connecter).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 void setup() { Serial.begin(115200); } void loop() { int r; if ((r = Serial.read()) != -1) { // si on a reçu un octet Serial.write((byte) r); // on le renvoie } }
Voilà avec cela on est paré, notre programme processing sait théoriquement parler à notre Arduino mais ne sait pas encore écouter ce qui vient de l'Arduino. On rajoute donc dans PERSO_10_2_1 à la fin un petit bout de code qui écoute ce qui arrive sur le port série et l'imprime dans la console série de Processing
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 // GESTION DU RETOUR DE L'ARDUINO void serialEvent(Serial aPort) { // read what the Arduino sent us back while (aPort.available() > 0) print((char) aPort.read()); }
Ensuite bien sûr il faut pouvoir définir ces messages, donc associer à un Pavé un message et l'envoyer si nécessaire.
dans l'onglet Pavé
Pour cela on va modifier la classe Pave dont héritent tous les pavés en rajoutant une variable d'instance de type String et en l'initialisant à vide dans le constructueurPar la magie de l'héritage, tous les pavés sont maintenant porteur d'un message. Il faut pouvoir définir ce message donc on rajoute une méthode à la classe Pavé pour cela:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 abstract class Pave { Forme[] formes; // les formes int couleur=GRIS; // couleur (par defaut) pour le pave int taille=1; // taile du pave (1 par defaut) ArrayList<Forme> retraits=new ArrayList<Forme>(); // les retraits String messageArduino; Pave(Forme... fs) { formes=fs; messageArduino = ""; } // constructeuret il faut bien sûr avoir une méthode généraliste d'émission de message. Donc on rajoute aussi une méthode d'envoi de ce message
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 // message à émettre void definirMessage(String m) { messageArduino = m; }(Ici on ne va pas faire très propre et on va dire que la classe Pavé dépend d'une variable globale existante arduinoSerial qui représente le port série. Dans une bonne approche objet, on aurait une variable de classe (variable statique) qu'on définirait pour porter ce port série)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 void emettreMessage() { if (messageArduino != "") { arduinoSerial.write(messageArduino); arduinoSerial.write('\n'); // on envoie un marqueur de fin de commande } }
On y est presque maintenant. il nous reste à dire que lorsque l'on clique sur un pavé, il faut émettre son message. Donc on va modifier la fonction mouseClicked() pour cela, au lieu de juste envoyer le message manoeuvrer au pavé, on va ensuite lui envoyer l'order de communiquer avec l'Arduino:Enfin il faut bien sûr associer des messages au pavés. Cela se fait dans l'onglet TCO. par exemple pour nos pavés de type Cercle qui sont nos boutons, on peut faire la déclaration de la fonction construire() comme cela:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 void mouseClicked() { int l, c; ; Pave p; l=(mouseY-BORDURE)/TAILLE_CASE/(int)ZOOM; // calcul de la ligne c=(mouseX-BORDURE)/TAILLE_CASE/(int)ZOOM; // calcul de la colonne if (l<0 || l>=LIGNES || c<0 || c>=COLONNES) return; // pas dans tco p=tco.paves[c][l]; // obtension du pave if (p!=null) { p.manoeuvrer(mouseButton==RIGHT); // manoeuvre des aiguilles et signaux p.emettreMessage(); // on emet un message si nécessaire } }
je déclare une variable p qui sera un pavé et avec new je lui associe un pavé. j'appelle ensuite sur cette instance la méthode de définition de son message
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 void construire() { // PERSO 10 complet //============================================================================== Pave p; // variable qui nous permet de travailler avec nos nouveaux pavés p = new PaveCercle(); p.definirMessage("C1V1"); ajouter(p); ajouter(new PaveTexte("C1\nV1", 2, NOIR, 0, 0)); // texte, taille texte, couleur, ∆x, ∆y espacer(1); p = new PaveCercle(); p.definirMessage("C2V1"); ajouter(p); ajouter(new PaveTexte("C2\nV1", 2, NOIR, 0, 0)); // texte, taille texte, couleur, ∆x, ∆y espacer(1); p = new PaveCercle(); p.definirMessage("C3V1"); ajouter(p); ajouter(new PaveTexte("C3\nV1", 2, NOIR, 0, 0)); // texte, taille texte, couleur, ∆x, ∆y alaligne(); // Ligne 2 ...et enfin on l'ajoute comme avant au TCO. On fait la même chose pour les autres.
Code : Sélectionner tout - Visualiser dans une fenêtre à part p.definirMessage("C1V1");
Voilà. on y est.
si vous compilez et lancez le programme processing, en cliquant sur les "boutons" de la première ligne, un message sera envoyé à l'arduino sur son port série. Comme l'Arduino a un programme qui fait écho, c'est renvoyé au programme Processing qui va l'afficher dans sa console puisque l'on a mis la fonction serialEvent()
dans l'onglet Pavé
Mais on ne va pas s'arrêter là. Comme le dit @JP il faut pouvoir distinguer les états et donc pour cela il faut pouvoir éventuellement modifier le message qui est émis en fonction de l'état du Pavé. Comme tous les pavés héritent de la classe Pave, il ont tous un message et une méthode d'émission. Mais en programmation orientée objet, les sous-classes peuvent se permettre de surcharger certaines méthodes et de faire ce qu'elles souhaitent. On va donc par exemple modifier ma classe PaveCercle pour lui rajouter sa propre méthode emettreMessage() en disant par exempleQuand le bouton est clické, la méthode emettreMessage() est appelée mais par le biais de l'héritage le code exécuté correspond à celui le plus bas dans la hiérarchie d'héritage, donc ici mon code spécifique et pas le code généraliste de la classe mère. Ce code ici est simpliste, je regarde la couleur du bouton, si c'est celle par défaut je rajoute "is OFF" au message envoyé à l'Arduino, sinon je rajoute "is ON".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 void emettreMessage() { if (messageArduino != "") { arduinoSerial.write(messageArduino); if (couleur == #0000FF) { // couleur non appui arduinoSerial.write(" is OFF"); } else { arduinoSerial.write(" is ON"); } arduinoSerial.write('\n'); } }
Voilà en lançant le code modifié ainsi, l'affichage sera celui ci
et dans la console Processing quand on clique sur les boutons on voit bien les ports disponibles, puis ce que nous renvoie l'Arduino:
[0] "/dev/cu.Bluetooth-Incoming-Port"
[1] "/dev/cu.usbmodem1401"
[2] "/dev/tty.Bluetooth-Incoming-Port"
[3] "/dev/tty.usbmodem1401"
C1V1 is ON
C2V1 is ON
C3V1 is ON
C1V1 is OFF
C2V1 is OFF
C3V1 is OFF
Le principe donc serait d'associer un message à tous les pavés contenant un aiguillage en faisant comme ci dessus avec definirMessage(). si on ne modifie pas la méthode héritée emettreMessage() alors on aura celle par défaut et le pavé émettra toujours le même message à chaque fois qu'il est appuyé. si côté Arduino on sait traiter cette alternance (bascule) alors il n'y a rien de plus à faire.
ci joint le fichier ZIP avec toutes les modifications indiquées
PERSO_10_2_1.zip
Si on voulait envoyer un message particulier en fonction de la position de l'aiguillage alors il faudrait pour chaque classe qui représente des aiguilles rajouter une méthode emettreMessage() qui va faire un peu ce que j'ai fait avec les couleurs, regarder si mon état à changé et décider quel message envoyer à l'arduino dans ce cas.
Tel que c'est codé un pavé contient une liste de formes et la fonction manœuvrer() réordonne les formes et certains pavés spécifiques par exemple PaveAiguilleTriple vont avoir le propre méthode manoeuvrer(). il n'y a pas de façon simple (comme je l'ai fait avec mes couleurs) de savoir dans quel état on est. Une option serait de rajouter aux pavés une variable d'instance de type entier qui représente l'état dans lequel on est et dans la fonction manoeuvrer() si on n'a que deux états on alterne entre 0 et 1 mais si on est dans une aiguilles triple alors on alternera entre 0,1,2 par exemple. cet état serait alors utilisé pour émettre le bon message, un peu comme je l'ai fait avec la couleur.
Partager