Hallo Leute,
ich verusche zur Zeit, den Sensor SHT21 mit einem ATmega128 auszulesen.
Ich will dazu die I2C-Lib von P.Fleury nutzen.
Die Lib habe ich bereits in mein Projekt eingebunden.
Unter "Projekte&Code" gibt es eine I2C-Sensor-Codesammlung, die auch den
SHT21 beinhaltet und die P.Fleury-Lib verwendet, leider ist der Code
fehlerhaft und unkompilierbar.
hat jemand etwas ähnliches versucht und etwas Code zum bereitstellen?
Grüße und Danke,
dionysos
dionysos 328 schrieb:> Unter "Projekte&Code" gibt es eine I2C-Sensor-Codesammlung, die auch den> SHT21 beinhaltet und die P.Fleury-Lib verwendet, leider ist der Code> fehlerhaft und unkompilierbar.
recht weit kann er aber nicht daneben sein.
Das kommt schon mal vor, dass insbesondere älterer Code in der
Codesammlung, für eine ältere Compilerversion geschrieben wurde, die
noch nicht so pingelig war.
Allerdings: meistens sind es Kleinigkeiten, die einen C-Programmierer
nicht wirklich vor große Probleme stellen sollten sie an die heutigen
Gegebenheiten anzupassen. Das Grundprinzip hat sich ja in der
Zwischenzeit nicht geändert.
Die erste Fehlermeldung lesen. Die entsprechende Stelle im Code
aufsuchen und den Fehler korrigieren. Wenn es mehrere Fehlermeldungen
gibt, dann sind die meistens vom gleichen Typ, wenn sie nicht ohnehin
durch die Korrektur das ersten Problems verschwinden. Also nicht durch
50 Fehlermeldungen verdriessen lassen. Das ist meistens schneller
korrigiert als die meisten 'Piep' sagen können. Die reine Zahl 50 beim
ersten Compilierversuch sagt da gar nichts aus. 1 Fehler korrigiert und
damit fallen dann oft schon wieder 30 weitere Folgefehler weg.
dionysos 328 schrieb:> leider ist der Code> fehlerhaft und unkompilierbar.>> hat jemand etwas ähnliches versucht und etwas Code zum bereitstellen?
Der Code ist ganz bestimmt nicht fehlerhaft!
Zeig mal her was du bisher programmiert hast und erklære am besten noch
was der Code macht und was er nicht macht.
Falls du den Code nur kopiert hast (was ich stark vermute), dann fang
damit an eine LED blinken zu lassen.
Ulli-B
dionysos 328 schrieb:> Beitrag "C: AVR: Library für verschiedene I2C-Chips unter Verwendung der P.Fleury-Lib inkl. Datenblätter">> etwas die Diskussion überfliegen gibt ein Bild davon, was ich meine.
Jetzt ist allerdings alles klar.
Ich hätt ja gerne geschrieben, dann nimm halt den oder diesen Code. Aber
ich muss dich freisprechen: Mit den Stichwort SHT21 findet sich
tatsächlich nichts anderes in der Codesammlung.
Obwohl: ich hab mir mal das Datenblatt zum SHT21 angesehen. Das kommt
mir sehr bekannt vor. Das hatten wir doch hier im Forum vor nicht
allzulanger Zeit schon mal.
Da du die Fleury Funktionen benutzt: Was spricht dagegen, selbst etwas
zu machen. So schwer sieht das laut Datenblatt nicht aus.
Jörg Wunsch schrieb:> rv = sht21_measure(0xe3, b, 3);
Wie hast du das Clock Stretching gelöst?
TWI abschalten und Leitung überwachen?
> Vielleicht kannst du das ja auf die Fleury-Lib anpassen.
Die Fleury kann Clock Stretching nicht.
Karl Heinz schrieb:> Jetzt ist allerdings alles klar.>> Ich hätt ja gerne geschrieben, dann nimm halt den oder diesen Code. Aber> ich muss dich freisprechen
Dankesehr :)
es spricht nichts dagegen, selber etwas zu schreiben, nur würde ich mich
gerne an etwas bestehendem entlanghangeln um einen groben Überblick
davon zu haben, was umzusetzten ist.
Man muß denke ich nicht jedes mal das Rad neu erfinden.
Ich habe versucht, den Code aus der Sammlung etwas auszumisten/zu
korrigieren.
Die sht21_init ist nun soweit kompilierbar.
Die Funktion zum Datenauslesen macht mir aber größere Kopfschmerzen:
int get_sht21_data_str (int measuretype, int holdmode, int crcmode)
{
int holdmode;
int crcmode;
int measuretype;
int string[8] AS command;
int string[16] AS sht21_data;
command.0 =1;
command.1 =1;
command.2 =1;
command.3 =holdmode;
command.4 = 0;
command.5 = measuretype.0;
command.6 = measuretype.1;
command.7 = measuretype.3
...
}
Die AS befehle kenne ich so nicht und auch nicht die Form der Befehle:
command.0...
Siehe Anahng. Ist aber für eine selbstgestrickte Soft-I2C Lib. Kann man
aber sehr leicht anpassen, einfach das i2c_start() mit dem
darauffolgenen i2c_write() verheiraten.
dionysos 328 schrieb:> Man muß denke ich nicht jedes mal das Rad neu erfinden.
In dem Fall schon.
Der Code aus der Codesammlung taugt nix.
Kannst du ganz leicht erkennen. Wenn ein Programmierer ohne Rücksicht
auf Verluste überall einfach int benutzt, dann hat er ein oder zwei
grundlegende Dinge der µC-Programmierung nicht begriffen. Ihm fehlen da
noch mindestens ein paar Monate, bis er das erste mal etwas
veröffentlichen sollte.
> Die AS befehle kenne ich so nicht und auch nicht die Form der Befehle:> command.0...
Da hat er sich einen Bitzugriff gebaut. Normalerweise würde man das mit
einem Bitfeld machen (Bitangaben in einer Struktur). Ist nur hier
sinnlos, weil es eh nur 2 relevante Kommandos gibt.
Du musst dich entscheiden:
Hold Mode oder Nicht Hold Mode.
Der Hold Mode beruht auf Clock Stretching. Das ist etwas, was die AVR so
nicht unterstützen. Müsste man selber machen. Fr mich wär die Sache
klar: Nicht Hold Mode. Und damit gibt es dann nur noch 2 Kommandos.
0xF3 für Tempertur abfragen
0xF5 für Feuchtigkeit auslesen.
Und der Rest findet sich in geballter Form im Diagramm 16 vom Datenblatt
wieder
http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_SHT21_Datasheet_V4.pdf
Für die Umrechnung hat Jörg schon was gepostet.
Edit: Und Falk wohl auch.
Karl Heinz schrieb:> Der Hold Mode beruht auf Clock Stretching. Das ist etwas, was die AVR so> nicht unterstützen.
Doch, ich denke schon, das ist ganz normales I²C-Prozedere.
Die i2c_measure()-Routine ist von meinem eigenen Beispielcode aus
den avr-libc-Beispielen abgeleitet:
Jörg Wunsch schrieb:> Karl Heinz schrieb:>> Der Hold Mode beruht auf Clock Stretching. Das ist etwas, was die AVR so>> nicht unterstützen.>> Doch, ich denke schon, das ist ganz normales I²C-Prozedere.
Autsch.
Wo hab ich das jetzt wieder aus dem Gedächtnis ausgekramt. Hab im
Datenblatt vom M32 nachgesehen: jep, der Slave darf SCL auf Low ziehen.
Mea culpa.
Falk Brunner schrieb:> Siehe Anahng. Ist aber für eine selbstgestrickte Soft-I2C Lib.> Kann man> aber sehr leicht anpassen, einfach das i2c_start() mit dem> darauffolgenen i2c_write() verheiraten.
Vielen Dank!
dürfte ich die zugehörige I2C-Lib auch einsehen, um Unterschiede zu der
Implementation von P.Fleury ausmachen zu können?
Eine Verständnisfrage habe ich noch, mit welchen Argumenten ruft man die
Funktion auf?
Sie erwartet ja ein int8_t* temperature und int8_t* humidity, wenn ich
das richtig sehe.
ich hätte jetzt gedacht, dass die Werte durch die Funktion zurück
geliefert werden, und nicht übergeben werden müssen
dionysos 328 schrieb:> ich hätte jetzt gedacht, dass die Werte durch die Funktion zurück> geliefert werden, und nicht übergeben werden müssen
Und wie willst du zwei Werte zurückgeben?
Allerdings: ehrlich gesagt, einen SHT-21 benutzen und dann das
Ergebnis auf den minimalistischen Wertebereich eines int8_t zu
beschränken, das passt zwar zu Falk :-), ist aber ansonsten Perlen
vor die Säue geschmissen. Der SHT-21 kann Temperaturschwankungen
im Bereich von wenigen 10 mK sicher detektieren (*), da sollte man
ihm schon ein paar Bits mehr für das Ergebnis spendieren.
(*) Zwei SHT-21, nebeneinander montiert, geben in ruhiger Umgebung
in der Tat bis auf wenige 10 mK identische Werte. Bereits ein leichter
Luftzug lässt sie unterschiedliche Werte berichten.
dionysos 328 schrieb:> ich hätte jetzt gedacht, dass die Werte durch die Funktion zurück> geliefert werden, und nicht übergeben werden müssen
Du sollst auch nciht die Werte übergeben, sondern jeweils einen Pointer
auf die Variablen, in denen die Funktion die Werte hinterlassen soll
1
int8_ttemp,hum;
2
3
sht21_read(&temp,&hum);
bis eben hatte ich noch eine prinzipiell gute Meinung zu deinen C
Kenntnissen :-)
Ich versuche nun, die erste Kommunikation aufzubauen und muss
feststellen, dass mein sht21 nicht antwortet, bzw nichtmal
Konfigurationsbefehle annimmt.
da mein µC mit 5V versorgt wird, habe ich einen pegelwandler realisiert,
dieser funktioniert auch soweit (geprüft mit Oszilloskop)
schon beim ausführen meiner init routine bleibt die Kommunikation
hängen, der µC taktet immer wieder den Startbefehl raus. (Oszilloskop)
nach dem i2c_start_wait(SHT21+I2C_WRITE); bleibt das Programm hängen, da
der µC abwartet, ob der Sensor busy ist.
1
void sht21_init (int resolution, int end_of_batt, int OCH, int OTP_r)
2
{
3
int userreg;
4
5
i2c_start_wait(SHT21+I2C_WRITE);
6
7
i2c_write(0b11111110); //soft reset
8
9
_delay_ms(20); //wait for the sht21 to reboot
10
11
i2c_rep_start(SHT21+I2C_WRITE);
12
13
i2c_write(0b11100110); //enter config register
14
15
...
was könnte die Ursache sein?
3V Versorgung kommt am Sensor an.
edit: okay fehler gefunden, die angabe der adresse funktioniert so
nicht.
(code stammt zum teil aus der lib hier in der codesammlung)
(SHT21+I2C_WRITE) ergibt nicht, wie im datenblatt gefordert 0b10000000,
sondern 0b100000, was natürlich käse ist :-)
ich berichte weiter 8-)
diese wird jedoch nicht korrekt abgearbeitet.
der erste teil mit dem senden von SHT21_CMD_MEAS_T_NO_HOLD läuft durch
bis i2c_stop();
der zweite teil zum lesen hängt sich allerdings auf.
Vielleicht versuchst du ja erstmal, auf die Pegelwandler zu
verzichten und lässt den Controller auf 3,3 V laufen?
Bidirektionale Pegelwandler sind nicht so ganz trivial.
steht nicht in meiner entscheidungsgewalt, eval board und sensor sind
gesetzt.
pegelwandler passt schon [quelle anbei]
denke eher, dass der code noch hakt.
@dionysos 328 (dionysos328)
>feststellen, dass mein sht21 nicht antwortet, bzw nichtmal>Konfigurationsbefehle annimmt.
Warum hast du die Prüfung rausgeschmissen, ob der SHT21 antwortet?
>schon beim ausführen meiner init routine bleibt die Kommunikation>hängen, der µC taktet immer wieder den Startbefehl raus. (Oszilloskop)
Mein SHT21 braucht die nicht.
>nach dem i2c_start_wait(SHT21+I2C_WRITE); bleibt das Programm hängen, da>der µC abwartet, ob der Sensor busy ist.
Dann stimmt wohl die Adresse nicht.
Ausserdem wäre ein VOLLSTÄNDIGER Quelltext nicht ganz falsch.
>(SHT21+I2C_WRITE) ergibt nicht, wie im datenblatt gefordert 0b10000000,>sondern 0b100000, was natürlich käse ist :-)
I2C_WRITE sollte 0 sein.
hier der vorläufige code
bin zunächst nur an der funktion read_temp dran.
die init funktion läuft mittlerweile durch (unabhängig ob benötigt oder
nicht).
die LCD ausgaben sind nur zu debugzwecken
@dionysos 328 (dionysos328)
>hier der vorläufige code
Man braucht nur EINE Adresse, meist die zum Schreiben (LSB=0). Die zu
lesen ergibt sich aus der Veroderung mit 0x01.
Ausserdem sollte man sehen/wissen, dass die Funktion i2c_start() der I2C
Lib von Perter Fleury im Fehlerfall den Wert 1 liefert und nicht wie
meine eigene Null! Also eher so und nicht einfach auskommentieren weil
es nicht geht!
if (i2c_start(SHT21_I2C_ADR)) return 0;
Logisch dass dazu SHT21_I2C_ADR per #define definert sein muss! vOK, ist
es im .h File.
Die Funktion ist real getestet, sie funktioniert.
okay.
also bei der Kommunikation µC => Sensor scheint der Pegelwandler zu
funktionieren. Die 5V µC Signale kommen am Sensor mit 3V an.
In die andere Richtung ist es nicht so einfach, das mit dem Oszilloskop
nachzuvollziehen.
Ein Fehler ist also nicht komplett auszuschließen.
Die Schaltung für den Pegelwandler habe ich aus dem Philips Dokument
(Quelle weiter oben) entnommen. Dem schenke ich also erstmal vertrauen.
Andererseits läuft meine init Routine ja durch.
Und dort gibt es ja ein start_wait().
Wäre der Sensor busy/nicht zu erreichen, würde die Funktion doch nicht
durchlaufen, oder?
edit: ich habe gerade rausgefunden, dass die delays in meiner sht21.c
nicht richtig funktionieren.
delays, die in der main.c aufgerufen werden, haben die richtige dauer.
in der sht21.c scheit es, als würden sie garkeine verzögerung bewirken.
in beiden dateien sind sie mit
#include <util/delay.h>
eingebunden.
edit II:
delays werden nun korrekt abgearbeitet, sensor antwortet.
@ dionysos 328 (dionysos328)
>In die andere Richtung ist es nicht so einfach, das mit dem Oszilloskop>nachzuvollziehen.
Warum? Wo liegt das Problem? Einfach Osziu anklemmen und gut!
>Die Schaltung für den Pegelwandler habe ich aus dem Philips Dokument>(Quelle weiter oben) entnommen. Dem schenke ich also erstmal vertrauen.
Der funktioniert auch, WENN man die richtigen Bauteile verwendet und
diese richtig anschließt. Welche Transistoren hast du benutzt?
>Andererseits läuft meine init Routine ja durch.>Und dort gibt es ja ein start_wait().
Kann Zufall sein.
>edit: ich habe gerade rausgefunden, dass die delays in meiner sht21.c>nicht richtig funktionieren.>delays, die in der main.c aufgerufen werden, haben die richtige dauer.>in der sht21.c scheit es, als würden sie garkeine verzögerung bewirken.>in beiden dateien sind sie mit>#include <util/delay.h>>eingebunden.
Und wo ist das #define F_CPU ?
>delays werden nun korrekt abgearbeitet, sensor antwortet.
AHA!