Gut die Odometrie ist jetzt fertig ich hab aber noch ein Frage zum Acs, wie stark darf man da die Frequenz für die reichweite verändern ?
Nun ich hab mal ein Programm geschrieben natürlich klapt es nicht kann mir bitte jemand helfen ? danke
Code:$regfile = "m128def.dat" $framesize = 42 $swstack = 32 $hwstack = 32 $crystal = 14745600 $baud = 19200 Tsop Alias Portd.2 Config Tsop = Input Ir Alias Porte.3 Config Ir = Output Irledleft Alias Portd.3 Config Irledleft = Output Irledright Alias Portd.5 Config Irledright = Output Irledleft = 1 Irledright = 1 Declare Sub Acslow() Declare Sub Acsmid() Declare Sub Acshigh() Declare Sub Acsoff() Declare Function Acsleft() As Byte Declare Function Acsright() As Byte Config Timer2 = Timer , Prescale = 8 Timer2 = Acspwm On Ovf2 On_ovf2 Enable Ovf2 Enable Interrupts Call Acshigh() Do If Acsright() = 1 Then Print 1 End If Loop End Sub Acslow() Acspwm = 225 End Sub Sub Acsmid() Acspwm = 228 End Sub Sub Acshigh() Acspwm = 231 End Sub Sub Acsoff() Irledleft = 1 Irledright = 1 End Sub Function Acsleft() Irledleft = 0 Irledright = 1 If Tsop = 1 Then If Tsop = 1 Then Acsleft = 1 End If End If Irledleft = 1 Irledright = 1 End Function Function Acsright() Irledleft = 1 Irledright = 0 If Tsop = 1 Then If Tsop = 1 Then Acsright = 1 End If End If Irledleft = 1 Irledright = 1 End Function On_ovf2: Timer2 = Acspwm Toggle Ir Return
Hallo
Der TSOP benötigt ca. 6-10 Pegelwechsel der Trägerfrequenz bevor er seinen Eingang umschaltet. Wenn ich mich recht erinnere wird sein Ausgang Low wenn das Trägersignal erkannt wird. Hier wird vermutlich nicht viel Unterschied zwischen den Lesungen entstehen können:
If Tsop = 1 Then
If Tsop = 1 Then
Ich löse das meist mit einer Hilfsvariablen die in der ACS-Funktion auf die Anzahl der zu wartenden Schwingungen gesetzt und in der ISR runtergezählt wird:
Das ist allerdings ungetestet. Ob der TSOP mehr Impulse benötigt, wenn die Frequenz nicht genau passt, kann ich nicht sagen. Wenn ich mich nicht verrechnet habe sollten ca. 25 Timertakte zwischen den ISR-Aufrufen etwa 36kHz ergeben.Code:$regfile = "m128def.dat" $framesize = 42 $swstack = 32 $hwstack = 32 $crystal = 14745600 $baud = 19200 Tsop Alias Portd.2 Config Tsop = Input Ir Alias Porte.3 Config Ir = Output Irledleft Alias Portd.3 Config Irledleft = Output Irledright Alias Portd.5 Config Irledright = Output Irledleft = 1 Irledright = 1 Declare Sub Acslow() Declare Sub Acsmid() Declare Sub Acshigh() Declare Sub Acsoff() Declare Function Acsleft() As Byte Declare Function Acsright() As Byte Dim Acspwm As Byte Dim Pulsanzahl As Byte Config Timer2 = Timer , Prescale = 8 Acspwm = 225 Timer2 = Acspwm On Ovf2 On_ovf2 Enable Ovf2 Enable Interrupts Call Acshigh() Do If Acsright() = 0 Then Print 0 End If Loop End Sub Acslow() Acspwm = 225 End Sub Sub Acsmid() Acspwm = 228 End Sub Sub Acshigh() Acspwm = 231 End Sub Sub Acsoff() Irledleft = 1 Irledright = 1 End Sub Function Acsleft() Irledleft = 0 Irledright = 1 Pulsanzahl = 20 While Pulsanzahl > 0 Wend Acsleft = Tsop Irledleft = 1 Irledright = 1 End Function Function Acsright() Irledleft = 1 Irledright = 0 Pulsanzahl = 20 While Pulsanzahl > 0 Wend Acsright = Tsop Irledleft = 1 Irledright = 1 End Function On_ovf2: Timer2 = Acspwm Toggle Ir If Pulsanzahl > 0 Then Pulsanzahl = Pulsanzahl -1 Return
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Das muss nicht unbedingt ein Fehler sein. Wird auch eine 0 angezeigt, wenn sich gar keine Trägerfrequenz im Raum befindet, weil z.B. das "Toggle Ir" in der ISR auskommentiert ist?...es wird dauernt 0 gesendet.
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Hallo
Ich bin das schon mal angegangen. Als Basis diente mir die allseits bekannte IR-Abstandsmessung beim asuro:
https://www.roboternetz.de/phpBB2/ze...=473142#473142
Aufgebohrt auf zwei gepulste Kanäle mit einem probot als Hardware:
https://www.roboternetz.de/phpBB2/ze...=459661#459661
Weiterentwickelt mit der bee:
https://www.roboternetz.de/phpBB2/ze...ag.php?t=52115
Und letzlich die Bascom-Variante mit der bee:
https://www.roboternetz.de/phpBB2/ze...=480966#480966
http://www.youtube.com/watch?v=upszgUzs69g
Die bee läuft mit 15MHz. Für einen schnellen Test kannst du vermutlich mein Timersetup verwenden.
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Gut jetzt ist das auch gelöst aber das nächste Problem ist schon da die lib ist so gut wie fertig aber ich habe einen Fehler in der Go-Sub mit dem Weg
kann mir da einer Helfen? Bascom Schreibt das es anscheinend die eigentlich viel kleinere Variable nicht in die Große passt.
Sub Go(byval Speed As Byte , Byval Dis As Byte)
Call Moveatspeed(speed , Speed)
Encleft = 0
Encright = 0
Local Relweg As Long
Local Strecke As Integer
Relweg = Encleft + Encright
Relweg = Relweg / 2
Strecke = Dis / 12
Do
Call Geradefahren
Loop Until Relweg > Strecke
Call Moveatspeed(0 , 0)
Waitms 10
End Sub
Danke
Ich hab jetzt eigentlich alles fertig ausser die Funktionen zur regullierten Fahrt. Mir macht die funktion zum Feradefahren zu schaffen. Er will einfach nicht gerade fahren. Kann irgendtjemand einen Fehler finden. danke.
Code:$regfile = "m128def.dat" 'es handelt sich um einen ATmega128 $framesize = 42 $swstack = 32 $hwstack = 32 $crystal = 14745600 'Systemtakt 14.7456 MHZ $baud = 19200 'UART Übertragungsgeschwindigkeit Encoderled Alias Portb.0 'es wird auf beide Encoder der Radencoder Config Encoderled = Output 'zugegriffen Motorleft Alias Portb.6 'Motor-PWM-Leitung-Links Config Motorleft = Output Motorright Alias Portb.5 'Motor-PWM-Leitung-Rechts Config Motorright = Output Motorenable Alias Portb.7 'Motorenable Config Motorenable = Output Encoderled = 0 'Die Encoder-Leds sind wieder über Ground Angeschlossen Motorenable = 0 'Motoren sind aus Declare Sub Moveatspeed(byval Sleft As Byte , Byval Sright As Byte) 'Stelt die Motor-PWM ein Declare Sub Encled(byval Status As Byte) 'schaltet die Encoder-Led bei 1 ein Declare Sub Intodometrie() 'konfiguriert die Encoder der Odmetrie und setzt Encleft und encright auf null Declare Sub Geradefahren() 'vergleicht die Odometriewerte und regelt nach Dim Encleft As Word 'der Zwischenspeicher für die Werte des linken Odometrie Encoders Dim Encright As Word 'der Zwischenspeicher für die Werte des rechten Odmetrie Encoders Dim Encoderenable As Byte 'nur wenn diese Varriable 1 werden die Odometrie-Encoder-Impulse gezählt Dim Sw0ys As Long 'Stopwatch 0 wird für die Sub Gerdefahren benötigt Dim Sw0ms As Long Config Timer3 = Timer , Prescale = 8 'Timer 3 (Stopwatches) wird als Timer eingestellt und mit den Prescaler 8 versehen Timer3 = 63693 'Timer 3 wird auf 63693 eingestellt dies passiert auch nach jedem Interrupt On Ovf3 On_ovf3 'wenn Timer 3 überläuft springt das Programm zu On_ovf3 Enable Ovf3 'der Overflow von Timer 3 wird aktiviert Enable Interrupts 'Interrups werden eingeschaltet Start Timer3 'Timer 3 wird gestartet Call Intodometrie() Do Call Moveatspeed(240 , 240) Call Geradefahren() Loop End Sub Encled(byval Status As Byte) 'Eigentlich unnötig aber der Vollständigkeit halber If Status = 1 Then Encoderled = 1 Elseif Status = 0 Then Encoderled = 1 End If Sub Intodometrie() 'Konfiguriert die Odometrie Encleft = 0 'Encleft wird zurückgesetzt Encright = 0 'Encright wird zurückgesetzt Encoderenable = 1 'die Odometrie-Encoder-Impulse können nun gezählt werden Call Encled(1) 'die Encoder-Leds werden eingeschaltet On Int7 Encoleft 'wenn ein Impuls vom linken Encoder kommt zu Encoleft springen On Int6 Encoright 'wenn ein Impuls vom rechten Encoder kommt zu Encoright springen Config Int7 = Falling 'springen wenn ein Impuls abgeschlossen ist Config Int6 = Falling 'springen wenn ein Impuls abgeschlossen ist Enable Int7 'Int7 freischalten Enable Int6 'Int6 freischalten Enable Interrupts 'Interrups aktivieren End Sub Sub Geradefahren() 'Sub für die Gerade Fahrt des Roboters Local Encdif As Integer 'Lokale Varriable für den Unterschied von Encleft und Encright Local Encregler As Integer 'Lokale Varriable für das nachregeln der Geschwindigkeit Sw0ms = Sw0ys / 10 'die ys von Stopwatch 0 werden in ms umgewandelt If Sw0ms = 10 Then 'sind 10ms vergangen ? Sw0ys = 0 'Stopwatch 0 zurück setzen If Encleft > Encright Then 'werden mehr Odometrie-Encoder-Impulse links gezählt ? Encdif = Encleft. - Encright 'Encoder Differenz berechnen Encregler = Encdif * 0.1 'Nachregelungsvarriable berechnen, diese berechnet sich aus 10% der Encoder Differenz Compare1a = Compare1a + Encregler 'PWM-Links um Nachregelungsvarriable erhöhen Compare1b = Compare1b - Encregler 'PWM-Rechts um Nachregelungsvarriable verringern Encleft = 0 Encright = 0 Elseif Encleft < Encright Then 'werden mehr Odometrie-Encoder-Impulse rechts gezählt? Encdif = Encright - Encleft 'Encoder Differenz berechnen Encregler = Encdif * 0.1 'Nachregelungsvarriable berechnen Compare1a = Compare1a - Encregler 'PWM-Links um Nachregelungsvarriable verringern Compare1b = Compare1b + Encregler 'PWM-Rechts um Nachregelungsvarriable erhöhen Encleft = 0 Encright = 0 End If End If End Sub Sub Moveatspeed(byval Sleft As Byte , Byval Sright As Byte) 'Sub zur Regelung der Motorgeschwindikeiten Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1 'Timer 1 wird als zwei 8-Bit PWM Leitungen mit dem Prescaler 1 konfiguriert Start Timer1 'Timer 1 wird gestartet Motorenable = 1 'Motoren werden entsperrt Compare1a = Sright 'PMW-A entspricht der linken Geschwindikeit Compare1b = Sleft 'PWM-B entspricht der rechten Geschwindikeit End Sub Encoleft: 'Interrupt-Rotine die ausgelöst wird wenn links ein Odometrie-Encoder-Impuls kommt If Encoderenable = 1 Then Encleft = Encleft + 1 End If Return Encoright: 'Interrupt-Rotine die ausgelöst wird wenn rechts ein Odometrie-Encoder-Impuls kommt If Encoderenable = 1 Then Encright = Encright + 1 End If Return On_ovf3: 'Hierher wird wenn Timer 3 überläuft Timer3 = 63693 Sw0ys = Sw0ys + 1 If Sw1enable = 1 Then Sw1ys = Sw1ys + 1 End If Return
Hallo
Was zählst du denn da?
Viele Funktionsgruppen des probot sind nahezu identisch vom asuro abgekupfert. Einen direkten Vergleich hatte ich hier mal gemacht:Code:Encoleft: 'Interrupt-Rotine die ausgelöst wird wenn links ein Odometrie-Encoder-Impuls kommt If Encoderenable = 1 Then Encleft = Encleft + 1 End If Return Encoright: 'Interrupt-Rotine die ausgelöst wird wenn rechts ein Odometrie-Encoder-Impuls kommt If Encoderenable = 1 Then Encright = Encright + 1 End If Return
https://www.roboternetz.de/phpBB2/ze...ag.php?t=49556
So ist, neben dem Aufbau der Antriebe (beim asuro ist Stellung der Ritzen zueinander besser), auch die Odometry fast völlig identisch. Deshalb gelten alle Odo-Beschreibungen für den asuro auch uneingeschränkt für den Probot!
Wesentlich ist, dass die Odometry keine "Impulse" erkennt, sondern die Helligkeit vor den Odo-Sensoren misst. In Abhängigkeit von der Stellung der Codescheibe, und dem zusätzlichen Fremdlicht, schwanken die gemessenen Werte zwischen einem minimalen und einem maximalen Wert. Der Trick ist nun, aus diesen Werten einen Segmentwechsel der Codescheibe zu erkennen und diese Wechsel in Radumdrehungen umzurechnen.
Um das Umzusetzen gibt es verschiedene Ansätze und viele Beispiele in C. In Bascom könntest du das als Startpunkt für deine probot-Odometry verwenden:
http://med.hro.nl/kemjt/Asuro/Asuro_Bascom.htm
(Link aus http://www.arexx.com/forum/viewtopic.php?f=9&t=468)
Zum Geradeausfahren reicht es allerdings nicht, nur die Raddrehung genau zu erfassen. Aber das wirst du selbst noch bemerken.
Weiterhin viel Spass und Erfolg.
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Lesezeichen