Forum: Mikrocontroller und Digitale Elektronik Beschleunigungs-Messbahn


von Johannes (Gast)


Lesenswert?

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!


von Rahul, der Trollige (Gast)


Lesenswert?

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.

von Johannes (Gast)


Lesenswert?

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!

von Johannes (Gast)


Lesenswert?

ä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?

von Rahul, der Trollige (Gast)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

>> 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.

von Rahul, der Trollige (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Unbekannter (Gast)


Lesenswert?

Wozu der Aufwand?
Die Erdbeschleunigung ist hinreichend bekannt.

von Johannes (Gast)


Lesenswert?

vielen Dank erstmal.

Im Tutorial finde ich jedoch nicht eindeutig erklärt wie ich Daten über 
RS232 schicken kann...;)

danke

von Rahul, der Trollige (Gast)


Lesenswert?

>Im Tutorial finde ich jedoch nicht eindeutig erklärt wie ich Daten über
>RS232 schicken kann...;)

Wo mangelt es denn deiner Meinung nach?

von Fritz (Gast)


Lesenswert?

> 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.

von johannes (Gast)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

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.

von johannes (Gast)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

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.

von Johannes (Gast)


Lesenswert?

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!

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.