Hallo liebe Leute!
Ich habe vor langer Zeit schon mal einen ähnlichen Beitrag hier ins
Forum geschrieben.
Nun möchte ich kurz erklären, was ich machen soll: Und zwar geht es um
ein Geschwindigkeits/Beschleunigungsmesser-Modell. Man stellt es sich am
besten als eine Schiene mit Gefälle vor, an deren Seite 4 Reed-Kontakte
(oder Lichtschranken, jedoch teuerer) angeordnet sind. Auf dieser
Schiene rollt nach dem Loslassen (ggf. durch "loslassen" des Wagens mit
einem Elektro-Magneten) der Wagen über diese Schiene und durchfährt die
Lichtschranken bzw. Reed-Kontakte. Nun soll aus der jeweiligen
Schließzeit der Kontakte die Beschleunigung/Geschwindigkeit des Wagens
erfasst und ermittelt werden. Außerdem sollen die Werte über RS232 an
einen PC übermittelt werden.
1) Welcher Controller würde sich am besten dafür eignen? ATmega16?
2) Wie erfasse ich die Zeiten, in denen die Kontakte geschlossen wurden,
als der Wagen darüber fuhr? Ich dachte an einen Timer, der losläuft,
sobald der Elektro-Magnet den Wagen "loslässt". Bei jedem Overflow des
Timer-Registers (255 zu 0) wird in eine Variable eine Zahl immer um eins
hochgezählt. Sobald wiederum der 1. Reed-Kontakt geschlossen wird, wird
der momentane Zählerstand + Variablenwert gespeichert. Das
Overflow-Register wird zurückgesetzt, der Timer läuft von 0 ..bis der
zweite Reed-Kontakt geschlossen wird usw. Abschließend wird der in einem
Register gespeicherte Momentanwert eines Timers plus Wert der
Zähl-Variablen mit der Schaltzeit eines einzigen Taktes multipliziert
und somit die Zeit ermittelt.
Würde meine Theorie funktionieren?
3) Das wohl schwierigste daran: Wie übertrage ich die ermittelten
Messdaten via RS232 an einen PC? Benötige ich dafür ein von mir
geschriebenes Programm dass die Daten an den Bildschirm ausgibt, oder
kann man die Daten auch "einfach" über ein Terminal-Programm ausgeben?
Vielen Dank für euere Hilfe!
1. Ja
2. Nimm lieber Lichtschranken - die prellen nicht
>Ich dachte an einen Timer, der losläuft, sobald der Elektro-Magnet den >Wagen
"loslässt".
Schon mal gar nicht so schlecht.
>Sobald wiederum der 1. Reed-Kontakt geschlossen wird, wird>der momentane Zählerstand + Variablenwert gespeichert.>Würde meine Theorie funktionieren?
ja.
>Das Overflow-Register wird zurückgesetzt, der Timer läuft von 0 ..bis der>zweite Reed-Kontakt geschlossen wird usw.
Das würde ich nicht so machen, sondern den Timer die ganze Zeit
durchlaufen lassen und nur den momentanen Wert bei Auslösen eines
Kontaktest sichern.
Mikrocontroller können rechnen...
>Benötige ich dafür ein von mir>geschriebenes Programm dass die Daten an den Bildschirm ausgibt, oder>kann man die Daten auch "einfach" über ein Terminal-Programm ausgeben?
Für den Anfang sollte ein Terminalprogramm reichen.
Wenn man es dann noch hübsch ("klickibunti") haben will, kann man auch
noch eins selber schreiben.
ok. vielen Dank :)
Habe bisher eigentlich nur "Blinkschaltungen" mit meinem µC gemacht.
Aber ich denke, ich werde es schon schaffen. Wird wohl nicht der letzte
Beitrag hier im Forum sein :)
Helfe nämlich einem Kumpel bei der Facharbeit.
Vielen Dank für die schnelle Antwort!
ähm....hast du vllt. einen Link zu einer Hilfe, wie man Daten an den PC
mit RS232 schicken kann??
Wäre sehr nett. Außer du kannst es mir kurz erklären.Außerdem: über
welche PINS würde das überhaupt gehen?
>> Das Overflow-Register wird zurückgesetzt, der Timer läuft von 0 ..bis>> der zweite Reed-Kontakt geschlossen wird usw.> Das würde ich nicht so machen, sondern den Timer die ganze Zeit> durchlaufen lassen und nur den momentanen Wert bei Auslösen eines> Kontaktest sichern.
Das Stichwort dazu lautet: Input Capture
Details dazu finden sich im Datenblatt des Controllers.
Leider gibt es dazu noch keinen Tutoriumsbeitrag.
Wenn du aber den Rest hinkriesgt, ist Input Capture
kein Problem mehr.
Input Capture mit mehreren Eingängen?
Letzten Monat hatten "wir" doch das Problem mit der
Pendellichtschranke...
Je nach gewünschter Auflösung kann man die Eingänge in einem
Timer-Interrupt pollen...
Sollte die einfachste Variante sein.
Rahul, der Trollige wrote:
> Input Capture mit mehreren Eingängen?
Wenn sichergestellt ist, dass ein Eingang wieder
in den Grundzustand zurükgeht, bevor der nächste Kontakt
schliesst ... warum nicht?
> Je nach gewünschter Auflösung kann man die Eingänge in einem> Timer-Interrupt pollen...> Sollte die einfachste Variante sein.
Yep.
> Die Erdbeschleunigung ist hinreichend bekannt.
Dann sag mir doch bitte, wie groß diese am Äquator ist.
Es gibt Leute, die in der Schule immer noch Dividieren lernen, obwohl es
Taschenrechner gibt. Denk mal drüber nach.
so. danke erstmal für die zahlreichen Antworten. Habe jetzt gerade mal
ein kleines Programm geschrieben, welches in die Variable "lschranke"
(steht für Momentanwert des Timers, wenn die Lichtschranke durchfahren
wird) geschrieben wird.
Könnte das so passen?
----------------------------------------------------------------------
#include <avr/io.h>
int main (void)
{
int i=0,lschranke=0; //Var.-Definition
DDRB = 0xFF; //PORTB auf Ausgang
(keineWirkung)
DDRD = 0x00; //PORTD als Eingang
PORTD = 0xFF; //PullUp-Widerstände ein
TCCR0 = 0x05; //64stel-Prescaler
for(;;)
{
if (TIFR & (1<<TOV0)) //wenn TimerOverflow 1 ist,....
{
TIFR |= (1<<TOV0); //setze ihn zurück
}
if (PIND == 0x01) //wenn der Schalter1 gedr. wird
{
lschranke=TCNT0; //schreibe Momentanen Wert in lschranke
}
}
}
----------------------------------------------------------------------
Vielen Dank!
Rechne dir doch mal aus, wie lange es dauert bis
der Timer 0 bei einem Prescaler von 64 und deiner
(für uns) unbekannten Taktfrequenz einmal rundum ist.
Dann weist du ob deine Messwerte vernünfitg sein können.
Im übrigen denke ich nicht, dass du den Timerwert
jedesmal wegsichern möchtest, wenn der Schalter
gedrückt ist. So schnell kannst du den Schalter
gar nicht wieder loslassen, dass der nicht schon
ein paar 10000 mal den Timerwert gesichert hat.
Ansonsten: Probiers einfach mal aus. Lass dir
den Messwert ausgeben und sieh selber nach ob
die Messwerte realistisch sind. Das Ausprobieren
ist doch mindestens der halbe Spass an der Sache.
nun ja, aber dann müsste ich ja eine Funktion verwenden, die bei
ansteigender Flanke den Wert speichert, damit ich dieses
"zulang-drücken" vermeiden kann.
Welche funktion vom µC müsste ich da nehmen??
Mein Timer im Simulator zählt irgendwie nicht Einer-Schrittweise,
sondern immer um 7 oder so. Woran kann das liegen? Ist auch so, wenn ich
KEINEN Prescaler verwende.
danke!
johannes wrote:
> nun ja, aber dann müsste ich ja eine Funktion verwenden, die bei> ansteigender Flanke den Wert speichert, damit ich dieses> "zulang-drücken" vermeiden kann.>> Welche funktion vom µC müsste ich da nehmen??
Man muss nicht für alles eine Spezialfunktion haben.
Preisfrage: Im folgenden Code, unter welchen
Unständen wird der "Abspeicher-Code" ausgeführt
uint8_t Previous = 0;
uint8_t Now = 0;
while( 1 ) {
Now = PIND & 0x01;
if( Now != Previous ) {
if( Now == 1 ) {
lschranke = TCNT0;
}
}
Previous = Now;
}
>> Mein Timer im Simulator zählt irgendwie nicht Einer-Schrittweise,> sondern immer um 7 oder so. Woran kann das liegen? Ist auch so, wenn ich> KEINEN Prescaler verwende.
Das liegt daran, dass dein Timer an den Systemtakt gekoppelt
ist. Die meisten C-Anweisungen dauern aber länger als einen
Systemtakt. Der Debugger führt aber eine C-Anweisung komplett
aus, egal wieviele Takte das benötigt.
ausgeführt wird er, wenn PIND UND-verknüpft mit 0x01 ungleich "Previous"
(0) ist. "Now" lässt nur einen "Preller" zu
steht das uint8_t für 8-bit-unsigned char?
Dankeschön!