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 ?
Druckbare Version
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
Leider Funktioniert es immer noch nicht es wird dauernt 0 gesendet.
Hast du noch irgenteine Idee ?
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?Zitat:
...es wird dauernt 0 gesendet.
ja aber wie kann man es dann machen soll ich das ganze neu angehen ?
wie würdest du es angehn ?
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
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