Émission de données (RTC)/Réception, adressage et affichage des données sur plusieurs shields

De Wiki L.A.B
Révision de 3 août 2017 à 13:42 par Clolus.m (discussion | contributions) (Etape 2 : Communication entre 4 CAN Bus Shields : 2 émetteurs et 2 récepteurs)

Aller à : navigation, rechercher

Etape 1 : Communication entre 3 CAN Bus Shields : 1 émetteur et 2 récepteurs

Nous allons faire communiquer 3 CAN Bus Shields Un CAN Bus Shield jouera le rôle de l’émetteur. Il sera muni d’un RTC avec module i2c et pourra donc transmettre les données (dates et heures) aux autres Shields. Les deux autres CAN Bus Shields joueront le rôle de récepteur et recevront donc les données envoyées par le premier. Ils pourront afficher ses données, dates et heures, sur leur moniteur série (Ctrl – Maj – M). Nous allons définir un récepteur comme le récepteur 0 et le second comme le récepteur 1. Chacun recevra et affichera des données bien précises venant de l’émetteur. Les deux récepteurs ne recevront donc pas les mêmes données, nous pouvons adresser un message à tel ou tel récepteur selon notre choix.


Pour réaliser cette manipulation, nous disposons de :

  • 3 cartes Arduino UNO
  • 3 Can Bus Shields v.1.2
  • une horloge RTC avec module i2c
  • des fils de liaisons
  • 3 câbles d’alimentation USB

3 CAN Bus Shields.PNG

Pour le montage :

  • Il faut brancher chaque shield sur un Arduino et relier les signaux CAN_H et CAN_L de chacun.
  • Sur un CAN Bus Shield il faut brancher une clock (RTC avec module i2c).

Montage Arduino et RTC.PNG

  • GND RTC => GND Shield
  • VCC RTC => +5V Shield
  • SDA RTC => pin analogique A4 Shield
  • SCL RTC => pin analogique A5 Shield


Une fois le montage réalisé, nous pouvons ouvrir le programme Arduino et écrire les 3 codes pour chacun des CAN Bus Shields.



Code Emetteur (CAN Bus Shield avec le RTC) :

// Code pour émettre et afficher date et heure sur le moniteur série à l'aide d'un RTC avec module i2c

#include "Wire.h" //librairie déjà disponible sur Arduino
#include "uRTCLib.h" // bibliothèque pour RTC DS1307 à télécharger : croquis - inclure une bibliothèque -gérer les bibliothèques - uRTCLib par Naguissa
#include <mcp_can.h> // télécharger cette librairie en ZIP sur https://github.com/Seeed-Studio/CAN_BUS_Shield et l'ajouter à notre logiciel Arduino
#include <SPI.h> // librairie déjà disponible sur Arduino

#define SPI_CS_PIN 9 // Chip Select bus CAN = broche 9
MCP_CAN CAN(SPI_CS_PIN); // configuration CAN

byte hours = 0; // variables pour l'horloge RTC DS1307
byte mins = 0;
byte sec = 0;
byte date = 0;
byte mois = 0;
int annee = 0;
byte jour = 0;

byte canId = 0;

unsigned char stmp[7] = {0,1,2,3,4,5,6};   // crée un tableau de 7 variables char = données à transmettre (secondes, minutes, heures, jour de la semaine, date, mois, année)
uRTCLib rtc; // création de l'objet rtc

void setup()
{
  Serial.begin(115200);   //nombre de bauds: définir le même nombre sur le moniteur série (Ctrl - Maj - M)
  
rtc.set(0, 48, 14, 3, 2, 8, 17); //Pour initialiser l'horloge : il faut fixer les valeurs correspondantes : 
(secondes, minutes, heures, jour de la semaine (Valeur qui va de 1 à 7 avec 1 = lundi), date, mois, année)


START_INIT:
    if(CAN_OK == CAN.begin(CAN_500KBPS))             // initialisation du bus can : baudrate = 500k
    {
        Serial.println("Initialisation du CAN BUS Shield ok!");   // si le bus can s'initialise correctement alors le moniteur série (Ctrl-Maj-M) affiche cela
    }
    else
    {
        Serial.println("Initialisation du CAN BUS Shield en echec");   //si l'initialisation du Can échoue il tente de se réinitialiser jusqu'à ce que ça fonctionne
        Serial.println("Réinitialisation CAN BUS Shield");
        delay(100);
        goto START_INIT;
    }
}

void loop()  // la fonction loop() s'éxecute sans fin en boucle tant que l'Arduino est sous tension
{
  lectureRTC();   // appel de la fonction lecture données RTC DS1307 : fonction détaillée plus bas
  stmp [0] = hours;
  stmp [1] = mins;
  stmp [2] = sec;
  stmp [3] = jour;
  stmp [4] = date;
  stmp [5] = mois;
  stmp [6] = annee;
  if (sec <= 30)
  {
    CAN.sendMsgBuf(0x00, 0, 7, stmp);  // envoi des données :  id = 0x00, standard frame = 0, nombre de données = 7, stmp : tampon de données
    canId = 0;
  }
  else
  {
    CAN.sendMsgBuf(0x01, 0, 7, stmp);  // envoi des données :  id = 0x01, standard frame = 0, nombre de données = 7, stmp : tampon de données
    canId = 1;
  }
  affRTC();   // appel de la fonction affichage des données RTC sur la console série: fonction détaillée ci-dessous
  delay(10000);
}

void affRTC()   //détails de la fonction affRTC
  {
    Serial.println("-----------------------------");
    Serial.println("Test du Module RTS DS1307 avec la bibliothèque uRTCLib");
    Serial.println("Test du Shield CAN en émission");
    Serial.print ("CAN ID = ");
    Serial.println(canId);
    Serial.print("Nous sommes le ");   //affichage du jour de la semaine
    switch (jour)
    {
      case 1:
        Serial.print("Lun. ");
        break;
      case 2:
        Serial.print("Mar. ");
        break;
      case 3:
        Serial.print("Mer. ");
        break;
      case 4:
        Serial.print("Jeu. ");
        break;
      case 5:
        Serial.print("Ven. ");
        break;
      case 6:
        Serial.print("Sam. ");
        break;
      case 7:
        Serial.print("Dim. ");
        break;
    }
    Serial.print(date);
    Serial.print("/");
    Serial.print(mois);
    Serial.print("/");
    Serial.println(annee);
    Serial.print("Il est : ");
    Serial.print(hours);
    Serial.print(":");
    Serial.print(mins);
    Serial.print(":");
    Serial.println(sec);
    Serial.println();
    delay(1000);
}

void lectureRTC()   // détails de la fonction lectureRTC
{
  rtc.refresh();
  hours = rtc.hour();
  mins = rtc.minute();
  sec = rtc.second();
  date = rtc.day();
  mois = rtc.month();
  annee = rtc.year();
  jour = rtc.dayOfWeek();
}


On va différencier les deux récepteurs : récepteur 0 et récepteur 1.

  • Le récepteur 0 affichera la date et l’heure sur son moniteur série ( Ctrl – Maj – M) si les secondes sont inférieures à 30 secondes.
  • Le récepteur 1 affichera la date et l’heure sur son moniteur série si les secondes sont supérieures à 30 secondes.


Code Récepteur 0 :

//Programme du recepteur 0 : il reçoit les messages transmis sur le bus CAN et les affiche sur le moniteur série (Ctrl - Maj - M)

#include <SPI.h> // librairie déjà disponible sur Arduino
#include <mcp_can.h> // télécharger cette librairie en ZIP sur https://github.com/Seeed-Studio/CAN_BUS_Shield et l'ajouter à notre logiciel Arduino

#define SPI_CS_PIN 9 // Chip Select bus CAN = broche 9
MCP_CAN CAN(SPI_CS_PIN); // configuration CAN

byte hours = 0; // variables pour l'horloge RTC DS1307
byte mins = 0;
byte sec = 0;
byte date = 0;
byte mois = 0;
int annee = 0;
byte jour = 0;

unsigned char canId = 0 ; // variable identifiant CAN

void setup()
{
    Serial.begin(115200);    //nombre de bauds: définir le même nombre sur le moniteur série (Ctrl - Maj - M)

START_INIT:
    if(CAN_OK == CAN.begin(CAN_500KBPS))        // initialisation du bus can : baudrate = 500k
    {
        Serial.println("Initialisation du CAN BUS Shield ok!");
    }
    else
    {
        Serial.println("Initialisation du CAN BUS Shield en echec");
        Serial.println("Réinitialisation CAN BUS Shield");
        delay(100);
        goto START_INIT;
    }
    CAN.init_Mask(0,0, 0x01); // initialisation mask 0 (buffer 1) on teste le dernier bit
    CAN.init_Mask(1,0, 0x01); // initialisation mask 1 (buffer 2) on teste le dernier bit

    CAN.init_Filt(0,0, 0x00); // positionnement du filtre 0 (buffer 1 - mask 0) réception si Id = 0
    CAN.init_Filt(1,0, 0x00); // positionnement du filtre 1 (buffer 1 - mask 0) réception si Id = 0
    CAN.init_Filt(2,0, 0x00); // positionnement du filtre 2 (buffer 2 - mask 1) réception si Id = 0   
    CAN.init_Filt(3,0, 0x00); // positionnement du filtre 3 (buffer 2 - mask 1) réception si Id = 0  
    CAN.init_Filt(4,0, 0x00); // positionnement du filtre 4 (buffer 2 - mask 1) réception si Id = 0  
    CAN.init_Filt(5,0, 0x00); // positionnement du filtre 5 (buffer 2 - mask 1) réception si Id = 0  
}

void loop()
{
    unsigned char len = 0;
    unsigned char buf[7];

    if(CAN_MSGAVAIL == CAN.checkReceive())            // vérifie l'arrivée d'un message
    {
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf
        canId = CAN.getCanId();
        hours = buf[0];
        mins = buf[1];
        sec = buf[2];
        jour = buf[3];
        date = buf[4];
        mois = buf[5];
        annee = buf[6];   
        affRTC();   // appel de la fonction affichage des données RTC sur la console série: fonction détaillée ci-dessous
    }
}

void affRTC()    //détails de la fonction affRTC
  {
    Serial.println("-----------------------------");
    Serial.println("Test du Shield CAN en réception");
    Serial.print("Réception de données sur le CAN N° : ");
    Serial.println(canId);
    Serial.print("Nous sommes le ");   //affichage du jour de la semaine
    switch (jour)
    {
      case 1:
        Serial.print("Lun. ");
        break;
      case 2:
        Serial.print("Mar. ");
        break;
      case 3:
        Serial.print("Mer. ");
        break;
      case 4:
        Serial.print("Jeu. ");
        break;
      case 5:
        Serial.print("Ven. ");
        break;
      case 6:
        Serial.print("Sam. ");
        break;
      case 7:
        Serial.print("Dim. ");
        break;
    }
    Serial.print(date);
    Serial.print("/");
    Serial.print(mois);
    Serial.print("/");
    Serial.println(annee);
    Serial.print("Il est : ");
    Serial.print(hours);
    Serial.print(":");
    Serial.print(mins);
    Serial.print(":");
    Serial.println(sec);
    Serial.println();
     delay(1000);
}



Code Récepteur 1 :

//Programme du recepteur 1 : il reçoit les messages transmis sur le bus CAN et les affiche sur le moniteur série (Ctrl - Maj - M)

#include <SPI.h> // librairie déjà disponible sur Arduino
#include <mcp_can.h> // télécharger cette librairie en ZIP sur https://github.com/Seeed-Studio/CAN_BUS_Shield et l'ajouter à notre logiciel Arduino

#define SPI_CS_PIN 9 // Chip Select bus CAN = broche 9
MCP_CAN CAN(SPI_CS_PIN); // configuration CAN

byte hours = 0; // variables pour l'horloge RTC DS1307
byte mins = 0;
byte sec = 0;
byte date = 0;
byte mois = 0;
int annee = 0;
byte jour = 0;

unsigned char canId = 0 ; // variable identifiant CAN

void setup()
{
    Serial.begin(115200);   //nombre de bauds: définir le même nombre sur le moniteur série (Ctrl - Maj - M)

START_INIT:
    if(CAN_OK == CAN.begin(CAN_500KBPS))     // initialisation du bus can : baudrate = 500k
    {
        Serial.println("Initialisation du CAN BUS Shield ok!");
    }
    else
    {
        Serial.println("Initialisation du CAN BUS Shield en echec");
        Serial.println("Réinitialisation CAN BUS Shield");
        delay(100);
        goto START_INIT;
    }
    CAN.init_Mask(0,0, 0x01); // initialisation mask 0 (buffer 1) on teste le dernier bit
    CAN.init_Mask(1,0, 0x01); // initialisation mask 1 (buffer 2) on teste le dernier bit

    CAN.init_Filt(0,0, 0x01); // positionnement du filtre 0 (buffer 1 - mask 0) réception si Id = 1
    CAN.init_Filt(1,0, 0x01); // positionnement du filtre 1 (buffer 1 - mask 0) réception si Id = 1
    CAN.init_Filt(2,0, 0x01); // positionnement du filtre 2 (buffer 2 - mask 1) réception si Id = 1   
    CAN.init_Filt(3,0, 0x01); // positionnement du filtre 3 (buffer 2 - mask 1) réception si Id = 1  
    CAN.init_Filt(4,0, 0x01); // positionnement du filtre 4 (buffer 2 - mask 1) réception si Id = 1  
    CAN.init_Filt(5,0, 0x01); // positionnement du filtre 5 (buffer 2 - mask 1) réception si Id = 1  
}

void loop()
{
    unsigned char len = 0;
    unsigned char buf[7];

    if(CAN_MSGAVAIL == CAN.checkReceive())            // vérifie l'arrivée d'un message
    {
        CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf
        canId = CAN.getCanId();
        hours = buf[0];
        mins = buf[1];
        sec = buf[2];
        jour = buf[3];
        date = buf[4];
        mois = buf[5];
        annee = buf[6];   
        affRTC();  // appel de la fonction affichage des données RTC sur la console série: fonction détaillée ci-dessous
    }
}

void affRTC()    //détails de la fonction affRTC
  {
    Serial.println("-----------------------------");
    Serial.println("Test du Shield CAN en réception");
    Serial.print("Réception de données sur le CAN N° : ");
    Serial.println(canId);
    Serial.print("Nous sommes le ");      // affichage jour de la semaine
    switch (jour)
    {
      case 1:
        Serial.print("Lun. ");
        break;
      case 2:
        Serial.print("Mar. ");
        break;
      case 3:
        Serial.print("Mer. ");
        break;
      case 4:
        Serial.print("Jeu. ");
        break;
      case 5:
        Serial.print("Ven. ");
        break;
      case 6:
        Serial.print("Sam. ");
        break;
      case 7:
        Serial.print("Dim. ");
        break;
    }
    Serial.print(date);
    Serial.print("/");
    Serial.print(mois);
    Serial.print("/");
    Serial.println(annee);
    Serial.print("Il est : ");
    Serial.print(hours);
    Serial.print(":");
    Serial.print(mins);
    Serial.print(":");
    Serial.println(sec);
    Serial.println();
   delay(1000);
}

Entre le récepteur 0 et le récepteur 1 il y a une seule différence au niveau du code : pour le récepteur 0, l’Id est à 0 et pour le récepteur 1, l’Id est à 1.


Une fois la compilation et le téléversement de chaque code sur son CAN Bus Shield, nous pouvons ouvrir les moniteurs série (Ctrl – Maj- M) du récepteur 0 et du récepteur 1.

Date et Heure.PNG


  • le moniteur série du récepteur 0 affiche donc bien les dates et heures lorsque les secondes sont inférieures à 30 secondes (canId=0 pour sec<=30)

Moniteur série du récepteur 0.PNG


  • le moniteur série du récepteur 1 affiche donc bien les dates et heures lorsque les secondes sont supérieures à 30 secondes (canId=1 pour sec=>30)

Moniteur série du récepteur 1.PNG


Grâce au CAN Bus Shields nous pouvons donc adresser nos messages à tel ou tel Shield à l’aide d’un identifiant (ici Id= 0 ou Id=1). Il s'agit de l'identifiant des messages et peuvent donc être adresser à plusieurs ou un seul shield.

On peut ainsi ajouter davantage de CAN Bus Shields récepteurs et leur adresser tel ou tel messages.




Etape 2 : Communication entre 4 CAN Bus Shields : 2 émetteurs et 2 récepteurs

Nous allons faire communiquer 4 CAN Bus Shields. Dans un premier temps, il faut les brancher ensemble: il suffit de brancher les shields sur les Arduinos et de relier les signaux CAN_H et CAN_L de chacun.


4 CAN Bus Shields.PNG

Une fois les quatre shields branchés, nous allons donc pouvoir les faire communiquer. Nous allons définir deux shields comme émetteurs : le premier aura un RTC avec module i2c branché et le second un capteur de température ou un capteur de luminosité. Les 2 autres shields seront des récepteurs : récepteur 0 et récepteur 1.

Nous allons donc dans un premier temps tester les capteurs sur les Arduino pour vérifier qu'ils fonctionnent bien.

Test du capteur de luminosité sur Carte Arduino UNO

Pour réaliser le montage nous avons besoin de:

  • 1 bread board
  • 1 câble d’alimentation USB
  • 1 carte Arduino UNO
  • 1 capteur de luminosité
  • une résistante 120 ohms
  • 1 led
  • 5 fils de liaison

Capteur de luminosité sur arduino.PNG

Une fois le montage réalisé comme ci-dessus, sur le programme Arduino nous pouvons donc ajouter le code suivant :


//code qui Lit la luminosité et fait clignoter une LED à vitesse variable.
 
const int luminosityPin = A0;   // Numéro de la broche du capteur de luminosité - brancher fil sur pin A0
const int ledPin = 9;   // Numéro de la broche de la LED - brancher fil sur pin 9
 
void setup() {

  Serial.begin(9600);    // Initialise la communication avec l'ordinateur - nombre de bauds à définir également sur le "moniteur série" (Ctrl - Maj - M)
  pinMode(ledPin, OUTPUT);       // Indique que la broche de la LED est une sortie
}
 
void loop() {
  int sensorValue = analogRead(luminosityPin);    // Lit la valeur du capteur de luminosité
  Serial.print(" Valeur du Capteur = " );   // affiche la valeur du capteur dans le "moniteur série" sur l'ordinateur
  Serial.print(sensorValue);

 int waitTime = map(sensorValue, 0, 1023, 20, 1000);   // Convertit la valeur en durée d'attente pour la LED: il sera nécessaire d'adapter les valeurs du "mapping" en fonction de la luminosité ambiante
 
 Serial.print("\t Delai de clignotement (millisecondes) = ");    // Envoie le résultat vers l'ordinateur
 Serial.println(waitTime);

 // Fait clignoter la LED au rythme de la luminosité
 digitalWrite(ledPin, HIGH); // allume la LED
 delay(waitTime); // attends la durée choisie
 digitalWrite(ledPin, LOW); // éteints la LED
 delay(waitTime); // attends la durée choisie
}


Une fois la compilation et le téléversement du code terminé sur la plateforme Arduino :

  • Nous observons que la LED clignote au rythme de la luminosité
  • Nous pouvons ouvrir le moniteur série où la valeur du capteur et le délais de clignotement de la LED sont indiqués

Moniteur série capteur de luminosité.PNG


Test du capteur de température sur Carte Arduino UNO

Pour réaliser le montage nous avons besoin de:

  • 1 bread board
  • 1 câble d’alimentation USB
  • 1 carte Arduino UNO
  • 1 capteur de température
  • 3 fils de liaison

Capteur de luminosité sur arduino.PNG

Une fois le montage réalisé comme ci-dessus, sur le programme Arduino nous pouvons donc ajouter le code suivant :


//code qui Lit la luminosité et fait clignoter une LED à vitesse variable.
 
const int luminosityPin = A0;   // Numéro de la broche du capteur de luminosité - brancher fil sur pin A0
const int ledPin = 9;   // Numéro de la broche de la LED - brancher fil sur pin 9
 
void setup() {

  Serial.begin(9600);    // Initialise la communication avec l'ordinateur - nombre de bauds à définir également sur le "moniteur série" (Ctrl - Maj - M)
  pinMode(ledPin, OUTPUT);       // Indique que la broche de la LED est une sortie
}
 
void loop() {
  int sensorValue = analogRead(luminosityPin);    // Lit la valeur du capteur de luminosité
  Serial.print(" Valeur du Capteur = " );   // affiche la valeur du capteur dans le "moniteur série" sur l'ordinateur
  Serial.print(sensorValue);

 int waitTime = map(sensorValue, 0, 1023, 20, 1000);   // Convertit la valeur en durée d'attente pour la LED: il sera nécessaire d'adapter les valeurs du "mapping" en fonction de la luminosité ambiante
 
 Serial.print("\t Delai de clignotement (millisecondes) = ");    // Envoie le résultat vers l'ordinateur
 Serial.println(waitTime);

 // Fait clignoter la LED au rythme de la luminosité
 digitalWrite(ledPin, HIGH); // allume la LED
 delay(waitTime); // attends la durée choisie
 digitalWrite(ledPin, LOW); // éteints la LED
 delay(waitTime); // attends la durée choisie
}


Une fois la compilation et le téléversement du code terminé sur la plateforme Arduino :

  • Nous observons que la LED clignote au rythme de la luminosité
  • Nous pouvons ouvrir le moniteur série où la valeur du capteur et le délais de clignotement de la LED sont indiqués

Moniteur série capteur de luminosité.PNG