PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ADS1115 I2C AD-Wandler Programmierung



alexander_ro
07.02.2019, 10:24
Hi ... Mädels ... Jungs ... :)

Ich bin gerade dabei mir eine C++ Klasse für den ADS1115 zu bauen. Ich verstehe nur gerade nicht so ganz wie das Teil Programmiert werden soll. Der hat mehrere Register welches man davon anspricht wird über das "Address Pointer Register" eingestellt. Schreibt man jetzt eine "1" in das "Address Pointer Register" gehen die nächsten Zugriffe auf das "Config Register". Will man aber jetzt zum Beispiel die Daten des Wandlers lesen woher weiß der nun das der nächste Schreibvorgang wieder das "Address Pointer Register" betrifft?

Mein Problem gerade ist das ich nur wenn ich bei jedem Wert den ich lese vorher die ganze Konfiguration mit sende funktioniert das. Wenn ich nur versuche in einer schleife zu warten bis die Wandlung fertig ist und dann die Daten der Wandlung lese gerät nach einigen Wandlungen das "Config Register" durcheinander. Ich vermute mal das das Umschalten zwischen dem "Config Register" und dem "Conversion Register" irgendwann durcheinander gerät.

Im Datenblatt beschreiben die zwar was die einzelnen Register oder Bits machen. Für den Ablauf der Programmierung habe ich aber nicht wirklich was gefunden.

Viele Grüße
Alexander

Ceos
07.02.2019, 11:05
Ich hole mal wegen I2C etwas weiter aus, du sendest immer erst eine I2C Adresse in der im niederwertigsten Bit codiert ist ob man lesen oder schreiben will. Alles was danach kommt ist entsprechend der Doku zu interpretieren und wer Sendet ist durch das R/W Bit geklärt.

Deine Nachricht nach der Doku zu lesen sieht also folgendermaßen aus:

(MACK/MNACK Master, SACK/SNACK Slave)
(*1) Sollte nach I2C Spec immer ein NACK sein nach dem letzten Byte, der Chip erlaubt aber beides

Schreiben only: START -> Adresse + W -> SACK -> APReg -> SACK -> MSB -> SACK -> LSB -> SACK -> STOP

Lesen only: START -> Adresse + R -> SACK -> MSB -> MACK -> LSB -> MACK/MNACK(*1) -> STOP

Wobei eine vollständige Lesen Routine folgendermaßen aussieht:

Lesen mit APReg: START -> Adresse + W -> SACK -> APReg -> SACK -> STOP+START/RESTART -> Adresse + R -> siehe oben...

die Doku sagt, ein REgister weiderholt zu lesen geht indem man nur einmal das APReg schreibt und dann wiederholt ließt
schreiben braucht aber immer das APReg bei jedem Schreibvorgang

alexander_ro
08.02.2019, 10:20
Bei einer "singel conversion" muss ich ja immer erst eine "1" in das Bit 15 schreiben damit ich einen neuen Wert bekomme. Dann ist es schon so das ich in diesem Fall immer das "Config Register" neu schreiben muss. Dann warten bis der Wert im Bit 15 beim lesen wieder "1" wird und dann das "Address Pointer Register" umschreiben um den Wert aus dem "Conversion Register" lesen.

Der ADS1115 erwartet also beim schreiben immer vorher einen Wert für das AP-Register und dann den Wert der in das dann gewählte Register geschrieben werden soll. Nur beim mehrfachem lesen liest er aus dem zuletzt im AP-Register eingestellten Register. Der Hinweis war gut das hatte ich nicht so richtig verstanden. Was vermutlich daran liegt das die immer in so einer unverständlichen Sprache schreiben ... ;)

Ich will ja erst mal Temperaturen messen. Da reicht die "singel conversion" weil der Wert sich nur relativ langsam verändert. Würde man dann bei einer "continuous conversion" die Werte einfach in einer Schleife aus dem "Conversion Register" lesen ohne das Bit 15 abzufragen. Woher weiß man dann denn das man nicht zweimal den gleichen Wert liest?

Ceos
08.02.2019, 10:30
Woher weiß man dann denn das man nicht zweimal den gleichen Wert liest?

Gegenfrage, warum muss einen das interessieren :D
Es geht ja um Temperaturen und solange ich jetzt nicht direkt einfach häufiger lese als er sampeln kann, sollte ich eher mal einen Wert verpassen als einen doppelt zu lesen, aber das sollte doch keine signifikante Wirkung auf die Aufgabe dahinter haben oder?

Edit: Will damit sagen, dass mir jetzt kein konkreter Anspruch einfällt der sowas erforderlich machen würde und cih daher keinen GRund sehe da unnötig Zeit zu investieren :) Vll. hat der ja einen physischen Pin um neue Samples zu melden statt das Register zu befragen, habe jetzt nicht tiefer in die Doku hineingelesen.

White_Fox
08.02.2019, 10:39
Gegenfrage, warum muss einen das interessieren :D
Es geht ja um Temperaturen und solange ich jetzt nicht direkt einfach häufiger lese als er sampeln kann, sollte ich eher mal einen Wert verpassen als einen doppelt zu lesen, aber das sollte doch keine signifikante Wirkung auf die Aufgabe dahinter haben oder?

Genau dieser Umstand war der Grund, warum bei uns in einem Uniprojekt die fabelhaft einfachen, arduinoartigen Bibliotheken für den STM32 wieder rausgeflogen sind. Für jede lächerlich einfache Art der Signalverarbeitung ist es schon sinnvoll zu wissen, ob ich den gleichen Wert ein- oder zweimal gelesen habe. Und sei es nur um mit mehreren Werten das Rauschen rauszumitteln. In unserem Fall damals wollten wir eine Sprungantwort einfach nur aufzeichnen. Selbst sowas geht nicht, wenn du keine Kontrolle darüber hast daß du keine Werte doppelt liest/überspringst.

Ceos
08.02.2019, 11:21
Für jede lächerlich einfache Art der Signalverarbeitung ist es schon sinnvoll zu wissen, ob ich den gleichen Wert ein- oder zweimal gelesen habe.

Je nach Aufgabe sollte man aber die Kirche im Dorf lassen. Eine Druckmessung sollte schon so schnell wie möglich sein damit ein heftiger Transient rechtzeitig unterdrückt werden kann und nicht das Rohr samt Sensor platzt.

Bei einer Temperaturmessung sind wir schon bei einer ganz anderen Prozessgeschwindigkeit. Wenn dieser Sensor keine physische Leitung präsentiert und obendrein auch noch erfordert multiple mal ein Status Register auf relativ aufwendige Weise auszulesen um dann den eindeutig neuen Messwert zu erfahren, hat man schlicht den falschen Sensor gewählt.

Meiner Meinung nach wäre hier der genau richtige Zeitpunkt zu hinterfragen ob man diese Messgeschwindigkeit benötigt oder die einfachste Lösung hinreichend ist (Free Run und langsamer als die Sampletime auslesen)


Und sei es nur um mit mehreren Werten das Rauschen rauszumitteln.

Das wäre auch mit o.g. Messmethode möglich, spricht jetzt effektiv nicht dagegen.


In unserem Fall damals wollten wir eine Sprungantwort einfach nur aufzeichnen.

Dann brauch man halt einen anderen Sensor der einem neue Samples einfacher zugänglich signalisiert.

-----------------------

Aber nochmal zurück zum eigentlichen Problem: wenn du uns etwa code zeigst (auch den I2C part) wie du derzeit deinen Sensor ausließt könnte man vielleicht mal drüber schauen ob es da einen Fehler im Ablauf gibt der das korrumpierte Config Register erklärt. Oder eine Beschreibung was genau du sendet und empfängst.

alexander_ro
08.02.2019, 12:45
Die C++ Klasse die ich gerade baue soll den Wandler best Möglich unterstützen weil ich den als Standard Messwandler benutzen will. Ich benutze wenn möglich gern immer die gleichen Teile erleichtert das vorankommen bei Projekten. Der AD-Wandler eignet sich ja nicht nur zum Temperaturmessen. Das ist nur mein momentaner Bedarf. Aber für den Stromsensor brauche ich den auch nochmal mit seiner Fähigkeit Differenzial Messungen machen zu können. Dann kann man auch die Stromrichtung feststellen.
https://www.conrad.de/de/honeywell-stromsensor-csla1ch-8-16-vdc-print-505261.html

Wurde ja schon gesagt es gibt schon Anwendungen wo es wichtig ist. Immer wenn ein Messwert irgendwie eine Beziehung zur Zeit hat ist es wichtig nicht mehrmals den gleichen Wert zu lesen. Nur als Beispiel wenn der Wandler das Signal eines Mikrophons Digitalisieren soll. Der Sänger zieht Dir bei Lebendigem Leib die Haut ab wenn er hört was Du aus seiner Stimme machst wenn Du mehrfach den gleichen Wert liest ... ;)

Evtl. liefert der Wandler bei "continuous conversion" ja selbst einen Wert erst wieder zurück wenn der nächste neue zur Verfügung steht. Er weiß ja ob der aktuelle schon gelesen wurde oder nicht. Liest man zu langsam werden die Wert sicher verworfen. Klar wo sollte er die speichern.

Klar Code gibts auch: https://git.hts-software.de/cgit.cgi/Athena-Api/tree/I2c
Im Verzeichnis Hardware ist die Klasse Ads1115 zum Wandler. ModulTest enthält das Testprogramm. Ich Teste es gerade auf einem Raspi mit einem Gentoo Linux. Es sollte aber mit anderen Linuxen auch gehen. Das im ersten Post genannte Problem ist ja schon gelöst. Man muss bei "singel conversion" wirklich immer das Bit 15 im "Config Register" wieder setzen um die Wandlung des nächsten Wertes zu starten. Das hatte ich übersehen. Bleibt nur noch die Frage nach dem "free run" wie Du es genannt hast.

Ich dachte es kennt jemand den Wandler und kann das leicht beantworten. Nicht das ich nicht gesucht hätte aber wie gesagt eine schwer verständliche Sprache im Datenblatt.

oberallgeier
08.02.2019, 13:07
Je nach Aufgabe sollte man aber die Kirche im Dorf lassen .. Bei einer Temperaturmessung sind wir schon bei einer ganz anderen Prozessgeschwindigkeit ..Genau, beides ist richtig. ABER es kommt halt aufs Detail drauf an. Wenn ich nen Dampfkessel ausmesse, dann darf ich mit nem recht trägen Temperaturverlauf rechnen (Pssst - pingelig - von Notfall-Dampferzeugern auf Raketenofenbasis abgesehen). Ganz anders siehts aus, wenn ich z.B. temperaturkritische Reaktionen in einem Rührkessel GENAU untersuchen will. In letzterem Fall dürfte ich bei der Temperaturmessung in den Bereich von einigen zig Hertz geraten um herumwirbelnde Temperaturnester in den Griff zu bekommen - oder eben ausschließen zu können. Der 1115er schafft immerhin - laut Datenblatt - bis zu 860 SPS. Wie schnell das dann in der Praxis bei den geforderten GEnauikeiten (siehe auch Temperatursensor) sein kann, würde ich bei gewünschten Frequenzen über 1 Hz sowieso erstmal in der kompletten Messkette mit ner Sprungantwort/Übergangsfunktion testen.


.. Eine Druckmessung sollte schon so schnell wie möglich sein ..Jein. Was ist schon "so schnell wie möglich"? Ich hab nen Drucksensor der vierhundert Kilohertz kann, bei sehr guter Genauigkeit, das ist schon recht flott und reicht (für meine Fragen und Belange) praktisch überall aus - sogar Stöße in Zentrifugalpumpen oder vor/nach Ventilen sind damit prächtig zu messen - einschließlich zeitlichem Verlauf. So schnell wie möglich geht dabei bald mächtig ins Geld.


.. Temperaturmessen. Das ist nur mein momentaner Bedarf. Aber für den Stromsensor ..Da hamma schon das Problemchen . . .

Frage: läuft das, ohne die Messaufgabe und die Peripherie zu kennen, nicht doch wieder mal auf ne Kristallkugel raus?

alexander_ro
08.02.2019, 15:11
Weder Kristall noch Kugel sondern viereckig Plastik und Drahtbeinchen ... ;)

Ich will nicht möglichst schnell und auch nicht nur Temperatur messen. Sondern mit der extra für diesen Chip geschriebenen Klasse eben jenen Chip und seine Fähigkeiten Nutzen können. Ich finde jetzt schon das ist eine sehr genaue Vorgabe. Wenn er 860 SPS kann wie bekomme ich die dann zur CPU ohne doppelte Werte zu lesen?

Als 16 Bit Wandler ist er ja eher ein präzisions Wandler. Da erscheint mir die Lösung einfach langsamer lesen als der Wandler ist ein wenig unpräzise. Dürft man mit dieser Lösung dann nicht nur Maximal 50% Nutzen also 430 SPS. Sonst könnte doch die Zeitrechnung Chip und CPU trotzdem doppelte Werte liefern.

oberallgeier
08.02.2019, 15:37
Weder Kristall noch Kugel sondern viereckig Plastik und Drahtbeinchen ... Da erscheint mir die Lösung einfach langsamer lesen als der Wandler ist ein wenig unpräzise ..Na ja, ich trau mich ja fast nicht aufs Datenblatt hinzuweisen (klar, ein total lästiger Hinweis) und auffordern den Satz zu suchen ".. The ALERT/RDY pin can also be configured as a conversion ready pin .." und dann den Pin per Interrupt abfragen . . .

Denn: ohne das zugehörige Datenblatt zu lesen ist der Umgang mit Mikrocontrollern/-elektronik eins der letzten großen Abenteuer unserer Tage.

alexander_ro
08.02.2019, 15:51
Schick mir eine Deutsche Übersetzung ... Dumme Sprüche kann ich auch machen.

Den PIN habe ich schon gesehen nur mutet es seltsam an wenn man einen Chip mit Bus hat das man zwingend extra Hardware braucht um den zu Nutzen. Wozu hab ich dann den Bus ein einfacher GPIO würde reichen um die 16 Bit zur CPU zu schieben.

Ja danke für die Blumen es ist sicher eine hervorragende Leistung ohne Datenblatt die Singel Conversion funktionierend einfach so aus der Luft zu Programmieren. Mir war nicht Bewusst was ich doch für ein Genialer Mensch bin ... :)

<Edit>
Kapitel 10.1.7 Quickstart (Seite 35): Beschreiben die "Continuous Converstion" in dem Schaltbild darunter benutzen die aber auch nicht den Alert Pin. Leider geben die in Schritt 3 nur an wie das erste Byte gelesen wird und auch da nicht woher man weiß das schon ein Wert verfügbar ist.
</Edit>

White_Fox
08.02.2019, 18:14
Das ist nicht unüblich die Daten auf einem Standardbus rauszuschieben und verschiedene Informationen auf Extrapins zu legen. Und eigentlich ist so eine Ansteuerung recht einfach...wenn man seinen Mikrocontroller einigermaßen beherrscht und nicht auf das Zusammenwürfeln irgendwelcher zusammengeklaubter Bibliotheken angewiesen ist. So wie sich dein erster Post liest scheint das bei dir ja aber nicht der Fall zu sein.

Sei doch froh daß es so ist, denn andernfalls hättest du z.B. mehr Protokolloverhead. So sollte es aber doch recht einfach sein.

alexander_ro
09.02.2019, 09:35
Ja das geht so keine Frage. Mich hat nur der Schaltplan in dem Quickstart auf die falsche Fährte gebracht. Da ich die Sprache nur schwer verstehe Orientiere ich mich halt an Schaltbildern, Diagrammen oder Tabellen.

Ja die Software ist eine Eigenentwicklung. Irgendwo oben hatte ich schon mal einen Link zur Software eingefügt. Das sollte mit jeder Linux Version ohne große Änderungen funktionieren.

Danke für eure Hilfe ... dann kann ich jetzt mal weiter bauen :)


Jetzt funktioniert die Klasse schon ganz gut. Für FreeRun und Comparator fehlt noch die Software Unterstützung. Nach meinen Tests erreicht man aber auch im Singel Mode relativ hohe SPS Werte. Klar erkauft man die mit mehr verbrauch bei der Rechenleistung.
Falls es jemanden Interessiert: https://git.hts-software.de/cgit.cgi/Athena-Api/tree/I2c/Hardware/Ads1115.hpp