Ich habe folgende Schaltung nachgebaut und für meinen Roller vorgesehen. Leider macht sie nicht so ganz, was sie soll. Der Mega zählt zwar Signale, wenn ich mit nem Magneten vorbeigehe und auch, wenn das Rad sich dreht aber das Ganze ist nicht wirklich zuverlässig. Ich wollte zwecks Genauigkeit auch mehrere Magnete an der Felge befestigen. Kann es sein, dass die Frequenz zu hoch für die Relais wird? Oder fürs NE? Wo ist der Schwachpunkt der Schaltung und kennt jemand eine bessere Lösung? Die Magneten sind stark genug.... Grüße!
die Schaltung ist prinzipiell in Ordnung, und mit ca. 2,5ms Aktivzeit auch richtig dimensioniert. Ich schätze mal, dass dir die Zündung reinhaut, entweder direkt auf den Eingang oder über den Umweg Versorgung/Masse. Funktioniert es denn, wenn der Motor nicht läuft?
Hallo, ich gehe davon aus, dass der Magnet am Rad montiert ist und der Controller dann die Pulse zählen soll, oder? Wenn dem so ist würde ich in keinem Fall ein Reedkontakt benutzen, da dieser i.d.R. wie ein Schalter prellt und auch die Reaktionzeiten (sprich max. Frequenz) beschränkt sind. Vorzugweise würde ich das mit einem Hallsensor (z.B TLE4905 o.ä.) realisieren. Dieser kann bis zu 20kHz Abtastrate und ist wesentlich zuverlässiger und prellt nicht. Wahrscheinlich kann man sich dann auch den NE555 sparen und direkt an den MC anschließen. Desweiteren muss die Spannungsversorgung solch einer Schaltung gut gefiltert werden (Elkos, Spulen etc.) um den o.g. Einfluß von Zündung etc. zu verringern. Wenn es um eine genaue Auswertung ankommt, würde ich mindestens 16 Magnete am Rad montieren. J.
Hi! Ich werden den Hall testen. Danke. Die Genauigkeit bei 3 Magneten ist nicht der Burner aber immerhin besser als bei 1 Magnet. Und das fahren auch viele. Ich finde es übrigens ziemlich mutig, dass Fahrradtachos mit einem Magneten die Geschwindigkeit mit Nachkommaanteil anzeigen. Ich mein, gehts noch? Hab mir das mal nachgerechnet und bin so auf 3 Magnete als akzeptables Minimum gekommen. Hängt natürlich auch davon ab, wie lang man misst. Aber bei langsamen Geschwindigkeiten bleibt natürlich eine nicht zu verachtene Ungenauigkeit. Um die solls aber hier gar nicht gehen. Die Spannungsversorgung sieht so aus, dass einem Brückengleichrichter ein dicker ElKo etc. nachgeschaltet ist. Dann kommt irgendwann ein Low Drop um aus 12V bzw. 6V 5 zu machen und noch ein dicker ElKo. Das Ganze macht einen ganz guten Eindruck. Ich probiers trotzdem bei Gelegenheit mit ner Batterie. Der TLE4905 prellt quasi gar nicht?! Das kann ich mir ja kaum vorstellen aber probieren tu ichs trotzdem mal. Das wär ja was ;) Grüße!
@ Gast (Gast) >in keinem Fall ein >Reedkontakt benutzen, machen aber fast alle Fahrradcomputer so. > da dieser i.d.R. wie ein Schalter prellt Dafür gibt es Entprellung > und auch >die >Reaktionzeiten (sprich max. Frequenz) beschränkt sind. Willst du Schallgeschwindigkeit erreichen? 26'er Reifen hat ca. 2,07m Umfang. Macht bei 100km/h ~ 13,4U/s Gähn. Reedkontakte schalten unter 1ms. >Vorzugweise würde ich das mit einem Hallsensor (z.B TLE4905 o.ä.) >realisieren. High Tec die kein Mensch braucht. Ausserdem brauch der ne Stromversorgung. >Wahrscheinlich kann man sich dann auch den NE555 sparen und direkt an >den MC anschließen. Sicher. >Wenn es um eine genaue Auswertung ankommt, würde ich mindestens 16 >Magnete am Rad montieren. ??? Akademiker? MFG Falk
@ He Gr (dare) >Ich werden den Hall testen. Danke. Die Genauigkeit bei 3 Magneten ist >nicht der Burner aber immerhin besser als bei 1 Magnet. Und das fahren Wieso? >auch viele. Ich finde es übrigens ziemlich mutig, dass Fahrradtachos mit >einem Magneten die Geschwindigkeit mit Nachkommaanteil anzeigen. Ich >mein, gehts noch? Hab mir das mal nachgerechnet und bin so auf 3 Magnete >als akzeptables Minimum gekommen. Rechnung? Kann es ein, dass du Auflösung und Genauigkeit verwechselst? > Hängt natürlich auch davon ab, wie >lang man misst. Aber bei langsamen Geschwindigkeiten bleibt natürlich >eine nicht zu verachtene Ungenauigkeit. Keineswegs. Nur die Messzeit wird länger. Siehe Grundlagen der Messtechnik. MFG Falk
Hi Falk! Danke für die Einwände bezüglich der Hall-Sensoren. Ich versuche mich dann weiter mit den Reeds. Rechnung? Genauigkeit? Ich messe nicht per Interrupt sondern in einem fixen Zeitraum. Timer starten, Dinge tun, Timer auslesen, hochrechnen. Vielleicht änder ich das für den Tacho noch. Bei der Drehzahl geht das in Ordnung. Wenn ich nun eine Geschwindigkeit von 10 km/h bei einem Radumfang von 1300 mm annehme, dann kommt bei mir in einem Messzeitraum von 1/2 Sekunde... so war der Ansatz. Irgendwann bin ich dann auf einen Kompromiss gestoßen... Vielleicht sollte ich das doch per Interrupt machen. Ist ja bei so niedrigen Frequenzen eigentlich angesagt? Der Ansatz die Signale pro Zeit zu zählen ist ja deutlich ungenauer. Interrupt on Pinchange, Timer starten. Nächster Interrupt Timer stoppen, Zeit zwischen den Signalen führt dann zu (Radumfang in cm/3)*(1/Zeit in s)=cm/s wenn ich nicht schief gewickelt bin. Das kann ich dann ja in ne Variable schreiben und auslesen, wenn ichs brauche. Vielleicht auch einfach die halbe Sekunde nutzen um nen gewichteten Wert aus drei Messwerten zu bilden oder so. Der Ansatz gefällt besser oder zu penibel?
@ He Gr (dare) >Ich messe nicht per Interrupt sondern in einem fixen Zeitraum. Ungünstig, weil . . . >in Ordnung. Wenn ich nun eine Geschwindigkeit von 10 km/h bei einem >Radumfang von 1300 mm annehme, dann kommt bei mir in einem Messzeitraum >von 1/2 Sekunde... so war der Ansatz. Na reicht doch. Bei 10 km/h braucht man keinen Update alle 10ms. >Vielleicht sollte ich das doch per Interrupt machen. Ist ja bei so >niedrigen Frequenzen eigentlich angesagt? Ja, weil bei niedrigen Frequenzen misst man sinnvollerweise die Periodendauer, nicht die Frequenz. >Der Ansatz die Signale pro Zeit zu zählen ist ja deutlich ungenauer. Logisch, denk mal drüber nach. >Der Ansatz gefällt besser oder zu penibel? Du ist auf dem richtigen Weg. MFG Falk
Hmm... mir ist wieder eingefallen, warum ich das nicht von Anfang an so gemacht habe. Und zwar liegt das daran, dass ich INT0 und INT1 am Atmega32 bereits mit dem Display belegt habe und die Platine so gefertigt wurde. Naja, zwei Kabel sind so schlimm ja nicht. Da zieh ich mir eins von nem anderen Pin rüber zum Display und eins vom INT0 zur Tachoschaltung und gut. Ich bin gespannt, wie das läuft. Morgen mehr. Heute komm ich leider nicht mehr dazu...
Hmm... den habe ich in der Tat frei gehalten. Kann der auch bei Flankenwechsel interrupts auslösen oder nur sowas wie input compare match (könnte man ja auch auf 1 setzen oder so). Ich überlege ja fast schon es so zu machen, dass ich den Drehzahlmesser auf ICP lege. Bei nem Interrupt auf INT0 (da den Tacho dran) dann nen Timer starten und beim nächsten stoppen. Die Zeit hochrechnen für die Geschwindigkeit und die Zeit mit dem ICP-Wert verrechnen für die Drehzahl. So bräuchte ich nur einen Timer (derzeit laufen drei).
@ He Gr (dare) >Flankenwechsel interrupts auslösen oder nur sowas wie input compare Das ist seine Kernaufgabe! >match (könnte man ja auch auf 1 setzen oder so). Ich überlege ja fast >schon es so zu machen, dass ich den Drehzahlmesser auf ICP lege. Bei nem >Interrupt auf INT0 (da den Tacho dran) dann nen Timer starten und beim Wo ist der Unterschie dzwischen Tacho und Drehzahlmesser? >nächsten stoppen. Die Zeit hochrechnen für die Geschwindigkeit und die >Zeit mit dem ICP-Wert verrechnen für die Drehzahl. So bräuchte ich nur ??? >einen Timer (derzeit laufen drei). Kann es sein, dass du deine Timer schlecht ausnutzt? Die Gnaze sache kriegt man locker mit EINEM (16 Bit) Timer hin. MFG Falk
He Gr wrote: > Ich überlege ja fast > schon es so zu machen, dass ich den Drehzahlmesser auf ICP lege. Was gibts denn daran zu überlegen, genauer kriegst Du nie den Zeitstempel. Allerdings mußt Du dann noch ne Totzeit abwarten, damit Du die Preller unterdrückst. Die Totzeit machst Du einfach mit nem Compareinterrupt:
1 | ISR( TIMER1_CAPT_vect ) |
2 | {
|
3 | OCR1A = ICR1 + TOTZEIT; |
4 | TIMSK &= ~(1<<TICIE1); |
5 | TIFR = 1<<OCF1A; |
6 | TIMSK |= 1<<OCIE1A; |
7 | ... hier Auswertung einfügen |
8 | }
|
9 | ISR( TIMER1_COMPA_vect ) |
10 | {
|
11 | TIMSK &= ~(1<<OCIE1A); |
12 | TIFR = 1<<ICF1; |
13 | TIMSK |= 1<<TICIE1; |
14 | }
|
Achja, der 555 ist flüssiger als Wasser, also vollkommen überflüssig. Peter
Der Unterschied zwischen Drehzahl und Tacho ist eigentlich nur die Frequenz. Beim Tacho kommen bei 3 Magneten und nem Radumfang von 130 bei 100km/h etwa 20 hz zusammen. Bei der Drehzahl gehts hoch bis zu 500 hz. Drei Timer habe ich benutzt weil ich zwei schon extern getaktet habe. Also einen mit DZM, einen mit Tacho und den dritten um die Messdauer zu zählen während ich anderen Kram erledigt habe. Ich will das jetzt aber umstellen. Leider stellen sich mir noch ein paar Fragen. Ich gehe also mit der Tachoschaltung auf den INT0 und mit der Drehzahlschaltung auf ICP. Beide lösen Interrupts aus. Was tue ich da? Bei einer Messung würde ich sagen, ich lese einen Timer aus, setze ihn wieder 0 und verarbeite den Wert. Bei zwei Messungen würde ich hierfür zwei Timer verwenden. Wie löse ich das mit nur einem Timer wie oben beschrieben? Da kommt mir grad schon die Lösung. Ich lasse den Timer einfach überlaufen und setze ihn nicht wieder 0. Dann schreib ich mir einfach den letzten Zählerstand in eine Variable und verrechne das. So sollts gehen, oder? Den Code da oben müsste ich mir mal in Ruhe ansehen und etwas nachlesen. Dafür bin ich noch nicht lang genug im Mikrocontroller-business. Oder hat jemand Lust, mir den zu kommentieren? Der NE555 ist warum überflüssig? Würdet ihr einfach VCC über den Reed und nen Widerstand auf nen Controllerpin legen? Entprellung dann über Software?
@ He Gr (dare) >Ich gehe also mit der Tachoschaltung auf den INT0 und mit der >Drehzahlschaltung auf ICP. Warum ZWEI Eingänge für praktisch die selbe Aufgabe? EINE Messung reicht, daraus kann man Drehzahl UND Geschwindigkeit ausrechnen, oder? >sollts gehen, oder? Ja. >Der NE555 ist warum überflüssig? Würdet ihr einfach VCC über den Reed >und nen Widerstand auf nen Controllerpin legen? Ja. > Entprellung dann über Software? Nein, hier per Hardware und RC-Filter. Geht auch einfach, der AVR hat Schmitt-Trigger Eingänge. MFG Falk
Motordrehzahl hat doch nichts mit Geschwindigkeit zu tun...
Wie man Drehzahl und Geschwindigkeit durch eine Messung erhalten will, will mir auch nicht in den Kopf. Außer man hat die Übersetzung. Dann könnte man das schon umrechnen. Müsste man halt irgendwie den eingelegten Gang ermitteln. Auch wieder doof. Ich denke, hier hat mich jemand falsch verstanden. Die Schmitt-Trigger kann ich zuschalten wo ich sie brauche (INT0 oder ICP) oder muss ich mit dem Signal auf nen Pin und von nem anderen Pin auf den INT0 bzw. ICP? Vielen Dank btw. - hier wird einem wirklich immer gut und kompetent geholfen. Ich bin ja noch ganz am Anfang (meines Studiums und auch im Hobby-Bereich) und es macht einfach viel mehr Spaß, wenn einem auf die Sprünge geholfen wird. Bis ich das alles aus dem Effeff kann, werden wohl noch einige Semester vergehen ;)
@ He Gr (dare) >will mir auch nicht in den Kopf. Außer man hat die Übersetzung. Eben. Klappt nur nicht bei gezogener Kupplung ;-) >jemand falsch verstanden. Die Schmitt-Trigger kann ich zuschalten wo ich >sie brauche (INT0 oder ICP) Die sind überall immer aktiv. Sinnvollerweise legt man das langsamere Signal (Tacho) auf INT0 oder INT1, das schnellere auf ICP oder einen Timer. MfG Falk
Hi nochmal! Ich habe jetzt den Tacho an INT0 gehängt und einfach mal im Interrupt Signale hochgezählt. So weit klappt das gut. Ein Problem hab ich noch mit dem Timer. Wenn ich den mitlaufen lasse, dann hängt der Mega sich auf. Zeitlich in etwa dann, wenn er das erste Mal überläuft. Ich habe an einen nicht abgefangenen Interrupt gedacht und einfach eine leere Routine eingefügt. Ändert aber nichts. Was mach ich hier falsch? //start timer for systemtime ( 4Mhz/256=16384 hz) TCCR1B |= (1<< CS12); ISR(TIMER1_OVF_vect) { } Dann ist mir aufgefallen, dass der Lösungsvorschlag oben davon ausgeht, dass man für die Drehzahlmessung Signale mit dem ICP zählt bzw. Timer1 benutzt. Timer1 ist aber doch der einzige 16Bit Timer, den ich habe - und den brauche ich für die Zeit. Oder wie jetzt? Wie gehe ich das mit der Drehzahl jetzt an? Kann ich, falls das alles nichts gibt auch einfach das Verfahren des Tachos nutzen? Also jedes Mal einen Interrupt auslösen und die Periodendauer messen? Geht das ohne Timer1 auf ICP oder muss ich dafür auch noch INT1 freischaufeln? Danke & Grüße!
@ He Gr (dare) >leere Routine eingefügt. Ändert aber nichts. Was mach ich hier falsch? >//start timer for systemtime ( 4Mhz/256=16384 hz) > TCCR1B |= (1<< CS12); Das kann schief gehen, den du weist nciht was vorher in TCCR1B dringestanden hat, ausser nach dem Reset. Hier besser so. TCCR1B = (1<< CS12); Die leere ISR brauchst du nicht, wenn der Interrupt nicht freigegeben ist. MFG Falk
Und schon hängt er sich nicht mehr auf. Schön. Nun muss ich halt noch nen Weg finden, die Drehzahl zu messen. Spricht etwas dagegen, T0 zu nehmen? Zum Beispiel könnte ich den Timer0 vorladen und den aktuellen Zählerstand von Timer1 auslesen. Nach sagen wir mal 10 Flanken löst T0 einen Overflow Interrupt aus. In diesem nehme ich wieder die Zeit von T1. Dann habe ich eine Zeit für 10 Zündungen. Bei 800 u/min. Interrupt auslösen. Im Leerlauf dauert das <1 sec. Bei meiner Zündung (zwei Zündungen pro Umdrehung) dauerts nur ne knappe halbe Sekunde. Ist das einigermaßen genau? Wie siehts aus, wenn das nur noch 20us dauert (500hz)? Oder kann ich das doch über ICP machen - auch, wenn ich T1 schon benutze?
@ He Gr (dare) >Spricht etwas dagegen, T0 zu nehmen? Zum Beispiel könnte ich den Timer0 Erstmal nicht. >Bei 800 u/min. Interrupt auslösen. Im Leerlauf dauert das <1 sec. Rechne doch erstmal ein paar Grenzwerte aus. Dann wirst du feststellen, dass die Periodendauermessung mit EINER sinnvoller ist. >Ist das einigermaßen genau? Wie siehts aus, wenn das nur noch 20us >dauert (500hz)? Bei mir sind 500 Hz = 2ms. Eine Ewigkeit für einen uC. >Oder kann ich das doch über ICP machen - auch, wenn ich T1 schon >benutze? Sicher. Der Timer und ICP laufen parallel (wobei ICP auf den laufenden Timer angewiesen ist, logisch!). Und wenn du es clever machst, brauchst du nur einen Interrupt und pollst! das ICP Ready Bit, damit wird deine Messung per INT0 genauer (weil der ICP Interrupt nicht dazwischenfunken kann). MFG Falk
Ok, danke! Dann habe ich erstmal nur ein paar kleine Fragen. 1. ein 16 bit Timer kann offensichtlich eine 16 Bit Variable überlaufen lassen. Zumindest resettet der Atmega jedes Mal, wenn ich den Inhalt von Timer1 in eine uint16_t schreiben will. Wenn ich den Inhalt vorher durch 10 teile gehts. Aber dauert ja alles Zeit (obwohl ich davon ne Menge hab)... Ich rechne nun (Radumfang in cm *59)/(Periodendauer/10). Darauf komme ich so: 16384/Periodendauer * Radumfang in cm/100000 * 3600 Da sollte km/h sein. Nun habe ich aber ein Problem. Und zwar zeigt das Ding natürlich nur etwas an, wenn der Interrupt auch ausgelöst wird. Angenommen ich stehe an der Ampel-dann zeigt mir das Ding immer den letzten Messwert an. Soll ich einfach nach einer Ausgabe die Geschwindigkeit auf 0 setzen? Bis zur nächsten sollte eigentlich die nächste Messung vorliegen. Obwohl...Angenommen ich möchte einen Refresh alle 0,25 bis 0,5 Sekunden. Bei langsamer Fahrt mit einem Magneten (hatte nur Ärger mit dreien) kommt da kein Messwert zustande. Wie würdet ihr das machen? Ein 8 Bit Timer läuft mit höchstem Prescaler noch 16 mal in der Sekunde über. Das geht also auch nicht. Bei der Drehzahl wird das gleiche passieren...
@ He Gr (dare) >1. ein 16 bit Timer kann offensichtlich eine 16 Bit Variable überlaufen Logisch. >lassen. Zumindest resettet der Atmega jedes Mal, wenn ich den Inhalt von >Timer1 in eine uint16_t schreiben will. Da ist was anderes faul. > Wenn ich den Inhalt vorher durch >10 teile gehts. Das ist Unsinn. >Geschwindigkeit auf 0 setzen? Bis zur nächsten sollte eigentlich die Nöö, einen Timeout einbauen. Wenn innerhalb von 500ms kein neuer Messwert kommt, DANN wird Null angezeigt. >ihr das machen? Ein 8 Bit Timer läuft mit höchstem Prescaler noch 16 mal >in der Sekunde über. Ja und? Das macht doch nichts? Ausserden, du hast den 16 Bit Timer! Nutze ihn! MfG Falk
Ich hab mich doof ausgedrückt. Klar kann der Timer die Variable überlaufen lassen, wenn er sie hochzählt-ich meinte, dass der Inhalt zu groß ist. Aber das ist quatsch. Ich sehs ein. Trotzdem funktionierts, wenn ich vorher durch 10 teile. Warum auch immer. Ich werd noch rausfinden ;) Son Timeout? Wie realisiere ich den? Ich habe ja schon angedeutet, welche Ideen mir kamen. Alles nicht sooo toll. Es wäre nett, wenn ihr da noch einen Tipp hättet. Den 16bit Timer nutze ich ja schon um Zeit zu messen. Der läuft ständig. Ich nehme dann den Zählerstand und verrechne ihn mit dem vorherigen etc.. Natürlich berücksichtige ich Überläufe.
@ He Gr (dare) >Son Timeout? Wie realisiere ich den? Ich habe ja schon angedeutet, Über die output compare Funktion kann man einen periodischen Interrupt auslösen, z.B. alle 100ms. >Den 16bit Timer nutze ich ja schon um Zeit zu messen. Der läuft ständig. >Ich nehme dann den Zählerstand und verrechne ihn mit dem vorherigen >etc.. Natürlich berücksichtige ich Überläufe. Ja und? Was hindert dich, den auch für die INT0 Auswertung auszulesen? MFG Falk
Das tu ich ja schon. Ich bin jetzt aber auch schon so weit, dass ich morgen wieder testen gehen kann. Output Compare schau ich mir aber noch an, bevor ich für heute schluss mache. Vielen Dank für Deinen Einsatz!
Es gibt eine wichtige Eigenschaft des Binärzahlensystems: Differenzen stimmen immer, auch wenn der Zähler überläuft. Man kann also ruhig den Timer ständig laufen lassen und somit mehrere Zeitdifferenzen ermitteln. Einfach erste Zeit merken und dann von der 2. Zeit abziehen. Sollten die Zeiten so groß werden, daß mehrere Timerüberläufe auftreten, dann kann man den Timer per Überlaufinterrupt erweitern: Beitrag "AVR Timer mit 32 Bit" Peter
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.