PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Drehzahl Messung



robonooby
22.07.2013, 13:58
Hallo,
ich habe mal wieder ein Problem :D.
Mein erster Roboter macht soweit ganz gute Vortschritte. Er basiert auf der RN-Control 1.4
bisher funktioniert soweit alles bis auf die Drehzahlmessung bzw. daraus resultierende Drehzahlregelung.

Programmierung tu ich mit BASCOM.

Irgendwie bekomm ich keine Drehzahl raus. Im Fahrgestell sind direkt am Motor Drehgeber angebracht die ein Rechtecksignal rausgeben sollten.

Die Drehgeber habe ich Testweise auch mal an nen Oszi drangehalten. Dort geben sie ein Signal raus. Allerdings ist es bei dem einen Drehgeber kein genaues Rechtecksignal :confused:
hier mal der Screenshot:
26064

Aber dennoch müsste doch zumindestens die eine Drehzahlerfassung funktionieren oder?
Irgendwas scheint also im Code etwas nicht zu stimmen.
Hier mal der Code als Ausschnitt:


.......
'Interrupt für Inkrementalgeber
'Inkrementalgeber 1 an Port D2 Rechts
Config Pind.2 = Input
Portd.2 = 1 'PullUp ein

'Der Interrupt INT0 wird ausgelöst wenn der Pin PD2 gegen GND gezogen wird.
'Also beim Übergang von HIGH nach LOW. Der Interrupt wird nicht ausgelöst, wenn
'der Pin bereits gegen GND zieht.
Config Int0 = Falling 'fallende Flanke Low Level

'Wenn der Interrupt INT0 auftritt, dann springe zum Label On_int0
On Int0 Irq0

'Int0 Einschalten
Enable Int0
'*********************************
'Inkrementalgeber 2 an Port D3 Links
Config Pind.3 = Input
Portd.3 = 1 'PullUp ein

'Der Interrupt INT1 wird ausgelöst wenn der Pin PD3 gegen GND gezogen wird.
'Also beim Übergang von HIGH nach LOW. Der Interrupt wird nicht ausgelöst, wenn
'der Pin bereits gegen GND zieht.
Config Int1 = Falling 'fallende Flanke Low Level

'Wenn der Interrupt INT0 auftritt, dann springe zum Label On_int0
On Int1 Irq1

'Int1 Einschalten
Enable Int1

Config Timer2 = Timer , Prescale = 1024 'Für Geschwindigkeitsmessung
On Timer2 Timer_irq2
Enable Timer2

'Interrupts global einschalten. Das ist der Hauptschalter für alle Interrupts
Enable Interrupts

............

Sub Inkrementgeberabfrage() 'Drehzahl der Räder ermitteln. Umdrehungen pro sekunde
'Prüfen welche Zeit abgelaufen ist, Prüfen wie viel Impulse am Rad entstanden sind. Berechnen der Drehzahl Rad hat 8 Impulse pro Umdrehung
'Bei 8Bit Timer, 16Mhz und einem Prescaler von 1024 hätte man nach einer Sekunde Timerdurchlauf=61,035 Interrups
Local Hilfsvariable As Word
'Formel: Umdrehungen [s^-1] = (Zählerirq/8) * (61,0352/Timerdurchlauf)
Hilfsvariable = Zaehlerirql / 8
Hilfsvariable = Hilfsvariable * Timerdurchlauf
Drehzahllinks = Hilfsvariable / 61.0352

Hilfsvariable = Zaehlerirqr / 8
Hilfsvariable = Hilfsvariable * Timerdurchlauf
Drehzahlrechts = Hilfsvariable / 61.0352

Print "Drehzahl Links [1/s]: " ; Drehzahllinks ; " Drehzahl Rechts [1/s]: " ; Drehzahlrechts

Zaehlerirqr = 0
Zaehlerirql = 0
Timerdurchlauf = 0
End Sub

............

'Interrupt und Timer Routinen:
'************************************************* ************************************************** *****************************
'Interrupt Int0 Unterprogramm. Wird gestertt wenn Signal an Int0 anliegt
Irq0:
Incr Zaehlerirqr
Return

Irq1:
Incr Zaehlerirql
Return

'Timer 2
Timer_irq2:
Incr Timerdurchlauf
Return


Hoffe jemand kann mir helfen.
Danke schonmal.

Ach hab auch mal das komplette Programm beigefügt.

Edit: hier mal nen kurzes Video:

http://www.youtube.com/watch?v=ES_R_DxPMuA

021aet04
22.07.2013, 22:29
Ich kenne mich mit Bascom nicht aus. Du könntest noch einen Schmitdtrigger verwenden oder auf einen Pegel Triggern (Low oder High ist egal). MfG Hannes

robonooby
30.07.2013, 07:50
hat keiner ne Idee wieso das Softwareseitig nicht funktionieren will?

RoboHolIC
30.07.2013, 10:23
Ich habe keine Löschung der Interruptflags gesehen. Geschieht die bei Bascom evtl. ohne ausdrücklichen Befehl ? Falls nein, wird der Controller wohl nach dem ersten Zählimpuls je Kanal (L/R) keine weiteren Zähl-Interrupts ausführen.

Besserwessi
30.07.2013, 10:44
Die Signale sehen nicht so schlecht aus. Das sollte der AVR noch als Signal erkennen können. Der gelbe Kanal hat wohl ein etwas schwächeres Signal. Das könnt z.B. an der Ausrichtung der LED liegen.

Beim Programm ist noch ein Fehler drin: es muss durch die Zahl der Timerüberläufe dividiert werden, und mit 61,... multipliziert - nicht anders herum. Anhängig davon wie oft die Routine aufgerufen wird muss man noch aufpassen das man keine Überläufe bekommt, oder bei sehr schnellem Aufruf den Fall 0/0 bekommt. Gegen das Problem mit zu häufigem Aufruf könnte es etwas helfen, wenn man das Zurücksetzen der Zähler nur macht wenn die Zeit größer als etwa 0,5 s war. Je nach Anwendung wäre zu überlegen eine andere Einheit als Umdrehungen pro Sekunde zu nutzen. Das gibt für die Räder nämlich wohl eher kleine Zahlen und damit ggf. Rundungsprobleme. Ggf. könnte man die beiden Faktoren 8 und 61,... auch noch gleich zusammenfassen: also nicht erst / 8 und dann mal 61,... sondern gleich nur mit 7,6.... multiplizieren.

robonooby
01.08.2013, 23:39
Ich habe keine Löschung der Interruptflags gesehen. Geschieht die bei Bascom evtl. ohne ausdrücklichen Befehl ? Falls nein, wird der Controller wohl nach dem ersten Zählimpuls je Kanal (L/R) keine weiteren Zähl-Interrupts ausführen.
Wie meinst du die Interruptflags löschen? Wie geht das?^^


Die Signale sehen nicht so schlecht aus. Das sollte der AVR noch als Signal erkennen können. Der gelbe Kanal hat wohl ein etwas schwächeres Signal. Das könnt z.B. an der Ausrichtung der LED liegen.

Beim Programm ist noch ein Fehler drin: es muss durch die Zahl der Timerüberläufe dividiert werden, und mit 61,... multipliziert - nicht anders herum. Anhängig davon wie oft die Routine aufgerufen wird muss man noch aufpassen das man keine Überläufe bekommt, oder bei sehr schnellem Aufruf den Fall 0/0 bekommt. Gegen das Problem mit zu häufigem Aufruf könnte es etwas helfen, wenn man das Zurücksetzen der Zähler nur macht wenn die Zeit größer als etwa 0,5 s war. Je nach Anwendung wäre zu überlegen eine andere Einheit als Umdrehungen pro Sekunde zu nutzen. Das gibt für die Räder nämlich wohl eher kleine Zahlen und damit ggf. Rundungsprobleme. Ggf. könnte man die beiden Faktoren 8 und 61,... auch noch gleich zusammenfassen: also nicht erst / 8 und dann mal 61,... sondern gleich nur mit 7,6.... multiplizieren.

also danke für den Tip. Das hab ich irgendwie mit der Berechnungseingabe vertauscht. Hab die Berechnung mal geändert. Überläufe dürften eigentlich keine entstehen da das Rad relativ Langsam sich dreht. vielleicht 25-max 100 Umdrehungen / minute. Der Bot soll ja nicht schnell fahren^^ Aber ich kann wenn er irgendwelche Werte schonmal raus bringt das mal einbauen. Ich werde jetzt erstmal die Berechnung prüfen.

Wäre aber noch schön wenn mir jemand sagen könnte ob man dieses Interruptflag löschen muss?

RoboHolIC
02.08.2013, 02:22
Wie meinst du die Interruptflags löschen? Wie geht das?

Bei Prozessoren zwingt ein gesetztes Interrupt Request Flag den Controller in die Interruptbearbeitung, sofern diese freigeschaltet ist. Diese Flags sind statisch und "speichernd", damit auch die Priorisierung (Rangfolge) zwischen verschiedenen Interruptquellen funktioniert, d.h. damit der Prozessor keinen rangniedrigeren Interrupt Request vergisst.

Wenn man in der Serviceroutine die Löschung des IRQ-Flags unterlässt, wird derselbe IRQ immer und immer wieder ausgeführt und der Prozessor kommt nicht mehr zur Bearbeitung des Hauptprogramms.

Nun weiss ich aber nicht wie Bascom das handhabt; dazu müsste sich ein Kenner äußern.

robonooby
02.08.2013, 07:47
Ah okay. ja scheinbar braucht man das nicht zu tun. War wirklich nur nen Berechnungsfehler wie Besserwessi geschrieben hat, dadurch kam dann nen 0,0... Wert raus und er hat nichts angezeigt.
Also vom Prinzip her funktioniert es jetzt. Raddrehzahl Rechts (Blaue Kurve oben im Oszi Bild) zeigt er jetzt ca 18 Umdrehungen pro Sekunde an. :D
Danke hierfür schonmal für eure Hilfe.

Was nicht richtig geht ist Drezahl Links (Gelbe Kurve oben im Oszi Bild). Hier erkennt er scheinbar doch nicht die kleinen Pieks. Sind scheinbar doch zu schmal. Es kommt hier immer Null raus. Wenn mans mal 5 Minuten laufen lässt auch ab und an mal 1 oder 2 aber mehr nicht. Also muss ich hier noch was machen.
Weis vielleicht jemand woran das liegen könnte? Ist wirklich der Sensor nicht richtig justiert? Hab das Fahrgestell so gekauft mit allem drum und dran.

RoboHolIC
02.08.2013, 10:39
Hallo robonooby.

Im oberen zeitgerafften Bild sieht man ja auch deutlich, dass der Scheitelwert des gelben Signals starken Schwankungen unterworfen ist, während der blaue Kanal immer voll in die Sättigung geht. Da solltest du wirklich vorrangig rangehen.

Bring es optisch und elektrisch in Ordnung, also Lichtschranke und ggf. Fächerscheibe justieren, kontrollieren. Fächerscheibe OK oder evtl. zu kontrastschwach???

Einen Schmitt-Trigger würde ich zuletzt einbauen. Wenn nach dem nächsten Stoß der vielleicht jetzt "auf Kante" gerade noch funktionierende Lichtschrankenkanal gar nicht mehr funktioniert, hilft dir nämlich auch kein Schmitt-Trigger mehr.


Gruß
RoboHolIC

robonooby
02.08.2013, 11:35
Okay. also muss ich wohl oder übel doch den Bot nochmal komplett zerlegen^^
Schade, wird wieder viel Arbeit xD

Werd das dann mal die nächste Woche angehen und Bericht erstatten ^^

Sauerbruch
02.08.2013, 18:36
Wenn man in der Serviceroutine die Löschung des IRQ-Flags unterlässt, wird derselbe IRQ immer und immer wieder ausgeführt und der Prozessor kommt nicht mehr zur Bearbeitung des Hauptprogramms.

Nun weiss ich aber nicht wie Bascom das handhabt; dazu müsste sich ein Kenner äußern.

...oder man schaut ins Datenblatt! Da steht folgendes:

"When an event on the INT0 pin triggers an interrupt request, INTF0 becomes set (one). If the Ibit
in SREG and the INT0 bit in GICR are set (one), the MCU will jump to the corresponding
Interrupt Vector. The flag is cleared when the interrupt routine is executed"

Heißt also im Klartext, dass das IRQ-Flag automatisch gelöscht wird, wenn die ISR ausgeführt wird. Soviel ich weiß gilt dies für alle Interrupts in allen AVR-Controllern. Und da die Löschung des IRQ-Flags auf Hardware-Ebene geschieht, ist es auch egal welche Sprache man zum programmieren des Controllers verwendet!

RoboHolIC
02.08.2013, 22:09
...oder man schaut ins Datenblatt! Da steht folgendes:
Danke dir, Sauerbruch, für die Korrektur!
Hab ich nicht gemacht, weil es nicht meine µC-Welt ist. Da habe ich mir wohl aus früheren Threads zu AVR-Interrupts falsch zusammengereimt, dass es mit dem Löschen der IRQ-Flags gleich wie bei den PICs wäre.


Heißt also im Klartext, dass das IRQ-Flag automatisch gelöscht wird, wenn die ISR ausgeführt wird . . . auf Hardware-Ebene . . . egal welche Sprache man zum programmieren des Controllers verwendet
Eine Fehlerquelle weniger, das macht ja auch Sinn. Wieder was gelernt.

Gruß
RoboHolIC

Besserwessi
03.08.2013, 10:17
Beim AVR hat jeder Interrupt eine eigene ISR. Entsprechend kann die Hardware das Interruptflag auch löschen. Beim PIC geht das nicht, weil man die Flags ggf. noch braucht um die genaue Interruptquelle zu finden.

In der Regel löscht die Hardware beim AVR auch das Interruptflag. Es gibt aber wohl ausnahmen bei der UART / USI, wo man man die Empfangenen Daten auslesen muss zum löschen. Aber das macht man in der ISR in aller Regel sowieso.

robonooby
06.08.2013, 13:14
Also hab jetzt mal den Bot auseinander gebaut und nachgeschaut. Der Inkrementalgeber funktioniert soweit noch. Das Problem ist wohl, dass die Inkrementalscheibe beim Zusammenstecken des Getriebes nicht richtig gerade drin sitzt und dadurch kein sauberes Signal entsteht.
Da muss ich mir jetzt was einfallen lassen. Aber bin erstmal froh, dass die Elektrik funktioniert :)
So schaut das Teil von innen aus:
26173

RoboHolIC
06.08.2013, 23:28
Das Problem ist wohl, dass die Inkrementalscheibe beim Zusammenstecken des Getriebes nicht richtig gerade drin sitzt und dadurch kein sauberes Signal entsteht . . . Aber bin erstmal froh, dass die Elektrik funktioniert :)


Hast du wirklich gemessen, ob/dass die Geberausgänge bei optimaler Stimulation bessere Signale geben können als die, die du anfangs gezeigt hattest? Sonst könnte das Problem ja doch in der Elektronik liegen.
Kann man denn ein "eiern" der Segmentscheibe beobachten? Beim Asuro ist das Problem wohl häufig das axiale Spiel der Segmentscheibe; es lässt sich anscheinend mit Passcheiben in den Griff kriegen.

Sieht die Segmenscheibe wirklich richtig kräftig schwarz und weiß aus? Reflexkoppler leben ja vom Kontrast der Segmentscheibe (Strichscheibe).