É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 à 10:43 par Clolus.m (discussion | contributions) (Etape 1 : Communication entre 3 CAN Bus Shields : 1 émetteur 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).