Hallo Leute! Habe seit geraumer Zeit ein Projekt mit einem Modellauto das von mir über einen Touchscreen und über Funk gesteuert wird. Nun möchte ich noch die Geschwindigkeit des Fahrzeugs messen. Dazu hatte ich an einen Hall Sensor gedacht und mir schon kleine Magnete besorgt. Um fein zu messen kommen 8 Magneten an die Innenseite eines Reifens. So, nr. 1 : Könnt Ihr irgend einen Hall Sensor empfehlen oder gibt es eine Seite die mir da auch weiterhilft? Nr. 2: Auf dem Modellauto sitzt ein Atmega8 der Daten Empfängt und den Wagen steuert. Ich hatte mir den Programmablauf ungefähr so gedacht: - Daten Empfangen - Motoren steuern - Timer starten für 20 ms - Interrupt für den ICR1 freischalten -> Die Interruptroutine reagiert bei jeder Highflanke und zählt dort über eine Variable wie oft eine Highflanke innerhalb dieser 20 ms kommt. -> Nach 20 ms kommt der Interrupt vom Timer und sperrt den Interrupt von ICR1 - Die Daten werden dann ausgewertet und versendet Ist das so ok? Ich bin mir über den Ablauf nicht ganz sicher. Könnte man doch bloß Threads programmieren, das würde mir viel erleichtern!
Franki C. schrieb: > Ist das so ok? Du denkst zu seriell > Ich bin mir über den Ablauf nicht ganz sicher. > Könnte man doch bloß Threads programmieren, das würde mir viel > erleichtern! Du kannst Threads programmieren auch wenn sie nicht Threads heissen. Deine 'Threadsteuerung' heißt: Timer! zb die Drehzahl messen. Du kannst zb den Input Capture Eingang des Timers1 benutzen. Bei jeder Flanke an diesem Eingang speichert der Timer seinen aktuellen Zählerstand weg und du kannst auch einen Interrupt aufrufen lassen. Durch Vergleich mit dem Zählerstand vom letzten Capture Event (einfach voneinander abziehen) hast du ein Mass für die Zeit zwischen den beiden Pulsen und damit auch für die Frequenz und damit über die Drehzahl des Rades und damit über die Geschwindigkeit. D.h. Drehzahlmessung eines Rades geschieht nebenher. Das macht ein Timer mit einer zusätzlichen Interrupt Service Routine eigenständig. Timer sind deine Threadsteuerung! Nutze sie. Du musst weg vom seriellen Denken, hin zu ereignisgesteuertem Programmieren. Nicht länger: Ich mach das, dann das, dann wird gewartet und dann passiert noch das. Hin zu: In der Hauptschleife werden regelmässig alle möglichen Ereignisse abgeklappert und nachgesehen ob sie eingetreten sind. Wenn ja, werden sie (mit kurzem Code!) bearbeitet. Ereignisse können alles mögliche sein, zb auch selbst generierte, die einfach nur eine Variable auf 1 setzen und in der Hauptschleife wird abgefragt, ob diese Variable auf 1 steht und wenn ja die entsprechende Aktion ausgeführt. Ein 'Thread' der zb eine LED regelmässig blinken lässt führt wieder über einen Timer. (Wann immer es etwas mit Zeitsteuerung zu tun gibt, musst du sofort Timer denken, und nicht delay) Der Timer wird so aufgesetzt, dass er ein regelmässiges Signal in Form eines Interrupt aufrufs generiert. ZB alle 1 Millisekunde wird die ISR aufgerufen. Dann zählst du in der ISR eine Variable hoch und wenn diese 1000 erreicht hat (oder von 1000 auf 0 runtergezählt hat), dann setzt du eine Variable (das Jobflag) auf 1. In der Hauptschleife wird natürlich unter anderem geprüft, ob das Flag auf 1 steht und wenn ja wird die LED umgeschaltet und das Flag wieder zurückgesetzt. Gewartet wird nicht mehr. Auf nichts und niemand. Ausser vielleicht wenn es sich um eine Wartezeit im µs Bereich handelt. Aber ansonsten wird nicht gewartet. Stattdessen wird in der Hauptschleife weitergemacht und reihum alle anderen möglichen Ereignisse geprüft. Solange bis dann das Ereignis 'Zeit abgelaufen' eingetreten ist. Auch Zustandsmaschinen kann man hier nutzbringend einsetzen. Sie passen wunderbar in das Konzept der ereignisgesteuerten Programmierung. Ein Zustandswechsel ist nichts anderes als eine Reaktion auf ein Ereignis. Was auch immer das Ereignis sein möge. Und ja: In den meisten Programmen stellt man einen Timer explizit dafür ab einen Basiszeittakt in Form eines ISR Aufrufs zu generieren. Das können 1 Millisekunden Intervalle sein oder auch mehr, je nachdem welche kleinste Zeiteinheit sinnvoll ist. Davon kann man dann immer längere Zeiteinheiten ableiten. Denn 100 mal 1 Millisekunde abgezählt, ergibt auch einen Zeitraum von 100 Millisekunden. In diesem Zusammenhang sind auch oft rückwärts zählende Variablen brauchbar einzusetzen, die als eine Art Stoppuhr fungieren. Die Variable wird in der ISR regelmässig runtergezählt. Ist sie ungleich 0, dann läuft die Zeit noch. Ist die Variable zu 0 geworden, so ist die zuvor eingestellte (durch Zuweisung) Zeit abgelaufen --- wieder ein Ereignis, auf das man reagieren kann. Und natürlich kannst du im Grunde auch das Abzählen der Impulse vom Hallsensor in so ein Schema, so wie du dir das ursprünglich gedacht hast einbauen ... wenn dir die Timer ausgehen. Einfacher ist es mit nur einem Timer, möglich ist es auch so wie du das angedacht hast. Aber was du auch immer tust: Sieh zu, dass du mindestens 1 Timer für eine allgemeine Zeitbasis freihältst.
Hallo und vielen Dank für die Hilfe! Ich finde es echt super das man sich hier so viel Mühe gibt den Leuten zu helfen. Ich werde das mit dem Timer mal ausprobieren, muss mal schauen wie ich das anstelle, habe nämlich den 16bit Timer für den Servo bei 20 ms laufen und den 8 bit Timer für den DC Motor. Nun muss ich mal gucken wie ich die 20ms vom 16 bit Timer ausnutze..
Franki C. schrieb: > Ich werde das mit dem Timer mal ausprobieren, muss mal schauen wie ich > das anstelle, habe nämlich den 16bit Timer für den Servo bei 20 ms > laufen Brauchst du nicht. Also: den Timer brauchst du schon. Aber du brauchst ihn nicht auf 20ms einstellen. Mit einem durchlaufenden Timer kann man wunderbar locker 10 oder mehr Servos ansteuern, ohne dass man den Timer in seiner Bewegungsfreiheit in irgendeiner Form einschränken muss. > und den 8 bit Timer für den DC Motor. PWM? > Nun muss ich mal gucken wie > ich die 20ms vom 16 bit Timer ausnutze..
Ich habe das Programm zum testen wie im Anhang geschrieben.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.