Forum: Mikrocontroller und Digitale Elektronik Problem mit mehreren Interrupts


von ArLev (Gast)


Lesenswert?

Guten Morgen.
Ich habe seid einiger Zeit ein Projekt am laufen und bin auf der 
Zielgeraden. Ich habe jetzt nur noch ein Problem mittels Interrupts und 
komme nicht weiter und hoffe auf gute Hilfe.
Ich habe eine kleine Box an der am Untergrund in allen Ecken 4 
Ultraschallsensoren verbaut sind. Mit einen Arduino Uno rechne ich die 
Entfernung zum Boden aus und wenn diese unter 20cm beträgt wird über den 
Arduino Uno ein logisches HIGH Signal an die Interrupt Eingänge (Pin 
18,19,20 und 21) eines Arduino Mega geliefert. Wenn jetzt Pin 18 ein 
High Signal bekommt, weil die Box über eine Kante fährt, soll das 
Programm stoppen und ein gesonderten Befehl durchführen (wie z.B. alle 
Motoren halt und Musik über ein Soundmodul abspielen). Das ganze halt 
für alle vier Ecken gesondert. Außerdem soll bei Hochheben der BOX 
(somit alle vier Sensoren ein High-Signal = etwas gesondertes 
Passieren). Problem ist jetzt, das es nicht geht. Entweder werden alle 
gesonderten Programme gleichzeitig ausgeführt oder es geht gar nichts. 
Das Problem liegt definitiv an dem Code, aber ich sehe zur zeit nur noch 
komische Zahlen und Formen und hoffe auf Hilfe.

Ich habe jetzt nur mal den Code mit den Interrupts eingestellt. Der 
ganze Code würde hier den Rahmen sprengen.
1
//Interrupt einbindung
2
/* Bemerkung: Das keyword "volatile" ist eine Anweisung für den Compiler:
3
Wird eine Variable so deklariert, wird sie aus dem RAM und nicht aus Registern geladen */
4
volatile int state1 = LOW;
5
volatile int state2 = LOW;
6
volatile int state3 = LOW;
7
volatile int state4 = LOW;
8
9
void setup() 
10
{
11
  attachInterrupt(2, Sensor1, RISING);    //Interrupt PIN18,Name:Sensor1,Rising=steigende Flanke
12
  attachInterrupt(3, Sensor2, RISING);    //Interrupt PIN19,Name:Sensor1,Rising=steigende Flanke
13
  attachInterrupt(4, Sensor3, RISING);    //Interrupt PIN20,Name:Sensor1,Rising=steigende Flanke
14
  attachInterrupt(5, Sensor4, RISING);    //Interrupt PIN21,Name:Sensor1,Rising=steigende Flanke
15
}
16
17
18
19
void Sensor1()
20
{
21
   if (state1 == HIGH && state2 == LOW && state3 == LOW && state4 == LOW) 
22
   {        
23
   motor1.run(RELEASE);                   //Motor1 Stoppt
24
   motor2.run(RELEASE);                   //Motor2 Stoppt
25
   motor3.run(RELEASE);                   //Motor3 Stoppt  
26
   delay(500);
27
   mp3_play (12);                         //Sound-File "0012.mp3" wird abgespielt
28
   delay(5000);
29
   } 
30
   else 
31
   {
32
   }  
33
}
34
35
void Sensor2()
36
{
37
   if (state1 == LOW && state2 == HIGH && state3 == LOW && state4 == LOW) 
38
   {        
39
   motor1.run(RELEASE);                   //Motor1 Stoppt
40
   motor2.run(RELEASE);                   //Motor2 Stoppt
41
   motor3.run(RELEASE);                   //Motor3 Stoppt  
42
   delay(500);
43
   mp3_play (12);                         //Sound-File "0012.mp3" wird abgespielt
44
   delay(5000);
45
   } 
46
   else 
47
   {
48
   }
49
}   
50
51
void Sensor3()
52
{
53
   if (state1 == LOW && state2 == LOW && state3 == HIGH && state4 == LOW) 
54
   {        
55
   motor1.run(RELEASE);                   //Motor1 Stoppt
56
   motor2.run(RELEASE);                   //Motor2 Stoppt
57
   motor3.run(RELEASE);                   //Motor3 Stoppt  
58
   delay(500);
59
   mp3_play (12);                         //Sound-File "0012.mp3" wird abgespielt
60
   delay(5000);
61
   } 
62
   else 
63
   {
64
   }
65
}
66
67
void Sensor4()
68
{
69
   if (state1 == LOW && state2 == LOW && state3 == LOW && state4 == HIGH) 
70
   {        
71
   motor1.run(RELEASE);                   //Motor1 Stoppt
72
   motor2.run(RELEASE);                   //Motor2 Stoppt
73
   motor3.run(RELEASE);                   //Motor3 Stoppt  
74
   delay(500);
75
   mp3_play (12);                         //Sound-File "0012.mp3" wird abgespielt
76
   delay(5000);
77
   } 
78
   else 
79
   {
80
   }
81
}

: Bearbeitet durch User
von Simpel (Gast)


Lesenswert?

Hmm... schon wieder eine Interrupt-Delay-Statemachine...

Haben die Smartphone-Hipster jetzt die Arduinos entdeckt? Hauptsache 
Delays und mp3 funktionieren sofort, und jeder Eingang löst irgendwie 
nen Interrupt aus...

Gibt's irgendwo ne neue Bastelseite mit dem Titel: "Mit Delays und 
Interrupts zur KI in 3 Schritten" ? :)

von ArLev (Gast)


Lesenswert?

Wenn ich ein blöden Kommentar möchte, dann hätte ich die Frage bei 
Bild.de gestellt.

von Kai M. (kai_mauer)


Lesenswert?

Simpel schrieb:
> Gibt's irgendwo ne neue Bastelseite mit dem Titel: "Mit Delays und
> Interrupts zur KI in 3 Schritten" ? :)

Ist das hier Deine Homepage:

http://www.vollidioten_die_nicht_helfen_koennen_aber_die_Schnauze_aufreißen

von Simpel (Gast)


Lesenswert?

@Kaimauer
Ich bin sicher, du präsentierst jetzt gleich deine Lösung...

von Peter D. (peda)


Lesenswert?

ArLev schrieb:
> Problem ist jetzt, das es nicht geht.

Darf ja auch nicht.
Alle state1..4 hast Du auf LOW gesetzt, d.h. kein if wird jemals wahr.
Oder fehlt da etwa noch Code?

Langen Code (>20 Zeilen) als Anhang und als *.c.

von Blinky (Gast)


Lesenswert?

Besser wäre es, die 4 Signale gleichzeitig einzulesen (entweder über 
einen gemeinsamen Interrupt oder über einen Timerinterrupt) und dann die 
entsprechende Aktion durchzuführen. Je nach Art der Sensoren muss das 
Signal noch entsprechend entprellt werden bzw. den anderen Sensoren auch 
die Möglichkeit gegeben werden ebenfalls aktiv zu werden (z.B. wenn die 
Box schräg hochgehoben wird).

von Kai M. (kai_mauer)


Lesenswert?

Simpel schrieb:
> @Kaimauer
> Ich bin sicher, du präsentierst jetzt gleich deine Lösung...

Nein. Ich bin ein höflicher Mensch, wie Du bereits an meiner Antwort auf 
Deinen Beitrag gesehen hast. Als höflicher Mensch maße ich mir im 
Gegensatz zu Dir nicht an, einen Haufen Scheiße zu hinterlassen, wenn 
ich nicht helfen will oder kann.

von ArLev (Gast)


Lesenswert?

Der Hauptcode ist für die Interrupts komplett unwichtig und würde nur 
stören.
@simple  and @kaimauer
Tragt bitte die unnötige Diskussion wo anders aus

@Peter Dannegger
>Alle state1..4 hast Du auf LOW gesetzt, d.h. kein if wird jemals wahr.
Ein kurzes anlaufen der Soundfile war schon möglich.
Nur hörte es sich an, als ob dann immer wieder alle 4 states ausgeführt 
wurden, da der Sound stotterte. Am beginn des Soundfiles.
Deswegen dachte ich die vier Interrupts mit UND-Gattern zu verriegeln.
Führt aber wohl nicht weiter

von Peter D. (peda)


Lesenswert?

ArLev schrieb:
> Der Hauptcode ist für die Interrupts komplett unwichtig und würde nur
> stören.

Nö, denn dann ginge es ja.

Außer, daß die Interrupts aus dem Main eine lahme Schnecke machen, kann 
keiner darin Fehler entdecken.
Ob es im Zusammenwirken mit dem Main zu Fehlern kommt, kann man ohne das 
Main nicht feststellen.
Aber wie Du meinst.

Ich würde sowas nie mit Interrupts machen, sondern als Statemaschine im 
Main.

von ArLev (Gast)


Lesenswert?

Über die Interrupts möchte ich das Hauptprogramm sofort stoppen und das 
Unterprogramm über den Interrupt durchgeführt werden. Bis wieder alle 
Sensoren eine logische Null senden und somit kein Interrupt durchgeführt 
wird.

von Peter D. (peda)


Lesenswert?

Entwickle und teste Dein Programm Stück für Stück.
Z.B. schalte mit dem Sensor ne LED ein und aus, ohne unnötigen 
Codeballast.

http://dept-info.labri.fr/~strandh/Teaching/PFS/Common/Strandh-Tutorial/bottom-up-programming.html

https://www.graphics.rwth-aachen.de/media/resource_files/DSAL_2.2-Entwurfsparadigmen.pdf

von Falk B. (falk)


Lesenswert?

@ArLev (Gast)

>Über die Interrupts möchte ich das Hauptprogramm sofort stoppen und das
>Unterprogramm über den Interrupt durchgeführt werden.

Auch das kann man problemlos über eine klassische Statemachine im 
Hauptprogramm machen. Denn "SOFORT" heißt im allgemeinen nicht in 100ns, 
sondern eher "so schnell, dass man es von aussen nicht verzögert 
empfindet".
Dazu reicht es, die Statemachine über ein Timer-Flag alle 1-10ms 
aufzurufen, siehe Multitasking. Sauber und einfach.

> Bis wieder alle
>Sensoren eine logische Null senden und somit kein Interrupt durchgeführt
>wird.

von Stefan F. (Gast)


Lesenswert?

Diese Mischung aus unterbrechbarem Zustandsautomaten mit Delays ist 
einfach nur krank. Dafür würde ich als Lehrer eine 5 vergeben, wenn es 
funktioniert. In deinem Fall eine 6. Denn schon der Ansatz ist 
grundsätzlich nicht empfehlenswert.

Interrupts brauchst du nur, um die Systemzeit zu messen. Zum Beispiel 
einen (long) Integer, der jede Millisekunde incrementiert wird.

Delays ersetzt du durch Zeit-Ereignisse, etwa so:

long lichtAusBei=jetzt+3000;  // Licht aus in 3 Sekunden

if (jetzt>=lichtAusBei) {
  mach das Licht aus
}

Die Ultraschallsensoren fragt du on-demand im Zustandautomaten ab. Wenn 
die Sensoren das nicht können, dann reduzierst du die Interrupt Routine 
so, dass sie lediglich den Messwert der Sensoren in jeweils eine 
Variable überträgt. Die Variable liest dann der Zustandsautomat aus.

Was aber gar nicht geht, ist, den Zustandsautomaten per Interrupt zu 
unterbrechen. Das ist Oberkäse, noch schlimmer als die delays.

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.