- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 10

Thema: Sensoren blockieren I2C Bus

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Das Beispiel von Oberallgeier kann man noch erweitern indem man den Bus Status abfragt oder wenn mehrere Anfragen fehlschlagen einfach mal einen Bus reset durchführt.
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    @damfino:
    ja, das habe ich zum probieren auch so gemacht mit den Status Abfragen, da ich das ganze dann im Interrupt verarbeiten möchte.
    so kann ich schön mit Breakpoints gucken wie der interne Status vom Controller steht.

    Code:
    //----------------------------------------------------------
    BOOL i2c_check(U8 address, U8 ReadWriteMode)
    { volatile U8 stat;
      BOOL result;
    
    // stat mueste 0xF8 sein
      stat = I2C_STAT;
    
    //  setze das Startflag
      I2C_CONSET = CON_STA;      // STA Set Start flag
      // Start Condition wird sofort ausgeschoben
    
      // warte auf das SI Flag, dann ist Startcondition fertig
      if (! i2c_waitSI())
      {
        i2c_stop();
        return FALSE;
      }
    
    // stat muesste nun 0x08 sein
      stat = I2C_STAT;
      I2C_CONCLR = CON_STAC;  // loesche das Start Flag
    //  set address and read/write bit to the dat register
      I2C_DAT = (address << 1 ) | ReadWriteMode;
      // loesche SI Flag startet das Ausschieben der Adresse und RW Bit
      I2C_CONCLR = CON_SIC;
    
      // warte auf das SI Flag
      if (! i2c_waitSI())
      {
        i2c_stop();
        return FALSE;
      }
    
      stat = I2C_STAT;
    // stat muesste nun 0x18 sein wenn ACK gesendet wurde vom Slave
    // oder 0x20 Adresse transmitted, no ACK received, kein Slave antwortet
    // wenn ReadMode also RW Bit = 1 dann wird der status 0x40 oder 0x48
      result = FALSE;
      if ((ReadWriteMode == I2C_WRITE) && (stat == 0x18)) result = TRUE;
      if ((ReadWriteMode == I2C_READ ) && (stat == 0x40)) result = TRUE;
    
    
      // neu 27.01.2018 , wir lesen ein Byte ein, damit sich die Chips wieder
      // synchronisieren können. Einige brauchen das anscheinend
      I2C_CONCLR = CON_AAC;   // clear the Ackflag // wir wollen danach nichts weiter lesen NACK
      I2C_CONCLR = CON_SIC;   // loesche SI Flag startet das Ausschieben der Adresse und RW Bit
    
      // warte auf das SI Flag
      if (! i2c_waitSI())
      {
        i2c_stop();
        return FALSE;
      }
    
      stat = I2C_STAT;
    
      // STOP condition
      I2C_CONCLR = CON_STAC;  // clear the Start flag
      I2C_CONCLR = CON_AAC;   // clear the Ackflag
      I2C_CONSET = CON_STO;   // set STO
    
      // loesche SI Flag startet, das Ausschieben der Stop condition
      I2C_CONCLR = CON_SIC;
    
    // stat mueste wieder 0xF8 sein
      stat = I2C_STAT;
    
      return result;
    }
    Geändert von Siro (27.01.2018 um 12:05 Uhr)

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.694
    Das Beispiel von Oberallgeier kann man noch erweitern ..
    Die aktuelle Abfragen des I²C-Busses beim Start von archie - > 1 m lang - erzeugen die folgenden Ausgaben auf UART/Terminal und LCD (bessere Auflösungen im Bild verlinkt ) . Angezeigt werden also drei (von mehreren Slaves), hier MotorController, KopfController und ArmRechtsCOntroller. Üblicherweise wird aber auch der ALCo (ArmLinksController) angezeigt :

    ......Bild hier  

    ......Bild hier  

    In der kompletten UART-Aufzeichnung (im Bild verlinkt) trennt der rote Strich zwei Zustände. Wenn die I²C-Leitung mit einem nicht-stromführenden Slave verbunden ist (Beispiel unterhalb rot - korrig.28.1.´18x) dann hängt das Programm beim ersten I²C-Aufruf. Ist "nur" die I2C-Leitung vom Bus abgeklemmt worden, dann kommen die kompletten Suchergebnisse, siehe oben.

    Der dazugehörige Code steht unten. Dem fehlt offenbar ne Abfrageschleife, die im main von archie den Fehler abfängt (existiert derzeit nicht) :
    Code:
    // ============================================================================= =
    // ============================================================================= =
     void i2clook (void)            // Welche I²C-Devices existieren? Liste ?
     {                              //                              Aufruf     main =>
    // Teste I²C-Schreibadressen von 0x70hex bis 0xAC, 112 - 254 (früher bis 0xFC)
    //   ##>> Testbereich einschränken auf 112 - 159 bzw x70 - x9F
    //      Erfolgsmeldung(en) ausgeben mit Adresse dez und hex, Fehlsuche mit "-"
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //              B E A C H T E   bei   S T O E R U N G
    //      https://www.roboternetz.de/community/threads/71534-Uhrschalt
    //      plan-%C3%BCberpr%C3%BCfen-MOSFET-und-MAG3110?p=642024&view
    //      full=1#post642024
    ////        Dazu lässt man SDA aus Sicht des Masters offen und erzeugt 9 mal einen
    ////            Takt auf SCL. Danach erzeugt man ein Stop. Das sollte die
    ////            Statemachine im Slave zurück setzen
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      uint8_t jaflag = 0;           // Ja-Flag
    // - - - - - - - - - - - - - - -
    
      uputs0 ("\r\tSuche I²C-Devices im Bereich 0x70/112dez - 0xFE/254dez"); 
      uputs0 ("\r\tJedes '-' bedeutet: Slave/s nicht vorhanden oder defekt\r\t");
                                    // war 0x70 - 0xAC
                                    // bzw 0x70/112dez - 0x9F/159dez bzw 0x70 - 0xAC
      Line2();                      // LCD vorbereiten für Anzeige
      lcd_string("                ");       // Zeile 2 löschen
    
      for ( u8 such=0x70; such <= 0xF0; such = such + 2 )   // Adressenbereich
      {                             // Teste den I2C-Adressbereich gemäß for-Schleife
        if(!(i2c_start(such)))      // Slave bereit zum schreiben?
        {                           // 
          i2c_stop();               // Zugriff beenden
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //##25Jun14,14h01    uputs0 ("\r\t\tSlave addr\t"); // Melde zugriffbereiten Slave
    //      =: SetCursor (2, 10) heisst SetCursor (x,y), x=zeile {1,2}, y=Pos {0, 15}
          uputs0 ("\r\t\tSlave addr\t");      // Melde zugriffbereiten Slave
          uputs0i (such); uputs0hex (such); //   .. mit dezimaler und Hex-Adresse
          // Hilfsschema zur Anordnung von Text am LCD     0123456789012345
          //                                               MoC KoC ARC ALC 
          if (such==130)            //
          { uputs0("\tMoCo"); SetCursor (2,  8); lcd_string("MoC "); }
          if (such==132)            //
          { uputs0("\tKoCo"); SetCursor (2,  4); lcd_string("KoC "); }
          if (such==134)            //
          { uputs0("\tARCo"); SetCursor (2,  0); lcd_string("ARC "); }
          if (such==136)            //
          { uputs0("\tALCo"); SetCursor (2, 12); lcd_string("ALC "); }
          jaflag = 55;              //
        }                   // ist if(!(i2c_start(such)))
        else                        // Melde: Kein Byte geschrieben
        {                           //      und Fehlermelde-Strich
          i2c_stop();               // Zugriff bei Fehlerfall beenden, sonst SDA low
          if ( jaflag == 55 )       // Flag "Slave erkannt" ??
          {                         //
            uputs0 ("\r\t");          //
          }                 // Ende if ( jaflag = 55; )
            jaflag    =  0;         // Flag zurücksetzen
          uputs0 ("-");             //
        }                   // Ende if(!(i2c_start(such)))
      }             // Ende for (uint8_t such=0x70..; Alle Slaveadressen sind getestet
     }              // Ende Ende void i2csuch (void)
    // ===  Ende Routine i2clook
    // ============================================================================= =
    Geändert von oberallgeier (28.01.2018 um 08:46 Uhr) Grund: Bilderupload komplett
    Ciao sagt der JoeamBerg

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    i2c_start liefert 0 oder 1 zurück. Wird aber vom Programm nicht ausgewertet da nur mit if(!(i2c_start(such))) abgefragt wird. Wenn jetzt der Bus hängt kommt man auch nicht mehr raus. Ein eventueller Stop Befehl hat gar keine Wirkung
    Wenn man aber bei 1 einen Bus reset macht, wird die nächste Abfrage an einen andere Slave funktionieren.

    Ich hatte das gleich in die library eingebaut, zB:


    zB:
    Code:
    void i2c_stop(void){
    unsigned short timeout=0;
     //uint8_t   twst;
        /* send stop condition */
        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
       // wait until stop condition is executed and bus released
    
        while((TWCR & (1<<TWSTO))&& ++timeout);
    
        if( TW_STATUS & 0xF8 == TW_BUS_ERROR) 
            { // TWI aus, Pause, wiedereinschalten.
            TWCR &= ~((1 << TWSTO) | (1 << TWEN));
            _delay_ms(2);
            TWCR |= (1<<TWEN);            
            } 
    
    
    
    
        _delay_us(5);
    
    
    
    }/* i2c_stop */

    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    14.02.2018
    Beiträge
    15
    Deshalb verwendet man in sicherheitskritischen Systemen keine solchen Busse sondern packt jeden Sensor an eine eigene Leitung und multiplext sie.

Ähnliche Themen

  1. Lift für Riesenglotze - Gasdruckfeder elektronisch blockieren (oder andere Lösung)?
    Von matzrh im Forum Vorstellung+Bilder+Ideen zu geplanten eigenen Projekten/Bots
    Antworten: 3
    Letzter Beitrag: 04.10.2019, 22:57
  2. Blockieren vom Steppermotor erkennen
    Von skywalker1979 im Forum Motoren
    Antworten: 11
    Letzter Beitrag: 01.08.2013, 08:39
  3. Kann ein Nabenmotor blockieren?
    Von Daniel002 im Forum Motoren
    Antworten: 5
    Letzter Beitrag: 24.07.2012, 12:44
  4. Zerstörung von Servos durch blockieren?
    Von avrrobot im Forum Motoren
    Antworten: 1
    Letzter Beitrag: 08.01.2012, 20:52
  5. [ERLEDIGT] IR-Sensoren
    Von highlow im Forum Sensoren / Sensorik
    Antworten: 0
    Letzter Beitrag: 25.10.2005, 15:57

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress