Go Down

Topic: Gérer 2 bus CAN avec un seul bus SPI (Read 373 times) previous topic - next topic

Maroko69

Mar 27, 2019, 04:22 pm Last Edit: Mar 27, 2019, 07:56 pm by Maroko69
Bonjour à tous,

Je suis actuellement en BTS et j'ai un projet de fin d'année à réalisé et l'information que je vais vous demandé est introuvable sur le net (peut-être que si...).

Mon projet concerne un CAN bus déjà existant sur lequel j'interposerais ma carte électronique permettant de filtrer les informations et de renvoyer ce qui m'intéresse.

J'utilise 2 CAN Shield sur une seule Arduino Uno.

J'ai réussi à récupérer les données mais je n'arrive pas à en avoir en sortie. Pourtant j'ai quand même réussi à créer 2 entités différentes. Mais rien à faire je n'ai pas de trames en sortie même si ma trames existe car affiché sur le port série : (Screen en Attach)

Voici mon code (si vous avez réussi à me suivre jusque là ^^) :

Code: [Select]

#include <mcp_can.h>                            //Récupération des biblihothèques CAN_BUS
#include <SPI.h>
#include "mcp_can.h"

#define CapteurLum analogRead(4)               //Récupération de la valeur de Lumière
#define EclairageInt 7

const int SPI_CS_PIN = 9;

MCP_CAN  SS1 (9);
MCP_CAN  SS2 (10);

void setup() {

  Serial.begin(250000);

  while (CAN_OK != SS1.begin(CAN_250KBPS))              // Initialisation CAN_bus entrant vitesse = 250kbit/s
  {
    Serial.println("Lancement du CAN echoue");
    Serial.println(" Redemarrage CAN bus");
    break;
  }
  while (CAN_OK != SS2.begin(CAN_250KBPS))              // Initialisation CAN_bus sortant: vitesse = 250kbit/s
  {
    Serial.println("Lancement du CAN echoue");
    Serial.println(" Redemarrage CAN bus");
    break;
  }


  Serial.println("Initialisation du CAN bus OK!");
  pinMode(7, OUTPUT);
                              //Création du filtre Id: 0xC2
}

unsigned char len = 0;
unsigned char buf[8];
unsigned char canId1 = SS1.getCanId();
unsigned char canId2 = SS2.getCanId();





void loop() {
if (CAN_MSGAVAIL == SS1.checkReceive())
  {
  if (CAN_MSGAVAIL == SS1.checkReceive())           // Check réception de données
  {
    SS1.readMsgBuf(&len, buf);                       // Lecture données,  len: Taille de la données, buf: Buffer données
    canId1 = SS1.getCanId();
   
      if (canId1 == 0xC2)
      {
        buf [0] = 0x54;
      }

    SS2.sendMsgBuf(canId1, 0, len, buf);            // Renvoie sur CAN 2 des données
   
    Serial.println("-----------------------------");
    Serial.println("SS2 Données envoyées avec Id: 0x");
    Serial.println(SS2.getCanId(), HEX);

    for (int i = 0; i < len; i++) // Ecriture de la données
    {
      Serial.print(buf[i]);
      Serial.print("\t");
    }
    Serial.println();
  }
}


Merci d'avance pour tout aide

Cordialement,
Un jeune électronicien :)

###############
#           EDIT            #
###############
 J'adorerais présenté ce projet sur ce forum, il existe peu de projet de ce type sur le net (surtout en français cela pourrais aider beaucoup de gens)

pomme-poire

Salut
tu veux pirater une voiture ? :)

qu'entends tu par "j'interposerais ma carte électronique  ?"

Maroko69

#2
Mar 27, 2019, 05:03 pm Last Edit: Mar 27, 2019, 05:06 pm by Maroko69
En fait je compte utiliser ma carte comme filtre CAN,  sachant que je ne peux rien reprogrammer sur le véhicule ( c'est un bus,  une voiture en plus gros :)).

Je pense que le problème vient du CS sur mon bus spi,  mais je ne sais pas comment le régler.

Merci d'avance pour vos réponses.



Maroko69

Bon,

Après quelque recherche sur le bus SPI, il semblerait que le ChipSelect puisse se faire sur n'importe quelle sortie digital (ce qui me paraît franchement bizarre, car dans les datasheet du CAN-Shield, nous pouvons choisir la pin du ChipSelect soit 9 soit 10.

J'ai adapté mon programme et je verrais demain si cela marche mais vraiment pas facile de trouver ses infos j'ai l'impression que peu de gens utilise des CAN-Shield (le CAN fait peut-être peur ^^)

Code: [Select]
#include <mcp_can.h>                            //Récupération des biblihothèques CAN_BUS
#include <SPI.h>
#include "mcp_can.h"

#define CapteurLum analogRead(4)               //Récupération de la valeur de Lumière
#define EclairageInt 7
//
//const int SPI_CS_PIN = 9;

MCP_CAN  SS1 (9);
MCP_CAN  SS2 (10);

void setup() {

  Serial.begin(250000);

  while (CAN_OK != SS1.begin(CAN_250KBPS))              // Initialisation CAN_bus entrant vitesse = 250kbit/s
  {
    Serial.println("Lancement du CAN echoue");
    Serial.println(" Redemarrage CAN bus");
    break;
  }
  while (CAN_OK != SS2.begin(CAN_250KBPS))              // Initialisation CAN_bus sortant: vitesse = 250kbit/s
  {
    Serial.println("Lancement du CAN echoue");
    Serial.println(" Redemarrage CAN bus");
    break;
  }


  Serial.println("Initialisation du CAN bus OK!");
  pinMode(7, OUTPUT);
                             
}

unsigned char len = 0;
unsigned char buf[8];
unsigned char canId1 = SS1.getCanId();
unsigned char canId2 = SS2.getCanId();





void loop() {
 
if (CAN_MSGAVAIL == SS1.checkReceive())               // Check réception de données
  {
    digitalWrite(10,HIGH);                            //Sélection de l'esclave SPI
    digitalWrite(9, LOW);                             //Sélection de l'esclave SPI
    SS1.readMsgBuf(&len, buf);                       // Lecture données,  len: Taille de la données, buf: Buffer données
    canId1 = SS1.getCanId();
   
      if (canId1 == 0xC2)
      {
        buf [0] = 0x54;
      }
     
    digitalWrite(9, HIGH);                         //Sélection de l'esclave SPI
    digitalWrite(10, LOW);                         //Sélection de l'esclave SPI
   
    SS2.sendMsgBuf(canId1, 0, len, buf);            // Renvoie sur CAN 2 des données
   
    Serial.println("-----------------------------");
    Serial.println("SS2 Données envoyées avec Id: 0x");
    Serial.println(SS2.getCanId(), HEX);
   
    digitalWrite(10,HIGH);                         //Sélection de l'esclave SPI

   
    for (int i = 0; i < len; i++) // Ecriture de la données
    {
      Serial.print(buf[i]);
      Serial.print("\t");
    }
    Serial.println();
   
  }


Si des personnes bien aimable on d'autre infos sur le CS ou SS sur une Arduino Uno :)

Je tiendrais au courant de l'avancé du projet.
Bonne soirée

Cordialement,
Un jeune électronicien

al1fch

#4
Mar 27, 2019, 10:01 pm Last Edit: Mar 27, 2019, 10:09 pm by al1fch
Bonsoir
Quote
Après quelque recherche sur le bus SPI, il semblerait que le ChipSelect puisse se faire sur n'importe quelle sortie digital
Exact

Quote
ce qui me paraît franchement bizarre, car dans les datasheet du CAN-Shield, nous pouvons choisir la pin du ChipSelect soit 9 soit 10.
L'alternative 9 ou 10 pour SS  est certainement une limitation propre au shield , une restriction par rapport à l'ensemble des connections théoriquement possibles. Les créateurs du shield on choix d'offrir un choix limité , c'est mieux que pas de choix.....


Maroko69

Quote
L'alternative 9 ou 10 pour SS  est certainement une limitation propre au shield , une restriction par rapport à l'ensemble des connections théoriquement possibles
Donc selon toi mon code est bon ? En déclarant ainsi mes pinoches avant le setup puis en le mettant à l'état haut et l'état bas cela marcherait ? Mes 2 shields sauraient quand ils sont sélectionné ?

Merci pour ton aide.

al1fch

#6
Mar 27, 2019, 10:12 pm Last Edit: Mar 27, 2019, 10:15 pm by al1fch
les shields sauront quand ils sont sélectionnés  ..... si sur ceux ci les connections correspondantes  9 ou 10 ont bien été établies (piste à couper, point de soudure, cavalier à placer....selon les diverses cartes.)
Sur la carte CAN Shield V2 de SeedStudio c'est bien expliqué

Maroko69

D'accord, merci pour ton aide je testerais ça demain au travail.

Je viendrais faire mon rapport :)

Bonne soirée

Maroko69

Avancement du projet :

En ayant fait le changement sur mon premier shield comme ceci : (Attach 1)

Mon montage est comme ceci : (Attach 2)

J'ai donc changé mon code et mon SPI_CS_PIN est donc maintenant égal à 10. Voici le code changé:
Code: [Select]

#include <mcp_can.h>                            //Récupération des biblihothèques CAN_BUS
#include <SPI.h>
#include "mcp_can.h"

#define CapteurLum analogRead(4)               //Récupération de la valeur de Lumière
#define EclairageInt 7

 const int SPI_CS_PIN = 10;

MCP_CAN  SS1 (10);
MCP_CAN  SS2 (9);

void setup() {

  Serial.begin(250000);

  while (CAN_OK != SS1.begin(CAN_250KBPS))              // Initialisation CAN_bus entrant vitesse = 250kbit/s
  {
    Serial.println("Lancement du CAN echoue");
    Serial.println(" Redemarrage CAN bus");
    break;
  }
  while (CAN_OK != SS2.begin(CAN_250KBPS))              // Initialisation CAN_bus sortant: vitesse = 250kbit/s
  {
    Serial.println("Lancement du CAN echoue");
    Serial.println(" Redemarrage CAN bus");
    break;
  }


  Serial.println("Initialisation du CAN bus OK!");
  pinMode(7, OUTPUT);
                              
}

unsigned char len = 0;
unsigned char buf[8];
unsigned char canId1 = SS1.getCanId();
unsigned char canId2 = SS2.getCanId();





void loop() {
  
if (CAN_MSGAVAIL == SS1.checkReceive())               // Check réception de données
  {
    SS1.readMsgBuf(&len, buf);                       // Lecture données,  len: Taille de la données, buf: Buffer données
    canId1 = SS1.getCanId();
    
      if (canId1 == 0xC2)
      {
        buf [0] = 0x54;
      }

    
    SS2.sendMsgBuf(canId1, 0, len, buf);            // Renvoie sur CAN 2 des données
    
    Serial.println("-----------------------------");
    Serial.println("SS2 Données envoyées avec Id: 0x");
    Serial.println(SS2.getCanId(), HEX);
    
    for (int i = 0; i < len; i++) // Ecriture de la données
    {
      Serial.print(buf[i]);
      Serial.print("\t");
    }
    Serial.println();
    
  }
}


Et le résultat est simplement que le CAN ne s'initialise même plus, je ne récupère plus aucune trame : (Attach 3)

Merci d'avance pour votre aide je ne vois plus quoi faire.

al1fch

Bonjour

Au vu de la  photo "CS en pin 10" il n'est pas  évident que la piste assurant à l'origine  la liaison  avec pin 9 ait été  coupée

Maroko69

Bonjour,

Elle n'avait pas été coupé (en testant la continuité), j'ai donc dessoudé et mis en pin 10 sur l'autre shield (beaucoup plus simple car pré-perçage), et coupé la pin 9 du CS, je vais aller tester en revenir par ici pour donner des nouvelles.

La commande "int SPI_CS_PIN = 9;" défini-t-elle bien la pin sur laquelle je choisis mon esclave ?

Je vais aller tester avant votre réponse :D

Merci encore 

al1fch

#11
Mar 28, 2019, 10:29 am Last Edit: Mar 28, 2019, 10:56 am by al1fch
Je ne connais pas la librairie utilisée mais il semble que les deux lignes suivantes servent à déclarer les positionnement  des SS de chacune des deux cartes CAN


Code: [Select]
MCP_CAN  SS1 (9);
MCP_CAN  SS2 (10);


Il n'est pas certain que la ligne suivante soit utilisée (seule une étude de la librairie CAN  permettrait  de conclure)
Elle parait faire double emploi avec les deux lignes citées ci dessus avec en plus l'inconvénient d'uen déclaration pour une seule carte......

Code: [Select]
const int SPI_CS_PIN = 10;



Maroko69

Donc selon toi je ne devrais pas utilisé cette commande? 

J'ai trouvé un topic sur ton lien mais ils n'ont pas fini la conversation https://github.com/Seeed-Studio/CAN_BUS_Shield/issues/70

Selon eux juste besoin de déclarer les SS de la même manière que je l'ai fais sans la Déclaration de l'entier...

Go Up