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à ^^) :
#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)
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.
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 ^^)
#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
Après quelque recherche sur le bus SPI, il semblerait que le ChipSelect puisse se faire sur n'importe quelle sortie digital
Exact
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.....
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é ?
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é
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 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
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......