Che Guevara
11.10.2009, 21:07
Hallo Freunde,
an dieser Stelle möchte ich nun meinen ersten Roboter vorstellen, der insgesamt aus 4 Ebenen besteht. Ich finde das sehr praktisch, da es gut aussieht und man das ganze jederzeit um ein paar Ebenen erweitern kann. Die einzelnen Ebenen sind alle aus 3mm starkem Plexiglas "freihändig" ausgeschnitten, deshalb sitzen sie nicht richtig übereinander, aber wenn ich einmal Zeit habe, werde ich mir etwas überlegen, wie ich die Teile schön gleichmäßig rund ausschneiden kann. An dieser Stelle sind natürlich Anregungen sehr erwünscht.
Hier nun die Funktionen der Ebenen (von unten):
1. Ebene: an der Unterseite das Tamya Twin-Motorset und oben der
Motortreiber
2. Ebene: der Slave-Controller, ein Atmega32 (läuft mit 16MHz)
3. Ebene: der Master-Controller, ein Atmega644P (läuft ebenfalls mit 16MHz)
4. Ebene: an der Unterseite die kleine Stromversorgungsplatine, mit einem L7805, einem L7806 und einer Verpolschutzdiode und diversen Elkos, usw. . ; und an der Oberseite ein Display (4*20 mit grüner Hintergrundbeleuchtung), ein SRF02 und ein GP2D12
Die beiden Controller kommunizieren über RS232 miteinander. Wie sind alle Periphergeräte angeschlossen (und wo)?
am Atmega644P: LCD, Motoren
am Atmega32: GP2D12, SRF02 (über RS232)
Folgendes habe ich mit dem "Kleinen" noch vor:
- Linienverfolgung mittels 3 CNY70
- Schallortung über 3 Mikrophone
- Drehzahlmessung zur Geradeausfahrt mittels PID-Regler (wahrscheinlich)
- Funkverbindung mit PC herstellen (entweder über RFM12 oder Easy Radio)
Das wichtigste jedoch ist zur Zeit die Drehzahlmessung. Wenn jemand Anregungen dazu hat oder auch zu anderen geplanten Erweiterungen, dann nur raus damit :-)
Hier nun die beiden Codes.
Atmega644P
$regfile = "m644pdef.dat"
$crystal = 16000000
$baud = 19200
$framesize = 140
$hwstack = 140
$swstack = 140
Declare Sub Serial0charmatch()
Declare Sub Direction(byval Direction_motors As String , Byval Pwm_left As Word , Byval Pwm_right As Word)
Config Serialin = Buffered , Size = 30 , Bytematch = 13
Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output
Config Portb.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Portb.0 = 0
Portb.1 = 0
Portb.2 = 0
Portb.3 = 0
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
Config Lcdbus = 4
Initlcd
Cls
Cursor Off Noblink
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 8
Pwm1a = 0
Pwm1b = 0
Config Timer0 = Timer , Prescale = 1024
Timer0 = 150
On Timer0 Isr_von_timer0
Enable Timer0
Dim J As Byte
Dim Tmp As Byte
Dim Lenght As Byte
Dim Timer_counter As Byte
Dim Ar(6) As String * 30
Dim Input_command As String * 30
Dim Distance_srf02 As Integer
Dim Distance_gp2d12 As Integer
Dim Start_flag As Bit
Dim Distance_limit As Byte
Start_flag = 0
Distance_limit = 50
Locate 1 , 1
Lcd "MEGA644P - Master"
Locate 2 , 1
Lcd "MEGA32 - Slave"
Locate 3 , 1
Lcd "SRF02 / GP2D12"
Locate 4 , 1
Lcd "MOTOR-PLATINE"
Wait 2
Cls
Enable Interrupts
Do
If Start_flag = 1 Then
If Distance_gp2d12 <= Distance_limit Or Distance_srf02 <= Distance_limit Then
Call Direction( "left" , 480 , 600)
Waitms 10
Else
Call Direction( "vorward" , 580 , 700)
End If
End If
Loop
End
Sub Direction(byval Direction_motors As String , Byval Pwm_left As Word , Byval Pwm_right As Word)
If Pwm_left >= 800 Then Pwm_left = 800
If Pwm_right >= 800 Then Pwm_right = 800
Pwm1a = Pwm_right
Pwm1b = Pwm_left
Select Case Direction_motors
Case "vorward"
Portb = &B00000101
Case "right"
Portb = &B00001001
Case "left"
Portb = &B00000110
Case "backward"
Portb = &B00001010
Case "stop"
Portb = &B00000000
Case Else
Portb = &B00000000
End Select
End Sub
Sub Serial0charmatch()
Input Input_command Noecho
Input_command = Lcase(input_command)
If Asc(input_command) = 10 Then
Lenght = Len(input_command)
Lenght = Lenght - 1
Input_command = Right(input_command , Lenght)
End If
Tmp = Split(input_command , Ar(1) , ":")
Input_command = ""
Cls
If Ar(1) = "mega32" Then
Locate 1 , 1
Lcd Ar(1) , " "
Locate 2 , 1
Lcd Ar(2) , " "
Locate 3 , 1
Lcd Ar(3) ; " cm SRF02"
Locate 4 , 1
Lcd Ar(4) ; " cm GP2D12"
Distance_srf02 = Val(ar(3))
Distance_gp2d12 = Val(ar(4))
End If
Start_flag = 1
For J = 1 To Tmp
Ar(j) = ""
Next J
End Sub
Isr_von_timer0:
Timer0 = 150
Incr Timer_counter
If Timer_counter = 50 Then
Timer_counter = 0
Print "mega32:distance"
End If
Return
Atmega32
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$framesize = 150
$hwstack = 150
$swstack = 150
Declare Function Srf02_entfernung(byval Slaveid As Byte) As Integer
Declare Sub Serial0charmatch()
Declare Function Gp2() As Integer
Open "COMB.0:9600,8,N,2" For Input As #2
Open "COMB.1:9600,8,N,2" For Output As #1
Config Serialin = Buffered , Size = 25 , Bytematch = 13
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Config Pina.0 = Input
Porta.0 = 0
Const Srf02_slaveid = 0
Dim Distance_srf02 As Integer
Dim Distance_gp2d12 As Integer
Dim Distance_gp2d12_array(4) As Integer
Dim Ab As Single
Dim J As Byte
Dim I As Byte
Dim Tmp As Byte
Dim Lenght As Byte
Dim Input_command As String * 25
Dim Ar(5) As String * 25
Dim D As Single
Dim X As Word
Dim Xi(3) As Word
Dim Volt As Single
Const A = 24.93
Const B = 0.0695
Const Ref = 5 / 1023
Enable Interrupts
Distance_srf02 = Srf02_entfernung(srf02_slaveid)
Distance_gp2d12 = Gp2()
Do
!nop
Loop
End
Sub Serial0charmatch()
Input Input_command Noecho
Input_command = Lcase(input_command)
If Asc(input_command) = 10 Then
Lenght = Len(input_command)
Lenght = Lenght - 1
Input_command = Right(input_command , Lenght)
End If
Tmp = Split(input_command , Ar(1) , ":")
Input_command = ""
If Ar(1) = "mega32" Then
If Ar(2) = "distance" Then
Distance_srf02 = Srf02_entfernung(srf02_slaveid)
Distance_gp2d12 = Gp2()
Print "mega32:distance:" ; Distance_srf02 ; ":" ; Distance_gp2d12 , Noecho
End If
Else
Print "Unknown SLAVE"
End If
For J = 1 To Tmp
Ar(j) = ""
Next J
End Sub
Function Srf02_entfernung(byval Slaveid As Byte) As Integer
Local Lob As Byte
Local Hib As Byte
Print #1 , Chr(slaveid) ; Chr(84);
Inputbin #2 , Hib , Lob
Srf02_entfernung = Makeint(lob , Hib)
End Function
Function Gp2() As Integer
For I = 1 To 3
Xi(i) = Getadc(0)
Next I
X = Xi(1) + Xi(2)
X = X + Xi(3)
X = X / 3
If X >= 77 And X <= 650 Then
Volt = X * Ref
D = Volt - B
Ab = A / D
Gp2 = Ab
Else
Gp2 = 90
End If
End Function
Bilder folgen später noch, muss erst noch meine Digicam aufladen.
Ich bin natürlich über jede Anregung, Kritik aber auch Idee und Lob sehr erfreut.
Gruß
Chris
Edit:
Hier nun wie versprochen die Bilder (wenn jemand einen bestimmen Ausschnitt genauer sehen möchte, schreibt mir einfach)
an dieser Stelle möchte ich nun meinen ersten Roboter vorstellen, der insgesamt aus 4 Ebenen besteht. Ich finde das sehr praktisch, da es gut aussieht und man das ganze jederzeit um ein paar Ebenen erweitern kann. Die einzelnen Ebenen sind alle aus 3mm starkem Plexiglas "freihändig" ausgeschnitten, deshalb sitzen sie nicht richtig übereinander, aber wenn ich einmal Zeit habe, werde ich mir etwas überlegen, wie ich die Teile schön gleichmäßig rund ausschneiden kann. An dieser Stelle sind natürlich Anregungen sehr erwünscht.
Hier nun die Funktionen der Ebenen (von unten):
1. Ebene: an der Unterseite das Tamya Twin-Motorset und oben der
Motortreiber
2. Ebene: der Slave-Controller, ein Atmega32 (läuft mit 16MHz)
3. Ebene: der Master-Controller, ein Atmega644P (läuft ebenfalls mit 16MHz)
4. Ebene: an der Unterseite die kleine Stromversorgungsplatine, mit einem L7805, einem L7806 und einer Verpolschutzdiode und diversen Elkos, usw. . ; und an der Oberseite ein Display (4*20 mit grüner Hintergrundbeleuchtung), ein SRF02 und ein GP2D12
Die beiden Controller kommunizieren über RS232 miteinander. Wie sind alle Periphergeräte angeschlossen (und wo)?
am Atmega644P: LCD, Motoren
am Atmega32: GP2D12, SRF02 (über RS232)
Folgendes habe ich mit dem "Kleinen" noch vor:
- Linienverfolgung mittels 3 CNY70
- Schallortung über 3 Mikrophone
- Drehzahlmessung zur Geradeausfahrt mittels PID-Regler (wahrscheinlich)
- Funkverbindung mit PC herstellen (entweder über RFM12 oder Easy Radio)
Das wichtigste jedoch ist zur Zeit die Drehzahlmessung. Wenn jemand Anregungen dazu hat oder auch zu anderen geplanten Erweiterungen, dann nur raus damit :-)
Hier nun die beiden Codes.
Atmega644P
$regfile = "m644pdef.dat"
$crystal = 16000000
$baud = 19200
$framesize = 140
$hwstack = 140
$swstack = 140
Declare Sub Serial0charmatch()
Declare Sub Direction(byval Direction_motors As String , Byval Pwm_left As Word , Byval Pwm_right As Word)
Config Serialin = Buffered , Size = 30 , Bytematch = 13
Config Portb.0 = Output
Config Portb.1 = Output
Config Portb.2 = Output
Config Portb.3 = Output
Config Portd.4 = Output
Config Portd.5 = Output
Portb.0 = 0
Portb.1 = 0
Portb.2 = 0
Portb.3 = 0
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.4 , Rs = Portc.5
Config Lcdbus = 4
Initlcd
Cls
Cursor Off Noblink
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 8
Pwm1a = 0
Pwm1b = 0
Config Timer0 = Timer , Prescale = 1024
Timer0 = 150
On Timer0 Isr_von_timer0
Enable Timer0
Dim J As Byte
Dim Tmp As Byte
Dim Lenght As Byte
Dim Timer_counter As Byte
Dim Ar(6) As String * 30
Dim Input_command As String * 30
Dim Distance_srf02 As Integer
Dim Distance_gp2d12 As Integer
Dim Start_flag As Bit
Dim Distance_limit As Byte
Start_flag = 0
Distance_limit = 50
Locate 1 , 1
Lcd "MEGA644P - Master"
Locate 2 , 1
Lcd "MEGA32 - Slave"
Locate 3 , 1
Lcd "SRF02 / GP2D12"
Locate 4 , 1
Lcd "MOTOR-PLATINE"
Wait 2
Cls
Enable Interrupts
Do
If Start_flag = 1 Then
If Distance_gp2d12 <= Distance_limit Or Distance_srf02 <= Distance_limit Then
Call Direction( "left" , 480 , 600)
Waitms 10
Else
Call Direction( "vorward" , 580 , 700)
End If
End If
Loop
End
Sub Direction(byval Direction_motors As String , Byval Pwm_left As Word , Byval Pwm_right As Word)
If Pwm_left >= 800 Then Pwm_left = 800
If Pwm_right >= 800 Then Pwm_right = 800
Pwm1a = Pwm_right
Pwm1b = Pwm_left
Select Case Direction_motors
Case "vorward"
Portb = &B00000101
Case "right"
Portb = &B00001001
Case "left"
Portb = &B00000110
Case "backward"
Portb = &B00001010
Case "stop"
Portb = &B00000000
Case Else
Portb = &B00000000
End Select
End Sub
Sub Serial0charmatch()
Input Input_command Noecho
Input_command = Lcase(input_command)
If Asc(input_command) = 10 Then
Lenght = Len(input_command)
Lenght = Lenght - 1
Input_command = Right(input_command , Lenght)
End If
Tmp = Split(input_command , Ar(1) , ":")
Input_command = ""
Cls
If Ar(1) = "mega32" Then
Locate 1 , 1
Lcd Ar(1) , " "
Locate 2 , 1
Lcd Ar(2) , " "
Locate 3 , 1
Lcd Ar(3) ; " cm SRF02"
Locate 4 , 1
Lcd Ar(4) ; " cm GP2D12"
Distance_srf02 = Val(ar(3))
Distance_gp2d12 = Val(ar(4))
End If
Start_flag = 1
For J = 1 To Tmp
Ar(j) = ""
Next J
End Sub
Isr_von_timer0:
Timer0 = 150
Incr Timer_counter
If Timer_counter = 50 Then
Timer_counter = 0
Print "mega32:distance"
End If
Return
Atmega32
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200
$framesize = 150
$hwstack = 150
$swstack = 150
Declare Function Srf02_entfernung(byval Slaveid As Byte) As Integer
Declare Sub Serial0charmatch()
Declare Function Gp2() As Integer
Open "COMB.0:9600,8,N,2" For Input As #2
Open "COMB.1:9600,8,N,2" For Output As #1
Config Serialin = Buffered , Size = 25 , Bytematch = 13
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Config Pina.0 = Input
Porta.0 = 0
Const Srf02_slaveid = 0
Dim Distance_srf02 As Integer
Dim Distance_gp2d12 As Integer
Dim Distance_gp2d12_array(4) As Integer
Dim Ab As Single
Dim J As Byte
Dim I As Byte
Dim Tmp As Byte
Dim Lenght As Byte
Dim Input_command As String * 25
Dim Ar(5) As String * 25
Dim D As Single
Dim X As Word
Dim Xi(3) As Word
Dim Volt As Single
Const A = 24.93
Const B = 0.0695
Const Ref = 5 / 1023
Enable Interrupts
Distance_srf02 = Srf02_entfernung(srf02_slaveid)
Distance_gp2d12 = Gp2()
Do
!nop
Loop
End
Sub Serial0charmatch()
Input Input_command Noecho
Input_command = Lcase(input_command)
If Asc(input_command) = 10 Then
Lenght = Len(input_command)
Lenght = Lenght - 1
Input_command = Right(input_command , Lenght)
End If
Tmp = Split(input_command , Ar(1) , ":")
Input_command = ""
If Ar(1) = "mega32" Then
If Ar(2) = "distance" Then
Distance_srf02 = Srf02_entfernung(srf02_slaveid)
Distance_gp2d12 = Gp2()
Print "mega32:distance:" ; Distance_srf02 ; ":" ; Distance_gp2d12 , Noecho
End If
Else
Print "Unknown SLAVE"
End If
For J = 1 To Tmp
Ar(j) = ""
Next J
End Sub
Function Srf02_entfernung(byval Slaveid As Byte) As Integer
Local Lob As Byte
Local Hib As Byte
Print #1 , Chr(slaveid) ; Chr(84);
Inputbin #2 , Hib , Lob
Srf02_entfernung = Makeint(lob , Hib)
End Function
Function Gp2() As Integer
For I = 1 To 3
Xi(i) = Getadc(0)
Next I
X = Xi(1) + Xi(2)
X = X + Xi(3)
X = X / 3
If X >= 77 And X <= 650 Then
Volt = X * Ref
D = Volt - B
Ab = A / D
Gp2 = Ab
Else
Gp2 = 90
End If
End Function
Bilder folgen später noch, muss erst noch meine Digicam aufladen.
Ich bin natürlich über jede Anregung, Kritik aber auch Idee und Lob sehr erfreut.
Gruß
Chris
Edit:
Hier nun wie versprochen die Bilder (wenn jemand einen bestimmen Ausschnitt genauer sehen möchte, schreibt mir einfach)