C Temperatursensor (STS3x)

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Moin Moin,

da bin ich mal wieder..
Habe gerade einen neuen Temperatursensor vor mir liegen, den (STS3x)..
Der sendet mir seine Temperatur in 3 Bytes zurück.

Byte 1: Temperatur MSB
Byte 2: Temperatur LSB
Byte 3: CRC

Nun kommt es ab und zu mal vor, dass die Temperatur von gut und böse liegt.
Ich muss dazu sagen, dass ich jeweils den jeh kleinsten gemessenen Wert speichere sowie den jeh größte Wert.

Ab und zu sehe ich auf dem Display (7 Segment) das die Temperatur (die jeh größte) deutlich größer als 40° angeblich sein soll.. Und das mit CRC..

Mache ich was falsch?
Wie unterdrücke ich das am besten?

Hier mal meine Routine zum auslesen des Sensors mit CRC..



CodeBox C und C++
uint8_t tmp[3]={0x00,0x00,0x00};
int16_t sts3x_read(void){
   
    #define MSB 0
    #define LSB 1
    #define CRC 2

   
       
    i2c_start_wait((0x4a<<1)+I2C_WRITE);
    i2c_write(0x20);
    i2c_write(0x2f);   
    i2c_rep_start((0x4a<<1)+I2C_READ);
    tmp[MSB]=i2c_readAck();
    tmp[LSB]=i2c_readAck();
    tmp[CRC]=i2c_readNak();
    i2c_stop();
   
    crc_glob = tmp[CRC]; // only for debug (usart output)
   
    uint8_t crc=0xff;
    crc=_crc8_ccitt_update(crc,tmp[0]);
    crc=_crc8_ccitt_update(crc,tmp[1]);
   
    /* data correct received? */
    if (crc==tmp[2]){
        return (uint16_t)tmp[0]<<8|tmp[1];
    }
    return -1;
}
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.088
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
Du hast kein Datenblatt des Sensors verlinkt, deswegen mal nur 'n Schuß ins Blaue:
Bist Du sicher, daß das Auslesen der Bytes bezüglich der Wandlungen atomar erfolgt? Also daß der Sensor die Register selbst während des Auslesens gegen neue Ergebnisse blockt/puffert, und Du Dich nicht selbst kümmern mußt, sicherzustellen, während eines potentiellen Updates nicht zu lesen?
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Ja. Ich sperre die Interrupts in der Zeit. Es kommt ja auch meistens der gleiche Wert raus. Es sind meistens 45 Grad. Sonst klappt das auslesen gut und die Genauigkeit ist auch inordnung. Werde das Datenblatt nach reichen.
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.088
57
48
Hennigsdorf
Sprachen
BascomAVR, Assembler
Nein, zu Deinem C-Code müssen Dirk, Hemi & co. was sagen, ich meinte ob Du sicher bist, daß Du nicht zufällig gerade während eines neuen Ergebnisses auf den Sensor zugreifst, und MSB und LSB zu zwei unterschiedlichen (aufeinanderfolgenden) Messungen gehören. (also ob der Sensor-IC selbst sowas ausschließt, indem er während des Lesens neue Updates blockt, oder den Lesezugriff puffert)
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Ich starte die Messung und lese dann die Temperatur. Also so zu sagen SingleShot und kein ständiges bit raus geballer..
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4.225
123
63
Mittelhessen, Giessen
Sprachen
C, Assembler, Pascal, C++, PHP, Java
Ich starte die Messung und lese dann die Temperatur. Also so zu sagen SingleShot und kein ständiges bit raus geballer..


CodeBox C und C++
i2c_start_wait((0x4a<<1)+I2C_WRITE); 
i2c_write(0x20); 
i2c_write(0x2f);


Mit 0x202F sendest du das Kommando für periodische Messung, nicht für "Single Shot" Messung.

Nach diesem Kommando sendest du ein START dann SlaveAdress+R. Antwortet der Slave mit NACK, sind keine Daten vorhanden und die Kommunikation wird abgebrochen.
Ist die Messung fertig und sind Daten vorhanden antwortet der Slave mit ACK. Nun kannst du MSB+LSB+CRC lesen.

EDIT:
Damit nicht jeder suchen muss: Datasheet STS3X
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Nach diesem Kommando sendest du ein START dann SlaveAdress+R. Antwortet der Slave mit NACK, sind keine Daten vorhanden und die Kommunikation wird abgebrochen[/B].
Ist die Messung fertig und sind Daten vorhanden antwortet der Slave mit ACK. Nun kannst du MSB+LSB+CRC lesen.
Das kann es wohl sein. Das Nack kann ich doch auch irgendwie abfragen oder? Ich benutze ja schon lange die fertigen Routinen für die Mega Serie.
Das Nack muss dann wahrscheinlich im Status Register stehen..!?
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4.225
123
63
Mittelhessen, Giessen
Sprachen
C, Assembler, Pascal, C++, PHP, Java
Ja, das sollte dann im TWI Statusregister TWSR stehen, ob nach MasterRead SLAVEADDR+R ein ACK oder NACK empfangen wurde, schau mal in das Datenblatt des Mikrocontrollers.

Dirk :ciao:
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Müsste dann aber nicht trodzdem der CRC fehlschlagen?

Sehe ich das richtig, dass es dann der Statuscode "$40" sein müsste?

Woher weiß ich jetzt ob es ein NACK oder ein ACK war?
 

Anhänge

Zuletzt bearbeitet:

Dirk

Administrator
Teammitglied
28 Jan 2007
4.225
123
63
Mittelhessen, Giessen
Sprachen
C, Assembler, Pascal, C++, PHP, Java
Ja, ich denke
0x40 für ACK
und
0x48 für NACK

Achtung in TWSR sind ggf. noch Prescaler bits, die müssen maskiert werden, sie sind nicht in dem Statuscode berücksichtigt.
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Müsste dann aber nicht trodzdem der CRC fehlschlagen?
Was ist hier mit? Wenn solch eine Temperatur angezeigt wird, die überhaupt nicht passt scheint der CRC aber trodzdem richtig zu sein. Das kann doch nicht angehn.
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4.225
123
63
Mittelhessen, Giessen
Sprachen
C, Assembler, Pascal, C++, PHP, Java
Was ist hier mit? Wenn solch eine Temperatur angezeigt wird, die überhaupt nicht passt scheint der CRC aber trodzdem richtig zu sein. Das kann doch nicht angehn.
Ich kann das nun auch nicht genau sagen, soweit habe ich mir das Datenblatt nicht angesehen.

Aber:

Du sendest immer ein Kommando "periodische Messung" und vermutest es ist ein Kommando für Einzelmessung.
Danach liest du sofort (irgendwelche) Daten aus, ohne auf das Timing zu achten oder ohne darauf zu achten, ob gültige Temperaturdaten vorhanden sind.

Ich nehme an, daran liegt es.

Vielleicht kann aber auch mal ein anderer User in das Datenblatt schauen. Ich habe leider nicht so die Zeit.
Damit nicht jeder suchen muss: Datasheet STS3X
EDIT:
Poste vielleicht auch noch mal deinen aktuellen Code.
 
Zuletzt bearbeitet:

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Moin,

Habe es bis heute nicht hin bekommen, das NACK auszuwerten.


CodeBox C und C++
uint16_t sts3x_read(void){

#define MSB 0
#define LSB 1
#define CRC 2

i2c_start_wait((0x4a<<1)+I2C_WRITE);
i2c_write(0x21);
i2c_write(0x30);


i2c_rep_start((0x4a<<1)+I2C_READ);
Temperature.Rx[MSB]=i2c_readAck();
Temperature.Rx[LSB]=i2c_readAck();
Temperature.Rx[CRC]=i2c_readNak();
i2c_stop();

uint8_t crc=0xff;
crc=_crc8_ccitt_update(crc,Temperature.Rx[MSB]);
crc=_crc8_ccitt_update(crc,Temperature.Rx[LSB]);


/* data correct received? */
if (crc==Temperature.Rx[CRC]){
return (uint16_t)Temperature.Rx[MSB]<<8|Temperature.Rx[LSB];
}

return 17000; // ad value for 0
}

 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Die Funktionen liefern mir zwar Werte zurück, dass hat doch aber nichts damit zu tun, dass der Sensor gerade keine neuen Daten für mich hat oder? Viel mehr das der Chip nicht Antwortet oder nicht da ist..



CodeBox C und C++
/**
@brief Issues a repeated start condition and sends address and transfer direction
@param addr address and transfer direction of I2C device
@retval 0 device accessible
@retval 1 failed to access device
*/
extern unsigned char i2c_rep_start(unsigned char addr);
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4.225
123
63
Mittelhessen, Giessen
Sprachen
C, Assembler, Pascal, C++, PHP, Java
Du sendest nun ein Kommando (0x2130) für periodische Messung. Das solltest du nur einmalig machen, zum Initialisieren der periodischen Messung, nicht permanent bevor du auslesen möchtest.

Beim Lesen der Temperaturdaten bei periodischer Messung hältst du dich nicht an das Protokoll.

Du wirst aktuell ggf. zwar irgenwas zurückbekommen, bei dem CRC stimmt. Dies schützt aber sicher nur gegen Übertragungsfehler auf dem I2C Bus und wird dir nicht bestätigen, dass die empfangenen Daten richtig sind und diese sind, welche du erwartest.

4.6 Readout of Measurement Results for Periodic Mode
Transmission of the measurement data can be initiated
through the fetch data command shown in Table 9. If no
measurement data is present the I2C read header is
responded with a NACK (Bit 9 in Table 9) and the
communication stops. After the read out command fetch
data has been issued, the data memory is cleared, i.e.
no measurement data is present.
upload_2017-8-8_15-37-3.png
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Moin Dirk.

Ich hatte in der main() schon einmal die Initalisierung vorgenommen (0x2130)..


CodeBox C und C++
i2c_start_wait((0x4a<<1)+I2C_WRITE);
i2c_write(0x21);
i2c_write(0x30);
i2c_stop();


Wenn ich nun zyklisch meine Daten auslese, sende ich ihn vorher..


CodeBox C und C++
uint16_t sts3x_read(void){

#define MSB 0
#define LSB 1
#define CRC 2

i2c_start_wait((0x4a<<1)+I2C_WRITE);
i2c_write(0xe0);
i2c_write(0x00);

i2c_rep_start((0x4a<<1)+I2C_READ);
Temperature.Rx[MSB]=i2c_readAck();
Temperature.Rx[LSB]=i2c_readAck();
Temperature.Rx[CRC]=i2c_readNak();
i2c_stop();

uint8_t crc=0xff;
crc=_crc8_ccitt_update(crc,Temperature.Rx[MSB]);
crc=_crc8_ccitt_update(crc,Temperature.Rx[LSB]);


/* data correct received? */
if (crc==Temperature.Rx[CRC]){
return (uint16_t)Temperature.Rx[MSB]<<8|Temperature.Rx[LSB];
}

return 17000; // ad value for 0
}


Und danach warte ich auf die Daten. Das hat leider gar nicht funktioniert. So bekomme ich wenigstens Gültige Daten.
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
eim Lesen der Temperaturdaten bei periodischer Messung hältst du dich nicht an das Protokoll.
Was meinst du damit? Das ich die einmalige Initialisierung nicht mache?
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4.225
123
63
Mittelhessen, Giessen
Sprachen
C, Assembler, Pascal, C++, PHP, Java
Was meinst du damit? Das ich die einmalige Initialisierung nicht mache?
Nein, in deinem Code zuvor in diesem Beitrag führst du die Initialisierung für periodische Messung permanent aus und sendest auch kein Kommando 0xE000, sondern versuchst sofort Daten zu lesen.

Dein Code danach macht das ja besser. Es wäre gut, wenn hier mal jemand mit I2C und C Erfahrungen helfen könnte.

Dirk :ciao:
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.291
10
38
Hannover
Sprachen
C, C#
Nabend,

habe MIch noch mal an den Sensor dran gesetzt. Da jetzt das lesen / schreiben / Temperatur berechenen klappt, bin Ich schon mal sehr froh das Ich soweit gekommen bin..
Jedoch verstehe Ich einen Punkt noch nicht ganz.

Der Chip hat einen "Alarm Pin" dieser schaltet wohl sobald die Schwelle für "Luftfeuchtigkeit / Temperatur" über bzw unterschritten werden.
Nun habe ich an dem Ausgang eine LED (high active). Diese leuchtet die ganze Zeit! Das liegt wohl daran das die Schwellen nicht richtig konfiguriert wurden?!

Wie bekomme Ich diese LED aus, ohne den Vorwiderstand oder die LED zu entfernen :D?
 

Mikro23

Mitglied
2 Jan 2017
285
21
18
Großraum Hannover
Sprachen
C, Assembler
Im Datenblatt steht:
The pin switches high, when alert conditions are met.
Und nirgendwo steht, daß man da irgendwas einstellen kann.
Da ich Deinen Schaltplan nicht kenne, gehe ich davon aus, daß Du die LED falsch angeschlossen hast.
Und wenn Du sie nur aus haben willst, brauchst Du sie nur vom Pin abzuklemmen. :D
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)