Modifications

Sauter à la navigation Sauter à la recherche
7 530 octets ajoutés ,  10 août 2013 à 17:23
Page créée avec « {{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... »
{{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 SlaveRegisterDataTypes ==

Le fonctionnement du programme Arduino est identique à celui de l'exemple du Registre dont vous trouverez [[ArduPi-I2C-Registre-CodeArduino|les détails du fonctionnement ici]].

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 MasterWriterDataTypes.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 demandes envoyées par Raspberry Pi
// Le but étant de tester la transmission de type de données entre
// Arduino et Raspberry.
// S'utilise avec le programme Arduino MasterWriterDataTypes.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 - Retourne un Float avec la valeur 5.67
// Commande 0x03 -
// registre 0x01: opérant 1 - non utilisé dans cet exemple
// registre 0x02: opérant 2 - non utilisé dans cet exemple
//
// 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 );
digitalWrite( 13, HIGH );
}

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 de valeur Float (rien à faire, l'operation et retour de donnée est exécuté à la demande de réponse)
break;
/* Issu d'un autre exemple

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 outil décomposant un double en array de Bytes
// et envoyant les données sur le bus I2C
//
// Basé sur le code obtenu ici:
// http://stackoverflow.com/questions/12664826/sending-float-type-data-from-arduino-to-python
void Wire_SendDouble( double* d){

// Permet de partager deux types distinct sur un meme espace
// memoire
union Sharedblock
{
byte part[4]; // utiliser char parts[4] pour port série
double data;

} mon_block;

mon_block.data = *d;

/*
pour...
mon_block.data = 5.67
le tableau part[x] vaut...
mon_block.part[0] = 164;
mon_block.part[1] = 112;
mon_block.part[2] = 181;
mon_block.part[3] = 64;

Ce sont les valeurs que l'on doit retrouver de l'autre cote du BUS I2C
*/

Wire.write( mon_block.part, 4 );
}

double valeurDouble;

// 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( 0x11 );
break;

case 0x02: // Retourne un Float
valeurDouble = 5.67;
// essayer aussi avec
// valeurDouble = 128.1245;

// Décompose la valeur en Bytes et l'envoi sur I2C
Wire_SendDouble( &valeurDouble );
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}}
29 918

modifications

Menu de navigation