I2C - Couldn't find a Board on the selected port

Bonjour à tous

J'ai fais mon propre micro-controleur avec un ATSAM21, comme pour l'ARduino Zero.

J'ai un problème au niveau de l'I2C qui me génère ce message

Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload

J'ai constaté que ceci se produit au moment ou l'I2C rentre en action.

L'erreur est générée à ce niveau

Si je mets un

Serial.println("1");

avant cette ligne, il s'affiche

Serial.println("2");

Après cette ligne, il s'affiche

Par conte, si je met

Serial.println("2");

après

Il ne s'affiche pas et le message d'erreur s'affiche.
Par contre, le message d'erreur ne s'affiche pas toujours, mais le Serial.println("3"), ne s'affiche jamais.

Je me demande si ce n'est du à un problème Hardware, mais je ne l'ai jamais eu, sur mes cartes précédentes

Avez-vous une idée par ou commencer à débuger?
Avez-vous eu ce problème?

Merci pour vos lumières

Jamais eu ce problème mais je n’ai jamais fait ma propre carte.

Dans quel contexte utilisez vous SiI2Cscan.cpp ? Quel boot loader ?

Pour ce qui est des print faites Serial.write(‘1’); Serial.flush(); en mettant la communication à 1 000 000 bauds avec votre ordinateur si vous voulez vraiment détecter où ça coince car Serial se fait par interruption en tâche de fond donc de manière asynchrone, votre code sera bien plus loin quand vous verrez apparaître ou pas le caractère envoyé. (Préférez write à print quand il n’y a qu’un seul caractère à écrire, c’est plus efficace)

le message d’erreur pourrait indiquer le programme fait planter le ATSAM21 qui ensuite fiche le bazar sur l’USB et le boot loader ne rétablit pas son port de communication.

Avez vous essayé avec un autre câble USB ?

Bonjour

la librairie SiI2Cscan me sert uniquement à lister les port I2C qui sont connectés.
Ce qui me permet de tester mes devise I2C.

J'ai essayé avec un autre cable, mais le problème est le même. D'ailleurs, je n'ai pas ce problème avec mes board précédents.

J'ai essayé avec un baud 115200, mais la plu rien ne s'affiche.

Je ne suis pas sûre que le port USB plante, car mon ordinateur biperais et le port est toujours affiché dans Menu -> Tools -> Ports.

Je me demande si le ATSAMD21 serait mal souder au PCB, mais pourtant un simple

loop(){
Serial.println(F("Helllo"));
delay(3000);
}

Fonctionne. Je peux allumer une led avec un bouton, mais j'ai pas encore tout testé, étant bloqué avec l'I2C.

vous avez des pullups pour vos lignes I2C ?

Bonjour,
oui j’ai deux résistances de 4.7K, comme le fait toujours.
J’ai essayé avec et sans les résistances.

si au lieu de Serial vous utilisiez des LEDs pour montrer où vous en êtes dans le code ? si ça fonctionne il faudra chercher une interaction néfaste entre Serial et I2C... (et ça aurait l'avantage de ne pas rajouter des interruptions et problèmes de timing éventuels)

C'est une très bonne idée, je vais essayé ceci ce soir

Malheureusement le problème est toujours là même sans le cable USB connecté.

J'ai alimenté mon circuit avec une batterie et j'ai modifié mon code pour qu'une LED flash 2 fois avant ceci

Puis, j'ai fait en sorte que cette LED reste allumée après cette ligne.

La LED flash deux fois, mais ne s'allume pas. Donc le code bloque au niveau de
à la fin de la transmission

error = Wire.endTransmission();

En principe, les adresses 0 à 7 et 78 à 7F sont réservées

Bonjour,
Je me demande si le problème vient de MOI.

J’ai essayé ceci
https://github.com/pierrot10/SiI2Cscan/blob/master/SiI2Cscan.cpp
avec une carte qui fonctionne et j’ai le même problème. Donc j’exclus cette librarie mais si malgré tout elle marche avec un de mes fichier ino.

J’ai repris mon fichier ino de référence et j’ai constaté que j’avais oublié de comment un capteur I2C qui n’étais pas sur ma nouvelle carte. Sur ma nouvelle carte, j’ai souder qu’un EEPROM I2C.

J’ai testé mon EEPROM avec un fichier eeprom.ino que j’ai créé pour un exemple
https://github.com/ecosensors/Ecoboard/tree/master/examples/eeprom et ca marche. Donc l’I2C fonctionne.

Je vais donc refaire mon fichier de référence en partant de zéro, mais pour ma nouvelle carte. Ce qui permettra de refaire un truc au propre et éliminer probablement une partie qui cause un problème.

Je reviens donner des nouvelles plus tard

Bonjour fdufnew

En principe, les adresses 0 à 7 et 78 à 7F sont réservées

Pourrais-tu me donner plus de précisions?

Qu'est-ce quite fait dire ceci?

Je pense que c'est un problème Hardware que je n'arrive donc pas à identifier.

J'ai repris mon fichier "référence" et j'ai commencer à le reconstruire.

Dans mon setup()je fais les truc Basic, sans faire I2C Scanner.
Quand mon code passe sur le RTC3231, le premier I2C, il plante comme décris plus haut.

Si j'upload ce code dans mon ancienne carte qui marche, CA PASSE. Donc dès qu'il voit le premier I2C, il plante.

//#define OLED

void setup() {
  // put your setup code here, to run once:
    
  Serial.begin(9600);
  Wire.begin();

  delay(8000);         // Wait for the terminal

  Serial.println(F("\r\n******************************************"));
  Serial.print(F("*             ECO-SENSORS "));
  Serial.print(VERSION);
  Serial.println(F(" *"));
  Serial.println(F("\r\n******************************************"));

  
// J'INITIE MA CARTE SD. CA PASSE!!
   if(Si.begin()==0){ // Init SD
    while(1){
      Si.sprintln(F("Error: Si.begin()"),0);
      delay(1000);
    }
  }

  //First LCD, PCF, then the RTC, the SD and the log files must be initiated
   
  Si.sprintln(F("\r\nSETUP"), 0);
  Si.sprintln(F("==================="), 0);
  
// OLED EST DESACTIVE
  #if defined(OLED)
  
    Si.sprintln(F("\r\nStarting OLED"),0);
    
    // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
    oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
    //oled.begin(SSD1306_SWITCHCAPVCC, 0x3D);  // initialize with the I2C addr 0x3D (for the 128x64)
    //oled.begin();
    oled.display(); 
                             
    #if defined(DEBUG)
      Si.sprintln(F("Wait for Splash"),0);
    #endif
    delay(2000); // Give a delay to display the Splash
    
    // Clear the buffer.
    oled.clearDisplay();                     // Clear buffer
    oled.fillRect(0, 0, oled.width(), 10, INVERSE);
        
    oled.display();
    oled.setTextColor(BLACK);
    oled.setCursor(1,1);
    oled.print("Setup");
    oled.display();
    oled.setTextColor(WHITE);
    oled.setCursor(0,16);
    oled.display();
    
    int o_y = 10; 
    Si.sprintln(F("[OK] OLED"),0);
    o_y = oledCursorY(o_y);
    oled.setCursor(0,o_y);
    oled.print("[OK] OLED");
    oled.display();
  #else
    Si.sprintln(F("[NA] OLED"),0);
  #endif


  #if defined(SENSOR_RTC_DS3231)
  
    Si.sprintln(F("\r\n# Start DS3231"),0); 
    if (!Si.RtcBegin())
    {
      #if defined(OLED)
        o_y = oledCursorY(o_y);
        oled.setCursor(0,o_y);
        oled.print("[KO] DS3231!");
        oled.display();
      #endif
      Si.sprintln(F("[KO] DS3231"),0);
   
      while (1)
      {
        #if defined(PCFlib) 
          expander.digitalWrite(wakeup_led, HIGH);
          delay(100);
          expander.digitalWrite(wakeup_led, LOW);
          delay(100);
          expander.digitalWrite(wattering_led, HIGH);
          delay(100);
          expander.digitalWrite(wattering_led, LOW);
          delay(100);
        #endif
      }
    }
   
    Si.RtcLostPower();
    
    Si.sprintln(F("[OK] DS3231"),0);
    #if defined(OLED)
      o_y = oledCursorY(o_y);
      oled.setCursor(0,o_y);
      oled.print("[OK] DS3231");
      oled.display();
    #endif      
  #endif

  /*
  * Get time
  */
  #if defined(SENSOR_RTC_DS3231)
    Si.sprintln(F("\r\n# Get time"),0); 
    Si.RtcGetTime(y,m,d,h,mn,s,lastTx,date_time);
  #else
    y = 1970;
    m = 1;
    d = 1;
    h = 0;
    mn = 0;
    s = 1;
    //date_time = "1970-01-01 00:00:01";
  #endif

  
  
  Serial.println(F("GOOOO"));
}

Voici ceque ca m'affiche dans mon terminal


  • ECO-SENSORS v1 *

Activation method ABP
SD card enable
LOGGER enable
PRINT enable
EEPROM enable

Begin SD

Listing files in root:
Current directory: /
0 2019-09-01 18:46:32 System Volume Information/
62 2000-01-01 01:00:00 clock.txt
0 2000-01-01 01:00:00 LOG/
88 2019-09-02 17:09:08 config.txt
235 2000-01-01 01:00:00 config_radio.txt
132 2000-01-01 01:00:00 config_sensors.txt
57 2019-09-02 16:59:14 config_irrigation.txt
235 2019-09-01 21:26:06 config_radio-otaa.txt
246 2019-09-02 16:53:02 config_radio-abp.txt
listing Files Done!
_isSdReady:1

SETUP

[NA] OLED
[OK] Wire

Start DS3231

On voit qu'il ne va pas plus loin que

Start DS3231

Juste après ceci, il commence a initier le RTC3231.

Ce qui a d'intéressant de voir, est que sur ma carte j'ai un switch pour allumer ou éteindre mon module. Forcément, ce swicth est ON. Qaund je le passe à OFF, il affiche ceci avant de s’éteindre

RTC lost power, lets set the time!
[OK] DS3231

Get time

C'est marrant, quand mon module est désalimenté, il affiche encore ceci!!!!!

J'ai pourtant vérifier mon schéma et je ne vois pas d'erreur.

Comment l'I2C peut être impacter de la sorte? Une idée?

Wire peut partir dans une boucle infinie selon certaines circonstances, peut être c’est ce qu’il vous arrive (voire aussi ce bug report là)

pierrot10:
Bonjour fdufnew
Pourrais-tu me donner plus de précisions?

Qu'est-ce quite fait dire ceci?

La spécification du bus I2C Voir page 17

Il faut s'assurer qu'il y ait toujours des pullups sur SCL et SDA même lorsque les périphériques sont non alimentés.
Il faut aussi s'assurer qu'un périphérique non alimenté ne tire pas la ligne SCL à zéro car cela bloque le bus (clock stretching, voir dans la spécification)

hum je reviens sur ce que je disais plus haut, j'ai jeté un oeil sur sur le code source et ils ont mis un timeout donc ça ne devrait plus être un souci et quand le timeout se déclenche, ça appelle la fonction void twi_handleTimeout(bool reset)

MAIS ... pour que le timeout fonctionne il faut que la variable twi_timeout_us soit non nulle, et elle est nulle pour le moment

cf ce qu'ils écrivent ici:

// twi_timeout_us > 0 prevents the code from getting stuck in various while loops here
// if twi_timeout_us == 0 then timeout checking is disabled (the previous Wire lib behavior)
// at some point in the future, the default twi_timeout_us value could become 25000
// and twi_do_reset_on_timeout could become true
// to conform to the SMBus standard
// http://smbus.org/specs/SMBus_3_1_20180319.pdf
static volatile uint32_t twi_timeout_us = 0ul;
static volatile bool twi_timed_out_flag = false;  // a timeout has been seen
static volatile bool twi_do_reset_on_timeout = false;  // reset the TWI registers on timeout

éventuellement essayez de recompiler en mettant 25000 au lieu de 0 et true au lieu de false

static volatile uint32_t twi_timeout_us = 25000ul; // **** J-M-L CHANGE ****
static volatile bool twi_timed_out_flag = false;  // a timeout has been seen
static volatile bool twi_do_reset_on_timeout = true;  // *** J-M-L CHANGE *** reset the TWI registers on timeout

Merci JML,
Je vais voir ceci plus cet après-midi. J'ai trouvé éventuellement une source du problème, mais je vais encore testé cet après-midi, avant de dire quelque chose

Bonjour,
Voici des nouvelles. J'ai une ancienne carte ou tout fonctionne.
J'ai fais une nouvelle version de cette carte.
Apres le premier assemblage de la nouvelle carte, je rencontre ce problème.

Il y a un truc que je n'ai pas dit car je ne pensais pas qu'il y aurait une influence et ca semble etre le cas.
La seule différence entre l'ancien PCB et le nouveau, j'ai ajouté un TPS6109 pour avoir du 5V en sortie.

J'ai assemblé un nouveau PCB, mais sans ce TPS6109 et sans aucun devise I2C.
J'ai mis un PCF8574 (extabder port) et ca marche.
J'ai ajouté un RTC3231, et ca marche

Mais pourtant j'ai toujours ce message d'erreur que je n'ai pas avec mon ancienne carte (je vais encore vérifier)

Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload

Mais j'ai l'impression que ce message ne s'affiche qu'une fois, quand on connecte le cable USB. Puis si je reset ma carte et le code s'exécute, il ne s'affiche plus.

A première vu le TPS6109 semble une cause de mon problème, mais je peux encore l'expliquer car il n'a pas de pi SDA, SCL.Mais j'aimerais bien supprimer ce message, tout comme l'erreur qui le génère :slight_smile:

J'ai oubliée de préciser un truc, j'ai fait ces teste sans

Je viens d'essayer avec e ca va un peu plus loin

Il dépasse cette ligne

et la fonction Wire.endTransmission()

me retourne l'erreur 2

Je vais chercher...

Mais j'ai l'impression que ce message ne s'affiche qu'une fois, quand on connecte le cable USB. Puis si je reset ma carte et le code s'exécute, il ne s'affiche plus.

Ma compréhension c'est que si le code qui plante bloque la gestion USB (il n'y a pas de composant dédié séparé - si vous êtes en attente active dans une interruption par exemple) alors le bootloader n'aura pas la main et donc l'IDE vous dira qu'il ne voit pas la carte.

Un reset vous sort de cette interruption et rend la main au bootloader qui peut accepter un upload

Bonjour J-M-L, bonjour tous

Merci pour votre aide, je pense que mon problème est résolu sans pouvoir donner d'explication, sauf bien entendu, les étapes que j'ai faite, jusqu'à maintenant.

Je viens de tester un nouveau I2C, le baromètre BME280 et il fonctionne aussi. Je continue à développer mon ino au fur et à mesure de mon avancement.

Aussi, j'avais l'IDE 1.8.3. Je l'ai mis à jour avec le 1.8.13 et j'ai mis à jour l'AVR comme me l'a proposé l'IDE.
Depuis je n'ai plus le message d'erreur

Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload

Je suis content, mais est-ce suffisent?