Forum: Mikrocontroller und Digitale Elektronik Frage zu Interrupts bei Atmega32U (Arduino Micro)


von Tom L. (tlin)


Lesenswert?

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.

von Tom L. (tlin)


Lesenswert?

Keiner eine Idee?

von Karl H. (kbuchegg)


Lesenswert?

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