Modifications

Sauter à la navigation Sauter à la recherche
7 338 octets ajoutés ,  15 avril 2013 à 20:17
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}}
29 836

modifications

Menu de navigation