Ligne 1 : |
Ligne 1 : |
| {{ArduPi-I2C-NAV}} | | {{ArduPi-I2C-NAV}} |
| | | |
| + | == Arduino == |
| | | |
| + | {{bloc-etroit | text = Voici ensuite le programme Arduino. |
| + | |
| + | Cette fois-ci, il est sensiblement plus compliqué car il implémente un système de registre de façon logiciel. |
| + | |
| + | Comme déjà précisé, c'est un <strong>Slave Listener</strong> (esclave qui écoute). Il reçoit des informations en provenance du Raspberry-Pi sur le bus I2C.}} |
| + | |
| + | == Programme SlaveRegister == |
| + | |
| + | Le programme Arduino fonctionne comme suit: |
| + | # Il reçoit un avis de transmission d'instruction par l'intermédiaire de l'évènement '''receiveEvent'''<br />(lorsque le maître "Raspberry" envoi des données). |
| + | ## Il s'agit d'instructions permettant de stocker une valeur dans un des registres. |
| + | ## De surcroît le stockage dans le registre 0x00 déclenche l'exécution de tâches<br />particulières (par exemple l'activation de la LED). |
| + | ## Finalement, on mémorisé également le premier octet dans la variable regIndex<br />ce premier octet c'est N° du registre ;-) |
| + | # Les demandes de lecture de registres est composé de deux évènements distinct: |
| + | ## La réception d'une instruction via '''receiveEvent''' réduite à un seul octet<br />qui est le numéro de registre à lire.<br />Ce numéro sera stocké dans la variable regIndex ('''voir ci-dessus'''). |
| + | ## La demande de lecture d'octet par le maître est intercepté par<br />l'évènement '''requestEvent''' qui renverra l'information demandée. |
| + | ## Il va de soit que le maître (Raspberry Pi) doit demander le bon nombre d'octets. |
| + | |
| + | N'oubliez pas d'ouvrir le moniteur série d'Arduino, car une communication série est initialisée pour permettre l'affichage de quelques informations utiles. |
| + | |
| + | {{ambox-stop|text=Avant de démarrer le programme MasterRegisterWriter.py sur votre Raspberry, assurez-vous de voir le message "Bus I2C pret" apparaitre sur le moniteur série d'Arduino IDE.}} |
| + | |
| + | <nowiki>// === ArduPi-I2C ================================================ |
| + | // Communication entre Arduino et Raspberry Pi via le BUS I2C |
| + | // =============================================================== |
| + | // Tutoriel: http://mchobby.be/wiki/index.php?title=ArduPi-I2C |
| + | // |
| + | // Programme Esclave qui Recoit les données données envoyées par Raspberry Pi |
| + | // S'utilise avec le programme Arduino MasterRegisterWriter.py |
| + | // |
| + | // Ce programme attend des instructions dans le registre de commande |
| + | // registre 0x00: registre d'exécution (commande a exécuter) |
| + | // commande 0x00 - nop |
| + | // Commande 0x01 - demande de numero de version (retourne un byte) |
| + | // Commande 0x02 - Addition. Additionne les valeurs du registre 0x01 et 0x02 |
| + | // retourne un byte. |
| + | // Commande 0x03 - Allume/eteind led Pin 13 en fonction de la valeur du registre 0x01 (1 ou 0) |
| + | // registre 0x01: opérant 1 pour addition POUR instruction exec = 0x02 |
| + | // Status Pin 13 (allumé/éteind) POUR instruction exe = 0x03 |
| + | // registre 0x02: opérant 2 pour addition |
| + | // |
| + | // Ecrit par D. Meurisse pour MCHobby.be |
| + | // www.mchobby.be - Vente de kit et composant Arduino et Raspberry Pi |
| + | // Licence CC-BY-SA |
| + | // |
| + | // Basé sur l'exemple de Nicholas Zambetti <http://www.zambetti.com> |
| + | // |
| + | #include <Wire.h> |
| + | |
| + | // déclaration des registres |
| + | byte regs[3]; |
| + | int regIndex = 0; // Registre à lire ou à écrire. |
| + | |
| + | // copie de la dernière instruction d execution écrite dans |
| + | // le registre reg0 pour le traitement asynchrone de |
| + | // requestEvent (demande de bytes) |
| + | byte lastExecReq = 0x00; |
| + | |
| + | void setup() |
| + | { |
| + | // Initialisation des registres |
| + | regs[0] = 0x00; // reg0 = registre d'exécution |
| + | // valeur 0x00 = NOP - No Operation = rien à faire |
| + | regs[1] = 0x00; |
| + | regs[2] = 0x00; |
| + | |
| + | // Joindre le Bus I2C avec adresse #4 |
| + | Wire.begin(4); |
| + | // enregistrer l'événement |
| + | // Lorsque des données sont écrites par le maitre et reçue par l'esclave |
| + | Wire.onReceive(receiveEvent); |
| + | // enregistrer l'événement |
| + | // Lorsque le Maitre demande de lecture de bytes |
| + | Wire.onRequest(requestEvent); |
| + | |
| + | // Démarrer une communication série |
| + | Serial.begin(19200); |
| + | Serial.println( F("Bus I2C pret") ); |
| + | |
| + | // Definir la broche 13 en sortie |
| + | pinMode( 13, OUTPUT ); |
| + | } |
| + | |
| + | void loop() |
| + | { |
| + | // Si NOP alors rien à faire |
| + | if( regs[0] == 0x00 ) { |
| + | delay(100); |
| + | return; |
| + | } |
| + | |
| + | // Exécution de l'opération |
| + | /* Serial.println( F("--- Traitement Requete ---") ); |
| + | Serial.print( F("reg0 = ") ); |
| + | Serial.println( regs[0], DEC ); |
| + | Serial.print( F("reg1 = ") ); |
| + | Serial.println( regs[1], DEC ); |
| + | Serial.print( F("reg2 = ") ); |
| + | Serial.println( regs[2], DEC ); |
| + | */ |
| + | |
| + | switch( regs[0] ){ |
| + | case 0x01 : // demande de version (rien à faire) |
| + | break; |
| + | case 0x02 : // demande d'addition (rien à faire, l'addition est exécutée à la demande de réponse) |
| + | break; |
| + | case 0x03 : // Activer/désactiver Pin 13 en fct de la valeur du registre 0x01 |
| + | if( regs[1] > 0 ) |
| + | digitalWrite( 13, HIGH ); |
| + | else |
| + | digitalWrite( 13, LOW ); |
| + | break; |
| + | } |
| + | |
| + | // reset to NOP |
| + | regs[0] = 0x00; |
| + | } |
| + | |
| + | // Fonction qui est exécutée lorsque des données sont envoyées par le Maître. |
| + | // Cette fonction est enregistrée comme une événement ("event" en anglais), voir la fonction setup() |
| + | void receiveEvent(int howMany) |
| + | { |
| + | int byteCounter = 0; |
| + | |
| + | // Pour faire du debug... mais attention cela peut planter |
| + | // la réception! |
| + | // |
| + | //Serial.println(F("---- LECTURE ---")); |
| + | //Serial.print(F("Numbre de Bytes: ")); |
| + | //Serial.println( howMany ); |
| + | |
| + | // Lire tous les octets sauf le dernier |
| + | while( byteCounter < howMany ) |
| + | { |
| + | // lecture de l'octet |
| + | byte b = Wire.read(); |
| + | byteCounter += 1; |
| + | |
| + | //Serial.println( b, DEC ); |
| + | |
| + | if( byteCounter == 1 ){ // Byte #1 = Numéro de registre |
| + | regIndex = b; |
| + | } |
| + | else { // Byte #2 = Valeur a stocker dans le registre |
| + | switch(regIndex) { |
| + | case 0: |
| + | regs[0] = b; |
| + | // maintenir une copie du dernier reg0 pour |
| + | // traitement d'une réponse via requestEvent (demande de byte) |
| + | lastExecReq = b; |
| + | break; |
| + | case 1: |
| + | regs[1] = b; |
| + | break; |
| + | case 2: |
| + | regs[2] = b; |
| + | break; |
| + | } |
| + | } |
| + | |
| + | |
| + | } // fin WHILE |
| + | } |
| + | |
| + | // Fonction est activé lorsque le Maitre fait une demande de lecture. |
| + | // |
| + | void requestEvent() |
| + | { |
| + | // Deboggage - Activer les lignes suivantes peut perturber fortement |
| + | // l'échange I2C... a utiliser avec circonspection. |
| + | // |
| + | // Serial.print( "Lecture registre: " ); |
| + | // Serial.println( regIndex ); |
| + | |
| + | // Quel registre est-il lu??? |
| + | switch( regIndex ){ |
| + | |
| + | case 0x00: // lecture registre 0 |
| + | // la réponse depend de la dernière opération d'exécution demandée |
| + | // par l'intermédiaire du registre d'exécution (reg 0x00). |
| + | switch( lastExecReq ) { |
| + | case 0x01: // demande de version |
| + | // current version = v3 |
| + | Wire.write( 0x03 ); |
| + | break; |
| + | |
| + | case 0x02: // Addition reg1 + reg2 |
| + | Wire.write( regs[1]+regs[2] ); |
| + | break; |
| + | |
| + | default: |
| + | Wire.write( 0xFF ); // ecrire 255 = il y a un problème! |
| + | } |
| + | break; |
| + | |
| + | default: // lecture autre registre |
| + | Wire.write( 0xFF ); // ecrire 255 = il y a un problème |
| + | } |
| + | |
| + | }</nowiki> |
| | | |
| {{ArduPi-I2C-TRAILER}} | | {{ArduPi-I2C-TRAILER}} |