Bonjour à tous,
Après avoir cherché des solutions sur ce forum pendant plusieurs jours, j’ai fini par décider de demander de l’aide. (Je précise que je suis plus ou moins novice en Arduino).
MISE EN CONTEXTE :
Je travaille sur la fabrication d’une machine emballeuse de barres de céréales, utilisant des moteurs CC (qui devront être synchronisés) et plusieurs capteurs.
Aujourd’hui, je suis encore bien loin de la fin, je m’intéresse pour l’instant à la communication I2C entre deux cartes MEGA et à la gestion d’interruption.
La carte maitre accueillera une interface homme/machine (un écran tactile TFT) qui enverra les ordres de l’opérateur. De son côté, la carte esclave accueillera les shields moteurs et les différents capteurs.
L’opérateur doit pouvoir, à tout moment, mettre en pause la machine si besoin (pour sa pause-café par exemple !).
EXPLICATION DE LA DEMARCHE :
Pour mettre en œuvre ceci, nous avons utilisé la bibliothèque Wire qui permet la communication, et la bibliothèque sleep_n0m1 pour la mise en veille du système.
PROBLEME :
Lorsque l’on fait fonctionner le système avec seulement la méthode I2C, tout fonctionne parfaitement. De même, le code de mise fonctionne bien lorsqu’il est testé sur une carte. Cependant, si on l’intègre au code, la mise en veille ne fonctionne plus (mise en veille suivi du réveil instantané).
Il y a donc clairement des interférences entre les méthodes d’I2C et d’interruptions.
Auriez-vous une solution ? Merci d’avance
Ci-joint respectivement les codes maître et esclave.
#include <Wire.h>
#define I2C_MASTER_ADRESS 0
#define I2C_SLAVE_ADDRESS 1
const int MAX_LENGTH = 10;
const int length = 7;
/* ordre */
char MPT1[10]="PT1:000";
const int BP1 = 2;
const int PT1 = 3;
const int BPINTERRUPT = 4;
const int INTERRUPT = 7;
boolean isRunning = true;
//------------------------------------------------------------------------------------
void setup(){
Serial.begin(9600);
Wire.begin(I2C_MASTER_ADRESS);
Serial.println(" - Je suis le maitre - ");
pinMode(BP1, INPUT);
pinMode(PT1, INPUT);
pinMode(BPINTERRUPT, INPUT_PULLUP);
pinMode(INTERRUPT, OUTPUT);
delay(1000);
}
//------------------------------------------------------------------------------------
/* Cette fonction se lance pour récupérer une information envoyé par une slave */
void RequestFromSlave() {
Wire.requestFrom(I2C_SLAVE_ADDRESS, length);
char message[MAX_LENGTH];
for(int j=0 ; j < length ; j++){
message[j] = Wire.read();
}
delay(500);
switch(message[0] + message[1]+ message[2]){
case 'T' + 'H' + '1':
TH1Function(message[4], message[5], message[6]);
break;
default:
Serial.println("Commande inconnue");
break;
}
}
//------------------------------------------------------------------------------------
void BPINTERRUPTFunction(){
if (digitalRead(BPINTERRUPT) == LOW){
if(isRunning){
digitalWrite(INTERRUPT, HIGH);
Serial.println("HIGH");
}else{
digitalWrite(INTERRUPT, LOW);
Serial.println("LOW");
}
delay(100);
isRunning = !isRunning;
}
}
//------------------------------------------------------------------------------------
/* Cette fonction se lance pour analyser l'information du capteur de température */
void TH1Function(char centaine, char dizaine, char unite){
int number = ((unite - 48) + ((dizaine - 48) * 10) + ((centaine - 48) * 100));
Serial.print("Température des résistances : ");
Serial.print(number);
Serial.print("°C");
Serial.println();
}
//------------------------------------------------------------------------------------
/* Cette fonction se lance dès que nous modifions la valeur du PT1 */
void PT1Function(){
int PreviousValPT1 = 0;
int ValPT1 = analogRead(PT1);
ValPT1 = map(ValPT1, 0, 1023, 0, 255);
if (PreviousValPT1 != ValPT1) {
PreviousValPT1 = ValPT1;
Serial.println(PreviousValPT1);
//48 <=> code ascii de '0'
MPT1[6] = (PreviousValPT1 % 10) + 48;
PreviousValPT1 /= 10;
MPT1[5] = (PreviousValPT1 % 10) + 48;
PreviousValPT1 /= 10;
MPT1[4] = (PreviousValPT1 % 10) + 48;
PreviousValPT1 = ValPT1;
Serial.println(MPT1);
Wire.beginTransmission(I2C_SLAVE_ADDRESS);
Wire.write(MPT1);
Wire.endTransmission();
delay(50);
}
}
//------------------------------------------------------------------------------------
void loop(){
RequestFromSlave();
PT1Function();
BPINTERRUPTFunction();
delay(100);
}
#include <Wire.h>
#include <AFMotor.h>
#include <Sleep_n0m1.h>
Sleep sleep;
#define I2C_MASTER_ADRESS 0
#define I2C_SLAVE_ADDRESS 1
const int MAX_LENGTH = 10;
const int PinTemperature = A10;
const int PinLED = 34;
const int PinInterrupt = 19;
AF_DCMotor MCC1(1);
/*ordre*/
char TH1[10]="TH1:000";
char CP1[10]="CP1:000";
boolean isRunning = true;
//------------------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
Wire.begin(I2C_SLAVE_ADDRESS);
Serial.println(" - Je suis l'esclave - ");
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvents);
pinMode(PinInterrupt, INPUT);
attachInterrupt(4, onRelease, RISING);
pinMode(PinLED, OUTPUT);
MCC1.setSpeed(0);
MCC1.run(RELEASE);
delay(1000);
}
//------------------------------------------------------------------------------------
/* Cette fonction se lance dès que nous recevons un message de la carte maitre */
void receiveEvent(int length){
char message[MAX_LENGTH];
for(int j = 0 ; j < length ; j++){
message[j] = Wire.read();
}
Serial.print("Ordre reçu : ");
Serial.println(message);
switch(message[0] + message[1]+ message[2]){
case 'P' + 'T' + '1':
Serial.println("Modification de la vitesse du MCC\n");
PT1Function(message[4], message[5], message[6]);
break;
default:
Serial.println("Commande inconnue\n");
break;
}
}
//------------------------------------------------------------------------------------
/* Cette fonction se lance pour envoyer une information au maitre */
void requestEvents(){
Serial.print("envoi de TH1 = ");
Serial.println(TH1);
Wire.write(TH1);
delay(100);
}
//------------------------------------------------------------------------------------
/* Cette fonction se lance dès que nous appuyons sur le bouton d'interruption */
void onRelease(){
Serial.println("SLEEP zzzz");
digitalWrite(PinLED, HIGH);
sleep.pwrDownMode();
sleep.sleepInterrupt(4, RISING);
attachInterrupt(4, onRelease, RISING);
digitalWrite(PinLED, LOW);
Serial.println("WAKE UP");
}
//------------------------------------------------------------------------------------
/* Cette fonction se lance pour récupérer la valeur de la température */
void TH1Function(){
int PreviousValTH1 = 0;
int sensorVal = analogRead(PinTemperature);
float voltage = (sensorVal/1024.0)* 5.0;
float ValTH1 = (voltage - 0.5)*100;
if (PreviousValTH1 != ValTH1){
PreviousValTH1 = ValTH1;
TH1[6] = (PreviousValTH1 % 10) + 48;
PreviousValTH1 /= 10;
TH1[5] = (PreviousValTH1 % 10) + 48;
PreviousValTH1 /= 10;
TH1[4] = (PreviousValTH1 % 10) + 48;
PreviousValTH1 = ValTH1;
Serial.println(ValTH1);
}
}
//------------------------------------------------------------------------------------
/* Cette fonction se lance dès que nous recevons un ordre PT1 */
void PT1Function(char centaine, char dizaine, char unite){
int number = (unite - 48) + ((dizaine - 48) * 10) + ((centaine - 48) * 100);
Serial.print("vitesse du MCC1 : ");
Serial.println(number);
MCC1.setSpeed(number);
MCC1.run(FORWARD);
}
//------------------------------------------------------------------------------------
void loop() {
TH1Function();
delay(100);
}