PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino Interrupt Programmierung



Jeko
31.01.2017, 12:15
Hallo zusammen,

ich brauche da mal bitte eure Hilfe.

Ich schreibe demnächst eine Prüfung und muss einen Interrupt Code erstellen.
Die Aufgabenstellung lautet.

Erstellen Sie einen Interrupt Code:
-Golfbälle rollen eine Rampe herunter
-Sie durchlaufen eine Lichtschranke
-Die Zeit wird gemessen
-An der Lichtschranke liegen 5V an, wenn sie unterbrochen wird.

int sensorPin*A0;
int sensorValue=0;
int ledPin=13;

void setup(){
pinMode(13,OUTPUT);
Serial.begin(9600);
}

void loop (){
sensorValue=analogRead(0);
Serial.println(sensorValue);
if (sensorValue >??) { //also hier meine ich wenn der Ball an diesem Sensor vorbeirollt
digitalWrite(13,HIGH); //Geht die LED an
}
else{ //ansonsten aus
digitalWrite(13,LOW);
}
}

Aber wie messe ich denn die Zeit wie in der Aufgabestellung gefragt.
Habe auch nicht so eine Ahnung von der Programmierung von Arduino.

Vielen Dank.

i_make_it
31.01.2017, 16:37
Um ein Zeit zu messen, muß man ja einmal bei "0" anfangen und dann bei irgendeinem Wert enden.
Dann hat man die Zeit von 0 bis "irgendein wert".

Entweder will man wissen wie lange ein Vorgang dauert (z.B. das runterollen der Rampe).
Oder man will wissen wie schnell ein Opbejtk ist (wie lange es braucht um eine bekannte Entfernung zurückzulegen).

Dafür bräufte man dann zwei Lichtschranken.
eine die per interrupt einen Timer startet.
Und eine zweite die per Interrupt den erreichten Timerwert ausließt.

Also musst Du dich mit Timern auseinander setzen und die Endzeit von der Startzeit abziehen um eine zeit zu erhalten.

Man kann einen freilaufenden Timer nutzen "millis()/micros()" oder einen Timer gezielt konfigurieren.
Bsp.:
http://playground.arduino.cc/Code/Timer1

Erarbeite Deinen Programmablauf doch erst mal als Text damit wir sehen können über was Du dir schon Gedanken gemacht hast und ob da Fehler drin sind.
Konkrete Arduino Befehle kann man daraus dann ja noch machen.

Peter(TOO)
01.02.2017, 05:15
Dafür bräufte man dann zwei Lichtschranken.
eine die per interrupt einen Timer startet.
Und eine zweite die per Interrupt den erreichten Timerwert ausließt.
Wenn man weiss wie Dick der Liststrahl ist, welchen Durchmesser der Ball hat und auf welcher höhe der Lichtstrahl angebracht ist, reicht auch eine einzelne Lichtschranke.
Man misst, wie lange die Schranke unterbrochen wird.

MfG Peter(TOO)

i_make_it
01.02.2017, 07:16
Wenn man weiss wie Dick der Liststrahl ist, welchen Durchmesser der Ball hat und auf welcher höhe der Lichtstrahl angebracht ist, reicht auch eine einzelne Lichtschranke.
Man misst, wie lange die Schranke unterbrochen wird.

MfG Peter(TOO)


Ja, funktioniert.
Aber man hat sich eine Variable eingehandelt, deren Toleranzen stark das Messergebniss beeinflussen.
Die Höhe des Lichtstrahls ist etwas das man mit Spigelleisten ausschalten kann in dem man sich einen Lichtvorhang baut.
Die Divergenz bzw. den Durchmesser des Strahls kann man mit Masken vor dem Empfänger korrigieren.
Toleranzen beim Durchmesser des Balls/der Kugel kann man nicht beeinflussen und somit kann man keine sichere Aussage machen welche Verlässlichkeit das Messergbniss hat.

Wenn der Lichtstrahl eine Breite von 1mm hat und der Ball von 20mm ist die Meßstrecke 21mm. bei einem Balldurchmesser von 20,1mm ändert sich die Meßstrecke auf 21,1mm.das sind 0,48% Meßfehler durch ein Toleranz des Meßobjektes die innerhalb üblicher Freimaßtoleranzen liegt.
Bei zwei Lichtschranken mit einem Abstand von 20mm zueinander gibt es diesen Meßfehler, prinzipbedingt nicht.
Zusätzlich könnte man durch integrieren der Flankenauswertung auch neben der Geschwindigkeit noch den Durchmesser ermitteln.

Man muß halt sehen was man misst, und wie die groß Toleranzen sind (aufgepumpter, elastisch verformbarer Ball oder starrer Körper) und dann entscheiden ob man ein Prinzipbedingt unsicheres Verfahren einsetzen kann oder nicht.
Sind die Durchmesserabweichungen aller Prüflinge klein genug und die geforderte Meßgenauigkeit klein genug, kann man das machen. Man ist sich aber halt nie sicher ob man grade eine andere Geschwindigkeit oder einen anderen Durchmesser gemessen hat wenn man grade einen Außreißer hat.
Aber die Schwächen beider Meßprinzipien könnte man schön vergleichen wenn man beides in einen Aufbau packt und die Steigung der Rampe bei unterschiedlichen Balldurchmessern so verändert, daß bei der Messung mit einer Lichtschranke jedes mal das selbe Ergebniss rauskommt und man dann die tatsächliche Ballgeschwindigkeit und den Durchmesser des Balls zum Vergleich ausgibt.

Ich persöhnlich bin kein Fan von Meßprinzipien bei denen zwei Größen das Ergebniss beeinflussen und man nur anhand von Annahmen das Ergebniss interpretieren muß.
Die Verlässlichkeit ist halt nur gegeben, wenn die zugrundeliegenden Annahmen zutreffen. Abweichungen können das selbe Ergebeniss liefern ohne das die tatsächlichen Werte überhaupt passen.
z.B. Egebniss für kleine Styrporkugel und große Stahlkugel identisch, da die geringere Masse die kleinere Kugel langsamer rollen lässt wie die große Masse der größeren Kugel, da der größere Durchmesser trotz größere Geschwindigkeit die Lichtschranke genau so lange unterbricht wie bei der kleineren lnagsameren Kugel.

Peter(TOO)
01.02.2017, 10:06
Die ganzen Probleme kenne ich.

Aber es ist ein Prüfungsaufgabe und da steht nur etwas von einer Lichtschranke.

MfG Peter(TOO)

HaWe
01.02.2017, 11:53
richtig, wie die Aufgabe praktisch / technisch zu lösen ist, ist nicht gefragt.

Einen Startzeitpunkt braucht man ntl, vielleicht gibt es einen Start-Button, der die Kugeln auf der Rampe startet? Muss man abklären!
wenn, dann wäre das der Startzeitpunkt. Man wartet solange, bis der button gedrückt wurde: gedrückt = high = true (pulldown gegen Masse, wenn gedrückt dann auf Vc hochgeschaltet), dann liest man die Systemzeit mit millis() aus.


#define startbtn 3 // wenn der Startbutton auf pin 3 liegt.
uint32_t t0;

while ( !( digitalRead(startbtn) ) );
t0 = millis();

in diesem Moment ist die Lichtscharnke lt. Aufgabenstellung noch auf LOW (niedriger Wert), wenn der Ball durchläuft, geht sie auf HIGH (5V, hoher Wert).
Sagen wir, die LS liegt auf pin A0:


#define LSpin A0

int ls;
ls = analogRead( LSpin );

Das ergibt im Moment des Kugel-Durchlaufs also einen Pinchange, und dafür gibt es bei Arduino einen Pinchange-Interrupt (LOW => HIGH)

Vermutlich (!) geht sie nach dem Durchlauf automatisch wieder auf LOW, aber auch das musst du rauskriegen.


Ich darf dir hier sicher nicht die Lösung für den Interrupt verraten, denn es ist ja eine Prüfungsaufgabe, aber dazu gibt es diesen Link:
http://playground.arduino.cc/Main/PinChangeInterrupt

Sobald dieser ausgelöst wird, wird wieder mit millis() die Zeit gemessen, diesmal t1.
Nun hast du 2 Systemzeiten, die Differenz ist die Laufzeit:



uint32_t t1, dt;

t1 = millis();
dt = t1 - t0;



da hier in der Aufgabenstellung aber nichts über einen Startbutton gesagt wurde, kann es auch sein, dass der Laufzeitunterschied zwischen 2 und mehreren darauf folgenden Bällen gemessen werden soll, dann geht es etwas anders:

t0 : Zeit millis() 1.Pinchange -Interrupt (LOW ->HIGH)
t1 : Zeit millis() beim darauffolgenden Pinchange interrupt (LOW ->HIGH)

dt = t1-t0;

jetzt die letzte Zeit als t0 speichern und dann wieder t1 beim 2. Ball lesen:
t0 = t1;
t1 : Zeit millis() beim darauffolgenden Pinchange interrupt (LOW ->HIGH)

usw.

wie gesagt, die Start-Bedungung für die Stoppuhr musst du rauskriegen!



klar soweit?
8)