Reconnexion auto suite perte communication i2c

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);
	}
}

:warning:
Post mis dans la mauvaise section, on parle anglais dans les forums généraux. déplacé vers le forum francophone.

Merci de prendre en compte les recommandations listées dans Les bonnes pratiques du Forum Francophone

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.

Bonsoir wawann

As-tu des résistances de pull up sur ton bus?

Cordialement
jpbbricole

Bonjour,
Non je n'ai pas ajouté de resistance, mais je crois que l'arduino mega 2560 intégre déjà ce type de résistance (RN1).

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);

Bonjour,
Je ne fais rien de r1 car r1 = 0

Mais le code fonctionne, c'est juste qu'il se stoppe après quelques minutes.

chez moi, la led est allumée fixe

Il faut le raspberry avec sinon effectivement ça marche pas.

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

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.