PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 3PI goes BASCOM



pinsel120866
02.12.2012, 17:20
Hallo,

ich habe mir einen BASCOM Code zurechtgelegt, der die LEDs, das Display und die Motoren bedient:


'=======================================
'==== 3PI goes BASCOM
'==== December 2012, pinsel120866
'=======================================
$regfile = "m328pdef.dat" ' Set the chip as a Mega 328p
$crystal = 20000000 ' Clock speed 20 MHZ
'=== Generic Port Setup ===
Config Portb = Output
Config Portc = Output
Config Portd = Output
re_led Alias Portd.7 ' Green User LED
li_led Alias Portd.1 ' Red User LED
'=== LCD SETUP ===
Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.4 , Db6 = Portb.5 , Db7 = Portd.7 , E = Portd.4 , Rs = Portd.2
Config Lcd = 16 * 2 ' Actually 8x2 but that is not recognized by BASCOM.
Rw Alias Portb.0 : Rw = 0 ' Set to Zero to write to the LCD
Cursor = Off
'=== PWM SETUP ===
Config Timer0 = Pwm , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Config Timer2 = Pwm , Prescale = 1 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down

'------------------------------------------------------------------------------------------------------------------------------
' Pin Configurations
' Portb.0 - LCD Function R/W
' Portb.1 - LCD Data DB4 ( Switch A )
' Portb.2 - Buzzer
' Portb.3 - Motor 2 Control Line
' Portb.4 - LCD Data DB5 ( Switch B )
' Portb.5 - LCD Data DB6 ( Switch C )
' Portb.6 -
' Portb.7 -
' Portc.0 - IR Sensor #1 ( Left )
' Portc.1 - IR Sensor #2
' Portc.2 - IR Sensor #3 ( Center )
' Portc.3 - IR Sensor #4
' Portc.4 - IR Sensor #5 ( Right )
' Portc.5 - ADC5
' Portc.6 - Motor Controller Not Standby
' Portc.7 -
' Portd.0 - RXD
' Portd.1 - TXD (RED LED)
' Portd.2 - LCD Function RS
' Portd.3 - Motor 2 Control Line
' Portd.4 - LCD Function E
' Portd.5 - Motor 1 Control Line
' Portd.6 - Motor 1 Control Line
' Portd.7 - LCD Data DB7 (GRN LED)
' ADC6 - Battery Power Indicator
' ADC7 - User Trim Pot on underside
'------------------------------------------------------------------------------------------------------------------------------


'=======================================
' Program Start Here
'=======================================
Dim X As Word ' Set up a simple variable


Cls
Lcd "START"
Locate 2 , 1
For X = 1 To 5
Lcd "*"
Wait 1
re_led = 1
li_led = 1
Next X

Cls
Lcd "Gerade"
X=60
re_led = 0
li_led = 0
Gosub Robot_forward
Waitms 1000

Cls
Lcd "Rechts"
X=100
re_led = 1
li_led = 0
Gosub Robot_right
Waitms 1000

cls
lcd "Zurück"
x=60
re_led = 0
li_led = 0
gosub ROBOT_REVERSE
waitms 1000

cls
lcd"Links"
x=100
re_led = 0
li_led = 1
gosub ROBOT_LEFT
waitms 1000

re_led = 0
li_led = 0
Cls
Lcd "Fertig"
Gosub Robot_stop
waitms 1000

'=======================================
Do ' Just waste time at the end

Loop
End 'end program

'=======================================
' Subroutines Here
'=======================================

Robot_forward:
Pwm0a = X : Pwm0b = 0 : Pwm2a = X : Pwm2b = 0
Return

Robot_stop:
Pwm0a = 0 : Pwm0b = 0 : Pwm2a = 0 : Pwm2b = 0
Return

Robot_reverse:
Pwm0a = 0 : Pwm0b = X : Pwm2a = 0 : Pwm2b = X
Return

Robot_right:
Pwm0a = 0 : Pwm0b = X : Pwm2a = X : Pwm2b = 0
Return

Robot_left:
Pwm0a = X : Pwm0b = 0 : Pwm2a = 0 : Pwm2b = X
Return


Läuft soweit ganz gut, bei den Liniensensoren komme ich nicht weiter.

Kann mich bitte jemand dabei unterstützen?
Wäre nett...

Michael
02.12.2012, 17:35
Hallo Pinsel,

meiner Erinnerung nach mußt du das Licht für die Liniensensoren einschalten. PortC.5, hab grad nachgeschaut.
Die 5 Sensoren werden dann über AD-Wandler eingelesen.
Ich meine, es wäre eine externe Referenz dran, deshalb bei der Config ADC Reference = Off

Gruß, Michael

pinsel120866
02.12.2012, 18:19
Hallo Michael,

danke für die Antwort.

Ich habe nun folgendes:



Declare Sub Linedata()

Dim Linesens1 As Integer
Dim Linesens2 As Integer
Dim Linesens3 As Integer
Dim Linesens4 As Integer
Dim Linesens5 As Integer
Config Adc = Single , Prescaler = Auto , Reference = Off
Start Adc

Sub Linedata()
Config Portc.5 = Output
Portc.5 = 1
Linesens1 = Getadc(0)
Linesens2 = Getadc(1)
Linesens3 = Getadc(2)
Linesens4 = Getadc(3)
Linesens5 = Getadc(4)
Portc.5 = 0
End Sub

Aufruf mit

call Linedata

Was meinst du?

Michael
02.12.2012, 19:17
Hallo Pinsel,

ja, so hab ich es auch gemacht.

PortC.0 bis PortC.4 muß Input sein. Linienlicht ist PortC.5, Output



Linienlicht = 1
Portc = Portc Or &B00011111
For I = 0 To 4
S = I + 1
Pc_(s) = Getadc(i)
Next

Gruß, Michael

seseb
03.11.2013, 18:50
Also laut der Anleitung auf der Webseite von Pololu werden die Licht bzw. Liniensensoren nicht über den ADC ausgelesen, sondern Man muss den entsprechenden Port als Output deklarieren, auf HIGH setzen, etwas warten (vielleicht ~ 10 us, um den Konsensator aufzuladen) und dann den Port auf einen Input umstellen, und pullup ausschalten. Nun misst man die Zeit, bis der Input wieder auf LOW geht (der Konsensator wird durch den Fototransistor entladen). Und je nach dem wieviel Licht in den Sensor trifft, ändert sich die Zeit.

Link : http://www.pololu.com/docs/0J21/5.d

Gesammter Artikel : http://www.pololu.com/docs/0J21/all

Michael
03.11.2013, 20:34
dann den Port auf einen Input umstellen, und pullup ausschalten. Nun misst man die Zeit, bis der Input wieder auf LOW geht
so kann man es natürlich auch machen. Mit dem AD-Wandler hast du halt nicht den Stress mit der Umschalterei und dem Impulse-messen. Dann hätte sich der Hersteller aber auch die genaue Verteilung auf die AD-Ports sparen können ;)

Gruß, Michael

oberallgeier
03.11.2013, 23:05
... Mit dem AD-Wandler hast du halt nicht den Stress mit der Umschalterei ...Meinst Du? Na ja, der ADWandler stellt sich nicht von alleine um (Stichwort: Multiplex). Und MÖGLICHERWEISE ist die Kennlinie dieses Kondensator-Entlade-Tricks für die gestellte Aufgabe zweckmässiger als die des ADC. Ist jetzt nur geraten/vermutet/alsmöglichgedacht, ich habs noch nicht verglichen.

Michael
03.11.2013, 23:26
Meinst Du? Na ja, der ADWandler stellt sich nicht von alleine um (Stichwort: Multiplex)
schau einfach mein letztes Programmbeispiel an. Ich glaube nicht, dass das mit DDR-Umschalten und Timerlesen einfacher geht.
Die Linienberechnung danach wichtet die Werte um die Position herauszukriegen. Selbst wenn die AD-Wandler eine andere Kennlinie haben, die Linienposition bekommst du trotzdem genau raus.

Gruß, Michael

Klebwax
04.11.2013, 10:00
schau einfach mein letztes Programmbeispiel an. Ich glaube nicht, dass das mit DDR-Umschalten und Timerlesen einfacher geht.
Die Linienberechnung danach wichtet die Werte um die Position herauszukriegen. Selbst wenn die AD-Wandler eine andere Kennlinie haben, die Linienposition bekommst du trotzdem genau raus.

Gruß, Michael

Wenn der Schaltplan aus dem Datenblatt stimmt:
26652

geht das mit dem ADC garnicht. Und selbst wenn man statt des Kondensators einen Widerstand nach Vcc einbaut, ist der Ausgangswiderstand des Phototransistors tendenziell eine Größenordnung (oder mehr) zu groß für einen typischen µC-ADC. Die Ergebnisse werden kaum besser sein, als wenn man den Port einfach digital einliest, und den Widerstand nach Vcc durch ausprobieren ermittelt.

MfG Klebwax

oberallgeier
04.11.2013, 11:09
... geht das mit dem ADC garnicht. Und selbst wenn man statt des Kondensators ...Hatte ich zwar vermutet, aber als Nicht-Elektroniker fällt mir da eine begründete Aussage schwer : - /

Michael
04.11.2013, 12:06
Wenn der Schaltplan aus dem Datenblatt stimmt:
Bild
geht das mit dem ADC garnicht.

wie du meinst. Ich will mit dir jetzt darüber nicht diskutieren, es funktioniert nämlich bei mir hier.


Und selbst wenn man statt des Kondensators einen Widerstand nach Vcc einbaut, ist der Ausgangswiderstand des Phototransistors tendenziell eine Größenordnung (oder mehr) zu groß für einen typischen µC-ADC. Die Ergebnisse werden kaum besser sein, als wenn man den Port einfach digital einliest, und den Widerstand nach Vcc durch ausprobieren ermittelt.
wie gesagt, die Original-Schaltung funktioniert mit dem Softwarebeispiel wunderbar ;)
Bedenke, dass die Widerstände nach Vcc im AVR sind. Der Rest ist Software.
Und egal, ob du mit ADC oder per Taktzyklenmessung einliest, eine Referenzmessung machst du eh am Anfang.

Gruß, Michael

Klebwax
04.11.2013, 13:00
Bedenke, dass die Widerstände nach Vcc im AVR sind.

Ich bin davon ausgegangen, daß die Pullups, wie im Datenblatt empfohlen, bei Verwendung des ADCs aus sind.

Andere µC disablen die, wenn man den ADC aktiviert.

MfG Klebwax