Bonjour,
Je suis sur un petit projet arduino qui me permet de générer un signal carré.
De manière globale tout fonctionne bien à l'exception que la communication i2c de l'arduino se coupe de temps en temps. Le truc c'est que comme le système doit être autonome, je voudrais savoir comment proprement relancer la connexion...
voici le code (qui fonctionne très bien quand pas de perte de com..) :
// code arduino slave sur COM6 port USB droit
#include <Wire.h>
#define SIGNAL1 12 // ici on definit les sorties
unsigned char prescaler = 0b00001101; // variable d'ajustement du prescaler
unsigned short frequenceInt; // frequenceInt
void setup () {
Wire.begin(8); // join i2c bus (address optional for master)
Wire.onReceive(receiveEvent);
Serial.begin(2000000); // terminal speed
pinMode (SIGNAL1, OUTPUT);
// ======================================================================================================================================================
// Paramétrage du timer1, pour qu'il déclenche une interruption,
// ======================================================================================================================================================
noInterrupts(); // On désactive les interruptions, pour commencer
TCCR1A = 0b00000000;
TIMSK1 = 0b00000010;
bitSet(TIMSK1, OCIE1A); // On met le bit OCIE1A à 1
TCNT1 = 0; // Mise du timer1 à zéro
interrupts(); // Et, on ré-active les interruptions
}
// ======================
// Routine d'interruption
// ======================
ISR(TIMER1_COMPA_vect) {
digitalWrite (SIGNAL1, !digitalRead(SIGNAL1));
TCCR1B = prescaler;
OCR1A = frequenceInt; // mise à jour de la valeur OCR1A
}
// =================
// Boucle principale
// =================
void loop ()
{
}
void receiveEvent(int howMany)
{
if (howMany > 0) // ici si le nombre de byte est superieur a 0
{
uint16_t r1 = Wire.read(); // reception du premier byte qui est egal a 0
uint16_t r2 = Wire.read(); // reception du second byte
uint16_t r3 = Wire.read(); // reception du troisieme byte
uint16_t valeur = r2 | r3 <<8; // mise en forme
Serial.print("valeur = "); // on affiche la valeur
Serial.println(valeur);
}
}
Ce n'est pas une liaison Ethernet. Il n'y a pas de connexion à proprement parler.
Le maitre recommence juste le transfert depuis le début.
Ceci dit, l'I²C n'est pas très robuste mais si la liaison ne fait pas plusieurs mètres et que l'ambiance n'est pas trop perturbée, il ne devrait, en principe, pas y avoir de perte.
Est-ce que la "perte" vue du maitre est un NACK ou juste un silence de l'esclave.
Bonjour,
Pas vu apparaître de NACK (en fait j'en sais rien) mais sur le moniteur l'affichage se stoppe.
C'est pas trés clair, mais peut être que je peux faire une commande qui permet un debugg plus facile.
Bon bah ce qu'il faut retenir de ces expériences, c'est que la communication I2C entre arduino fonctionne extrêmement bien.
La communication i2c arduino / raspberry n'est pas fiable.
Les tests en cours démontrent que la communication UART est plutot bonne entre Raspberry / arduino.
J'utiliserai donc cette solution.
Merci pour vos conseils.
hello
je regarde ton code et je me dis qu'il ne peut fonctionner.
je le copie et le mets dans une méga équipée d'une led + résistance sur D12 et effectivement, il ne fonctionne pas
accessoirement dans ton calcul de valeur, que fais du de r1 ?
uint16_t r1 = Wire.read(); // reception du premier byte qui est egal a 0
uint16_t r2 = Wire.read(); // reception du second byte
uint16_t r3 = Wire.read(); // reception du troisieme byte
uint16_t valeur = r2 | r3 <<8; // mise en forme
Serial.print("valeur = "); // on affiche la valeur
Serial.println(valeur);
le timer ne peut démarrer tant que TCCR1B n'est pas initialisé à au moins 0b00001001
tu le fais effectivement mais dans la routine d'interruption de comparaison.
et comme le timer ne peut compter, il ne va pas dans la routine d'interruption.
ta variable valeur contient la valeur reconstruite de ce que tu as reçu du rapsberry, mais tu n'en fais rien.
je suppose que tu veux la mettre dans OCR1A, en passant par frequence int . mais là aussi, il faut passer par la routine d'interruption de comparaison.
perso, j'aurai probablement utilisé le toggle sur OC1B, lequel est D12 de la Méga