- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 8 von 8

Thema: Ansteuerung eines SparkFun AS7265x Triad Sensors

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.210

    Ansteuerung eines SparkFun AS7265x Triad Sensors

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Ich habe Probleme das oben genannte Sensor Board über I2C anzusprechen.

    Anscheinend gibt es da 4 Register die man ansprechen kann.
    Der Rest ist in sogenannten virtuellen Registern.

    Über I2C kann man doch eigentlich nur die Adresse des Bausteins angeben und eines oder mehrere Bytes senden bzw. empfangen.

    Wie kann man z.B. das Status Register auslesen? Gibt man die Adresse des Bausteins mit einem Lesebefehl an, kann man die Register doch nicht mehr addressieren.
    Das Datenblatt gibt sich da kryptisch.
    Im Pseudocode werden da direkt die Registeradressen mit 0x00 bis 0x03 angesprochen.

    Die Arduino library hab Ich mir auch angesehen, aber auch daraus werd Ich nicht schlau, zudem werden da auch noch weitere Bibliotheken der ARDUINO Plattform verwendet.

    Hat sich da schon mal wer damit beschäftigt?

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.04.2015
    Beiträge
    881
    Bei I2C musst Du ja das "adressierte Lesen" (Zugriff auf eine adressierte Speicherzelle oder ein "Register") normalerweise durch zwei Sequenzen ausführen.
    1. Schreibbefehl, um die abzufragende Adresse zu setzen
    2. Lesebefehl, bei dem der Slave die adressierten Daten zurückgibt.
    Zwischen den beiden Sequenzen wird wirklich ein I2C-Stop-Status (die richtige Konstellation der Pegelwechsel auf SDA und SCL) erwartet und der Lesebefehl enthält am Anfang auch noch einmal die Slave-Adresse (dieses mal mit gesetztem Leseflag).

    Also wird wohl die Übertragung zum Lesen sein
    Sequenz 1:
    - I2C-Slave-Adresse mit Schreib-Flag
    - Adresse Statusregister
    - Stop

    Sequenz 2:
    - I2C-Slave-Adresse mit Lese-Flag
    - Rückgabe des adressierten (Status-)Registerwertes
    - Stop
    Das bitteschön zusammen mit Sequenz 1 so lange wiederholt, bis das Tx-Flag das Schreiben oder lesen zulässt

    Sequenz 3:
    - I2C-Slave-Adresse mit Schreib-Flag
    - Adresse Write-Register
    - Registeradresse mit Read-Flag
    - Stop

    Sequenzen 5 und 6:
    - Wie 1 und 2, nur auf das Rx-Flag im Statusregister angewendet

    Sequenz 7:
    - I2C-Slave-Adresse mit Schreib-Flag
    - Adresse Read-Register
    - Stop

    Sequenz 8:
    - I2C-Slave-Adresse mit Lese-Flag
    - Holla, schon kommt der Wert
    - Stop

    Klingt kompliziert, ist aber ein probates Mittel, das Busy-Stretchen des Ack-Flags aus der I2C-Spec zu vermeiden.

    Was Du eigentlich brauchst, ist eine Bibliothek, die sich an den Parametern der Funktionen im Pseudocode orientiert, also...
    status = i2cm_read(I2C_AS72XX_SLAVE_STATUS_REG)
    ...würde dann für Dich die Sequenzen 1 und 2 in einem Rutsch ausführen.

    Wenn Du da nix findest UND es sich bei Deinem Master um den zuletzt durchgekauten AVR32DB32 (UPDI) handelt:
    Die TWI-Registerbeschreibung ähnelt sehr der Tiny-1er-Serie und da hab ich auch mal was gemacht.

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.210
    Hast Du das mit so einem Sensor schon mal ausprobiert?
    Wenn das so funktioniert wäre Ich schon weiter.
    Das Datenblatt und der Pseudocode lassen sich im Endeffekt darüber nicht aus, es wird immer nur auf die Arduino Library verwiesen.
    I2C Lese und Schreiboperationen hab Ich schon geproggt, die AS7265x programmteile müssen jetzt nur noch darauf zugreifen.

    Mir war einfach nicht klar, das man die Adressierung in 2 Schritten, mit einer Stop Condition dazwischen, durchführen muss.

    Übrigens geht die I2C Steuerung der AVR32DBxx Chips wesentlich einfacher, als die bei den ATMEGA's.
    Die Geschwindigkeitsberechnung ist allerdings etwas schwierig.

    Ich werd das mal mit dem Auslesen eines Wertes testen und geb dann wieder Bescheid.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.04.2015
    Beiträge
    881
    Scheint aber wirklich so zu funktionieren.
    (https://github.com/sparkfun/SparkFun...un_AS7265X.cpp)

    Code:
    uint8_t AS7265X::readRegister(uint8_t addr)
    {
      _i2cPort->beginTransmission(AS7265X_ADDR);
      _i2cPort->write(addr);
      if (_i2cPort->endTransmission() != 0)
      {
        //Serial.println("No ack!");
        return (0); //Device failed to ack
      }
    
      _i2cPort->requestFrom((uint8_t)AS7265X_ADDR, (uint8_t)1);
      if (_i2cPort->available())
      {
        return (_i2cPort->read());
      }
    
      //Serial.println("No ack!");
      return (0); //Device failed to respond
    }
    wobei...
    Code:
    i2cPort->beginTransmission(AS7265X_ADDR);
      _i2cPort->write(addr);
    ...die I2C-SlaveAdresse und die Registeradresse auf den Sensor schreiben und...
    Code:
    if (_i2cPort->endTransmission() != 0)
      {
        //Serial.println("No ack!");
        return (0); //Device failed to ack
      }
    ...das abschließende Ack der Sequenz auf der SDA-Leitung abfragt...


    Code:
      _i2cPort->requestFrom((uint8_t)AS7265X_ADDR, (uint8_t)1);
      if (_i2cPort->available())
      {
        return (_i2cPort->read());
      }
    Bei der anschließenden Lesesequenz geht Arduino dann mit einer Abfrage dran, deren Erfolg über das 'available', und deren Daten über Read aus einem Puffer zurückgegeben werden.
    Details findest Du, wenn Du nach "Arduino Wire.h" suchst.

    Und die Funktion
    uint8_t AS7265X::virtualReadRegister(uint8_t virtualAddr)
    ist vielleicht auch ganz lesenswert. Da steht z.B. am Anfang ein Dummy-Lesen auf das Read-Register. Kann also sein, dass man ggf. anstehende Werte erst lesen muss, damit das AS7265X_RX_VALID-Flag im Status zurückgesetzt wird?!?
    Geändert von Holomino (13.09.2024 um 13:03 Uhr)

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.210
    Das was Du jetzt schreibst ist ja genau mein Problem.
    Wie wird dem Sensor mitgeteilt auf welches der 3 Hardware Register Ich lesen oder schreiben will?

    In der Sequenz wird ja nur die Adresse eines virtuellen Registers angegeben - Muss da in einer Sequenz vorher die Adresse eines Hardwareregisters angegeben werden ( Wie Du in deinem ersten Post schreibst )?
    Es muss ja dann mehrmals das Status Register wieder ausgelesen werden, bis die Transaktion intern wieder beendet ist, also muss die Adresse vom Write Register wieder auf das Status Register umgeschaltet werden.
    Beim lesen ist ja sonst unklar, ob Ich aus dem Status Register, oder aus einem anderen Register gelesen werden soll.
    So ganz verstanden hab Ichs leider immer noch nicht.

    Meine Idee war, ob nicht bei einem Schreib bzw. Lesebefehl gleich 3 Bytes geschrieben, bzw gelesen werden, das die 3 Hardware Register symbolisiert?
    Darauf findet sich in der library allerdings kein Hinweis.

    Oder es werden tatsächlich die Adressen 0x00, 0x01, 0x02 per I2C angesprochen, dann wärs im Prinzip ganz einfach, allerdings bräuchte man dann keine zusätzliche I2C Adresse für die Platine ( 0x49 ).

    Ich werd da mal mit meinem Debugger etwas rum spielen.

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.210
    Ich denke Ich hab jetzt die Routinen soweit im Griff, das alles funktionieren sollte, allerdings reagiert der Sensor nicht wie erwartet.
    Klicke auf die Grafik für eine größere Ansicht

Name:	TWI1.jpg
Hits:	3
Größe:	124,1 KB
ID:	36015
    Im ersten Step wurde Adresse 0x92 ( Schreiben ) ausgewählt und die Adresse des Hardware Status Registers 0x00 angesprochen.
    Beides wurde vom AS7265 mit ACK quittiert.
    Der Master sendete dann Stop mit anschließenden Start.
    Nun wurde die Adresse 0x93 ( Lesen ) ausgewählt der Slave quittiert und das Byte wurde ausgelesen.
    Dieses enthielt aber leider den Wert 0x80, der aber nirgends dokumentiert ist.
    Der Wert 0x01, 0x02 oder 0x03 wurde erwartet.
    Der Master sendete NACK weil ja kein weiteres Byte mehr erwartet wurde.

    Das Ganze hab Ich mit dem Debugger gemacht.
    Lässt man den Controller frei Laufen hängt sich irgendwann die Bus Arbritation auf.
    Manchmal vom Master Manchmal vom Slave und eine der Leitungen wird nach GND gezogen.
    Code:
    //Write to virtual Register
    void i2m_AS72xx_topwrite(uint8_t virtualReg, uint8_t d)
    {
        uint8_t status;
        TWI_timeout=TWI_timeout_time;
        while (1)
        {
            //Read slave I²C status to see if the write buffer is ready.
            TWI_Buffer[0]=I2C_AS72XX_SLAVE_STATUS_REG;
            FEHLER = twi0_send(AS7265_adr,TWI_Buffer,0x01);
            FEHLER = twi0_receive(AS7265_adr,TWI_Buffer,0x01);
            status = TWI_Buffer[0];
            if ((status & I2C_AS72XX_SLAVE_TX_VALID) == 0)
            // No inbound TX pending at slave.  Okay to write now.
            break ;
            if(TWI_timeout==0)
            {
                break;
                FEHLER=20;
            }
            _delay_ms(AS7265X_POLLING_DELAY);
        }
        //Send Data to virtual Register
        TWI_Buffer[0]=(virtualReg | 0x80);
        //Send 1 Bytes
        FEHLER = twi0_send(AS7265_adr,TWI_Buffer,0x01);
        TWI_timeout=TWI_timeout_time;
        while (1)
        {
            //Read slave I²C status to see if the write buffer is ready.
            TWI_Buffer[0]=I2C_AS72XX_SLAVE_STATUS_REG;//****** Die Sequenz wurde hier gestoppt ******
            FEHLER = twi0_send(AS7265_adr,TWI_Buffer,0x01);
            FEHLER = twi0_receive(AS7265_adr,TWI_Buffer,0x01);
            status = TWI_Buffer[0];
            if ((status & I2C_AS72XX_SLAVE_TX_VALID) == 0)
            // No inbound TX pending at slave.  Okay to write now.
            break ;
            if(TWI_timeout==0)
            {
                break;
                FEHLER=21;
            }
            _delay_ms(AS7265X_POLLING_DELAY);
        }
        //Send data
        TWI_Buffer[0]=I2C_AS72XX_SLAVE_WRITE_REG;
        TWI_Buffer[1]=d;
        FEHLER=twi0_send(AS7265_adr,TWI_Buffer,0x2);
    }

    Hat da von Euch jemand eine Idee was da falsch läuft?
    Geändert von wkrug (Heute um 12:18 Uhr)

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    07.04.2015
    Beiträge
    881
    Dieses enthielt aber leider den Wert 0x80, der aber nirgends dokumentiert ist.
    Der Wert 0x01, 0x02 oder 0x03 wurde erwartet.
    Meine bescheidene Ansicht nach einem Blick in den Pseudocode im DB des Sensors,...
    Code:
    while (1) 
    {
       // Read slave I²C status to see if the write buffer is ready.
       status = i2cm_read(I2C_AS72XX_SLAVE_STATUS_REG);
       if ((status & I2C_AS72XX_SLAVE_TX_VALID) == 0)
         // No inbound TX pending at slave. Okay to write now.
         break ;
    }
    ...dass das oberste Bit in Status offensichtlich nicht verwendet wird. Stattdessen werden die beiden Flags im Statusregister einzeln als Bits ausmaskiert. Eine 0 gibt dabei an, dass Du auf das Read-, bzw. Write-Register zugreifen darfst (weil der Sensor da nicht gerade busy ist).
    Vereinfacht:
    0x81, 0x82, oder 0x83 sind also böse, da musst Du auf irgendwas warten.
    0x80 ist gut, dann darfst Du weitermachen.


    P.S.: Code als Zitat sieht grauselig aus. Über die "Erweitert"-Schaltfläche unten kannst Du ein Code-Tag einfügen.

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.210
    0x81, 0x82, oder 0x83 sind also böse, da musst Du auf irgendwas warten.
    0x80 ist gut, dann darfst Du weitermachen.
    Das die beiden Bits ausmaskiert werden ist mir schon klar.
    Was seltsam ist: Auch nach mehreren Versuchen taucht da niemals ein Wert in den unteren 2 Bytes auf.
    Obwohl der Chip eigentlich was zu tun haben müsste.
    Ich hab auch schon versucht die "Firmware Version Bytes" abzurufen, aber da kommt immer nur der Wert 0x00 zurück.
    Dann hab Ich versucht die LED's zu aktivieren, aber auch das klappt nicht.
    Irgendwie bin Ich ratlos!

    P.S.
    Das mit dem Code TAG hab Ich auch noch mal geändert!
    Geändert von wkrug (Heute um 12:19 Uhr)

Ähnliche Themen

  1. Normalisierung von Daten eines Beschl.sensors
    Von Snaper im Forum Sensoren / Sensorik
    Antworten: 8
    Letzter Beitrag: 05.08.2011, 18:22
  2. Genauigkeit eines Sensors
    Von Student123 im Forum Sensoren / Sensorik
    Antworten: 8
    Letzter Beitrag: 04.08.2011, 14:03
  3. Wie berechne ich die Temperatur eines NTC Sensors ?
    Von Shadow992 im Forum Sensoren / Sensorik
    Antworten: 7
    Letzter Beitrag: 27.05.2010, 14:41
  4. Antworten: 13
    Letzter Beitrag: 18.02.2006, 16:19
  5. Anschluss eines Sensors an einen PCF8574
    Von batti112 im Forum Elektronik
    Antworten: 6
    Letzter Beitrag: 16.03.2005, 01:01

Berechtigungen

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

LiFePO4 Speicher Test