- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 6 von 6

Thema: Texas Instruments tmp100 über i2c Auflösung einstellen

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    17.02.2009
    Ort
    Aachen
    Beiträge
    1.178

    Texas Instruments tmp100 über i2c Auflösung einstellen

    Anzeige

    E-Bike
    Hallo miteinander,

    ich spiele seit gestern zum ersten Mal mit einem i2c-fähigen Sensor.
    Dazu habe ich ihn über einen Raspberry Pi angeschlossen und werte ihn über die GPIO-Pins aus.

    Ich habe einen Codefetzen im Netz gefunden, der auf den tmp102 ausgerichtet war, mit aber auch die Temperatur des tmp100 ausgibt:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <linux/i2c-dev.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    int main(int argc, char **argv)
    {
            unsigned int temp = 0;
            unsigned char msb, lsb;
    
            int fd;                                    // File descritor
            char *fileName = "/dev/i2c-1";             // Name of the port we will be using
            int  address = 0x4f;                       // Address of TP102
            unsigned char buf[10];                     // Buffer for data being read/ written on the I2C bus
    
            if ((fd = open(fileName, O_RDWR)) < 0)
            {   // Open port for reading and writing
                    printf("Failed to open I2C port\n");
                    exit(1);
            }
    
            if (ioctl(fd, I2C_SLAVE, address) < 0)
            {  // Set the port options and set the address of the device we wish to speak to
                    printf("Unable to get bus access to talk to slave\n");
                    exit(1);
            }
    
    
            buf[0] = 0;                                // This is the register we wish to read from
    
            if ((write(fd, buf, 1)) != 1)
            {  // Send register to read from
                    printf("Error writing to I2C slave\n");
                    exit(1);
            }
    
            if (read(fd, buf, 1) != 1)
            {  // Read back data into buf[]
                    printf("Unable to read from slave\n");
                    exit(1);
            }
            else
            {
    
    
    
    
      for (;;)
                    {
                            msb = buf[0];
    
                            if (read(fd, buf, 1) != 1)
                            {
                                    printf("Unable to read from slave\n");
                                    exit(1);
                            }
                            else
                            {
                                    lsb = buf[0];
                                    temp = (msb<<8) | lsb;
                                    temp >>= 4;
                                     printf("Temp: %f \n",temp*0.0625);
                                    printf("Raw: %f \n\n", temp*1.00);
                                    usleep(1000000);
                            }
                    }
    
    
    
    
            }
            return 0;
    }
    Laut Datenblatt soll der tmp100 ein einstellbare Auflösung haben. Aber ich bin noch nicht wirklich dahinter gestiegen, wie ich die Auflösung einstellen kann.
    Momentan kann ich nur Messwerte in 1°C-Schritten auslesen. Da der Sensor einen Messbereich von 180°C hat und mit 12Bit = 4096 Werten auflösen können soll, ergibt sich doch theoretisch eien Schrittweite von 180/4096 von 0.0439453125°C.
    Allerdings bekomme ich imemr nur volle Werte alla 23.06250°C oder 24.06250°C ausgegeben.

    Die Zahl dieht verdammt nach dem Umrechnungsfaktor aus. Aber ohne den Multiplkator bekomme ich nichts ausgegeben.

    Wie kann ich den Sensor nun dazu bewegen, feiner aufgelöste Werte auszuspucken?

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Welchen Abschnitt im Datenblatt verstehst du nicht?

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    17.02.2009
    Ort
    Aachen
    Beiträge
    1.178
    Puh, da gibts mehrere Denkschwierigkeiten.
    Das wären einmal die Bitoperatoren im Code
    Code:
    msb = buf[0];
    ...
    lsb = buf[0];
    temp = (msb<<8) | lsb;
    temp >>= 4;
    Und dann gehts im Datenblatt los auf Seite 5 unten:
    Temperaturregister:
    P1: 0 P0: 0
    Read only
    ...12-bit read only register

    Die Table 3, 4 & 6 sagen mir überhaupt nichts


    Also liefert der Sensor eigentlich schon die ganze Zeit 12-bit-Werte? Oder muss ich das erst mit Hilfe der Tabelle 6 einstellen, da der Sensor ja 9-12 Bit liefern könnte?

    Hmmm...okay, auf 12-Bit stellt man m.H. der Tabelle 7. Aber wie teile ich das dem Sensor mit?

    Btw: Wenn ich nen Rohwert von buf[0] ausgebe, bekomme ich was, das ich weder lesen noch benennen kann. Ein Rechteck mit scheinbar 4 Zahlen drin.
    Geändert von Cysign (05.04.2013 um 16:04 Uhr)

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.070
    Der Ablauf sieht so aus:
    Code:
    Start
    Adresse senden (beim TMP100 und ADD0 und ADD1 auf 0V => 10010000 => Hex 90)
    Pointerregister senden
    Variable schreiben
    Stopp
    für Lesen:
    Code:
    Start
    Adresse senden (beim TMP100 und ADD0 und ADD1 auf 0V => 10010000 => Hex 90)
    Pointerregister senden
    Repeated Start (mit Adresse Hex 91 => durch R/W Bit)
    Variable lesen
    immer mit ACK bestätigen, Ausnahme letztes Byte dort mit NACK abschließen
    Stopp
    Wenn du jetzt also nur die Temp lesen willst schreibst du:
    Code:
    Start
    Adresse
    Pointer (0x00 => 0000 0000)
    repeated start
    Highbyte lesen
    Lowbyte lesen
    stopp
    Mit diesem Code hast du 9Bit Auflösung, wenn du 12Bit brauchst/willst musst du das zuerst im Configurationregister einstellen (einmal bei Programmstart)
    Der Ablauf sieht so aus:
    Code:
    Start
    Adresse
    Pointeradresse (0x01 => 0000 0001)
    Configbyte schreiben (0x60 => 0110 0000)
    Stopp
    Das lesen funktioniert dann wie oben.

    MfG Hannes

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    17.02.2009
    Ort
    Aachen
    Beiträge
    1.178
    Wenn ich ehrlich bin, ist mir das noch ne Ecke zu hoch.
    Kannst du diene Erklärung vielleicht ein bisschen anfängerfreundlicher formulieren?

    Es hapert schon daran, das ich nicht weiß, was ich für einen Rückgabewert bekomme.
    Wenn ich buf[0] einfach ausgebe, bekomme ich etwas, das aussieht wir ein Rechteck mit 4 Ziffern drin.
    Ist das ein Byte, das mittels lsb und msb in Binärcode umgeschrieben wird?

    Können wir den Code vielleicht mal auseinander nehmen?

    Code:
    (fd = open(fileName, O_RDWR)
    Hier wird festgelegt, dass auf ic2 zugegriffen wird.
    Was bedeutet das O_ vor dem ReadWrite?

    Code:
    ioctl(fd, I2C_SLAVE, address)
    ioctl = input output control?
    Sensor dieser Adresse als I2C_SLAVE definieren

    Code:
    write(fd, buf, 1)
    'buf' an Gerät 'fd' übergeben. Wofür steht die 1?
    Steht buf also für ein Array, das 10 byte = 10 Register beinhaltet, die jeweils 8 bit groß sind?

    Code:
    read(fd, buf, 1)
    Wieder diese 1. Hier wird das Array Buf also dann mit den Sensordaten gefüllt.

    Code:
    msb = buf[0];
    Code:
    lsb = buf[0];
    temp = (msb<<8) | lsb;
    Hier wird das erste Register, welches die Temperatur beinhaltet, aus dem Array gezogen und an lsb übergeben.
    In temp wird der Rückgabewert gespeichert, der mittels
    Code:
    (msb<<8) | lsb;
    irgendwie umformatiert wird. Was geschieht hier genau?

    Code:
    temp >>= 4;
    Und hier haben wir schon die nächste Transformation, die ich nicht verstehe.


    Wofür werden die Pina ADD0 und ADD1 benötigt?

    Woher kommt der Wert Hex 90?

    Wie kann ich die Hex-Codes alla 0x01, 0x00, etc. interpretieren bzgl. der am Anfang stehenden "0x"?

    Das sind vielleicht ein paar viele Fragen...aber ich häng schon den ganzen Tag davor und werd nicht so wirklich schlau darauß.
    Irgendwie hab ich kein wirklich vollständiges Tutorial gefunden.

  6. #6
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.070
    Wie du den I2C Bus von deinem Controller (Raspberry) ansteuerst weiß ich nicht. Buf ist ein Array, das mit 10 definiert ist, das bedeutet 10Byte. Bei der Read bwz write Funktion könnte ich mir vorstellen das das so aufgebaut ist: z.B.
    Code:
    read(Ort von dem die Daten übernommen werden, Variable, Anzahl der Bytes)
    jedoch kann es auch etwas anderes bedeuten. Du solltest mehr darüber im Handbuch, Hilfe,... erfahren. Eventuell findest du mehr in der Headerdatei bzw C-Datei (werden C-Dateien verwendet?).

    Zu den einzelnen Umwandlungen kannst du den Windowsrechner recht gut verwenden (bei "Ansicht" umschalten auf "Programmierer").
    "|" bedeutet bitweises Oder, byteweise wäre "||"
    (msb<<8 ) bedeutet z.B. die Variable msb um 8 nach links schieben (beim Win Rechner ist das "RoL" => Rotate left),
    das gleiche gilt auch mit >>, bedeutet rechts schieben (RoR),
    temp>>=4 bedeutet temp wird gelesen, um 4 nach rechts geschoben und dieser Wert wird dann wieder in die Variable temp geschrieben (ist eine Kurzform von temp = temp>>4)

    Wofür die ADD Pins sind findest du auf S8.
    Die Adresse beginnt immer mit 1001, dann kommt es auf die Konfiguration der ADD Pins an, als letztes Bit ist das R/W Bit, dieses Bit wird dazu genutzt um dem Slave zu sagen ob geschrieben wird oder gelesen wird.
    In der Tabelle zu den ADD Pins findest du die bezeichnung 0, 1 und Float. 0 bedeutet das dieser Pin mit Masse (GND) verbunden ist, 1 bedeutet das dieser Pin mit VCC (pos. Versorgungsspannung) verbunden ist, Float bedeutet das dieser weder mit GND, noch mit VCC verbunden ist, der Pin wird einfach unbeschalten gelassen.

    Wenn du jetzt also ADD0 und ADD1 mit Masse verbindest hast du die Adressen: 1001000x (x steht für das R/W Bit), wenn du das umwandelst in Hex hast du 90 (wenn RW Bit 0 ist => Master sendet an Slave) bzw 91 (wenn RW Bit 1 ist => Master liest vom Slave). Das kannst du ebenfalls mit dem Win Rechner kontrollieren.

    Ich habe z.B. 0x00 geschrieben. Das 0x ist ein Präfix und bedeutet das die Zahl als Hex geschrieben wird (du hast somit 0x00 bis 0xff bei einem Byte). Diese Schreibweise ist in C-Dateien üblich. Wenn man keinen Präfix verwendet (z.B. 100) ist das automatisch Dezimal, bei Binär muss man 0b am Anfang schreiben (also z.B. 0b10010000 bei deiner Adresse).

    Hier noch ein Link zum I2C Bus http://www.timmermann.org/ralph/inde...tronik/i2c.htm




    Wenn du die Registerbits liest musst du einmal grundsätzlich das Byte kennen bzw deren Aufbau (als Beispiel das Configuration Register), das du auf S6 findest (Table 6):

    Der Aufbau ist: OS/Alert R1 R0 F1 F0 POL TM SD
    Das nutzt dir aber so noch nichts, da du nicht weißt was die einzelnen Bits bedeuten. Du musst jetzt durchlesen was die einzelnen Bits bedeuten.

    SD: ist das Shutdown Bit, damit kannst du den Sensor "schlafen legen", damit dieser Strom spart, er mist aber in dieser Zeit nicht. Mit einer 1 aktivierst du den Schlafmodus, mit 0 wird dieser deaktiviert.

    TM: damit aktivirerst du den Thermostat Mode, dazu findest du die Tabelle

    POL: damit kann man einstellen ob bei einem Fehler (Thigh oder Tlow über- bzw unterschritten) eine 1 oder 0 beim OS/Alert bzw Alarm Output (beim TMP101) geschrieben wird

    F1, F0: sind die Fault Queue Bits, damit stellst du die Anzahl ein bevor ein Alarm ausgelöst wird

    R1, R0: sind Auflösungsbits, damit stellst du die Auflösung des Sensors ein.

    OS/Alert: Dieser hat je nach Configuration 2 Aufgaben. Wenn du im SD Bit eine 1 stehen hast (Shutdownmode) löst du mit diesem Bit eine Messung aus, der TMP geht dann wieder in den Schlafmodus zurück, wenn SD jedoch 0 ist wird dieses Bit als Alarm Bit genutzt (die Grenze im Thigh bzw Tlow Register wurde über bzw unterschritten).



    Wenn du den TMP an die Versorgungsspannung legst (bei jedem einschalten) sind alle Bits 0 (außer das Temparaturregister). Somit musst du bei jedem Start einmal die Einstellungen senden (wird in einem Ram gespeichert).
    Wenn du eine Funktion nicht brauchst ignorierst du es einfach.
    OS/Alert => brauchst du nicht => 0
    R1/R2 => für 12Bit beides auf 1 schalten (Table 8 )
    F1/F0 => brauchst du nicht => beides 0
    POL => Brauchst du nicht => 0
    TM => Brauchst du nicht => 0
    SD => Brauchst du nicht => 0

    Somit ergibt sich: 0b01100000 => 96 => 0x60

    MfG Hannes

Ähnliche Themen

  1. [ERLEDIGT] TexasInstruments tmp100 Pullup?
    Von Cysign im Forum Elektronik
    Antworten: 2
    Letzter Beitrag: 04.04.2013, 12:54
  2. Texas Instruments INA-169 gesucht
    Von xxrider im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 4
    Letzter Beitrag: 13.09.2011, 00:28
  3. Texas Instruments LaunchPad
    Von Zwerwelfliescher im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 0
    Letzter Beitrag: 03.08.2011, 14:40
  4. Texas Instruments kauft National Semiconductor
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 05.04.2011, 11:40
  5. Fusebit beim ATMega16 über Bascom einstellen
    Von feitzi im Forum Elektronik
    Antworten: 0
    Letzter Beitrag: 25.10.2006, 11:50

Berechtigungen

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

12V Akku bauen