ArduPi-I2C-Registre-CodeArduino

De MCHobby - Wiki
Aller à : navigation, rechercher

MCHobby investit du temps et de l'argent dans la réalisation de traduction et/ou documentation. C'est un travail long et fastidieux réalisé dans l'esprit Open-Source... donc gratuit et librement accessible.
SI vous aimez nos traductions et documentations ALORS aidez nous à en produire plus en achetant vos produits chez MCHobby.

Arduino

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 Slave Listener (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:

  1. Il reçoit un avis de transmission d'instruction par l'intermédiaire de l'évènement receiveEvent
    (lorsque le maître "Raspberry" envoi des données).
    1. Il s'agit d'instructions permettant de stocker une valeur dans un des registres.
    2. De surcroît le stockage dans le registre 0x00 déclenche l'exécution de tâches
      particulières (par exemple l'activation de la LED).
    3. Finalement, on mémorisé également le premier octet dans la variable regIndex
      ce premier octet c'est N° du registre ;-)
  2. Les demandes de lecture de registres est composé de deux évènements distinct:
    1. La réception d'une instruction via receiveEvent réduite à un seul octet
      qui est le numéro de registre à lire.
      Ce numéro sera stocké dans la variable regIndex (voir ci-dessus).
    2. La demande de lecture d'octet par le maître est intercepté par
      l'évènement requestEvent qui renverra l'information demandée.
    3. 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.

 // === 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
  }  
  
}

Ecrit par Meurisse D. pour mchobby.be

Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : «  Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.

L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.