Super, tolle Arbeit - danke mic.
Ich habe mir dein Programm gleich geschnappt und so erweitert, dass die Bee autonom durch den Raum fährt:
Code:
'Verwendeter Compiler Bascom V 1.11.9.3
'
'Aufgabe:
'Autonome Bewegung mit
'Abstandsmessung (IR-LEDs 2x links, 2x rechts)
'und Werte auf DODM 3x16 LCD ausgeben
'Autor: Pinsel120866
'###################################################
Declare Sub Motorpwm(byval Pwm_l As Byte , Byval Pwm_r As Byte) 'Pwm für Motoren setzen (0-255)
Declare Sub Motordir(byval Dir_l As Byte , Byval Dir_r As Byte) 'Drehrichtungen der Motoren setzen (1/0)
Declare Sub Setleds(byval Leds As Byte) 'Leds als Bitmuster setzen &B000xxxx
Declare Function Getkeys() As Byte 'Bitmuster der Tasten einlesen &B0000xxxx
Declare Sub Odo_reset ' Odometryzähler auf null setzen
Declare Sub Sleep(byval Pause As Byte) 'Pause 1/36000 Sekunde warten
Declare Sub Msleep(byval Pause As Word) 'Pause 1/1000 Sekunde warten
Declare Sub Acs ' acs_left und acs_right aktuallisieren
$regfile = "m16def.dat"
$crystal = 15000000
$hwstack = 48 ' kleiner 48 ergibt Stapelüberlauf!
$swstack = 8
$framesize = 24
$baud = 19200
Acs_led_left Alias Porta.1 'acs Anoden
Acs_led_right Alias Porta.0
Acs_led_36khz Alias Porta.3 ' Kathode mit Widerstand
Acs_tsop Alias Pina.2 'Eingang!
Led0 Alias Portb.0
Led1 Alias Portb.1
Led2 Alias Portb.2
Led3 Alias Portb.3
Lineled Alias Portb.4
$lib "Lcd_i2c_DOGM.lib" 'I2c driver for the LCD
Config I2cdelay = 1
Const Pcf8574_lcd = &H4E 'Defines the address of the I/O expander for LCD
Config Scl = Portc.0 'Configure I2C SCL
Config Sda = Portc.1 'Configure I2C SDA
Config Led0 = Output ' LEDs 0-3
Config Led1 = Output
Config Led2 = Output
Config Led3 = Output
Config Lineled = Output ' Lineled
Config Acs_led_left = Output 'acs
Config Acs_led_right = Output
Config Acs_led_36khz = Output
Config Acs_tsop = Input
Config Portc.4 = Input ' keys
Config Portc.5 = Input
Config Portc.6 = Input
Config Portc.7 = Input
Portc = &B11110000 'Tasten-PullUp Bit 4-7 einschalten
Config Portd.2 = Input ' odo_l int0
Config Portd.3 = Input ' odo_r int1
Config Portd.4 = Output ' pmw_r
Config Portd.5 = Output ' pwm_l
Config Portd.6 = Output ' dir_l
Config Portd.7 = Output ' dir_r
'Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1
Config Timer2 = Phase Correct , Compare Pwm = Disconnect , Prescale = 1
Ocr2 = 151 '36kHz mit Puls:Pause 50:50
Tcnt2 = 99 'Frequenzkorrektur beim Start
Config Adc = Single , Prescaler = 64 , Reference = Avcc ' 235 kHz
Config Int0 = Change
Config Int1 = Change
Dim B As Byte , W As Word
Dim Odo_count_l As Word , Odo_count_r As Word
Dim Count36khz As Byte
Dim Acs_left As Byte , Acs_right As Byte
Dim Acs_count As Byte
Dim _lcd_e As Byte 'Needed to control 4 line LCD
Config Lcd = 16 * 3 , Chipset = Dogm163v5 '16*3 type LCD display 5V
I2cstart
Start Adc
On Oc2 Isr_timer2_comp
On Ovf2 Isr_timer2_ovl
On Int0 Isr_int0
On Int1 Isr_int1
Enable Oc2
Enable Ovf2
Enable Int0
Enable Int1
Enable Interrupts
_lcd_e = 128 'Upper half of 4-line display is selected
Cls 'clear the LCD display
Lcd "Pinsel's NIBOBee" 'display this at the top line
Waitms 1
Lowerline 'select the lower line
Lcd "Abstandsmessung mit 2x2 IR-LEDs"
Waitms 1 'display this at the lower line
_lcd_e = 64 'Lower half of 4-line display is selected
Lcd "nix"
Waitms 1
Lowerline
Lcd "nix"
Waitms 500
Do
Call Acs
Reset Led0
Reset Led1
Reset Led2
Reset Led3
Call Motordir(1 , 1)
Call Motorpwm(197 , 197)
If Acs_left > 251 And Acs_right > 251 Then
_lcd_e = 128
Cls
Lcd "" 'display this at the top line
Waitms 1
Lowerline 'select the lower line
Lcd "Abstand li: " ; Acs_left ; " Abstand re: " ; Acs_right ; 'Wert ausgeben auf Display
Set Led1
Call Motordir(1 , 0)
Call Motorpwm(0 , 0)
Waitms 100
Call Motorpwm(127 , 127)
Waitms 300
End If
If Acs_left > 251 Then
_lcd_e = 128
Cls
Lcd "" 'display this at the top line
Waitms 1
Lowerline 'select the lower line
Lcd "Abstand li: " ; Acs_left ; " Abstand re: " ; Acs_right ; 'Wert ausgeben auf Display
Set Led1
Call Motordir(1 , 1)
Call Motorpwm(0 , 0)
Waitms 100
Call Motorpwm(127 , 0)
Waitms 300
End If
If Acs_right > 251 Then
_lcd_e = 128
Cls
Lcd "" 'display this at the top line
Waitms 1
Lowerline 'select the lower line
Lcd "Abstand li: " ; Acs_left ; " Abstand re: " ; Acs_right ; 'Wert ausgeben auf Display
Set Led2
Call Motordir(1 , 1)
Call Motorpwm(0 , 0)
Waitms 100
Call Motorpwm(0 , 127)
Waitms 300
End If
Loop
End
Sub Acs
Ocr2 = 253
Set Acs_led_left
While Acs_tsop = 1 And Ocr2 > 151
Acs_count = 8
While Acs_count > 0
Wend
Ocr2 = Ocr2 - 1
Wend
Reset Acs_led_left
Acs_left = Ocr2
While Acs_tsop = 0
Wend
Ocr2 = 253
Set Acs_led_right
While Acs_tsop = 1 And Ocr2 > 151
Acs_count = 8
While Acs_count > 0
Wend
Ocr2 = Ocr2 - 1
Wend
Reset Acs_led_right
Acs_right = Ocr2
While Acs_tsop = 0
Wend
End Sub
Sub Motorpwm(byval Pwm_l As Byte , Byval Pwm_r As Byte)
Pwm1a = Pwm_l * 4
Pwm1b = Pwm_r * 4
End Sub
Sub Motordir(byval Dir_l As Byte , Byval Dir_r As Byte)
If Dir_l = 0 Then Portd.6 = 0 Else Portd.6 = 1
If Dir_r = 0 Then Portd.7 = 1 Else Portd.7 = 0
End Sub
Function Getkeys() As Byte
Getkeys = Pinc / 16 ' Pins einlesen und nach rechts schieben
Getkeys = Getkeys Xor 255 ' invertieren
Getkeys = Getkeys And 15 ' Bit4-7 ausblenden
End Function
Sub Odo_reset
Disable Interrupts
Odo_count_l = 0
Odo_count_r = 0
Enable Interrupts
End Sub
Sub Sleep(byval Pause As Byte)
Count36khz = Pause
While Count36khz > 0
Wend
End Sub
Sub Msleep(byval Pause As Word)
While Pause > 0
Call Sleep(36)
Decr Pause
Wend
End Sub
Isr_int0:
Incr Odo_count_l
Led0 = Pind.2
Return
Isr_int1:
Incr Odo_count_r
Led3 = Pind.3
Return
Isr_timer2_comp:
Toggle Acs_led_36khz
Return
Isr_timer2_ovl:
Tcnt2 = Tcnt2 + 99 'Frequenzkorrektur 36kHz
Reset Acs_led_36khz
If Count36khz > 0 Then Decr Count36khz
If Acs_count > 0 Then Decr Acs_count
Return
Lesezeichen