Servus,
bin neu hier im Forum und habe ein Problem mit der Programmierung meines
RP pico.
Ich will die Timerfunktion verstehen. Sie soll ja den Prozessor nicht
blockieren wie dir Sleepfunktion. Dazu habe ich ein Program geschrieben
bzw zusammenkopiert, das eine Led 2 Sekunden leuchten läßt und
währenddessen ein Thermometer Und Feuchtigkeitsmesser (dht11) ausliest.
Hier der Code: 1 | #include <stdio.h>
| 2 | #include <math.h>
| 3 | #include "pico/stdlib.h"
| 4 | #include "hardware/gpio.h"
| 5 |
| 6 | const uint LED_PIN = PICO_DEFAULT_LED_PIN;
| 7 | //const uint DHT_PIN = 15;
| 8 | const uint DHT_PIN = 0;
| 9 | const uint MAX_TIMINGS = 85;
| 10 | bool led_status = false;
| 11 | bool nix_schalter = false;
| 12 | struct repeating_timer timer; //structure declaration
| 13 | typedef struct {
| 14 | float humidity;
| 15 | float temp_celsius;
| 16 | } dht_reading;
| 17 |
| 18 |
| 19 | bool tCallback( repeating_timer_t *timer){
| 20 | led_status = !led_status;
| 21 | gpio_put(LED_PIN, led_status);
| 22 | printf("das ist der nix_schalter am Eingang %i, \n ",nix_schalter);
| 23 | nix_schalter = false;
| 24 | printf("das ist der nix_schalter am Ausgang %i, \n",nix_schalter);
| 25 | return true;
| 26 | }
| 27 |
| 28 |
| 29 | void read_from_dht(dht_reading *result);
| 30 | uint DHT11_Read_Data(dht_reading *result);
| 31 | int main() {
| 32 | uint32_t i,k, l;
| 33 | i=k=l=0;
| 34 |
| 35 | // Pico pios initialisieren
| 36 | stdio_init_all();
| 37 | gpio_init(LED_PIN);
| 38 | gpio_init(DHT_PIN);
| 39 | gpio_set_dir(LED_PIN, GPIO_OUT);
| 40 | gpio_put(LED_PIN, false);
| 41 | sleep_ms(10000); // Warten, daß ich nach dem Start das Terminal aufmache
| 42 |
| 43 | printf("das kommt jetzt %d \n",i);
| 44 | i++;
| 45 | // Sensoren auslesen
| 46 | dht_reading reading;
| 47 | DHT11_Read_Data(&reading);
| 48 | float fahrenheit = (reading.temp_celsius * 9 / 5) + 32;
| 49 | printf("Humidity = %.1f%%, Temperature = %.1fC (%.1fF)\n",reading.humidity, reading.temp_celsius, fahrenheit);
| 50 |
| 51 | // Timer starten
| 52 | add_repeating_timer_ms(2000,tCallback,NULL,&timer); //starting the timer
| 53 | l++;
| 54 | // Schleife um die Sensoren nach dem Timeraufruf einmal auszulesen
| 55 | while(1) {
| 56 | printf("das ist der nix_schalter am Anfang der Whileschleife %i, \n",nix_schalter);
| 57 | l++;
| 58 | // nix_schalter abfragen, damit nur einmal ausgelesen wird
| 59 | if (!nix_schalter) {
| 60 | printf("das kommt jetzt %d, %d, %f, %i, \n",k,l); // Ausgabe um zu sehen was er alles so gemacht hat
| 61 | k++;
| 62 | i++;
| 63 | dht_reading reading;
| 64 | DHT11_Read_Data(&reading);
| 65 | float fahrenheit = (reading.temp_celsius * 9 / 5) + 32;
| 66 | printf("Humidity = %.1f%%, Temperature = %.1fC (%.1fF)\n",reading.humidity, reading.temp_celsius, fahrenheit);
| 67 | }
| 68 | l=l+1;
| 69 | nix_schalter = true; // nix_schalter auf true setzen, damit er beim nächsten Durchlauf die Sensoren nicht ausliest.
| 70 | i++;
| 71 | }
| 72 | }
|
Das ganze Drumrum um das Auslesen der Sensoren hab ich nicht angehängt
Die meisten Zähler und print Befehle hab ich nur eingefügt um zu sehen
wann er was macht bzw. nicht macht.
Das Problem erscheint nach dem Aufruf von "add_repeating_timer_ms" in
Zeile 52.
Wenn ich die Zeile prinf... (Zeile 56) habe durchläuft es die
Whileschleifen sauber und wenn nicht (auskommentiert oder gelöscht) dann
nicht! Ich will aber den ganzen Mist den er mir dann schickt nicht haben
und ich will das Verhalten verstehen. Zum Schluß: bin mir nicht sicher
ob ich die Ausgaben richtig eingebunden habe, hab aber nix gefunden wie
die formatiert werden sollten.
Und jetzt erst mal vielen Dank für Antworten.
Das ist die Ausgabe mit Zeile 56:
das kommt jetzt 0
Humidity = 56.0%, Temperature = 20.0C (68.0F)
das ist der nix_schalter am Anfang der Whileschleife 0,
das kommt jetzt 0, 2, 0.000000, 536876024,
Humidity = 0.0%, Temperature = 0.0C (32.0F)
das ist der nix_schalter am Anfang der Whileschleife 1,
das ist der nix_schalter am Anfang der Whileschleife 1, ...ca 33000 mal
dann
das ist der nix_schalter am Eingang 1,
das ist der nix_schaltdas ist der nix_schalter am Anfang der
Whileschleife 1,
das kommt jetzt 1, 33390, 0.000000, 0,
Humidity = 56.0%, Temperature = 20.0C (68.0F)
das ist der nix_schalter am Anfang der Whileschleife 1,
das ist der nix_schalter am Anfang der Whileschleife 1, ... usw
Hier die Ausgabe ohne Zeile 56:
das kommt jetzt 0
Humidity = 55.0%, Temperature = 20.0C (68.0F)
das kommt jetzt 0, 2, 0.000000, 536876024,
Humidity = 0.0%, Temperature = -infC (-infF)
das ist der nix_schalter am Eingang 1,
das ist der nix_schalter am Ausgang 0,
das ist der nix_schalter am Eingang 1,
das ist der nix_schalter am Ausgang 0, ... usw.
Falls Du einen zweiten Pico hast, kannst Du den zweiten Pico als
Debug-Probe benutzen:
https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html#swd
Oder Du kaufst eine Pico-Probe.
Es steht zu befürchten, dass:
eine ISR ist. Und wenn dort drin globale Variablen modifiziert werden 1 | bool led_status = false;
| 2 | bool nix_schalter = false;
|
wird das Hauptprogramm dies ohne weitere sachdienliche Anweisungen wohl
gar nicht erst mitbekommen.
Danke für die Antworten,
an Datenreisender: hab nen 2. pico, muß mir aber erst noch Kabel
besorgen. Ein Pico-probe schadet sicher auch nix, wenn ich mir den
zuleg. Das wird also noch etwas dauern, werd ich aber auf jeden Fall
angehen.
an der_Norbert:
"led_status" ist nicht das Problem, die Leds werden geschaltet.
"nix_schalter" wird geschaltet, wenn die ominöse printf-Zeile drin ist,
und nicht, wenn sie nicht drin ist.
Ich versteh die Abhängigkeit von dem printf - Kommando nicht.
Theo H. schrieb:
> "nix_schalter" wird geschaltet, wenn die ominöse printf-Zeile drin ist,
> und nicht, wenn sie nicht drin ist.
Das ist eine (verständliche) Fehlannahme.
"nix_schalter" wird in der ISR geschaltet, aber das Hauptprogramm
bekommt es nicht mit weil es mit einer, nennen wir es mal ›lokalen,
temporären Kopie‹ arbeitet!
Wenn es dir nichts ausmacht (Achtung Insiderwitz) knietief durch Blut zu
waten, dann suche im Forum mal nach volatile.
Theo H. schrieb:
> an Datenreisender: hab nen 2. pico, muß mir aber erst noch Kabel
> besorgen. Ein Pico-probe schadet sicher auch nix, wenn ich mir den
> zuleg. Das wird also noch etwas dauern, werd ich aber auf jeden Fall
> angehen.
Drei Kabel reichen:
https://pip-assets.raspberrypi.com/categories/610-raspberry-pi-pico/documents/RP-008276-DS-1-getting-started-with-pico.pdf?disposition=inline
Seite 17 zeigt Dir die Verkabelung.
> an der_Norbert:
> "led_status" ist nicht das Problem, die Leds werden geschaltet.
> "nix_schalter" wird geschaltet, wenn die ominöse printf-Zeile drin ist,
> und nicht, wenn sie nicht drin ist.
> Ich versteh die Abhängigkeit von dem printf - Kommando nicht.
Norbert wollte Dir den type qualifier "volatile" nahelegen: Deine
Callback ist eine ISR (ich nehme mal an), und da kann alles moegliche
passieren (https://de.wikipedia.org/wiki/Volatile_(Informatik)). Es kann
auch sein, dass durch die Optimierung des Compilers die Reihenfolge der
Kommandos veraendert wurde.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|