Bonjour à tous,
Je suis actuellement sur un projet professionnel qui concerne les réseaux BUSCAN embarqués dans des véhicules du domaine agricole. L’idée à terme va être de piloter des fonctions d’un véhicule et de réceptionner des données pour de l’affichage distant bref, manipuler des données qui transitent sur le BUSCAN.
J’ai démarré ce projet par l’étude la plus complète possible sur le réseau BUSCAN, ça fait deux / trois mois que j’y suis. J’ai dans un premier temps étudié à l’oscilloscope le réseau qui transite sur les différents véhicules à ma disposition en concession afin de maitriser la détection de la vitesse du BUS, voltage des CAN H / CAN L, types de trames, etc.
J’ai eu au départ de mon projet beaucoup de mal à faire fonctionné des analyseurs de trame ( chinois ) sur les véhicules afin de déceler les trames qui m’intéressent, je me suis du coup penché sur l’idée de créer moi-même mon propre analyseur BUS CAN et je pense que c’est une bonne solution pour progresser dans ce domaine.
Voici la présentation de l’analyseur que j’aimerais créer :
- Une carte microcontrôleur Arduino Méga 2560
- Deux relais de sélection de BUS
- Un module MCP2515
- Bibliothèque ACAN2515 de PierreMOLINARO
- 3 contacteurs : 1 pour la sélection du BaudsRate / 1 pour la sélection du BUS et 1 pour la sélection des masques.
- Un encodeur rotatif analogique ( fonctionnement par ocpto-coupleur )
- Un DAC 4725 pour l’alimentation analogique de mon encodeur
- Des leds néopixel pour l’affichage de la sélection du BaudRate / état du système
- Un afficheur LCD 4 lignes 16x4 I2C
- Un boitier aluminium BOLPLA
- Brochage faisceau électrique / boitier par broche D-SUB
Voici en image le boitier et son schéma de câblage :
Voici le fonctionnement souhaité :
Lors du démarrage du programme, le voyant « Power » clignote en bleu le temps de l’initialisation du programme et passe en vert lorsque le démarrage du MCP2515 est validé.
Le programme sélectionne le BaudsRate de 100 KB/s ainsi que la valeur de Serial.begin(valeur) ; par défaut puis peut être modifié via un des contacteurs jaunes et ainsi caler la vitesse du réseau BUSCAN avec le débit USB du port série.
Le programme propose de sélectionner ensuite le réseau BUS CAN à écouter ( sur les véhicules agricoles, plusieurs BUS s’interconnectent via un calculateur passerelle). Dans mon cas, il s’agit soit d’un réseau BUSCAN Véhicule, soit un réseau BUS CAN Equipement qui ont tous deux différentes vitesses de fonctionnement ( 500Kbits/s pour l’un et 250Kbits/s pour l’autre ). Le voyant concerné s’allume en fonction de la sélection.
Le programme récupère ensuite les données via le moniteur série lorsque des messages sont réceptionnés et seront enregistrés dans un fichier via le logiciel PUTTY.
Dans le cadre de la recherche des identifiants de trame qui concerne les données qui m’intéressent, je souhaite pouvoir faire évoluer les masques et les filtres en actionnant le contacteur orange et grâce à la molette de l’encodeur faire avancer et reculer les valeurs des filtres ou masques dans des tableaux ce qui va me permettre de faire un focus sur des portions de d’identifiants car en une seconde sur le véhicule, il doit y avoir plus de 100 trames / seconde rendant illisible la trame qui nous intéresse.
L’arrivée des messages est représentée par le voyant interruption avec un flash led rapide qui représente le flux des messages en réception.
Le cavalier de la résistance 120 ohm présente ou non selon le réseau sur lequel on souhaite se connecter doit être présente ou non suivant le cas.
Voila pour le projet, pour le moment, le programme est fonctionnel sur sa partie démarrage et arrivé des messages sans sélection d’identifiants ou de masque. Voici le programme provisoire qui n’est pas terminé, j’ai toute la partie sélection des filtres et masques qui n’est pas faite et j’ai des soucis sur certains points du programme qui ne marche pas comme je le souhaite donc je compte un peu sur vous pour m’aider à comprendre certaines choses et trouver les axes d’amélioration à apporter.
Voici le code réalisé pour le moment :
// _______________ Déclaration de la bibliothèque MCP2515 ____________________________________
#include <ACAN2515_Buffer16.h>
#include <ACANBuffer.h>
#include <ACAN2515Settings.h>
#include <ACAN2515.h>
#include <ACAN2515_CANMessage.h>
// ________________ Déclaration des filtres ____________________________
volatile int compteur = 0; // Position (en nombre de pas) du codeur
bool etatArriverMessages = false;
int valeurFiltreUn;
int valeurFiltreDeux;
int valeurFiltreTrois;
int valeurFiltreQuatre;
int valeurFiltreCinq;
int valeurFiltreSix;
static const uint8_t MCP2515_CS = 53;
static const uint8_t MCP2515_INT = 19;
ACAN2515 controleurCAN(MCP2515_CS, SPI, MCP2515_INT);
// ________________ Déclaration du Baud Rate ___________________________
unsigned long tableauValeurBaudRate[5]{ 125ul, 250ul, 500ul, 800ul, 1000ul };
unsigned long tableauValeurSerialBegin[5]{ 125000, 250000, 500000, 800000, 1000000 };
unsigned long valeurBaudRate = tableauValeurBaudRate[0];
unsigned long valeurSerialBegin = tableauValeurSerialBegin[0];
int commutateurBaudRate = 0;
int commutateurFitresEtMasques = 0;
int commutateurAffichageEncodeur = 0;
static const uint32_t FREQUENCE_DU_QUARTZ = 16ul * 1000ul * 1000ul;
static const uint32_t FREQUENCE_DU_BUS_CAN = valeurBaudRate * 1000ul;
// ____________________________________ Fonction de lecture des trames BUSCAN _______________________________________________
void messagesDesFiltres(const CANMessage & inMessage, String nomDuFiltre){
etatArriverMessages = true;
if(etatArriverMessages == true) {
clignotementLedInterruption();
}
Serial.print("Reception messages des filtres : ");
Serial.print(nomDuFiltre);
Serial.print(" : ");
Serial.println("Identifiant : " + String(inMessage.id) + "\t" + "Std ou ext : " + String(inMessage.ext) + "\t" + "Taille : " + String(inMessage.len) + "\t" + "Data[32] : " + String(inMessage.data32[0]));
}
void messageValFiltreUn(const CANMessage & inMessage){
messagesDesFiltres(inMessage, "Filtre un");
}
void messageValFiltreDeux(const CANMessage & inMessage){
messagesDesFiltres(inMessage, "Filtre deux");
}
void messageValFiltreTrois(const CANMessage & inMessage){
messagesDesFiltres(inMessage, "Filtre trois");
}
void messageValFiltreQuatre(const CANMessage & inMessage){
messagesDesFiltres(inMessage, "Filtre quatre");
}
void messageValFiltreCinq(const CANMessage & inMessage){
messagesDesFiltres(inMessage, "Filtre cinq");
}
void messageValFiltreSix(const CANMessage & inMessage){
messagesDesFiltres(inMessage, "Filtre six");
}
const ACAN2515Mask typeDeMasqueStandardUn = standard2515Mask(0x7FF, 0, 0); /* Que des 1 sur 11 bits */
const ACAN2515Mask typeDeMasqueStandardDeux = standard2515Mask(0x7FF, 0, 0); /* Que des 1 sur 11 bits */
const ACAN2515AcceptanceFilter filtres[] = {
{ standard2515Filter(valeurFiltreUn, 0, 0), messageValFiltreUn },
{ standard2515Filter(valeurFiltreDeux, 0, 0), messageValFiltreDeux },
{ standard2515Filter(valeurFiltreTrois, 0, 0), messageValFiltreTrois },
{ standard2515Filter(valeurFiltreQuatre, 0, 0), messageValFiltreQuatre },
{ standard2515Filter(valeurFiltreCinq, 0, 0), messageValFiltreCinq },
{ standard2515Filter(valeurFiltreSix, 0, 0), messageValFiltreSix }
};
void changementDesFiltresEtMasquesEtendu(){
ACAN2515Settings reglagesEtendu(FREQUENCE_DU_QUARTZ, FREQUENCE_DU_BUS_CAN);
reglagesEtendu.mReceiveBufferSize = 100 ;
reglagesEtendu.mTransmitBuffer0Size = 0;
const ACAN2515Mask typeDeMasqueEtenduUn = extended2515Mask(0x1FFFFFFF);
const ACAN2515Mask typeDeMasqueEtenduDeux = extended2515Mask(0x1FFFFFFF);
const ACAN2515AcceptanceFilter filtresEtenduApresDemarrage[] = {
{ extended2515Filter(valeurFiltreUn), messageValFiltreUn },
{ extended2515Filter(valeurFiltreDeux), messageValFiltreDeux },
{ extended2515Filter(valeurFiltreTrois), messageValFiltreTrois },
{ extended2515Filter(valeurFiltreQuatre), messageValFiltreQuatre },
{ extended2515Filter(valeurFiltreCinq), messageValFiltreCinq },
{ extended2515Filter(valeurFiltreSix), messageValFiltreSix }
};
const uint16_t codeErreurEtendu = controleurCAN.begin(reglagesEtendu, [] { controleurCAN.isr(); }, typeDeMasqueEtenduUn, typeDeMasqueEtenduDeux, filtresEtenduApresDemarrage, 6 );
if (codeErreurEtendu == 0) {
Serial.print("CAN controleur etendu apres demarrage configurer / ");
Serial.print("Etat codeErreurEtendu (begin) : ");
Serial.println(codeErreurEtendu);
delay(1000);
} else {
Serial.print("CAN controleur etendu apres demarrage non configurer / ");
Serial.print("Etat codeErreurEtendu (begin) : ");
Serial.println(codeErreurEtendu, HEX);
delay(1000);
while (1);
}
}
void changementDesFiltresEtMasquesStandard(){
ACAN2515Settings reglagesStandard(FREQUENCE_DU_QUARTZ, FREQUENCE_DU_BUS_CAN);
reglagesStandard.mReceiveBufferSize = 100 ;
reglagesStandard.mTransmitBuffer0Size = 0;
const ACAN2515Mask typeDeMasqueStandardUnApresDemarrage = standard2515Mask(0x7FF, 0, 0);
const ACAN2515Mask typeDeMasqueStandardDeuxApresDemarrage = standard2515Mask(0x7FF, 0, 0);
const ACAN2515AcceptanceFilter filtresStandardApresDemarrage[] = {
{ standard2515Filter(valeurFiltreUn, 0, 0), messageValFiltreUn },
{ standard2515Filter(valeurFiltreDeux, 0, 0), messageValFiltreDeux },
{ standard2515Filter(valeurFiltreTrois, 0, 0), messageValFiltreTrois },
{ standard2515Filter(valeurFiltreQuatre, 0, 0), messageValFiltreQuatre },
{ standard2515Filter(valeurFiltreCinq, 0, 0), messageValFiltreCinq },
{ standard2515Filter(valeurFiltreSix, 0, 0), messageValFiltreSix }
};
const uint16_t codeErreurStandard = controleurCAN.begin(reglagesStandard, [] { controleurCAN.isr(); }, typeDeMasqueStandardUnApresDemarrage, typeDeMasqueStandardDeuxApresDemarrage, filtresStandardApresDemarrage, 6 );
if (codeErreurStandard == 0) {
allumagePowerLed();
Serial.print("CAN controleur standard apres demarrage configurer / ");
Serial.print("Etat codeErreurStandard (begin): ");
Serial.println(codeErreurStandard);
delay(1000);
} else {
problemeAllumagePowerLed();
Serial.print("CAN controleur standard apres demarrage non configurer / ");
Serial.print("Etat codeErreurStandard (begin) : 0x");
Serial.println(codeErreurStandard, HEX);
delay(1000);
while (1);
}
}
// __________________________ Bibliothèque Adafruit DAC MCP4725 et encodeur JD _________________________________
#define adresseI2CduMCP4725 0x60
#define memorisationTensionDeSortieUn false
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dacEncodeur;
int etatPrecedentCanalUn;
int etatPrecedentCanalDeux;
int pinCanalUn = A0;
int pinCanalDeux = A1;
int etatAnalogiqueCanalUn = 0;
int etatAnalogiqueCanalDeux = 0;
int etatNumeriqueCanalUn = 0;
int etatNumeriqueCanalDeux = 0;
int etatActuelCanalUn = 0;
int etatActuelCanalDeux = 0;
// __________________________ Bibliothèque Néopixel _________________________________
const unsigned long tempoClignotementLed = 25;
unsigned long tempsEcouler = millis();
#include <Adafruit_NeoPixel.h>
#define ledPinDeux 9
#define ledCountDeux 6
#define ledPinUn 8
#define ledCountUn 4
Adafruit_NeoPixel stripUn(ledCountUn, ledPinUn, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripDeux(ledCountDeux, ledPinDeux, NEO_GRB + NEO_KHZ800);
void allumageProgramme() {
for (int t = 0; t <= 30; t++) {
delay(100);
for (int i = 0; i <= 0; i++) {
stripUn.setPixelColor(i, 0, 0, 255);
stripUn.show();
delay(45);
stripUn.setPixelColor(i, 0, 0, 0);
stripUn.show();
}
}
}
void allumagePowerLed() {
for (int i = 0; i <= 0; i++) {
stripUn.setPixelColor(i, 0, 140, 0);
stripUn.show();
}
}
void problemeAllumagePowerLed(){
for (int i = 0; i <= 0; i++) {
stripUn.setPixelColor(i, 255, 0, 0);
stripUn.show();
}
}
// _______________________________________ Fonction de réception des messages standards _______________________________________________
int relaisSelectionDesBus = 12;
int etatDuRelaisDeSelectionDesBus = 0;
// ________________ Déclaration des boutons ____________________________
#include "OneButton.h"
OneButton boutonSelectionBaudsRate;
OneButton boutonSelectionDesBus;
OneButton boutonSelectionFitresEtMasques;
// _______________ Déclaration de la bibliothèque afficheur ____________________________________
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20, 20, 4);
//___________________________________________________________________________________ SETUP ________________________________________________________________________________
void setup() {
SPI.begin();
pinMode(relaisSelectionDesBus, OUTPUT);
digitalWrite(relaisSelectionDesBus, LOW);
Serial.begin(115200);
stripUn.begin();
stripUn.show();
stripUn.setBrightness(15);
stripDeux.begin();
stripDeux.show();
stripDeux.setBrightness(15);
lcd.init();
lcd.backlight();
// __________________ Initialisation du DAC _________________________
dacEncodeur.begin(0x60);
dacEncodeur.setVoltage(4095, true);
etatPrecedentCanalUn = etatNumeriqueCanalUn;
etatPrecedentCanalDeux = etatNumeriqueCanalDeux;
delay(200);
// __________________ Initialisation SETUP des boutons _____________________ //
boutonSelectionBaudsRate.setup(6, INPUT, true);
boutonSelectionBaudsRate.attachClick(selectionBaudsRate);
boutonSelectionDesBus.setup(4, INPUT, true);
boutonSelectionDesBus.attachClick(selectionDuBus);
boutonSelectionFitresEtMasques.setup(7, INPUT, true);
boutonSelectionFitresEtMasques.attachClick(appuiDuBoutonDesMasquesEtFiltres);
// ______________________ Initialisation SETUP du MCP2515 _________________________
lcd.setCursor(4, 1);
lcd.print("Analyseur de");
lcd.setCursor(7, 2);
lcd.print("BUS CAN");
lcd.setCursor(16, 3);
lcd.print("Ludo");
delay(2000);
allumageProgramme();
for (int i = 1; i <= 1; i++) { // Sélection Baud Rate par défaut
stripDeux.setPixelColor(i, 0, 0, 255);
stripDeux.show();
}
ACAN2515Settings reglages(FREQUENCE_DU_QUARTZ, FREQUENCE_DU_BUS_CAN);
reglages.mReceiveBufferSize = 100 ;
reglages.mTransmitBuffer0Size = 0;
lcd.clear();
const uint16_t codeErreur = controleurCAN.begin(reglages, [] { controleurCAN.isr(); }, typeDeMasqueStandardUn, typeDeMasqueStandardDeux, filtres, 6 );
if (codeErreur == 0) {
allumagePowerLed();
lcd.setCursor(3, 1);
lcd.print("Demarrage ok !");
Serial.print("CAN controleur au demarrage configurer / ");
Serial.print("Etat codeErreur (begin) : ");
Serial.println(codeErreur);
delay(1500);
lcd.clear();
} else {
problemeAllumagePowerLed();
Serial.print("Etat codeErreur (begin) : 0x");
Serial.println(codeErreur, HEX);
delay(1500);
lcd.clear();
while (1);
}
lcd.setCursor(2, 1);
lcd.print("Selectionner un");
lcd.setCursor(3, 2);
lcd.print("reseau BUS CAN");
}
//____________________________________________________________ LOOP _____________________________________________________________
void loop() {
boutonSelectionBaudsRate.tick();
boutonSelectionDesBus.tick();
boutonSelectionFitresEtMasques.tick();
gestionEncodeur();
calculDesFiltres();
if ( commutateurAffichageEncodeur == 1 ){
lcd.setCursor(16, 1);
lcd.print(compteur);
lcd.print(" ");
lcd.setCursor(3, 3);
lcd.print("De : ");
lcd.setCursor(6, 3);
lcd.print(valeurFiltreUn);
lcd.print(" ");
lcd.setCursor(11, 3);
lcd.print("a");
lcd.setCursor(14, 3);
lcd.print(valeurFiltreSix);
lcd.print(" ");
}
controleurCAN.dispatchReceivedMessage() ;
}
// _________________________________________________________________ FONCTION(S) _____________________________________________________________
// ______________________________________________________________ Fonction sélection du BUS CAN Véhicule ou équipement ______________________________________________________
void selectionDuBus() {
switch (etatDuRelaisDeSelectionDesBus) {
case 0:
Serial.print("Action sur bouton de selection des BUS CAN : ");
Serial.println(boutonSelectionDesBus.debouncedValue());
lcd.clear();
digitalWrite(relaisSelectionDesBus, HIGH);
Serial.println(" Sélection du BUS Vehicule ");
for (int i = 1; i <= 1; i++) {
stripUn.setPixelColor(i, 0, 0, 0);
stripUn.show();
}
for (int i = 2; i <= 2; i++) {
stripUn.setPixelColor(i, 0, 0, 255);
stripUn.show();
}
lcd.setCursor(4, 0);
lcd.print("Selection du ");
lcd.setCursor(7, 1);
lcd.print("BUS CAN");
lcd.setCursor(6, 2);
lcd.print("Vehicule");
delay(1500);
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("Selectionner votre ");
lcd.setCursor(5, 2);
lcd.print("BaudsRate");
Serial.println(" Sortie du Case 0 sélection des circuits CAN ");
delay(750);
etatDuRelaisDeSelectionDesBus = 1;
commutateurAffichageEncodeur = 0;
break;
case 1:
Serial.print("Action sur bouton de selection des BUS CAN : ");
Serial.println(boutonSelectionDesBus.debouncedValue());
lcd.clear();
digitalWrite(relaisSelectionDesBus, LOW);
Serial.println(" Sélection du BUS Equipement ");
for (int i = 2; i <= 2; i++) {
stripUn.setPixelColor(i, 0, 0, 0);
stripUn.show();
}
for (int i = 1; i <= 1; i++) {
stripUn.setPixelColor(i, 0, 0, 255);
stripUn.show();
}
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Selection du ");
lcd.setCursor(7, 1);
lcd.print("BUS CAN");
lcd.setCursor(5, 2);
lcd.print("Equipement");
delay(1500);
lcd.clear();
lcd.setCursor(1, 1);
lcd.print("Selectionner votre ");
lcd.setCursor(5, 2);
lcd.print("BaudsRate");
Serial.println(" Sortie du Case 1 sélection des circuits CAN ");
delay(750);
etatDuRelaisDeSelectionDesBus = 0;
commutateurAffichageEncodeur = 0;
break;
}
}
// ______________________________________________________________ Fonction sélection du Baud Rate ______________________________________________________
void selectionBaudsRate() {
switch (commutateurBaudRate) {
case 0: // baud 250
lcd.clear();
valeurBaudRate = tableauValeurBaudRate[1];
Serial.begin(tableauValeurSerialBegin[1]);
for (int i = 1; i <= 1; i++) {
stripDeux.setPixelColor(i, 0, 0, 0);
stripDeux.show();
}
for (int i = 2; i <= 2; i++) {
stripDeux.setPixelColor(i, 0, 0, 255);
stripDeux.show();
}
lcd.setCursor(0, 1);
lcd.print("Baud Rate = ");
lcd.setCursor(12, 1);
lcd.print(tableauValeurBaudRate[1]);
lcd.setCursor(16, 1);
lcd.print("Kb/s");
lcd.setCursor(0, 2);
lcd.print("Serial = ");
lcd.setCursor(9, 2);
lcd.print(tableauValeurSerialBegin[1]);
lcd.setCursor(17, 2);
lcd.print("Ba");
commutateurBaudRate = 1;
delay(1000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("selectionner les");
lcd.setCursor(0, 2);
lcd.print("masques identifiants");
lcd.setCursor(0, 3);
lcd.print("filtres identifiants");
commutateurAffichageEncodeur = 0;
break;
case 1: // baud 500
valeurBaudRate = tableauValeurBaudRate[2];
Serial.begin(tableauValeurSerialBegin[2]);
stripDeux.Color(0, 0, 0);
stripDeux.show();
for (int i = 1; i <= 2; i++) {
stripDeux.setPixelColor(i, 0, 0, 0);
stripDeux.show();
}
for (int i = 3; i <= 3; i++) {
stripDeux.setPixelColor(i, 0, 0, 255);
stripDeux.show();
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Baud Rate = ");
lcd.setCursor(12, 1);
lcd.print(tableauValeurBaudRate[2]);
lcd.setCursor(16, 1);
lcd.print("Kb/s");
lcd.setCursor(0, 2);
lcd.print("Serial = ");
lcd.setCursor(9, 2);
lcd.print(tableauValeurSerialBegin[2]);
lcd.setCursor(17, 2);
lcd.print("Ba");
commutateurBaudRate = 2;
delay(1000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("selectionner les");
lcd.setCursor(0, 2);
lcd.print("masques identifiants");
lcd.setCursor(0, 3);
lcd.print("filtres identifiants");
commutateurAffichageEncodeur = 0;
break;
case 2: // baud 800
valeurBaudRate = tableauValeurBaudRate[3];
Serial.begin(tableauValeurSerialBegin[3]);
for (int i = 1; i <= 3; i++) {
stripDeux.setPixelColor(i, 0, 0, 0);
stripDeux.show();
}
for (int i = 4; i <= 4; i++) {
stripDeux.setPixelColor(i, 0, 0, 255);
stripDeux.show();
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Baud Rate = ");
lcd.setCursor(12, 1);
lcd.print(tableauValeurBaudRate[3]);
lcd.setCursor(16, 1);
lcd.print("Kb/s");
lcd.setCursor(0, 2);
lcd.print("Serial = ");
lcd.setCursor(9, 2);
lcd.print(tableauValeurSerialBegin[3]);
lcd.setCursor(17, 2);
lcd.print("Ba");
commutateurBaudRate = 3;
delay(1000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("selectionner les");
lcd.setCursor(0, 2);
lcd.print("masques identifiants");
lcd.setCursor(0, 3);
lcd.print("filtres identifiants");
commutateurAffichageEncodeur = 0;
break;
case 3: // baud 1000
valeurBaudRate = tableauValeurBaudRate[4];
Serial.begin(tableauValeurSerialBegin[4]);
for (int i = 1; i <= 4; i++) {
stripDeux.setPixelColor(i, 0, 0, 0);
stripDeux.show();
}
for (int i = 5; i <= 5; i++) {
stripDeux.setPixelColor(i, 0, 0, 255);
stripDeux.show();
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Baud Rate = ");
lcd.setCursor(12, 1);
lcd.print(tableauValeurBaudRate[4]);
lcd.setCursor(16, 1);
lcd.print("Kb/s");
lcd.setCursor(0, 2);
lcd.print("Serial = ");
lcd.setCursor(9, 2);
lcd.print(tableauValeurSerialBegin[4]);
lcd.setCursor(17, 2);
lcd.print("Ba");
commutateurBaudRate = 4;
delay(1000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("selectionner les");
lcd.setCursor(0, 2);
lcd.print("masques identifiants");
lcd.setCursor(0, 3);
lcd.print("filtres identifiants");
commutateurAffichageEncodeur = 0;
break;
case 4:
valeurBaudRate = tableauValeurBaudRate[0];
Serial.begin(tableauValeurSerialBegin[0]);
for (int i = 1; i <= 5; i++) {
stripDeux.setPixelColor(i, 0, 0, 0);
stripDeux.show();
}
for (int i = 1; i <= 1; i++) {
stripDeux.setPixelColor(i, 0, 0, 255);
stripDeux.show();
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Baud Rate = ");
lcd.setCursor(12, 1);
lcd.print(tableauValeurBaudRate[0]);
lcd.setCursor(16, 1);
lcd.print("Kb/s");
lcd.setCursor(0, 2);
lcd.print("Serial = "); // 9
lcd.setCursor(9, 2);
lcd.print(tableauValeurSerialBegin[0]);
lcd.setCursor(17, 2);
lcd.print("Ba");
commutateurBaudRate = 0;
delay(1000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("selectionner les");
lcd.setCursor(0, 2);
lcd.print("masques identifiants");
lcd.setCursor(0, 3);
lcd.print("filtres identifiants");
commutateurAffichageEncodeur = 0;
break;
default:
valeurBaudRate = tableauValeurBaudRate[0];
Serial.begin(tableauValeurSerialBegin[0]);
for (int i = 0; i <= 0; i++) {
stripDeux.setPixelColor(i, 0, 0, 255);
stripDeux.show();
}
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Baud Rate = ");
lcd.setCursor(12, 1);
lcd.print(tableauValeurBaudRate[0]);
lcd.setCursor(16, 1);
lcd.print("Kb/s");
lcd.setCursor(0, 2);
lcd.print("Serial = ");
lcd.setCursor(9, 2);
lcd.print(tableauValeurSerialBegin[0]);
lcd.setCursor(17, 2);
lcd.print("Ba");
delay(1000);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("selectionner les");
lcd.setCursor(0, 2);
lcd.print("masques identifiants");
lcd.setCursor(0, 3);
lcd.print("filtres identifiants");
commutateurAffichageEncodeur = 0;
break;
}
}
// ______________________________________________________________ Fonction sélection des filtres et masques ______________________________________________________
void appuiDuBoutonDesMasquesEtFiltres() {
switch (commutateurFitresEtMasques) {
case 0:
Serial.print("Action sur bouton de selection des masques et filtres : ");
Serial.println(boutonSelectionFitresEtMasques.debouncedValue());
lcd.clear();
for (int i = 0; i <= 0; i++) {
stripDeux.setPixelColor(i, 0, 0, 0);
stripDeux.show();
}
for (int i = 0; i <= 0; i++) {
stripDeux.setPixelColor(i, 0, 255, 0);
stripDeux.show();
}
changementDesFiltresEtMasquesEtendu();
lcd.setCursor(2, 0);
lcd.print("Masque etendu");
lcd.setCursor(1, 1);
lcd.print("ID de 6 en 6 : ");
lcd.setCursor(2, 2);
lcd.print("Filtres etendu");
commutateurAffichageEncodeur = 1;
commutateurFitresEtMasques = 1;
compteur = 0;
Serial.println("Sortie ok de case 0");
delay(1000);
break;
case 1:
Serial.print("Action sur bouton de selection des masques et filtres : ");
Serial.println(boutonSelectionFitresEtMasques.debouncedValue());
lcd.clear();
for (int i = 0; i <= 0; i++) {
stripDeux.setPixelColor(i, 0, 0, 0);
stripDeux.show();
}
for (int i = 0; i <= 0; i++) {
stripDeux.setPixelColor(i, 255, 255, 0);
stripDeux.show();
}
changementDesFiltresEtMasquesStandard();
lcd.setCursor(2, 0);
lcd.print("Masque standard");
lcd.setCursor(1, 1);
lcd.print("ID de 6 en 6 : ");
lcd.setCursor(2, 2);
lcd.print("Filtres standard");
commutateurFitresEtMasques = 0;
compteur = 0;
Serial.println(" Sortie ok de case 1 ");
delay(1000);
break;
}
}
// ______________________________________________________________ Fonction allumage Led lors d'un interruption du MCP2515 ______________________________________________________
void clignotementLedInterruption() {
static boolean ledOn; // Pour garder l'état de la LED
if (millis() - tempsEcouler >= tempoClignotementLed) {
ledOn = !ledOn; // Inverser l'état de la LED
if (ledOn) {
stripUn.setPixelColor(3, 255, 255, 255);
stripUn.show();
} else {
stripUn.setPixelColor(3, 0, 0, 0);
stripUn.show();
}
tempsEcouler = millis();
etatArriverMessages = false;
}
}
// ______________________________________________________________ Fonction gestion encodeur ______________________________________________________
void gestionEncodeur() {
etatAnalogiqueCanalUn = analogRead(pinCanalUn);
etatAnalogiqueCanalDeux = analogRead(pinCanalDeux);
if (etatAnalogiqueCanalUn < 300) {
etatNumeriqueCanalUn = LOW;
} else {
etatNumeriqueCanalUn = HIGH;
}
if (etatAnalogiqueCanalDeux > 500) {
etatNumeriqueCanalDeux = HIGH;
} else {
etatNumeriqueCanalDeux = LOW;
}
etatActuelCanalUn = etatNumeriqueCanalUn;
etatActuelCanalDeux = etatNumeriqueCanalDeux;
if (etatActuelCanalUn != etatPrecedentCanalUn) {
if (etatPrecedentCanalDeux == 1 && etatActuelCanalUn == 1) {
compteur++;
}
if (etatPrecedentCanalUn == 1 && etatActuelCanalDeux == 0) {
compteur++;
}
if (etatPrecedentCanalDeux == 0 && etatActuelCanalUn == 1) {
compteur--;
}
if (etatPrecedentCanalDeux == 1 && etatActuelCanalUn == 0) {
compteur--;
}
}
if (etatActuelCanalDeux != etatPrecedentCanalDeux) {
if (etatPrecedentCanalUn == 1 && etatActuelCanalDeux == 0) {
compteur++;
}
if (etatPrecedentCanalUn == 0 && etatActuelCanalDeux == 1) {
compteur++;
}
if (etatPrecedentCanalUn == 1 && etatActuelCanalDeux == 1) {
compteur--;
}
if (etatPrecedentCanalUn == 0 && etatActuelCanalDeux == 0) {
compteur--;
}
}
etatPrecedentCanalUn = etatActuelCanalUn;
etatPrecedentCanalDeux = etatActuelCanalDeux;
if (compteur <= 0) {
compteur = 0;
}
//Serial.println("Etat actuel canal un : " + String(etatActuelCanalUn) + "\t" + "Etat precedent canal un : " + String(etatPrecedentCanalUn) + "\t" + "Etat actuel canal deux : " + String(etatActuelCanalDeux) + "\t" + "Etat precedent canal deux : " + String(etatPrecedentCanalDeux) + "\t" + "Compteur : " + String(compteur));
//Serial.println(" Etat numerique canal un : " + String(etatNumeriqueCanalUn) + "\t" + " Etat numerique canal deux : " + String(etatNumeriqueCanalDeux));
}
// ______________________________________________________________ Calcul des six filtres ___________________________________________________
void calculDesFiltres(){
valeurFiltreUn = 1 + 6 * (compteur);
valeurFiltreDeux = valeurFiltreUn + 1;
valeurFiltreTrois = valeurFiltreUn + 2;
valeurFiltreQuatre = valeurFiltreUn + 3;
valeurFiltreCinq = valeurFiltreUn + 4;
valeurFiltreSix = valeurFiltreUn + 5;
/*Serial.print("compteur : ");
Serial.print(compteur);
Serial.print(" ");
Serial.print("Filtre un : ");
Serial.print(valeurFiltreUn);
Serial.print(" ");
Serial.print("Filtre deux : ");
Serial.print(valeurFiltreDeux);
Serial.print(" ");
Serial.print("Filtre trois : ");
Serial.print(valeurFiltreTrois);
Serial.print(" ");
Serial.print("Filtre Quatre : ");
Serial.print(valeurFiltreQuatre);
Serial.print(" ");
Serial.print("Filtre cinq : ");
Serial.print(valeurFiltreCinq);
Serial.print(" ");
Serial.print("Filtre six : ");
Serial.println(valeurFiltreSix);*/
}
Pour plus de clarté sur ce sujet, je poserais une question qui me bloque step by step afin d’avancer au mieux et pour commencer, je rencontre une difficulté sur le voyant d’interruption qui me ralenti l’arrivé des messages, j’ai fait deux petites vidéos démontrant la différence de vitesse ( j'ai décommenté pour le moment la fonction dans la loop ) :
Moniteur série avec voyant d'interruption actif
Moniteur série sans voyant d'interruption actif
Merci par avance à tous pour l'entraide.
Ludo




