Für einen ATmega328 gibt es schon einen Beitrag zur Auswertung eines PT1000: Beitrag "PT1000, einfache Auswertung mit AVR (ATmega328)" Dort wird ein 10 Bit ADC verwendet, welcher bei höheren Temperaturen eine nicht so hohe Auflösung liefert. Der RP2040 hat nun einen 12 Bit ADC, zu dem es allerdings keine genauen Daten gibt, weshalb auch keine genauere Bestimmung des Messfehlers möglich ist. Für eigene Versuche/Spielereien hier ein angepasstes Programm für Arduino-IDE und eine beispielhafte .log-Datei, die Temperaturen im Bereich -54 °C bis +385 °C mit 1 K Auflösung aufgezeichnet hat. Da sich beim RP2040 Ein- und Ausgangssignale durch Setzen eines CTRL-Bits invertieren lassen, sind hier beim UART1 die Signale invertiert. Das TxD1-Signal an GP0 kann somit direkt an einen RS232-USB-Wandler angeschlossen werden. Sollte auch RxD1 an GP1 verwendet werden, ist auf jeden Fall ein serieller Schutzwiderstand (3k3 - 10k) vor dem Eingang notwendig. Je nach Anwendung könnte es vorteilhaft sein, anstatt den PT1000 mit langem Kabel anzuschließen, den PT1000 direkt am pico-Board zu betreiben und das TxD-Signal mit +5 V und GND über eine längere Leitung zu führen.
:
Bearbeitet durch User
Mi N. schrieb: > Für einen ATmega328 gibt es schon einen Beitrag zur Auswertung eines > PT1000: Beitrag "PT1000, einfache Auswertung mit AVR (ATmega328)" Ja. Du hättest den dortigen thread auch lesen durfen. Oder noch schlimmer, du bis.N. bzw. m.n. selbst unter erneut neuem Namen. Die Schaltung ist Scheisse. Man betreibt Pt1000 nicht mit einer Spannung über dem Pt1000 von 2.5V, 1.65V, 1.25V, 0.55V, das führt zu hohem Messfehler durch Eigenerwärmung, und man belastet Referenzspannungsausgänge nicht mit vielen Milliampere. Beim RP2040 hast du zudem die Schaltung verschwiegen, der hat auf den üblichen Platinen eine RC gefilterte Referenzspannung von 3.3V, es wird aber vielleicht von dir ratiometrisch zur ungefilterten Betriebsspannung (Versorgung Output Pin) gemessen, was dann keineswegs mehr ratiometrisch ist, sondern nur noch verrauscht. Statt immer wieder zielgenau die schlechteste aller Lösungen anzustreben, sollte man einfach mal lesen, wie man es richtig macht. https://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.32
Anbei noch die von der Arduino-IDE exportierte .uf2-Datei, die man direkt auf das pico-Boards kopieren kann.
Im Programm steht neben der Funktionsbeschreibung auch wie die beiden Widerstände angeschlossen werden müssen. Hier noch einmal das Schaltbild dazu. Der serielle Ausgang ist GP0: Pin 1 des pico-Boards. Wenn man den ser. Monitor in der Arduino-IDE nutzen möchte, müssen die Serial1.xxx() Aufrufe nach Serial.xxx() geändert werden.
Mi N. schrieb: > Hier noch einmal das Schaltbild dazu Ja, schlimm, hier sieht man, wie ARef vom RP2040 aussieht https://proto-pic.co.uk/wp-content/uploads/2021/03/RPI-PICO-R3-PUBLIC-SCHEMATIC.pdf Also 200 Ohm Ausgangswiderstand und er belastet mit 2k, da bricht die Spannung schon mal um 10% auf 3V ein, und es kommen satte 1.5V mit 1.5mA an den Pt1000, statt der üblichen 0.1V und maximalen 0.33V. Was er da noch ausser Hausnummern messen will, bleibt schleierhaft.
MaWin schrieb: > und er belastet mit 2k MaWin schrieb: > satte 1.5V mit 1.5mA > an den Pt1000 dazu kommt noch diese schicke Codezeile:
1 | pinMode(PT_IN_0, OUTPUT); // PT1000 wieder kurzschließen |
Lustigerweise ohne klare Definition, ob der Pin anschließend hart LOW oder HIGH ist. d.H. entweder wird Aref meistens mit 1k belastet, oder der PT1000 mit 3.3mA
Εrnst B. schrieb: > Lustigerweise ohne klare Definition, ob der Pin anschließend hart LOW > oder HIGH ist. Blind aber gut gelaut. Schön! Als Programmieranfänger muß man lernen, daß es explizite und implizite Funktionen gibt. Nur weil Du etwas nicht siehst, bedeutet das ja nicht, daß es nicht existiert. Statt Götzenanbeterei hätte Du auch fragen können. Aber es ging Dir wohl garnicht um einen konstruktiven Beitrag.
Mi N. schrieb: > Als Programmieranfänger(*) muß man lernen, Gut erkannt. Hier eine kleine Übungsaufgabe für dich, so zum Start: Was muss passieren, dass diese Funktion hier ein "gpio_put" ausführt, wenn sie mit Parametern "PT_IN_0, OUTPUT" aufgerufen wird?
1 | extern "C" void pinMode(pin_size_t ulPin, PinMode ulMode) { |
2 | switch (ulMode) { |
3 | case INPUT: |
4 | gpio_init(ulPin); |
5 | gpio_set_dir(ulPin, false); |
6 | gpio_disable_pulls(ulPin); |
7 | break; |
8 | case INPUT_PULLUP: |
9 | gpio_init(ulPin); |
10 | gpio_set_dir(ulPin, false); |
11 | gpio_pull_up(ulPin); |
12 | gpio_put(ulPin, 0); |
13 | break; |
14 | case INPUT_PULLDOWN: |
15 | gpio_init(ulPin); |
16 | gpio_set_dir(ulPin, false); |
17 | gpio_pull_down(ulPin); |
18 | gpio_put(ulPin, 1); |
19 | break; |
20 | case OUTPUT: |
21 | gpio_init(ulPin); |
22 | gpio_set_dir(ulPin, true); |
23 | break; |
24 | default:
|
25 | DEBUGCORE("ERROR: Illegal pinMode mode (%d)\n", ulMode); |
26 | // Error
|
27 | return; |
28 | }
|
29 | |
30 | if (ulPin > 29) { |
31 | DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin); |
32 | return; |
33 | }
|
34 | _pm[ulPin] = ulMode; |
35 | }
|
Falls du diese schwere Aufgabe gemeisterst hast, nächste Frage, diesmal mehr in die "Lesen und verstehen"-Richtung: Wer definiert den Zustand des Pins bei Programmstart, wenn dein Programm es nicht explizit vorgibt? A) Das Arduino-Framework. Wenn ja: Wo dokumentiert, wo definiert? B) Die Registerinhalte des RP2040 bei Reset. Bonusfrage: Unter welchen Umständen kann ein Programm ohne vorherigen Hardware-Reset ausgeführt werden? Oder ist das kategorisch ausgeschlossen? Und als Finale: Welche schlimmen Folgen hätte es gehabt, einfach in der setup() mit einem digitalWrite für klare Verhältnisse zu sorgen? *) Falls du dich fragst, was dich als blutigen Anfänger geoutet hat: Es war hauptsächlich die Überflüssige "do {} while (1);" - Schleife in deiner loop(). Die verhindert nämlich u.A. dass "yield()" aufgerufen wird, und macht damit die TinyUSB-Funktionalität kaputt.
Ist ja alles ganz nett, aber interessiert nicht die Bohne. Hier geht es um einen PT1000 und nicht um TinyUSB. Der Controller setzt per Hardware-Reset seine Peripherie in einen definierten Zustand. Sofern die IDE anschließend nicht unerlaubter Weise daran herumdreht, steht das Ausgangsdatenregister von GPIO26 / ADC0 auf '0'. So ist es im hier vorliegenden Programm der Fall! Den ADC0-Pin im Programm wiederholt auf seinen Ausgangswert zu bringen, ist dann ein "Angstkondensator" in Software. Zur Sicherheit natürlich nicht in setup() sondern in loop(). Gut, es schadet nicht. Aber dann bitte auch die RxD und TxD Pins noch einmal "richtig" auf Eingang bzw. Ausgang setzen - man weiß ja nie.
Der ADC im RP2040 schafft leider keine 12 Bit. Es gibt einen Silicon-Bug, einer der Referenzkondensatoren ist falsch dimensioniert. Deswegen steht im Datenblatt ja auch eine ENOB von 8.7, gibt diverse Abhandlungen im Netz dazu. Effektiv ist der ADC nur bis 8 Bit zu gebrauchen.
Andreas M. schrieb: > Der ADC im RP2040 schafft leider keine 12 Bit. Das ist alles bekannt. Sieh Dir bitte die .txt-Datei an und zeige mir die Stelle, an der das passieren müßte. Ich habe sie nicht gefunden; vielleicht gelingt es Dir. Der ADC-Wert 2560 abzüglich des Offsets von 16 ergibt 2544. Dazu werden 170 °C errechnet wie auch zu 2543, da keine Nachkommstelle angezeigt wird. Die "Ausraster" könnte man kompensieren, indem man an den kritischen Stellen einen kleinen Offset zuschaltet (Pullup/Pulldown) oder seinen Messbereich zwischen zwei "Fehlerstellen" verschiebt. Auch damit bleiben der Aufwand gering und der gesamte Messbereich sehr hoch.
Mi N. schrieb: > Das ist alles bekannt. Sieh Dir bitte die .txt-Datei an und zeige mir > die Stelle, an der das passieren müßte. Ich habe sie nicht gefunden; > vielleicht gelingt es Dir. Deine Messung bringt so nix. Du nimmst einen ADC Wert, berechnest daraus eine Temperatur und versuchst darin dann was zu sehen. Die berechnete Temperatur ist aber einfach nur eine andere Darstellung des ADC Werts, sie ist eine davon abhängige Größe. Was du machen müsstest wäre die berechnete Temperatur mit der Temperaturmessung eines zweiten, unabhängigen Messgerätes zu vergleichen. Dann wirst Du einen schönen Sprung sehen, so etwa bei 178 °C ( Nach Deiner Formel ) Allerdings nutzt Du ja gerade mal ca 25% des Messbereichs des ADCs Nimm ein Poti, Klemme das an den ADC und an ein Multimeter. Dann machst Du eine Messreihe in mV Schritten, notiere ADC Werte und Spannung auf dem Multimeter. Es reichen die Regionen um die ADC Zählwerte 512, 1536, 2560, und 3584. Mi N. schrieb: > Die "Ausraster" könnte man kompensieren, indem man an den kritischen > Stellen einen kleinen Offset zuschaltet (Pullup/Pulldown) oder seinen Nicht wirklich, der Fehler ist auch an den nicht kritischen Stellen noch sehr groß. Schau dir das INL Diagramm in http://pico-adc.markomo.me/INL-DNL/#why-does-the-dnl-spike an. Aus Softwaresicht besteht das Problem, das ein ADC Zählwert mehrere Spannungen bedeuten kann. Du kannst also vom Zählwert nicht ableiten, in welche Richtung du korrigieren musst.
Andreas M. schrieb: > Die berechnete > Temperatur ist aber einfach nur eine andere Darstellung des ADC Werts, > sie ist eine davon abhängige Größe. Genau darum geht es, wenn man einen PT1000 auswertet ;-) Andreas M. schrieb: > Nicht wirklich, der Fehler ist ... daß Du mich nicht verstanden hast. Im Datenblatt sind die Fehlstellen benannt. Folglich kann man an den Stellen, die diesen Werten entsprechen, einen Offset hinzufügen/abziehen, um den ADC in einen unkritischen Bereich zu bringen. Ein paar Millivolt sollten reichen. Anschließend muß der neue ADC-Wert um den Offset korrigiert werden. Dazu braucht es noch ein wenig Gehirnschmalz, um den Offset automatisch zu erfassen. Für die doppelte Messung ergibt sich eine kleine Verzögerung (< 1 ms) des Ergebnisses, was nicht stören dürfte. Die Auflösung bleibt hoch und die erreichbare Genauigkeit hängt von ADC und den verwendeten Bauteilen ab. Wer +/- 1 mK erwartet, ist hier falsch!
Mi N. schrieb: > Genau darum geht es, wenn man einen PT1000 auswertet ;-) Du hast nicht verstanden was ich geschrieben habe.
Gut, und was ist Deine Lösung? Einen diskreten ADC verwenden oder doch nur einen billigen Widerstand? Vieleicht sind die neueren RP2040 auch schon verbessert.
Mi N. schrieb: > Gut, und was ist Deine Lösung? > Einen diskreten ADC verwenden oder doch nur einen billigen Widerstand? Ich nutze nur 8 Bit, das reicht zum Glück für meine Zwecke aus. Wenn ich mehr brauche dann würde ich ne externen nehmen oder nen Sigma Delta in Software implementieren wenn es sich um eine langsame Größe (wie z.B. Temperatur handels). Da reicht ein GPIO Pin. müsste über die PIO eigentlich gehen: https://www.microchip.com/en-us/application-notes/an700 https://elmicro.com/files/elmicro/due9810_sigdelta.pdf Mi N. schrieb: > Vieleicht sind die neueren RP2040 auch schon verbessert. Nein, aktuell ist da kein Silicon Fix geplant. (Wäre auch garn icht ohne weiteres möglich weil da ganze Flächen umorganisiert werden müssen)
Andreas M. schrieb: >> Gut, und was ist Deine Lösung? >> Einen diskreten ADC verwenden oder doch nur einen billigen Widerstand? > > Ich nutze nur 8 Bit, das reicht zum Glück für meine Zwecke aus. Vielleicht berücksichtige ich die Kompensation noch in der Schaltung und im Programm. Im Grunde reicht es, einen 100 k Widerstand zum 1 k parallel zu schalten - einfach 3,3 V per GPIO über diesen Widerstand an den ADC-Eingang - und sonst "fliegend" zu lassen. Alternativ nimmt man einen etwas größeren Wert als 1 k, um mit dem ADC-Wert im Bereich 1536 - 2560 zu liegen. -50 -> +200 °C sollten dann unkorrigiert messbar sein.
Andreas M. schrieb: > Nicht wirklich, der Fehler ist auch an den nicht kritischen Stellen noch > sehr groß. Schau dir das INL Diagramm in > http://pico-adc.markomo.me/INL-DNL/#why-does-the-dnl-spike an. Aus > Softwaresicht besteht das Problem, das ein ADC Zählwert mehrere > Spannungen bedeuten kann. Du kannst also vom Zählwert nicht ableiten, in > welche Richtung du korrigieren musst. Die Sache habe ich mir noch einmal näher angeschaut und ein paar Versuche durchgeführt. Danke für Deinen Einwand. Eine (Bereichs-)Umschaltung vorzunehmen, um aus den kritischen Bereichen herauszukommen, ist nicht so sinnvoll, es sei denn, man könnte bei Stückzahlen dadurch richtig viel sparen. Beschränkt man sich beim ADC auf den Wertebereich von 1536 - 2559 (INL_INDEX = 2 bzw. 3. Segment der INL-Kurve) und erhöht zudem R1 auf 1,200 kOhm, erhält man einen Messbereich von rund -70 bis +250 °C. Im neuen Programm ist eine Korrektur der INL laut Datenblatt vorhanden, um den ADC-Fehler zu reduzieren. Weitere und dominante Fehlerquellen sind jedoch die Güteklasse des PT1000 selbst, der genaue Wert von R1, der 0-Offset des ADCs und der recht grobe Skalierungsfaktor von 0,0385. Hier wäre es angesagt, über Tabellenwerte zu interpolieren. Beispiele dazu gibt es an anderer Stelle. Hier wollte ich das Demo-Programm übersichtlich und durch Debug-Ausgaben die Funktion nachvollziehbar halten. Getestet habe ich die Funktion mit Drehpoti und USB-Ausgabe, wodurch der Aufbau recht einfach war. Vielleicht nutzt es.
:
Bearbeitet durch User
Mi N. schrieb: > Die Sache habe ich mir noch einmal näher angeschaut Ich halte es für eine sehr schlechte Idee, den V_Ref zu belasten. Wenn Dein µC seine Betriebsspannung als Referenz nutzt, kommt der Spannungsteiler samt PTC direkt an diese. Wenn diese sich ändert, macht das garnichts, weil ja das Verhältnis gemessen wird. Auf µC-net beliebig oft durchgekaut, "Ratiometrische Messung".
Ich bin nicht sicher, ob das hier schon genannt wurde, aber die Referenzspannung auf dem Pico-Board ist ziemlich unsauber. Man kann aber einfach am Vref-Pin einen Referenz-Shunt (LM4040 mit 3V bietet sich an) nach Masse schalten. Der R7 auf dem Pico-Board dient dann schon als Vorwiderstand für die Referenz. Im Anhang der Ausschnitt aus dem Datenblatt des Pico-Boards. PS: Die Referenz sollte man natürlich nicht belasten. :)
:
Bearbeitet durch User
Jonny O. schrieb: > Ich bin nicht sicher, ob das hier schon genannt wurde, aber die > Referenzspannung auf dem Pico-Board ist ziemlich unsauber. Man kann aber > einfach am Vref-Pin einen Referenz-Shunt (LM4040 mit 3V bietet sich an) > nach Masse schalten. Der R7 auf dem Pico-Board dient dann schon als > Vorwiderstand für die Referenz. Dann mache es! Meine Schaltungen/Programme sind nicht in Stein gemeißelt und konstruktive Erfahrungsberichte sind willkommen. Was erwartest Du von einer absolut stabilen Referenz? Mehr Auflösung, höhere Genauigkeit? Ich habe da meine Zweifel. R9 in der Schaltung mit 1R ist eher eine Lötbrücke. V_REF und V_ADC sind (fast) identisch und daher werden hier ratiometrische Messungen gemacht. R7 mit 200R und C13 mit 2µ2 filtern die restlichen 1 MHz Spitzen vom Schaltregler locker weg. Das Kurzschließen des PT1000 läßt die Spannung V_REF leicht wackeln, was bei einer ratiometrischen Messung aber nicht stört. Bei einigen Schaltungen schalte ich den lokalen Schaltregler des Pico-Boards ab und verwende einen extenern 3,3 V LDO für das gesamte Board. Das halte ich hier für nicht notwendig. Den NOS-Wert (number of samples) hatte ich testweise von 1 auf 100 gesetzt, um beim fliegenden (Poti-)Aufbau Störungen zu vermeiden. Aktuell habe ich dann wieder mit einer Einzelmessung und 1000 Ohm für R1 gemessen: die Ergebnisse sind gleich. Selbst die dummy-Messung vor der Erfassung des Messwertes kann entfallen, wenn die Zuleitung keine zu große Kapazität aufweist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.