Forum: Projekte & Code PT1000 an RP2040-pico-Board


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mi N. (msx)


Angehängte Dateien:

Lesenswert?

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
von MaWin (Gast)


Lesenswert?

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

von Mi N. (msx)


Angehängte Dateien:

Lesenswert?

Anbei noch die von der Arduino-IDE exportierte .uf2-Datei, die man 
direkt auf das pico-Boards kopieren kann.

von ossi (Gast)


Lesenswert?

Wie sieht die Schaltung aus?

von Mi N. (msx)


Angehängte Dateien:

Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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.

von Εrnst B. (ernst)


Lesenswert?

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

von Mi N. (msx)


Lesenswert?

Ε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.

von Εrnst B. (ernst)


Lesenswert?

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.

von Mi N. (msx)


Lesenswert?

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.

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
Noch kein Account? Hier anmelden.