LOCODUINO
Discussions Générales => Bus CAN => Discussion démarrée par: JeeLet le avril 13, 2020, 03:31:58 pm
-
Bonjour
depuis 2 semaines, Je test et re-test le CAN pour une application domotique personnelle ( capteurs Température et hygrométrie LCD .. etc)
j'ai épluché une bonne quantité de croquis Arduino, lue toute les pages du forum, mais Rien sur le sujet.
bien vue une histoire de "Union" (non pas le magazine) la fonction qui coupe et colle les valeurs de plus "255" ... rien comprit.
donc j'ai laissé tomber le CAN pour voir du coter du Rs485/ModBus, mais la horreur, la liaison filaire n'est pas aussi simple,
et le Code Arduino indigeste (pour un débutant, oui moi)
re-donc retour au CAN 8)
ma question, ma demande, un exemple de croquis pour envoie et réception de valeur décimal pour de la mesure ambiante.
... du 18.40°C ou -12°c
bref des valeurs qui existe sur terre.
Merci
(un bleu-bite qui découvre l'Arduino) :o
-
Bonjour,
exceptionnellement, confinement oblige, voici en PJ 2 sketchs (émission/réception) de démo pour le bus CAN.
Pourquoi exceptionnellement car sur ce site on ne traite que de train miniature, mais comme j'ai envoyé ces sketchs à un ami qui tente de s'y mettre aussi, pourquoi ne pas vous en faire profiter, mais à vous de vous débrouiller avec.
Cordialement
Antoine
-
... merci beaucoup, oui je pensais que ma demande était limite, mais lorsque on désespère :'(
bon je recâble les Arduino en version CAN, avec capteur DHT22 et afficheur LCD et repart en test.
vais enfin pouvoir lire mes capteurs de température après la virgule 8)
un truc, Les valeurs "analogique - décimal" dans le monde du modélisme ferroviaire c'est pas utile ??
encore merci
-
Bonjour,
Quelle bibliothèque utilisez vous ? (je fais une exception aussi)
-
Re
.. "Quelle bibliothèque utilisez vous ?" rien de figer pour l'instant,
la mcp_can de Seeed-Studio ou mcp2515 de https://github.com/autowp/arduino-mcp2515
merci pour l'exception ..... Ah c Bo la vie :)
-
Je répond également parce que finalement ce n'est pas spécifique à votre problème,
En fait votre problème n'est pas lié au CAN, vous l'auriez avec n'importe quel réseau.
Votre problème est de coller les octets constituant votre nombre à virgule dans les octets du message.
Pour émettre votre message vous utilisez un truc du genre
can.sendMsgBuf(id,type,data,longueur);
où id est l'identifiant du message, type le type (0 = standard, 1 = extended), data un pointeur vers, au plus, une successions de 8 octets de données et longueur la longueur en octets, un byte.
Pour envoyer une variable v de type float dans un message standard, il faut écrire :
can.sendMsgBuf(id,0,(byte *)(&v),sizeof(v));
&v donne un pointeur sur v, (byte *) le converti en un pointer sur un octet, sizeof(v) retourne la taille en octets de v, c'est à dire 4 mais c'est mieux de l'écrire comme ça.
À la réception, vous appelez :
can.readMsgBuf(data, longueur);
Où data est un pointeur vers, au plus, une successions de 8 octets de données et longueur un pointeur vers un byte ou sera écrit la longueur en octets du message reçu.
Si v2 est votre variable de type float où vous souhaitez recevoir la donnée et len un byte où vous souhaiter voire écrit la longueur, il faut écrire :
can.readMsgBuf((byte *)(&v2), &len);
-
Bonjour et merci Jean-Luc,
je viens d'apprendre quelque chose même si mes besoins ne sont pas des nombres à virgule que j'envoie.
Bon lundi soir de Pâques
Cordialement
Antoine
-
Bonsoir Antoine,
Joyeuses Pâques à toi également
Un dernier truc. Il faut faire attention à l'endianess. Si le message est transmis entre une plateforme où les octets ne sont pas rangés dans le même ordre, il y aura un soucis. Exemple sur un nombre entier de 4 octets (32 bits) que l'on écrit 0x11223344 peut être stocké en little endian, vu comme un tableau d'octet, il s'écrirait { 0x44, 0x33, 0x22, 0x11 } ou big endian : { 0x11, 0x22, 0x33, 0x44 }
En pratique, autour de l'Arduino, il n'y a pas de soucis : un AVR, un ARM, un ESP ou un PIC32, tout le monde est little Endian.
-
... mais non c'est pas des Sauvages sur Locoduino, tu vois!!
Bonjour
merci pour le ++ d'info sur le sujet 8)
je revient avec des croquis sous l'bras.
-
Bonsoir
Recu hier mes 5 "Module Bus-CAN SBC-CAN01" de chez JOY-hic, refait le câblage en plus propre.
avec la biblio ACAN / ACAN2515
j'ai Tester les croquis (2BP et 2 Led) donner sur le super Tuto ACAN number ON , c'est implacable .. heu ... impeccable.
Donc me revoilà avec ma virgule :o
j'ai mis en application une "recette" donnée par skywodd sur le forum Arduino.
"Tu multiplies ton float par le nombre de dizaines après la virgule,
tu le convertis en int(),
tu l'envoies à l'Arduino.
Coté Arduino, tu réceptionnes ce int en le recomposant,
tu le divises par le nombre de dizaine que tu avais derrière la virgule,
tu le convertis en float()."
Et c'est impeccable, enfin presque ;D
pour le croquis émission rien a dire, le problème c'est pour la réception.
comprend pas comment diviser quoi ou ??!!
int ival = ????
et
float val = ival / 100.0;
voila mes super Croquis.
RE-Edit du samedi 25
j'ai supprimé les croquis, c'est une horreur :D
mais je continue a avancer.
info du jour https://www.hackster.io/monkbroc/poor-man-s-can-bus-602636
du super light :)
-
Bonsoir Jeelet,
comme ton problème n'a rien à voir avec les trains et que visiblement tu cherches et trouves des réponses sur d'autres forums je pense que les exceptions à la règle sont arrivées à leur termes en tous les cas pour moi.
Désolé, le règlement c'est le règlement.
Bonne chance pour la suite de ton projet.
Cordialement
Antoine
-
bonsoir Antoine
... mais non " tu cherches et trouves des réponses sur d'autres forums" ... j'ai fais aucune demande sur les autres Forum.
seulement du copier coller de bout de code de Si de Là.
et j'ai pas voulue encore te déranger par mail, tu a un big projet a géré ( le peut de compris)
bon c pas grave
A+
-
j'ai mis en application une "recette" donnée par skywodd sur le forum Arduino.
"Tu multiplies ton float par le nombre de dizaines après la virgule,
tu le convertis en int(),
tu l'envoies à l'Arduino.
Coté Arduino, tu réceptionnes ce int en le recomposant,
tu le divises par le nombre de dizaine que tu avais derrière la virgule,
tu le convertis en float()."
C'est pas terrible comme recette. :o
Je te suggère plutôt de passer par une union (d'ailleurs je vais suggérer à Pierre Molinaro d'ajouter un accès en float aux CANMessage).
typedef union {
float f;
uint32_t i;
} floatOr32bitsInt;
Ensuite côté émetteur :
floatOr32bitsInt tmp;
tmp.f = val; /* val c'est ton flottant */
message.data32[0] = tmp.i;
controleurCAN.tryToSend(message);
Côté récepteur :
if (controleurCAN.receive(message)) {
floatOr32bitsInt tmp;
tmp.i = message.data32[0];
float val = tmp.f;
...
}
-
Jean-Luc Bonjour
oui Pierre Molinaro a fait un super boulot avec ACAN, j'ai même faillie le contacter (toi aussi ;)
mais après une semaine a essayer de comprendre la mis en pratique de la biblio de pierre, j'ai jeter l'éponge hier :)
( le fichier pdf fournie avec la lib est super pour les anglophone )
je suis repartir sur mcp.can de SeeedStudio, les exemples son super nombreux sur le web ....... mais avec ton message, demi-tour :)
et pour "suggérer à Pierre Molinaro d'ajouter un accès en float aux CANMessage)" ..... oui il ya une vrais demande sur un bus CAN Domotique filaire.
mais beaucoup abandonne faute d'exemple mis en pratique :(
un big merci pour ton aide, je regarde bien ta réponse.
à ce soir (sur le forum)
MERCI
-
Re
oui j'ai papy j'ai pas pu attendre ce soir :o
c'est impeccable, magnifique, du 1er coup, j'en revient pas ::)
une recopie d'écran des 2 IDE en service
(https://nsm09.casimages.com/img/2020/04/27//20042702184323870816764865.png) (https://www.casimages.com/i/20042702184323870816764865.png.html)
les 2 croquis
Emi_dht_ACAN2515_v1.ino
/*
* Locoduino: 1er mai 2020
* https://www.locoduino.org/spip.php?article268
*
* Envoi et Réception de valeur numerique a deux digit apres la virgule
* ( valeur positif ou négatif)
*
* sur une base de Locoduino (JL)
* avec Biblio ACAN de pierre Molinaro https://github.com/pierremolinaro/acan2517
* bricolage par : JeeLet
* -X- compil des exemples 1 et 2 (partie eraser)
* -X- Ajout partie float "virgule" et valeur négatif
* -o- reste ajout les capteurs (tres simple avec dhtNEW de Rob Tillaart)
* -o-
*/
// ------------- Debut Pgm Emission ----------------
// ----- inclusion des bibliothèques -------------
#include <ACAN2515Settings.h> // les reglages
#include <ACAN2515.h> // le controleur
#include <CANMessage.h> // les messages
// ------ config des E/S -----------
static const uint8_t MCP2515_CS = 10; // pin SPI_CS
static const uint8_t MCP2515_INT = 2; // pin interruption
// ------- les déclarations ----------
// objet de type ACAN2515 est instancié pour gérer le MCP2515
ACAN2515 CAN(MCP2515_CS, SPI, MCP2515_INT); //pin CS,SPI ,pin INT.
static const uint32_t FREQUENCE_DU_QUARTZ = 8000000; // quartz du MCP2515 en hertz
static const uint32_t FRENQUENCE_DU_BUS_CAN = 125000; // fréquence du bus CAN
CANMessage message; // objets pour les messages CAN en emission.
// ------ début du defini union ----
typedef union
{
float f; // valeur f ?
uint32_t i; // valeur i ?
}
floatOr32bitsInt; // ..
// ---------------fin ------------------
float vala = 32.45; // simulation Valeur en virgule flottante
static uint32_t milliEnvoi = 0; // Tempo d’envoi
// -------------- Setup --------------
void setup() {
Serial.begin(9600); // com série
SPI.begin(); // bus SPI
Serial.println("Configuration du MCP2515");
ACAN2515Settings configuration(FREQUENCE_DU_QUARTZ, FRENQUENCE_DU_BUS_CAN);
// ---- Demarrage et control d'erreur du CAN ----
const uint32_t codeErreur = CAN.begin(configuration, [] { CAN.isr(); });
if (codeErreur == 0)
{
Serial.println("Configuration ok");
}
else
{
Serial.println("Probleme de connexion");
while (1);
}
message.len = 4; //message avec 4 octets de donnee
}
//------------ Loop --------------
void loop()
{
uint16_t milliEncour = millis();
if (milliEncour - milliEnvoi >= 2000) //envoi toutes les 2 secondes
{
floatOr32bitsInt tmp;
tmp.f = vala; /* val c'est ton flottant */
message.data32[0] = tmp.i;
CAN.tryToSend(message); // envoi du message
Serial.print(tmp.f);
Serial.print(" --Emi--> ");
Serial.println(message.data32[0]);
milliEnvoi = milliEncour; // reset tempo
}
}
// ----------- Fin du pgm ------------------
Rec_dht_ACAN2515_v1.ino
/*
* Locoduino: 1er mai 2020
* https://www.locoduino.org/spip.php?article268
*
* Envoi et Réception de valeur numerique a deux digit apres la virgule
* ( valeur positif ou négatif)
*
* sur une base de Locoduino (JL)
* avec Biblio ACAN de pierre Molinaro https://github.com/pierremolinaro/acan2517
* bricolage par : JeeLet
* -X- compil des exemples 1 et 2 (partie eraser)
* -X- Ajout partie float "virgule" et valeur négatif
* -o- reste ajout les capteurs (tres simple avec dhtNEW de Rob Tillaart)
* -o-
*/
// ------------- Debut Pgm Reception ----------------
// ----- inclusion des bibliothèques -------------
#include <ACAN2515Settings.h> // les reglages
#include <ACAN2515.h> // le controleur
#include <CANMessage.h> // les messages
// ------ config des E/S -----------
static const uint8_t MCP2515_CS = 10; // pin SPI_CS
static const uint8_t MCP2515_INT = 2; // pin interruption
// ------- les déclarations ----------
// objet de type ACAN2515 est instancié pour gérer le MCP2515
ACAN2515 CAN(MCP2515_CS, SPI, MCP2515_INT); //pin CS,SPI ,pin INT.
static const uint32_t FREQUENCE_DU_QUARTZ = 8000000; // quartz du MCP2515 en hertz
static const uint32_t FRENQUENCE_DU_BUS_CAN = 125000; // fréquence du bus CAN
CANMessage message; // objets pour les messages CAN
// ------ début du defini union ----
typedef union
{
float f;
uint32_t i;
}
floatOr32bitsInt; // ..
// ---------------fin ------------------
// -------------- Setup --------------
void setup() {
Serial.begin(9600); // com série
SPI.begin(); // bus SPI
Serial.println("Configuration du MCP2515");
ACAN2515Settings configuration(FREQUENCE_DU_QUARTZ, FRENQUENCE_DU_BUS_CAN);
// ---- Demarrage et control d'erreur du CAN ----
const uint32_t codeErreur = CAN.begin(configuration, [] { CAN.isr(); });
if (codeErreur == 0)
{
Serial.println("configuration ok");
}
else
{
Serial.println("Probleme de connexion");
while (1);
}
}
//------------ Loop --------------
void loop()
{
if (CAN.receive(message)) // signal arrive message CAN
{
floatOr32bitsInt tmp;
tmp.i = message.data32[0];
float val = tmp.f;
Serial.print(tmp.i);
Serial.print(" --Rec--> ");
Serial.println(tmp.f);
}
}
// -------------- fin Pgm -------------------
valeur décimal, négatif ou positif a 2digit après la virgule passe bien sur le Bus CAN ( un grand pas pour l'humabinaire)
Jean-Luc T génial ( merci a toi Antoine d'avoir amorcer la pompe à connaissance)
Ah oui, une question :
comment pour ajouter plusieurs mesures de capteur, plusieurs sondes ????
8)
-
Et bien il faut mettre des identifiants différents selon le capteur.
C'est l'objet du prochain article.
-
Ah oui, une question :
comment pour ajouter plusieurs mesures de capteur, plusieurs sondes ????
8)
Bah, il faut faire plusieurs messages ou combiner plusieurs mesures dans les 8 octets d'un message (la 1ère solution est préférable, le Can est rapide et ne perd rien.
Ah, Jean-Luc a déjà répondu avant moi...
-
Bonjour,
Pierre a fait une release (version 2.0.4). Exit l'union, il suffit maintenant d'écrire :
Côté émetteur :
message.dataFloat[0] = val;
controleurCAN.tryToSend(message);
Côté récepteur :
if (controleurCAN.receive(message)) {
float val = message.dataFloat[0];
...
}
-
Jean-Luc Bonjour
...release (version 2.0.4) , mis a jour biblio de l'IDE et modification comme dit.
Impeccable, les croquis on encore Rétréci, cela devient inquiétant :P :)
donc je passe les codes Arduino en version 2, avec la modif du float et ajout d'un capteur DHT22 (temp/humidité)
( les version 1 reste pour les nouveaux arrivant ??)
Emi_dht_ACAN2515_v2.ino
/*
* Locoduino: 1er mai 2020
* https://www.locoduino.org/spip.php?article268
*
* Envoi et Réception de valeur numerique a deux digit apres la virgule
* (valeur positif ou négatif)
*
* sur une base de Locoduino (JL) et bricol par JeeLet
*
* - librarie ACAN2515 ver.2.0.4 de pierre Molinaro https://github.com/pierremolinaro/acan2517
* - librarie "dhtnew.h" Ver:0.1.5 de Rob Tillaart's
*
* -X- compil des exemples 1 et 2 (partie eraser)
* -X- Ajout partie float "virgule" et valeur négatif
* -X- ajout capteur DHT22 (température-humidité)
* -X- ver. 2.0.4 de ACAN2515 (ajout float) et croquis V1 en V2
* -o- gestion des ID can pour multi capteurs (quatres ?)
* -o-
*/
// ------------- Debut Pgm Emission ----------------
// ----- inclusion des bibliothèques -------------
#include <ACAN2515Settings.h> // les reglages
#include <ACAN2515.h> // le controleur
#include <CANMessage.h> // les messages
#include <dhtnew.h> // Capteur temp/humi
// ------ config des E/S -----------
static const uint8_t MCP2515_CS = 10; // pin SPI_CS
static const uint8_t MCP2515_INT = 2; // pin interruption
DHTNEW dht1 (5); // pin capteur DHT22
// ------- les déclarations ----------
// objet de type ACAN2515 est instancié pour gérer le MCP2515
ACAN2515 CAN(MCP2515_CS, SPI, MCP2515_INT); //pin CS,SPI ,pin INT.
static const uint32_t FREQUENCE_DU_QUARTZ = 8000000; // quartz du MCP2515 en hertz
static const uint32_t FRENQUENCE_DU_BUS_CAN = 125000; // fréquence du bus CAN
CANMessage message; // objets pour les messages CAN en emission.
// ----------------- capteur1 DHT22 -----------
float t1 = 0.0; // température
float h1 = 0.0; // humidité
static uint32_t milliEnvoi = 0; // Tempo d’envoi CAN
// -------------- Setup --------------
void setup() {
Serial.begin(9600); // com série
SPI.begin(); // bus SPI
dht1.read(); // lecture capteurs
Serial.println("Configuration du MCP2515");
ACAN2515Settings configuration(FREQUENCE_DU_QUARTZ, FRENQUENCE_DU_BUS_CAN);
// ---- Demarrage et control d'erreur du CAN ----
const uint32_t codeErreur = CAN.begin(configuration, [] { CAN.isr(); });
if (codeErreur == 0)
{
Serial.println("Configuration ok");
}
else
{
Serial.println("Probleme de connexion");
while (1);
}
message.len = 4; //message avec 4 octets de donnee
}
//------------ Loop --------------
void loop()
{
uint16_t milliEncour = millis();
if (milliEncour - milliEnvoi >= 6000) //envoi toutes les 2 secondes
{
// ------------- partie capteur ----------------
capteur(); //apl sous pgm du capteur
h1 = dht1.humidity ; //humidite 1
t1 = dht1.temperature; //Temperature 1
// ------------- partie CAN ----------------
message.dataFloat[0] = t1; // valeur float du capteur
CAN.tryToSend(message); // envoi CAN
Serial.print(t1);
Serial.print(" Temp --Emi--> ");
Serial.println(message.data32[0]);
Serial.print(h1);
Serial.print(" hum --Emi--> ");
Serial.println(message.data32[0]);
milliEnvoi = milliEncour; // reset tempo
}
}
// ------ control Capteurs ------
void capteur()
{
int chk = dht1.read();
switch (chk)
{
case DHTLIB_OK:
Serial.println("DHT22 OK,\t");
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.println("Checksum error,\t");
break;
case DHTLIB_ERROR_TIMEOUT:
Serial.println("Time out error,\t");
break;
default:
Serial.println("Unknown error,\t");
break;
}
// ----- fin sous pgm ------------
}
// ----------- Fin du pgm ------------------
Rec_dht_ACAN2515_v2.ino
/*
* Locoduino: 1er mai 2020
* https://www.locoduino.org/spip.php?article268
*
* Envoi et Réception de valeur numerique a deux digit apres la virgule
* (valeur positif ou négatif)
*
* sur une base de Locoduino (JL) et bricol par JeeLet
*
* - librarie ACAN2515 ver.2.0.4 de pierre Molinaro https://github.com/pierremolinaro/acan2517
* - librarie "dhtnew.h" Ver:0.1.5 de Rob Tillaart's
*
* -X- compil des exemples 1 et 2 (partie eraser)
* -X- Ajout partie float "virgule" et valeur négatif
* -X- ajout DHT22 (température-humidité) en Emission
* -X- ver. 2.0.4 de ACAN2515 ( ajout float) et croquis V1 en V2
* -o- gestion des ID can pour multi capteurs (quatres ?)
* -o-
*/
// ------------- Debut Pgm Reception ----------------
// ----- inclusion des bibliothèques -------------
#include <ACAN2515Settings.h> // les reglages
#include <ACAN2515.h> // le controleur
#include <CANMessage.h> // les messages
// ------ config des E/S -----------
static const uint8_t MCP2515_CS = 10; // pin SPI_CS
static const uint8_t MCP2515_INT = 2; // pin interruption
// ------- les déclarations ----------
// objet de type ACAN2515 est instancié pour gérer le MCP2515
ACAN2515 CAN(MCP2515_CS, SPI, MCP2515_INT); //pin CS,SPI ,pin INT.
static const uint32_t FREQUENCE_DU_QUARTZ = 8000000; // quartz du MCP2515 en hertz
static const uint32_t FRENQUENCE_DU_BUS_CAN = 125000; // fréquence du bus CAN
CANMessage message; // objets pour les messages CAN
// -------------- Setup --------------
void setup() {
Serial.begin(9600); // com série
SPI.begin(); // bus SPI
Serial.println("Configuration du MCP2515");
ACAN2515Settings configuration(FREQUENCE_DU_QUARTZ, FRENQUENCE_DU_BUS_CAN);
// ---- Demarrage et control d'erreur du CAN ----
const uint32_t codeErreur = CAN.begin(configuration, [] { CAN.isr(); });
if (codeErreur == 0)
{
Serial.println("configuration ok");
}
else
{
Serial.println("Probleme de connexion");
while (1);
}
}
//------------ Loop --------------
void loop()
{
if (CAN.receive(message)) // signal arrive message CAN
{
float val1 = message.dataFloat[0];
Serial.print(" --Rec--> ");
Serial.println(val1);
}
}
// -------------- fin Pgm -------------------
Jean-Luc Merci
-
Bonjour
Modif des croquis du dessus, alléger pour plus de clarté
(valeurs des capteurs température virtuel )
il me reste la partie masque et filtre ou toujours rien ne fonctionnent
le détail :
Partie Émission :
/* CAN : numero des (éléments) capteurs pour les messages */
const uint16_t CAPTEUR1 = 10; /* le Capteur */
.....
/* Nbr de Bits pour les poids fort et faible */
const uint16_t NBBITS_TYPE_MESSAGE = 6; /* Groupe */
const uint16_t NBBITS_ID_CAPTEUR = 5; /* Element */
const uint16_t MESSAGE_GROUPE = 4; /*type de message (le Groupe 7,la clim)*/
const uint16_t MASK = MESSAGE_GROUPE << NBBITS_ID_CAPTEUR;
const uint16_t ID_1 = (MESSAGE_GROUPE << NBBITS_ID_CAPTEUR) | CAPTEUR1;
....
--------------------------
me donne sur le terminal
---------------------------
80 10000000 le masque "MASK"
---------------------------
8A :Msg1 envoye: 10001010 et les capteurs
8B :Msg2 envoye: 10001011
8C :Msg3 envoye: 10001100
-----------------------------
Pour la partie Réception:
...
const uint16_t capteurs = message.id & 0x8A; le capteur 1
const uint16_t capteurs = message.id & 0x8B; 2
const uint16_t capteurs = message.id & 0x8C; 3
...
et
..
const ACAN2515Mask masque = standard2515Mask( 0, 0, 0);
const ACAN2515AcceptanceFilter filtres[] = {
{ standard2515Filter( 0, 0, 0), receive1 }
.../
(masque mis à Zéro)
------------------------------
Visu sur le terminal des valeurs:
numero capteurs: 138 : 138 : 136
11.11 <--T1 --A-- H1--> 51.11
11.11 <--T2 --B-- H2--> 51.11
11.11 <--T3 --C-- H3--> 51.11
numero capteurs: 138 : 139 : 136
22.22 <--T1 --A-- H1--> 52.22
22.22 <--T2 --B-- H2--> 52.22
22.22 <--T3 --C-- H3--> 52.22
----------------------
c'est le fouillis 8) :'(
Question: quelles valeur Hexa a Changer / Ajouter ?????
j'ai tester toutes les combinaison possible depuis 3 jours, et rien de rien de valable
même crée un pdf sur la question ;)
Voili Voila
merci
-
Bonjour,
En réception, je ne comprends rien à ce que tu essayes de faire.
Quel est le sens de :
const uint16_t capteurs = message.id & 0x8A; /* adresse capteur */
?
message.id c'est l'identifiant du message. Normalement le numéro du capteur étant dans les 5 bits de poids faible, il faut l'isoler en faisant :
const uint16_t capteur = message.id & 0x1F;
Et c'est tout
Je ne comprends pas la triplication du code de réception. Pour « classer les message » il faudrait au moins faire des test ! :)
-
...... "faire des test !"
bonjour Jean-Luc
mais les Test c Ok
un exemple de recopie du terminal
la c'est modifiant les Numéro des Groupes :
pour Nbits Msg :6 / Nbits Capt:5
Msg Groupe:
0 0 0
20 100000 1
40 1000000 2
60 1100000 3
80 10000000 4
A0 10100000 5
C0 11000000 6
E0 11100000 7
100 100000000 8
la c les numéro des capteurs:
B5 :Msg1 envoye: 10110101 21
B6 :Msg2 envoye: 10110110 22
B7 :Msg3 envoye: 10110111 23
et des valeurs mis en Hexa coter réception
Rein ni fait, je cale et il me manque une cale
:-X
-
Je ne parle pas de faire des tests du logiciel
Je parle de tester l'identifiant du message reçu pour savoir de quel message il s'agit !
switch (message.id & 0x1F) {
case CAPTEUR1: ...
break;
case CAPTEUR2: ...
break;
...
Tu devrais aller lire https://www.locoduino.org/spip.php?article70 parce que là il te manque pas mal de bases
-
Bonjour
un demande d'aide sur comment signaler a la partie réception que l"émetteur est hors service?
ou que les données coter réception ne sont plus actualisé.
Lorsqu'une perte de com. intervient entre l'émetteur et récepteur CAN, les valeurs coté récepteur sont fausses , le récepteur garde la dernière valeur.
comment mettre c'est valeur à Zéro ??
les deux croquis
Emission ACAN2515_Test_Tx.ino
/*
*
* DESCRIPTION : Test bus CAN de valeur décimal sur Arduino UNO avec pseudo sonde DHT22
* avec 2 croquis,
* ACAN2515_Test_Tx.ino et ACAN2515_Test_Rx.ino
*
* BASES : sur une base https://www.locoduino.org/spip.php?article268
* : Sujet: Bus CAN et Décimal
*
* * Libraries:
* - ACAN2515 ver.2.1.0 de pierre Molinaro
* - https://github.com/pierremolinaro/acan2515
*
* Modif/Afaire:
* -o- a revoir filtrage non fonctionnelle
* -o- sur perte CAN émission les valeurs ne sont pas mises à zéro
* -o-
* -o-
* (3%) de l'espace de stockage de programmes
*
*/
//----------- 2022 ---------------- Fonctionnelle -----------------//
// ----- inclusion des bibliothèques -------------
#include <ACAN2515_Buffer16.h>
#include <ACANBuffer.h>
#include <ACAN2515Settings.h> // les reglages
#include <ACAN2515.h> // le controleur
#include <CANMessage.h> // les messages
/* Module CAN MCP2515 */
static const uint8_t MCP2515_CS = 10; /* pin SPI_CS */
static const uint8_t MCP2515_INT = 2; /* pin interruption */
/* objet de type ACAN2515 est instancié pour gérer le MCP2515 */
ACAN2515 CAN(MCP2515_CS, SPI, MCP2515_INT); /* pin CS,SPI ,pin INT */
static const uint32_t FREQUENCE_DU_QUARTZ = 8ul * 1000ul * 1000ul; /*quartz du MCP2515*/
static const uint32_t FREQUENCE_DU_BUS_CAN = 125ul * 1000ul; /*fréquence du bus*/
CANMessage messageCANdht; /* objets CAN pour les messages en emission */
/* CAN : numero des capteurs pour les messages */
const uint16_t ID_1 = 10;
const uint16_t ID_2 = 11;
//----------Virtuel DHT22 ---------------
/* capteur1 */
float t1 = 21.5; // température
float h1 = 51.5; // humidité
/* capteur2 */
float t2 = 22.6; // température
float h2 = 52.6; // humidité
static uint32_t milliEnvoi = 0; // Tempo d’envoi des messages CAN
void setup() { // -------------- Setup --------------
Serial.begin(115200); /* com série */
SPI.begin(); /* bus SPI */
Serial.println("Configuration du MCP2515");
/* création de l'objet ACAN2515Settings */
ACAN2515Settings reglages(FREQUENCE_DU_QUARTZ, FREQUENCE_DU_BUS_CAN);
/* objet nommer "reglages" dans l'exemple */
reglages.mReceiveBufferSize = 0; // nbr d'emplacement buffer
reglages.mTransmitBuffer0Size = 3; // file d'attente d'emission
/* Demarrage et control d'erreur du CAN */
const uint16_t codeErreur = CAN.begin(reglages, [] { CAN.isr(); });
if (codeErreur == 0)
{
Serial.println("Configuration ok");
}
else
{
Serial.println("Probleme de connexion");
while (1);
}
/* longeur des messages CAN */
messageCANdht.len = 8; // 8 octets pour les 2 float (temp-humid)
}
void loop() //------------------ Loop --------------
{
// --------------- envoie des messages CAN ----------------------------
uint16_t milliEncour = millis(); /* Tempo d'envoi ..*/
if (milliEncour - milliEnvoi >= 4000) { /*..toutes les 4 secondes */
//capteur1 -----------------------
messageCANdht.id = ID_1; /*Numéro d'intentifiant*/
messageCANdht.dataFloat[0] = t1;
messageCANdht.dataFloat[1] = h1;
if (CAN.tryToSend(messageCANdht)) {
Serial.println("message 1 envoyer");
Serial.print(" : t=");
Serial.print(messageCANdht.dataFloat[0]);
Serial.print(" , h=");
Serial.println(messageCANdht.dataFloat[1]);
Serial.println(" -----------------");
}
//capteur2 -----------------------
messageCANdht.id = ID_2;
messageCANdht.dataFloat[0] = t2;
messageCANdht.dataFloat[1] = h2;
if (CAN.tryToSend(messageCANdht)) {
Serial.println("message 2 envoyer");
Serial.print(" : t=");
Serial.print(messageCANdht.dataFloat[0]);
Serial.print(" , h=");
Serial.println(messageCANdht.dataFloat[1]);
Serial.println(" -----------------");
}
milliEnvoi = milliEncour; /* reset de la tempo */
}
}
// ----------- Fin du pgm ------------------
réception ACAN2515_Test_Rx.ino
/*
*
* DESCRIPTION : Test bus CAN de valeur décimal sur Arduino UNO avec pseudo sonde DHT22
* avec 2 croquis,
* ACAN2515_Test_Tx.ino et ACAN2515_Test_Rx.ino
*
* BASES : sur une base https://www.locoduino.org/spip.php?article268
* : Sujet: Bus CAN et Décimal
*
* * Libraries:
* - ACAN2515 ver.2.1.0 de pierre Molinaro
* - https://github.com/pierremolinaro/acan2515
*
* Modif/Afaire:
* -o- a revoir filtrage non fonctionnelle
* -o- sur perte CAN émission les valeurs ne sont pas mises à zéro
* -o-
* -o-
* (3%) de l'espace de stockage de programmes
*
*/
//----------- 2022 ---------------- Fonctionnelle -----------------//
/* ----- inclusion des bibliothèques -------------*/
#include <ACAN2515_Buffer16.h> /* les buffers */
#include <ACANBuffer.h>
#include <ACAN2515Settings.h> /* les reglages */
#include <ACAN2515.h> /* le controleur*/
#include <CANMessage.h> /* les messages */
/* ----- capteurs virtuelle -------------*/
float T1; float H1; /*capteur 1 */
float T2; float H2; /*capteur 2 */
/* Module CAN MCP2515 */
static const uint8_t MCP2515_CS = 53; /* pin SPI_CS */
static const uint8_t MCP2515_INT = 2; /* pin interruption */
/* objet de type ACAN2515 est instancié pour gérer le MCP2515 */
ACAN2515 CAN(MCP2515_CS, SPI, MCP2515_INT); /* pin CS,SPI ,pin INT */
static const uint32_t FREQUENCE_DU_QUARTZ = 8ul * 1000ul * 1000ul; /*quartz du MCP2515*/
static const uint32_t FREQUENCE_DU_BUS_CAN = 125ul * 1000ul; /*fréquence du bus*/
CANMessage message; // objets CAN pour les messages en réception
// -------------- Reception msg CAN --------------------------
void receive1 (const CANMessage & message) {
const uint16_t capteurs = message.id & 0x1F;
switch (capteurs) { /* ---- classement des messages CAN ----*/
case 10:
T1 = message.dataFloat[0]; /* ---- capteur A ----*/
H1 = message.dataFloat[1];
break;
case 11:
T2 = message.dataFloat[0]; /* ---- capteur B ----*/
H2 = message.dataFloat[1];
break;
}
}
/* ----- défini masques et filtres pour les messages ------*/
const ACAN2515Mask masque = standard2515Mask( 0, 0, 0);
const ACAN2515AcceptanceFilter filtres[] = {
{ standard2515Filter( 0, 0, 0), receive1 }
};
// --- defilement pour Debug --------------------------
unsigned long previousMillis = 0; /*reset du compteur des millisecondes*/
const long interval = 10000; /*Fréquence affichage debug (1000millisecondes=1mn) */
//-------------------------- SETUP ------------------------//
void setup() {
Serial.begin(115200); /* com série */
SPI.begin(); /* bus SPI */
Serial.println("Configuration du MCP2515");
ACAN2515Settings reglages(FREQUENCE_DU_QUARTZ, FREQUENCE_DU_BUS_CAN);
reglages.mReceiveBufferSize = 4; /* nbr d'emplacement buffer*/
reglages.mTransmitBuffer0Size = 0; /* file d'attente d'emission*/
/* Demarrage et control d'erreur du CAN */
const uint16_t codeErreur = CAN.begin(reglages,[] {CAN.isr(); }, masque, filtres, 1 );
// const uint16_t codeErreur = CAN.begin(reglages, [] { CAN.isr(); });
if (codeErreur == 0) {
Serial.println("configuration ok"); }
else {
Serial.println("Probleme de connexion");
while (1);
}
}
//------------------------------LOOP------------------------//
void loop() {
CAN.dispatchReceivedMessage();
// ------- tempo affichage print ---------------------
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
Serial.println( "--- test valeur CAN ----");
Serial.print(T1);
Serial.print( " deg : capteur A: % ");
Serial.println(H1);
Serial.println( " ------------------- ");
Serial.print(T2);
Serial.print( " deg : capteur B: % ");
Serial.println(H2);
}
}
// -------------- fin Pgm -------------------
-
Il y a au moins deux possibilités:
Un Time-out (Pas de réponse après un certain temps).
Ou un échange avec un message de service décrivant l’état de l’émetteur,
Et sans doute les deux.
Svp: utilisez le bouton “Modifier” pour éliminer les fautes ou mieux formuler une question.
-
Dominique merci pour le début de piste.
Mais je pensais que la librairie ACAN avait déjà une instruction, une fonction, pour ce genre de défaut?
je vais fouiller encore sur les exemples de pierre Molinaro, voir comment.
sinon "Un Time-out (Pas de réponse après un certain temps)." comment l’appliqué :(
“Modifier” .. c'est bon :)
-
Bonjour,
ACAN ignorant le contenu des messages, elle ne peut pas décider de valeur par défaut en cas de timeout
Pour faire un timeout il faut :
- Une variable qui reçoit la date courante (millis()) lorsqu'une donnée est reçue
- Un test dans loop qui compare la date courante moins la variable à une délai. Si le délai est dépassé, la donnée est mise à la valeur par défaut (0 ici)
Ça suppose évidemment que la réception (et donc l'envoi) est périodique.
-
Autant je pensais avoir compris le problème, autant je ne comprends plus rien maintenant.
Deux contrôleurs CAN ne maintiennent pas une connexion, l'émetteur se contente d'envoyer des trames et le récepteur de les recevoir. En l'absence d'un envoi de trame, il n'y a aucun moyen pour le récepteur de savoir que l'émetteur n'est plus là. C'est pas du TCP/IP.
Donc c'est à l'application de gérer l'absence de réception.
-
C’est à vous de définir (inventer) votre message de service.