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 */
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" ? :)
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.
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).
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.
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
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.
Ü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.
@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.
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.