Arduino - Snootlab I2C Pwm Driver

Toutes les discussions sur l'Arduino !

Modérateur : MOD

Répondre
Avatar du membre
Barbadidoua
Bavard
Messages : 61
Enregistré le : lun. 31 juil. 2006, 19:11
Club : AMFBC73
Site Internet : http://fadiese.hd.free.fr/cms/
Localisation : Chambery

Arduino - Snootlab I2C Pwm Driver

Message par Barbadidoua » mer. 07 mai 2014, 15:57

Bonjour,

Lors de la rénovation de la maquette du train a crémaillère Aix-les_Bains / Le Revard ( Video), j'ai mis en place un bus I2C permettant de placer dans chaque module (il y en a 5) et un dans le pupitre de commande un module Snootlab I2C Pwm Driver. Un Arduino Uno Rev3 est placé au milieu du Bus I2C, avec les alimentations nécessaires (+5V et +3,3V) qui transitent sur le Bus.

Je vous propose de trouver ici le programme correspondant (Pas d'utilisation de l'instruction Delay !):

Code : Tout sélectionner

/* =============================================================
Description : Programme d'animation de la maquette de la cremaillère du Revard
              avec des cartes "I2C PWM Driver"
              pour Arduino équipé du shield maison "Signal_I2C_V2"
2014/04/10  X.Bouillard  Module Pre Japert pour Exposition Chamnord
______________________________________________________________
Cahier des charges:
              Phases: enchainement de 100 cycles de durée 1s, pouvant passer à une étape 
              - Attente             (Phase 0)
              - Arrivée d'un train  (Phase (Module -1)*2 +1)
              - Départ d'un train   (Phase (Module -1)*2 +2)
              - Balayage            (Phase 11)
              Le démarrage d'une phase est effectué suite à:
              - La reception d'une commande USB ou l'appui d'un bouton
              - Automatiquement en fin de phase d'attente
_______________________________________________________________
Sur le shield, on dispose de:
- 1 départ bus I2C
    - SCL
    - SDA
    - +5V
    - +3V3
    - GND
- 8 boutons connectés sur l'entrée A0
- 3 commandes pour servo moteurs
    - Brun:  GND
    - Rouge: +5V
    - Jaune: Cmd
- 1 recepteur IR compatible RC5/RC6    
________________________________________________________________
Numérotation des sorties de la carte "I2C PWM Driver" :
et les registres de programmation correspondants (pour chaque colonne):
            ----------------------------        -----------------------
      N°:  19     17    15    13    11    09    07    05    03    01     
      N°:  20     18    16    14    12    10    08    06    04    02
registre:        0x13  0x12  0x11  0x10        0x17  0x16  0x15  0x14

les broches 9 et 19 sont à la masse (0V)
les broches 10 et 20 délivrent + 5V

Après réglage du Setup (voir "void Setup" ci-dessous),
Une commande en sortie d'intensité variable sur une des broches (1 à 8, 11 à 18)
se programme avec le code :

Wire.beginTransmission(address);
   Wire.send( reg);
   Wire.send( data);
Wire.endTransmission();

où "reg" est l'adresse en hexa du registre (colonne dans le tableau ci-dessus) ,
par exemple "0x11" si on veut commander la sortie 13
et où "data" indique avec deux chiffres en hexa, l'intensité que l'on veut délivrer sur chacune des deux broches du registre (0 pour le maxi à f pour le minimum),
la place de ces deux chiffres correspond aux numéros de broches croissants de droite à gauche.
par exemple : un data "0xf0" commandé sur le registre "0x11" donnera l'intensité maxi sur la broche 13 et l'intensité mini sur la broche 14.
         ou : un data "0x0f" commandé sur le registre "0x11" donnera l'intensité mini sur la broche 13 et l'intensité maxi sur la broche 14.
         
Ces modules permettent de:
- Piloter des Leds en PWM (16 pas)
Il devrait être possible de (a verifier)
- Piloter des Servomoteurs en PWM (16 pas)
- Tester des boutons en tout ou rien
________________________________________________________________
*/


// ========================================================
#include <Servo.h>             // bibliotheque de gestion des servomoteurs 
#include <Wire.h>              // bibliotheque de gestion I2C

// ========================================================
// Definition des servomoteurs
#define Servo_WCRevard 10      // Servo Porte WC Le Revard  
Servo WCRevard;                // creation d'un objet pour controller un servo
#define Servo_BalayeusePreJapert 11  // Servo balayeuse Pre Japert  
Servo BalayeusePreJapert;      // creation d'un objet pour controller un servo

// ========================================================
// Definition des modules "I2C PWM Driver"
// L'adresse de chaque "I2C PWM Driver" est choisie en plaçant les 3 ponts de soudure sur la carte.
// void SendToMax(byte address, byte reg, byte data);
byte M0_Address = 0x10;        // Adresse I2C pour Pupitre.
byte M1_Address = 0x11;        // Adresse I2C pour Aix les bains.
byte M2_Address = 0x12;        // Adresse I2C pour Mouxy
byte M3_Address = 0x13;        // Adresse I2C pour Pugny Chatenod
byte M4_Address = 0x10;        // Adresse I2C pour Pre Japert.
byte M5_Address = 0x14;        // Adresse I2C pour Le Ravard
int  intensity = 0xff;         //

// ========================================================
// Gestion de la communication PC via USB
String inputString = "";        // Chaine permettatnt de recevoir les informations du PC via USB
boolean stringComplete = false; // Drapeau indiquant que la chaine recue est complete (finit par CR)

#define  led 13

// ========================================================
// Gestion des boutons du shield par interruption
const byte NON_PRESSE = 0;
const byte ENFONCE = 1;
const byte PRESSE = 2;

byte etatAutomate = NON_PRESSE;
int  etatPoussoir = -1;
int  btn;

const byte AUCUN_EVENEMENT = 0;
const byte EVENEMENT_PRESSE = 1;
const byte EVENEMENT_RELACHE = 2;

const int pinPoussoirs = 0;

// ========================================================
// Parametrage de la boucle principale
long previousMillis = 0;        // Enregistre le top chrono de la dernière mise a jour
long interval = 1000;           // Durée du cycle (en milliseconds)
int  phases[6];                 // Phase de chaque module
int  cpt[6];                    // Compteur de cycle dans une étape
int  EnCours[6];                // Permet de bloquer le démarrage d'une nouvelle phase temps que la précédente n'est pas achevée. 
int  Etat[6];                   // Etat gare module. 
#define  MaxCpt 59              // Nombre de cycle maximum
//int  phase=0;                   // Phase (par défaut Attente)
//int  PhaseEnCours =0;           // Permet de bloquer le démarrage d'une nouvelle phase temps que la précédente n'est pas achevée. 

// ========================================================
// Definition des messages
#define  Msg_Patience           "Patientez S.V.P."
#define  Msg_Depart_M_Aix       "Depart Montant Aix :"
#define  Msg_Depart_M_Mouxy     "Depart Montant Mouxy :"
#define  Msg_Depart_M_Pugny     "Depart Montant Pugny :"
#define  Msg_Depart_M_Japert    "Depart Montant Pre Japert :"
#define  Msg_Depart_D_Revard    "Depart Descendant Le Revard :"
#define  Msg_Depart_D_Japert    "Depart Descendant Pre Japert :"
#define  Msg_Depart_D_Pugny     "Depart Descendant Pugny :"
#define  Msg_Clean              "Balayage :"
#define  Msg_Recu_USB           "Recu :"
#define  Msg_Bouton_Down        "Presse : "
#define  Msg_Bouton_Up          "Relache : "

// ========================================================
// initialisation
// ========================================================
void setup() {
  BalayeusePreJapert.attach(Servo_BalayeusePreJapert);  // attache les servos à l'objet servo 
  BalayeusePreJapert.write(0);
  WCRevard.attach(Servo_WCRevard);  // attache les servos à l'objet servo 
  WCRevard.write(0);
  pinMode(led, OUTPUT);
  Wire.begin();              // join i2c bus (address optional for master)
  Serial.begin(9600);        // initialise la communication USB:
  Serial.println(Msg_Patience);
  inputString.reserve(200);  // reserve 200 bytes pour la chaine en reception USB:
  // configuration des modules "I2C PWM Driver"
  InitI2CPWM(M1_Address);
  InitI2CPWM(M2_Address);
  InitI2CPWM(M3_Address);
  InitI2CPWM(M4_Address);
  InitI2CPWM(M5_Address);
  // initialisations des modules
  for (int i = 0; i <6; i++)  {
    phases[i]=0;
    cpt[i]=0;
    EnCours[i]=0;
    Etat[i]=0;
  } 
//  phase=0;
//  // Intiialize Timer interrupt.
//  TCCR2B = 0b00000010;
//  TIMSK2 = 0b00000001;
//  sei();  // Interrupt enable
}

//// Gestion interruption
//ISR(TIMER2_OVF_vect) {
//  volatile byte cntpf;
//  TCNT2=62;         // Basic loop 100ms
//  if (cntpf++>50) { // Restrict to 5 ms =50*100 
//    cntpf=0;
//      Serial.print("cntpf:");
//      Serial.println(cntpf);
//  }
//  // Increment Cnt every loop
////  if (cpt++>100) {
////    cpt=0;
//////    Balai();
////  }
//}

// ========================================================
// lecture des boutons poussoirs
// ========================================================
int lirePoussoirs() {
    int resultat;
    int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;
    
    int nouvelEtatPoussoir = etatPoussoir; /* à priori rien ne change */

    switch (etatAutomate) {
        case NON_PRESSE:
            if (numPoussoir < 8 )
                etatAutomate = ENFONCE;
            break;
        case ENFONCE:
            if (numPoussoir < 8 ) {
                etatAutomate = PRESSE;
                nouvelEtatPoussoir = numPoussoir;
            } else {
                etatAutomate = NON_PRESSE;
            }
            break;
        case PRESSE:
            if (numPoussoir == 8 ) {
                etatAutomate = NON_PRESSE;
                nouvelEtatPoussoir = -1;
            }
            break;
    }
    
    return nouvelEtatPoussoir;
}

// ========================================================
// Construction d'un événement en comparant
// le nouvel état des poussoirs avec l'état précédent.
// ========================================================
byte lireEvenement(int *numPoussoir) {
    byte evenement;
    int nouvelEtatPoussoir = lirePoussoirs();
    
    if (nouvelEtatPoussoir == etatPoussoir)
        evenement = AUCUN_EVENEMENT;
    if (nouvelEtatPoussoir >= 0 && etatPoussoir == -1)
        evenement = EVENEMENT_PRESSE;
    if (nouvelEtatPoussoir == -1 && etatPoussoir >= 0)
        evenement = EVENEMENT_RELACHE;

    etatPoussoir = nouvelEtatPoussoir;
    *numPoussoir = etatPoussoir;
    
    return evenement;
}

// ========================================================
// Lecture USB Serial event reader
// ========================================================
void serialEvent() {
  while (Serial.available()) {
    // acquisition d'un nouveau caratere:
    char inChar = (char)Serial.read(); 
    // si c'est LF, positionne le drapeau pour que la boucle principale prenne en compte le message:
    if (inChar == '\n') {
      stringComplete = true;
    } else {
    // sinon l'ajouter au message en cours de construction:
      inputString += inChar;
    }
  }
}


// ========================================================
// Initialisation d'un "I2C PWM Driver" tout en sortie
// ========================================================
void InitI2CPWM(byte M_Address) {
  SendToMax(M_Address, 0x0f, 0x10); // blink disable, gl int. dis.
  SendToMax(M_Address, 0x06, 0x00); // config P7-P0 out
//  SendToMax(M_Address, 0x06, 0xff); // config P7-P0 in  
  SendToMax(M_Address, 0x07, 0x00); // config P15-P8 out
  SendToMax(M_Address, 0x02, 0xff); // global intensity reg.
  SendToMax(M_Address, 0x03, 0xff);
  SendToMax(M_Address, 0x0e, 0xff); // config bit
}

// ========================================================
//  Definition des étapes
// ========================================================
void Etape(int module, int etape){
    switch (module) {
      case 1: // Aix
        switch (etape) {
          case 0: // 000000
            SendToMax(M1_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M1_Address, 0x16, 0xff);  // Off Off 1er Gauche 6 Perron Droit 5
            SendToMax(M1_Address, 0x17, 0xff);  // Off Off 1er Milieu 7 1er Droit 8
            break;
          case 1: // 000000
            break;
          case 2: // 000000
            break;
          case 3: // 000000
            break;
          case 4: // 000000
            break;
          case 5: // 000000
            break;
          case 6: // 000000
            break;
          case 7: // 000000
            break;
        }   
        break;
      case 2: // Mouxy
        switch (etape) {
          case 0: // 000000
            SendToMax(M2_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M2_Address, 0x16, 0xff);  // Off Off 1er Gauche 6 Perron Droit 5
            SendToMax(M2_Address, 0x17, 0xff);  // Off Off 1er Milieu 7 1er Droit 8
            break;
          case 1: // 000000
            break;
          case 2: // 000000
            break;
          case 3: // 000000
            break;
          case 4: // 000000
            break;
          case 5: // 000000
            break;
          case 6: // 000000
            break;
          case 7: // 000000
            break;
        }   
        break;
      case 3: // Pugny
        switch (etape) {
          case 0: // 000000
            SendToMax(M3_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M3_Address, 0x16, 0xff);  // Off Off 1er Gauche 6 Perron Droit 5
            SendToMax(M3_Address, 0x17, 0xff);  // Off Off 1er Milieu 7 1er Droit 8
            break;
          case 1: // 000000
            break;
          case 2: // 000000
            break;
          case 3: // 000000
            break;
          case 4: // 000000
            break;
          case 5: // 000000
            break;
          case 6: // 000000
            break;
          case 7: // 000000
            break;
        }   
        break;
      case 4: // Pre Japert
        switch (etape) {
          case 0: // 000000
            SendToMax(M4_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M4_Address, 0x16, 0xff);  // Off Off 1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0xff);  // Off Off 1er Milieu 7 1er Droit 8
           break;
          case 1: // 100000
            SendToMax(M4_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M4_Address, 0x16, 0x0f);  // On  Off 1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0xff);  // Off Off 1er Milieu 7 1er Droit 8
            break;
          case 2: // 110000
            SendToMax(M4_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M4_Address, 0x16, 0x0f);  // On  Off 1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0xf0);  // On  Off 1er Milieu 7 1er Droit 8
            break;
          case 3: // 010000
            SendToMax(M4_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M4_Address, 0x16, 0xff);  // Off Off 1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0xf0);  // On  Off 1er Milieu 7 1er Droit 8
            break;
          case 4: // 011000
            SendToMax(M4_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M4_Address, 0x16, 0xff);  // Off Off 1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0x00);  // On  On  1er Milieu 7 1er Droit 8
            break;
          case 5: // 001000
            SendToMax(M4_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M4_Address, 0x16, 0xff);  // Off Off 1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0x0f);  // Off On  1er Milieu 7 1er Droit 8 
            break;
          case 6: // 001111
            SendToMax(M4_Address, 0x15, 0x99);  // On  On Perron Milieu 3 et Gauche 4
            SendToMax(M4_Address, 0x16, 0xf9);  // Off On  1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0x0f);  // Off On  1er Milieu 7 1er Droit 8
            break;
          case 7: // 000111
            SendToMax(M4_Address, 0x15, 0x99);  // On  On  Perron Milieu 3 et Gauche 4
            SendToMax(M4_Address, 0x16, 0xf9);  // Off On  1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0xff);  // Off Off 1er Milieu 7 1er Droit 8
            break;
          case 8: // 000111
            SendToMax(M4_Address, 0x15, 0xAB);  // On  On  Perron Milieu 3 et Gauche 4
            SendToMax(M4_Address, 0x16, 0xfC);  // Off On  1er Gauche 6 Perron Droit 5
            SendToMax(M4_Address, 0x17, 0xff);  // Off Off 1er Milieu 7 1er Droit 8
            break;
        }
        break;
      case 5: // Le Revard
        switch (etape) {
          case 0: // 000000
            SendToMax(M5_Address, 0x15, 0xff);  // Off Off Perron Milieu 3 et Gauche 4 
            SendToMax(M5_Address, 0x16, 0xff);  // Off Off 1er Gauche 6 Perron Droit 5
            SendToMax(M5_Address, 0x17, 0xff);  // Off Off 1er Milieu 7 1er Droit 8
            break;
          case 1: // 000000
            break;
          case 2: // 000000
            break;
          case 3: // 000000
            break;
          case 4: // 000000
            break;
          case 5: // 000000
            break;
          case 6: // 000000
            break;
          case 7: // 000000
            break;
        }   
        break;
    }    

}  
// ========================================================
// Gestion de la balayeuse 
// ========================================================
void Mvt(Servo ServoMoteur,int coups,int angle_Arrive,int vitesse){
  for (int j = 0; j < coups; j++)  {
    for (int i = angle_Arrive; i >= 0; i--)  {
      ServoMoteur.write(i);
      delay(vitesse);
    } 
  }
}

// ========================================================
// Fonction pour commander une sortie sur les deux broches d'un registre
// ========================================================
void SendToMax(byte address, byte reg, byte data){   
  Wire.beginTransmission(address);
  Wire.write( reg);
  Wire.write( data);
  Wire.endTransmission();
}

// ========================================================
// Fonction pour lire une entree sur un registre
// ========================================================
char ReadMax(byte address, byte reg){
  Wire.beginTransmission(address);
  Wire.write( reg);
  //Wire.write( data);
  if(2 <= Wire.available()) {
    char c = Wire.read(); // receive a byte as character
    //Serial.print(c);         // print the character
  }
  Wire.endTransmission();
}

// ========================================================
// fonction pour éteindre toutes les sorties
// ========================================================
void toutEteindre(byte M_Address) {                               
   SendToMax(M_Address, 0x10, 0xff);
   SendToMax(M_Address, 0x11, 0xff);
   SendToMax(M_Address, 0x12, 0xff);
   SendToMax(M_Address, 0x13, 0xff);
   SendToMax(M_Address, 0x14, 0xff);
   SendToMax(M_Address, 0x15, 0xff);
   SendToMax(M_Address, 0x16, 0xff);
   SendToMax(M_Address, 0x17, 0xff);
   digitalWrite(led, HIGH);
}

// ========================================================
// Boucle principale du programme : 
// clignotement successif des sorties
/*
Si reception d'une commande USB
- Affichage USB de l'interpretation de la commande
- Passage à l'étape demandée
Si un bouton a changé d'état
- Affichage USB de l'interpretation du bouton
- Initialisation du cycle de la phase demandée
Gestion de l'évolution du cycle par increment du compteur cpt
*/
// ========================================================
void loop() {
  int numPoussoir;
  byte evenement = lireEvenement(&numPoussoir);

// Gestion des info USB : 1(Aix)/2(Mouxy)/3(Pugny)/4(PreJapert)/5(Le Revard) 1(Montant)/2(Descendant) 
  if (stringComplete) {
    inputString.toUpperCase();
    Serial.print(Msg_Recu_USB);
    Serial.println(inputString);
    Serial.print(inputString.substring(0,1).toInt());
    switch(inputString.substring(0,1).toInt()) {
      case 1:
        Serial.println(Msg_Depart_M_Aix);
        phases[1]=2;
        cpt[1]=0;
        EnCours[1]=0;            
        phases[2]=1;
        cpt[2]=0;
        EnCours[2]=1;            
        break;
      case 2:
        phases[2]=2;
        cpt[2]=0;
        EnCours[2]=0;            
        switch(inputString.substring(2,3).toInt()) {
          case 1:
            Serial.println(Msg_Depart_M_Mouxy);
            phases[3]=1;
            cpt[3]=0;
            EnCours[3]=1;                    
            break;
//          case 2:
//            Serial.println(Msg_Depart_D_Mouxy);
//            phases[1]=1;
//            cpt[1]=0;
//            EnCours[1]=1;                    
//            break;
        }    
        break;
      case 3:
        phases[3]=2;
        cpt[3]=0;
        EnCours[3]=0;                    
        switch(inputString.substring(2,3).toInt()) {
          case 1:
            Serial.println(Msg_Depart_M_Pugny);
            phases[4]=1;
            cpt[4]=0;
            EnCours[4]=1;                    
            break;
          case 2:
            Serial.println(Msg_Depart_D_Pugny);
            phases[2]=1;
            cpt[2]=0;
            EnCours[2]=1;                    
            break;
        }    
        break;
      case 4:
        phases[4]=2;
        cpt[4]=0;
        EnCours[4]=0;                    
        switch(inputString.substring(2,3).toInt()) {
          case 1:
            Serial.println(Msg_Depart_M_Japert);
            phases[5]=1;
            cpt[5]=0;
            EnCours[5]=1;                    
            break;
          case 2:
            Serial.println(Msg_Depart_D_Japert);
            phases[3]=1;
            cpt[3]=0;
            EnCours[3]=1;                    
            break;
        }    
        break;
      case 5:
        Serial.println(Msg_Depart_D_Revard);
        phases[5]=2;
        cpt[5]=0;
        EnCours[5]=0;                    
        phases[4]=1;
        cpt[4]=0;
        EnCours[4]=1;                    
        break;
    }
    // re-initialize la chaine recue:
    inputString = "";
    stringComplete = false;
  }

//  if (stringComplete) {
//    inputString.toUpperCase();
//    Serial.print(Msg_Recu_USB);
//    Serial.println(inputString);
//    Serial.print(inputString.substring(0,1).toInt());
//    Serial.print(" ");
//    Serial.print(inputString.substring(1,2).toInt());
//    Serial.print(" ");
//    Serial.println(inputString.substring(2,3).toInt());
//    Etape(4,inputString.substring(0,1).toInt());
//    // re-initialize la chaine recue:
//    inputString = "";
//    stringComplete = false;
//  }

// Gestion des bouton shield
  switch (evenement) {
    case EVENEMENT_PRESSE:
      Serial.print(Msg_Bouton_Down);
      btn=numPoussoir;
      Serial.println(btn);
      switch (btn) {
        case 0: // depart Pugny
          Serial.println(Msg_Depart_M_Pugny);
          if (EnCours[4]!=1) {
            phases[4]=1;
            cpt[4]=0;
            EnCours[4]=1;                    
          }
          break;
        case 1: // depart Pugny
          Serial.println(Msg_Depart_M_Pugny);
          if (EnCours[4]!=1) {
            phases[4]=1;
            cpt[4]=0;
            EnCours[4]=1;                    
          }
          break;
        case 2: // depart Revard
          Serial.println(Msg_Depart_D_Revard);
          if (EnCours[4]!=1) {
            phases[4]=1;
            cpt[4]=0;
            EnCours[4]=1;                    
          }
          break;
        case 3: // depart Revard
          Serial.println(Msg_Depart_D_Revard);
          if (EnCours[4]!=1) {
            phases[4]=1;
            cpt[4]=0;
            EnCours[4]=1;                    
          }
          break;
        case 4: // depart Pre Japert
          Serial.println(Msg_Depart_M_Japert);
          phases[4]=2;
          cpt[4]=0;
          EnCours[4]=0;                    
          break;
        case 5: // depart Pre Japert
          Serial.println(Msg_Depart_M_Japert);
          phases[4]=2;
          cpt[4]=0;
          EnCours[4]=0;
          break;
        case 6: // Coups de balais
          Serial.println(Msg_Clean);
          phases[4]=3;
          cpt[4]=0;
          break;
        case 7: // Coups de balais
          Serial.println(Msg_Clean);
          phases[4]=3;
          cpt[4]=0;
          break;
      }
      break;
    case EVENEMENT_RELACHE:
      Serial.print(Msg_Bouton_Up);
      Serial.println(btn);
      break;
  }
 
// Gestion des cycles 
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   // Sauvegarde dernière mise a jour
    for (int j = 0; j < 6; j++)  {
      if (cpt[j]++>MaxCpt) {
        cpt[j]=0;
      }
      CycleModule(j);
    }
    Serial.println("");
//    Serial.println("==============================");
  }
}

// ========================================================
// Gestion des changement d'étape par module
// ========================================================
void CycleModule(int module) {
  Serial.print("(M");
  Serial.print(module);  
  switch (module) {
    // ======================================================== 
    case 0: // Pupitre 
      Serial.print(" P");
      Serial.print(phases[module]);
      Serial.print(" C");
      Serial.print(cpt[module]);
      Serial.print(" E");
      Serial.print(Etat[module]);
      Serial.print(")");   
      break;  
    // ======================================================== 
    case 1: // Aix
      Serial.print(" P");
      Serial.print(phases[module]);
      Serial.print(" C");
      Serial.print(cpt[module]);
      switch (phases[module]) {
        case 0: // Attente. Apres 50 cycles sans rien faire, on va balayer!
          switch (cpt[module]) {
            case 50: 
              phases[module]=3;
              cpt[module]=0;
              break;  
          }
          break;  
        case 1: // Arrivée train a Aix
          switch (cpt[module]) {
            case 1: // Allumage de la chambre :   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 10: // Allumage de la SAM:       110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 11: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 30: // Allumage du quai:         001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 31: // Allumage du quai:         000111
              Etape(module,7);
              Serial.print(":000111");
              phases[module]=0;
              Etat[module]=1;
              break;
          }       
          break;       
        case 2: // Depart train de Aix
          switch (cpt[module]) {
            case 11: // Extinction du quai:       001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 12: // Extinction du quai:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 30: // Allumage de la chambre:   110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 31: // Allumage de la chambre:   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 40: // Extinction de la chambre: 000000
              Etape(module,0);
              Serial.print(":000000");
              phases[module]=0;
              Etat[module]=0;
              break;           
          }          
          break;       
        case 3:
          Etape(module,0);
          switch (cpt[module]) { //Balai(int coups,int angle,int vitesse)
            case 1: // 
              Serial.print(":A");
//              Mvt(PorteWCRevard,2,5,40);
//              Mvt(PorteWCRevard,2,50,10);
              break;
          }
          break;  
      }            
      Serial.print(" E");
      Serial.print(Etat[module]);
      Serial.print(")");   
      break;  
    // ======================================================== 
    case 2: // Mouxy
      Serial.print(" P");
      Serial.print(phases[module]);
      Serial.print(" C");
      Serial.print(cpt[module]);
      switch (phases[module]) {
        case 0: // Attente. Apres 50 cycles sans rien faire, on va balayer!
          switch (cpt[module]) {
            case 50: 
              phases[module]=3;
              cpt[module]=0;
              break;  
          }
          break;  
        case 1: // Arrivée train à Mouxy
          switch (cpt[module]) {
            case 1: // Allumage de la chambre :   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 10: // Allumage de la SAM:       110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 11: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 30: // Allumage du quai:         001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 31: // Allumage du quai:         000111
              Etape(module,7);
              Serial.print(":000111");
              phases[module]=0;
              Etat[module]=1;
              break;
          }       
          break;       
        case 2: // Depart train de Mouxy
          switch (cpt[module]) {
            case 11: // Extinction du quai:       001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 12: // Extinction du quai:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 30: // Allumage de la chambre:   110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 31: // Allumage de la chambre:   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 40: // Extinction de la chambre: 000000
              Etape(module,0);
              Serial.print(":000000");
              phases[module]=0;
              Etat[module]=0;
              break;           
          }          
          break;       
        case 3:
          Etape(module,0);
          switch (cpt[module]) { //Balai(int coups,int angle,int vitesse)
            case 1: // 
              Serial.print(":A");
//              Mvt(PorteWCRevard,2,5,40);
//              Mvt(PorteWCRevard,2,50,10);
              break;
          }
          break;
      }            
      Serial.print(" E");
      Serial.print(Etat[module]);
      Serial.print(")");   
      break;  
    // ======================================================== 
    case 3: // Pugny
      Serial.print(" P");
      Serial.print(phases[module]);
      Serial.print(" C");
      Serial.print(cpt[module]);
      switch (phases[module]) {
        case 0: // Attente. Apres 50 cycles sans rien faire, on va balayer!
          switch (cpt[module]) {
            case 50: 
              phases[module]=3;
              cpt[module]=0;
              break;  
          }
          break;
        case 1: // Arrivée train à Pugny
          switch (cpt[module]) {
            case 1: // Allumage de la chambre :   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 10: // Allumage de la SAM:       110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 11: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 30: // Allumage du quai:         001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 31: // Allumage du quai:         000111
              Etape(module,7);
              Serial.print(":000111");
              phases[module]=0;
              Etat[module]=1;
              break;
          }       
          break;       
        case 2: // Depart train de Pugny
          switch (cpt[module]) {
            case 11: // Extinction du quai:       001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 12: // Extinction du quai:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 30: // Allumage de la chambre:   110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 31: // Allumage de la chambre:   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 40: // Extinction de la chambre: 000000
              Etape(module,0);
              Serial.print(":000000");
              phases[module]=0;
              Etat[module]=0;
              break;           
          }          
          break;       
        case 3:
          Etape(module,0);
          switch (cpt[module]) { //Balai(int coups,int angle,int vitesse)
            case 1: // 
              Serial.print(":A");
//              Mvt(PorteWCRevard,2,5,40);
//              Mvt(PorteWCRevard,2,50,10);
              break;
          }
          break;      
      }            
      Serial.print(" E");
      Serial.print(Etat[module]);
      Serial.print(")");   
      break;  
    // ======================================================== 
    case 4: // Pre Japert
      Serial.print(" P");
      Serial.print(phases[module]);
      Serial.print(" C");
      Serial.print(cpt[module]);
      switch (phases[module]) {
        case 0: // Attente. Apres 50 cycles sans rien faire, on va balayer!
          switch (cpt[module]) {
            case 50: 
              phases[module]=3;
              cpt[module]=0;
              break;  
          }
          break;  
        case 1: // Arrivée train à Pre Japert
          switch (cpt[module]) {
            case 1: // Allumage de la chambre :   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 10: // Allumage de la SAM:       110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 11: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 30: // Allumage du quai:         001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 31: // Allumage du quai:         000111
              Etape(module,7);
              Serial.print(":000111");
              phases[module]=0;
              Etat[module]=1;
              break;
           }    
           break;
        case 2: // Depart train de Pre Japert
          switch (cpt[module]) {
            case 11: // Extinction du quai:       001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 12: // Extinction du quai:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 30: // Allumage de la chambre:   110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 31: // Allumage de la chambre:   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 40: // Extinction de la chambre: 000000
              Etape(module,0);
              Serial.print(":000000");
              phases[module]=0;
              Etat[module]=0;
              break;
          }    
          break;           
        case 3: // On balaie devant la porte de Pre Japert
          Etape(module,0);
          switch (cpt[module]) { //Balai(int coups,int angle,int vitesse)
            case 1: // 
              Serial.print(":A");
              Mvt(BalayeusePreJapert,2,5,40);
              Mvt(BalayeusePreJapert,2,50,10);
              break;
            case 6: // 
              Serial.print(":B");
              Mvt(BalayeusePreJapert,5,50,10);
              Mvt(BalayeusePreJapert,2,5,40);
              break;
            case 20: // 
              Serial.print(":C");
              Mvt(BalayeusePreJapert,2,5,40);
              Mvt(BalayeusePreJapert,3,25,10);
              break;
            case 30: // 
              Serial.print(":D");
              Mvt(BalayeusePreJapert,2,5,40);
              Mvt(BalayeusePreJapert,2,50,10);
              Mvt(BalayeusePreJapert,2,5,40);
              break;
            case 36: // 
              Serial.print(":E");
              Mvt(BalayeusePreJapert,2,5,40);
              Mvt(BalayeusePreJapert,5,50,10);
              break;
            case 40: // 
              Serial.print(":F");
              Mvt(BalayeusePreJapert,2,5,40);
              Mvt(BalayeusePreJapert,3,50,10);
              break;
            case 49: // 
              Serial.print(":G");
              Mvt(BalayeusePreJapert,10,10,40);
              break;
            case 50: // 
              Serial.print(":H");
              Mvt(BalayeusePreJapert,2,5,40);
              Mvt(BalayeusePreJapert,4,50,10);
              break;
            case 51: // 
              Serial.print(":J");
              Mvt(BalayeusePreJapert,2,5,40);
              Mvt(BalayeusePreJapert,3,50,10);
              break;
          }       
          break;       
        }    
      Serial.print(" E");
      Serial.print(Etat[module]);
        Serial.print(")");   
        break;  
    // ======================================================== 
    case 5: // Le Revard 
      Serial.print(" P");
      Serial.print(phases[module]);
      Serial.print(" C");
      Serial.print(cpt[module]);
      switch (phases[module]) {
        case 0: // Attente. Apres 50 cycles sans rien faire, on va balayer!
          switch (cpt[module]) {
            case 50: 
              phases[module]=3;
              cpt[module]=0;
              break;  
          }
          break;  
        case 1: // Arrivée train au Revard
          switch (cpt[module]) {
            case 1: // Allumage de la chambre :   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 10: // Allumage de la SAM:       110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 11: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 30: // Allumage du quai:         001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 31: // Allumage du quai:         000111
              Etape(module,7);
              Serial.print(":000111");
              phases[module]=0;
              Etat[module]=1;
              break;
          }       
          break;       
        case 2: // Depart train du Revard
          switch (cpt[module]) {
            case 11: // Extinction du quai:       001111
              Etape(module,6);
              Serial.print(":001111");
              break;
            case 12: // Extinction du quai:       001000
              Etape(module,5);
              Serial.print(":001000");
              break;
            case 20: // Allumage de la SAM:       011000
              Etape(module,4);
              Serial.print(":011000");
              break;
            case 21: // Allumage de la SAM:       010000
              Etape(module,3);
              Serial.print(":010000");
              break;
            case 30: // Allumage de la chambre:   110000
              Etape(module,2);
              Serial.print(":110000");
              break;
            case 31: // Allumage de la chambre:   100000
              Etape(module,1);
              Serial.print(":100000");
              break;
            case 40: // Extinction de la chambre: 000000
              Etape(module,0);
              Serial.print(":000000");
              phases[module]=0;
              Etat[module]=0;
              break;           
          }          
          break;       
        case 3:
          Etape(module,0);
          switch (cpt[module]) { //Balai(int coups,int angle,int vitesse)
            case 1: // 
              Serial.print(":A");
                digitalWrite(led, HIGH);
//              Mvt(PorteWCRevard,2,5,40);
//              Mvt(PorteWCRevard,2,50,10);
              break;
            case 30: // 
              Serial.print(":A");
                digitalWrite(led, LOW);
//              Mvt(PorteWCRevard,2,5,40);
//              Mvt(PorteWCRevard,2,50,10);
              break;
          }
          break;  
      }            
      Serial.print(" E");
      Serial.print(Etat[module]);
      Serial.print(")");   
      break;  
  }    
}
Un Shield spécifique a été développé pour les tests (Schéma et Typon TCI disponible sur demande), il est aussi possible d'utiliser le Shield Snootlab I2C Power Protoshield V2:
- Interface I2C avec le bus Snootlab
- 3 Servomoteurs
- 8 Boutons Poussoirs sur une entrée analogique
- Recepteur IR 36kHz (compatible RC6 non utilisé)

Pour le moment, et faute de temps (l'exposition vient de commencer!):
- Un seul module est fonctionnel: Pre-Japert (le programme est conçu pour intégrer simplement les suivants)
- Le servomoteur est directement connecté sur L'Arduino
- Les entrées sont directement connectées sur L'Arduino

Reste à tester sur ces modules I2C Pwm Driver:
- Entrées
- PWM pour les servomoteurs.

Un programme en VB.net 2010 permet un dialogue, et une sonorisation complémentaire. (La source est, bien entendu, disponible à la demande)

Xavier.
Modifié en dernier par Barbadidoua le mer. 07 mai 2014, 16:53, modifié 2 fois.
Ech N, DCC LokMaus 2, CDM-Rail

Avatar du membre
Steam
Passe-Partout
Messages : 1233
Enregistré le : lun. 23 oct. 2006, 00:15
Localisation : Là où l'on a préparé le record du monde

Re: Arduino - Snootlab I2C Pwm Driver

Message par Steam » mer. 07 mai 2014, 16:41

Juste une petite remarque qui n'a rien à voir avec l'Arduino et l'electronique.
Dans le premier lien, il faudrait changer sur votre page le nom du donateur. Il me semble que c'est François Fouger et non François Fauger, parce que si Môssssieur Pignon, alias Fouger François qui sévit sur ce forum lit cette page, il risque de ne pas être content.

Steam
Il y a pire que de ne jamais réussir, c'est de ne jamais essayer !

Avatar du membre
jlb
Fécond
Messages : 692
Enregistré le : jeu. 04 oct. 2012, 16:38
Echelle pratiquée : N
Prénom : Jean-Luc
Site Internet : http://modelleisenbahn.triskell.org

Re: Arduino - Snootlab I2C Pwm Driver

Message par jlb » mer. 07 mai 2014, 18:06

Bonjour,

Projet intéressant !

2 questions :

Quelle distance as-tu entre l'Arduino et chaque module Snootlab ?

As-tu testé une communication I2C sur cette distance avec des moteurs électriques qui tournent à côté ?

Avatar du membre
Barbadidoua
Bavard
Messages : 61
Enregistré le : lun. 31 juil. 2006, 19:11
Club : AMFBC73
Site Internet : http://fadiese.hd.free.fr/cms/
Localisation : Chambery

Re: Arduino - Snootlab I2C Pwm Driver

Message par Barbadidoua » jeu. 08 mai 2014, 14:08

Bonjour,

Ayant travaillé chez Philips, le bus I2C s'est imposé comme une évidence!
J'ai fait des tests avec 1m de chaque coté de l'Arduino. Le bus est fait avec du câble Ethernet blindé.
Sur la maquette, pour l'exposition tout est regroupé avec 20cm de bus.
Après l'exposition, nous poursuivrons les tests en augmentant la longueur du Bus.
Je n'ai pas d'autres moteurs que les servomoteurs et les locomotives DC en HOe.
Ech N, DCC LokMaus 2, CDM-Rail

Avatar du membre
jlb
Fécond
Messages : 692
Enregistré le : jeu. 04 oct. 2012, 16:38
Echelle pratiquée : N
Prénom : Jean-Luc
Site Internet : http://modelleisenbahn.triskell.org

Re: Arduino - Snootlab I2C Pwm Driver

Message par jlb » jeu. 08 mai 2014, 14:31

Effectivement, avec un câble blindé et une longueur de 20cm, ça ne devrait pas poser de problème ;)

Répondre