Bonjour
Dans mon projet solaire, J’ai un contrôleur maitre avec un Atmega1284P. J’ai 3 passerelles RS485 I2C avec un Atmega328P Arduino.
La passerelle « Transmetteur » Reçoit une chaine de 8 octet sur le port série. Les 8 octets sont stockés dans un tableau. Le maitre récupère les 8 octets via l’I2C. Cette passerelle est unidirectionnelle.
Le 2 autre passerelles « Onduleur » reçoivent les 8 octets sur le bus I2C pour les renvoyer à l’onduleur via le port série. En retour elle reçoit 15 octets émis par l’onduleur, pour les stokers dans un tableau, qui sera lu par le maitre via l’I2C. cette passerelle est bidirectionnelle.
Dans mon contrôleur maitre, il y a plusieurs modes de fonctionnement. On va rester sur le MODE 1.
Dans ce mode, je récupère les 8 octets depuis la passerelle « Transmetteur » pour les renvoyer à l’identique vers les 2 autres passerelle « Onduleur ».
Mon souci, c’est que je ne parviens pas à lire les 8 octets le la passerelle transmetteur via l’I2C.
Code du maitre
if (BoucleR == 100)
{
i2c_Trs(); // Recuperation des données du Tansmetteur de mesure de puissance
//Transforme deux byte de 8 bits en un mot 16 bits
Pconsommer = (Transmetteur[4] << 8) | Transmetteur[5]; // Recuperation de la puissance consomé instantané
SommeDeControle = Transmetteur[7]; // Recuperation de la somme de controle
}
if (Mode == 1) // ~~~~~~~~~~ MDE DIRECT, RENVOIE LA MESURE DE PUISSANCE DANS CHAQUES ONDULEURS
{
aff1(); // AFFICHE 1 sur 7 SEGMENTS pour le mode 1
for (int p = 0; p < 8; p++)
{
Onduleur1send[p] = Transmetteur[p]; // Transfére les données du transmetteur directement dan l'onduleurs N°1
Onduleur2send[p] = Transmetteur[p]; // Transfére les données du transmetteur directement dan l'onduleurs N°2
}
PU_inst = Pconsommer * N_Onduleurs; // ON LA RE-MILTIPLIE PAR LE NOMBRE D'ONDULEUR POUR L'AFFICHAGE
A_PuissanceInjecte = PU_inst / N_Onduleurs; // Affichage de la puissance envoyer dan l'onduleur N°1
if (A_PuissanceInjecte > 700) // Si la puissance est superieure a 700 Watts
{
A_PuissanceInjecte = 700; // On affiche la puissance maxi de l'onduleur qui est de 700 Watts
}
B_PuissanceInjecte = PU_inst / N_Onduleurs; // Affichage de la puissance envoyer dan l'onduleur N°2
if (B_PuissanceInjecte > 700) // Si la puissance est superieure a 700 Watts
{
B_PuissanceInjecte = 700; // On affiche la puissance maxi de l'onduleur qui est de 700 Watts
}
}
if (BoucleR == 500 && Commtrs_ok == true) // Au cycle 150, on interoge les onduleurs solaire
{
i2c_OndA(); // Appel sous programme de communication I2C Onduleur N°1
Onduleur1Ubatt = (Onduleur1rcv[5] << 8) | Onduleur1rcv[6]; // On met deux octets da un mot
Onduleur1Ibatt = (Onduleur1rcv[7] << 8) | Onduleur1rcv[8]; // On met deux octets da un mot
Onduleur1Ures = Onduleur1rcv[10]; // Tension reseau
Onduleur1Freq = Onduleur1rcv[11] / 2; // Frequence reseaux
int Calcul11 = (Onduleur1rcv[13] >> 4) | 0x000F;
int Calcul12 = Onduleur1rcv[13] | 0X000f;
int Calcul13 = (Calcul11 * Calcul12) / 10;
int Calcul14 = Onduleur1rcv[12] | 0X000f;
int Calcul15 = Calcul14 / 10;
Onduleur1Temp = Calcul13 + Calcul15; //
}
// _______________________________________________________________ ONDULEUR N°2
if (BoucleR == 1000 && Commtrs_ok == true)
{
i2c_OndB(); // Appel sous programme de communication I2C Onduleur N°2
Onduleur2Ubatt = (Onduleur2rcv[5] << 8) | Onduleur2rcv[6]; // On met deux octets da un mot
Onduleur2Ibatt = (Onduleur2rcv[7] << 8) | Onduleur2rcv[8]; // On met deux octets da un mot
Onduleur2Ures = Onduleur2rcv[10]; // Tension reseau
Onduleur2Freq = Onduleur2rcv[11] / 2; // Frequence reseaux
int Calcul21 = (Onduleur2rcv[13] >> 4) | 0x000F;
int Calcul22 = Onduleur2rcv[13] | 0X000f;
int Calcul23 = (Calcul21 * Calcul22) / 10;
int Calcul24 = Onduleur2rcv[12] | 0X000f;
int Calcul25 = Calcul24 / 10;
Onduleur2Temp = Calcul23 + Calcul25;
}
Code de la passerelle transmetteur
void loop()
{
Cycle = Cycle + 1; // Incrementation du cycle programme
//------------------------------------------------------
if (Cycle == 1) // Au cycle 1 appel sous programme affichage RUN
{
LCDrun(); // Appel sous programme
}
//------------------------------------------------------
if (Serial.available() > 0) // tant qu'il y a quelque chose à lire
{
int rLen = Serial.readBytes(Transmetteur, 8); // Reception des 8 octets depuis le transmetteur
CommRS485_OK = true; // On a bien recu la chaine d'octets depuis le transmetteur, on met le bit a 1
}
if (CommI2C_OK == false) // Si le bit de comm est a 0, il y a une erreur
{
TimeoutI2C = TimeoutI2C + 1;
if (TimeoutI2C > 1000000)
{
Cerreur = 10;
void LCDtimeoutE1(); // Appel sous programme d'affichage de l'erreur
TimeoutI2C = 0;
}
} else if (CommRS485_OK == false)
{
TimeoutRS485 = TimeoutRS485 + 1;
if (TimeoutRS485 > 1000000)
{
Cerreur = 20;
void LCDtimeoutE2(); // Appel sous programme d'affichage de l'erreur
TimeoutRS485 = 0;
}
} else {
Cerreur = 0;
TimeoutI2C = 0;
TimeoutRS485 = 0;
}
//------------------------------------------------------
if (Cycle == 10) // Au 10eme cycle on affice la puissance conssomé
{
Pinst = (Transmetteur[4] << 8) | Transmetteur[5]; // Puissance consomé instantané, 2 bytes dans un Mot
LCDaffiche(); // Appel sous programme d'affichage de la puissance
}
//------------------------------------------------------
if (Cycle >= 90000)
{
Cycle = 0; // Remise a ZERO du Cycle
CommI2C_OK = false; // Remise a ZERO du bit de communication I2C
CommRS485_OK = false; // Remise a ZERO du bit de communication RS485
}
}
//------------------------------------------------------
// réponse à une requête I2C
// mode Esclave
// cette fonction "handler" a été enregistrée dans le setup()
//------------------------------------------------------
void requestEvent()
{
//for (int t = 0; t < 8; t++)
//{
Wire.write(Transmetteur[0]); // répond par un message
Wire.write(Transmetteur[1]); // répond par un message
Wire.write(Transmetteur[2]); // répond par un message
Wire.write(Transmetteur[3]); // répond par un message
Wire.write(Transmetteur[4]); // répond par un message
Wire.write(Transmetteur[5]); // répond par un message
Wire.write(Transmetteur[6]); // répond par un message
Wire.write(Transmetteur[7]); // répond par un message
CommI2C_OK = true; // Le maitre a bien recupéré les octets, on met le bit a 1
//}
}
Sur mes circuits, j’ai mi une LED sur le signal SDA pour visualisé l’activité du bus. Dans mon code, j’ai mis des bits de surveillance de la communication. Si la passerelle transmetteur ne répond pas, on ne dialogue plus avec les passerelles des onduleurs. Ça fonctionne.
Cdt