Moin, ich habe mir mit einem Arduino Micro eine kleine Sensoranzeige gebaut. Das Teil hat - neben den diversen Sensoren (DS1820, DHT22, SCT13 und LDR) - 2 Buttons. Mit dem einen dieser Buttons kann man durch eine Menüstruktur gehen (nur 1 Ebene: einfach eine Seite pro Sensor, recht primitiv also). Das Ding funktioniert soweit so wie ich das haben wollte: http://youtu.be/kgwBwX49tQ8 . Das hier ist der aktuelle Source: http://www.daemon.de/idisk/Sensorita.ino.txt. Nun habe ich folgendes Problem: zunächst hatte ich die Tastendrücke einfach innerhalb der loop()-Funktion abgefragt. Da jedoch das Auslesen der ganzen Sensoren etwas Zeit in Anspruch nimmt, ist es immer mal wieder dazu gekommen, dass ein Tastendruck ignoriert wurde. Das habe ich gelöst, indem ich die Tastendrücke über Interrupts abfrage (siehe Code). Das funktioniert soweit wunderprächtig, führt aber zu einem anderen Problem: hin und wieder (schwierig reproduzierbar) erscheint unmittelbar nach einem Tastendruck Zeichensalat auf dem LCD. Abgestürzt ist er dann nicht, weil er immer noch auf die Buttons reagiert und sich die Anzeige auch ändert (von einem Salat zum nächsten). Ich gehe daher davon aus, dass das deshalb passiert, weil der Interrupt in dem Moment eine laufende Sensorabfrage unterbrochen hat und dadurch irgendwelche Variablen leer/falsch befüllt sind (also ein Bufferoverflow ausgelöst wird). Die Frage ist nun: wie kann man sowas lösen? Ich möchte, dass das Gerät grundsätzlich auf Tastendrücke ohne grosse Verzögerung reagiert und trotzdem alle 5 Sekunden die Sensoren ausgewertet werden ohne, dass der Vorgang unterbrochen wird. Ich könnte zwar während der Sensorabfrage temporär die Interrupts abschalten, was aber wieder zu Problem Nummer 1 führt, dass ab und zu Tastendrücke untergehen.
Taster über Interrupts sind meistens keine gute Idee. Was du aber tun könntest, um in deinem Programm nicht allzuviel ändern zu müssen.
1 | void get_sensors () { |
2 | // fetch all sensor readings
|
3 | get_dallas(); |
4 | get_lux(); |
5 | get_dht(); |
6 | get_current(); |
7 | }
|
kein Mensch zwingt dich, immer alle Sensoren zur gleichen Zeit auszulesen. Wenn du das zeitlich staffelst, dann dauert das Auslesen lediglich eines Sensors nicht so lange. Dafür liest du eben alle halbe Sekunde einen anderen der Sensoren aus. Speziell die hier
1 | void get_dallas () { |
2 | // fetch all dallas DS1820 temperature readings
|
3 | sensors.requestTemperatures(); |
4 | for (int id=0; id<TempPins; id++) { |
5 | CurrentTemps[id] = sensors.getTempCByIndex(id); |
6 | }
|
7 | }
|
werden den Löwenanteil der Zeit beim Sensorauslesen benötigen. Aber wie gesagt: lies halt nicht alle auf einmal, sondern bei jedem
1 | void loop(void) { |
2 | // record current moments
|
3 | LCDMoment = SensorMoment = millis(); |
4 | |
5 | // check if there is enough time gone, to re-check the sensors
|
6 | if (SensorMoment - SensorTimer > SensorReadIntervall) { |
7 | get_sensors(); |
einen nur EINEN anderen. Aber eben jedesmal reihum jeweils den nächsten.
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.