PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ultraschallsensoren Messung zu langsam?



Alpha2000
20.05.2012, 23:42
Hi

Also erstmal zur hardware.
Altes RC auto mit 2 motoren
Orangutan SV-328 Bord
Ultraschall SRF02

Funst auch alles recht gut der code selbst macht was er soll bis darauf das der abstand wo das auto bremst immer unterschiedlich ist. schätze mal das es an meinem code ligt und daran wan er messen tut aber ich weis nicht wie ich es verbessern soll. ist mein erster roboter.

Die derzeitige funktion ist halt Wen nix im weg ist langsam beschleunigen und wen ein gegenstand im weg ist bremsen. ist der gegenstand wieder weg wieder langsam anfahren.

ps. ja die motoren werden unterschiedlich angesteuert da der eine woll ein knacks weg hat und nicht die selbe leistung bringt. so wie er jetzt ist fahrt er gerade aus ungefäht :)

So hier noch der code ich hoffe ich könnt mir helfen was zu verbessern.


$prog &HFF , &HF6 , &HD9 , &HFC 'Standard Fusebits für Orangutan SV-328

'Die üblichen Definitionen bei Standardprogrammen für Orangutan B-328
$regfile = "m328pdef.dat"
$crystal = 20000000 'Quarzfrequenz
$hwstack = 32
$framesize = 64
$swstack = 32
' ------ Anwendungsspezifische Configurationen ---------




Declare Function Srf02_firmware(byval Slaveid As Byte) As Byte
Declare Function Srf02_entfernung(byval Slaveid As Byte) As Integer
Declare Sub Anhalten()
Declare Sub Ruckwarts()

'Ports benennen
Motor1a Alias Portd.6
Motor1b Alias Portd.5
Motor2a Alias Portd.3
Motor2b Alias Portb.3

Config Pind.1 = Output
Config Pinb.3 = Output
Config Pind.3 = Output
Config Pind.5 = Output
Config Pind.6 = Output

Config Scl = Portd.2 'Gelb Ports fuer IIC-Bus
Config Sda = Portd.0 'Lila

Config Pind.1 = Output
Red_led Alias Portd.1

Const Srf02_slaveid = &HE0 'Standard I2C Adresse von SRF02


'Variablen
Dim I As Integer
Dim A As Integer


Dim Entfernung As Integer
Dim V As Byte
Dim X As Byte

' PWM Register setzen
' see the ATmega48/168/328P datasheet for detailed register info
' configure for inverted PWM output on motor control pins
Tccr0a = &HF3
Tccr2a = &HF3
' use the system clock / 8 (2.5 MHz) as the timer clock
Tccr0b = &H02
Tccr2b = &H02

Main:

Wait 3 'Warte 3 Sekunden
I2cinit
V = 1
I = 0
A = 0
Do

Do

Entfernung = Srf02_entfernung(srf02_slaveid)
If Entfernung >= 40 Then

Ocr2a = 0 'Links
Ocr2b = I 'Links
Ocr0a = A 'Rechts
Ocr0b = 0 'Rechts
Else
Anhalten

End If
Waitms 500
If I < 50 Then
I = I + 5
A = A + 6
End If
Loop Until I > 50
Loop



End



'------------- Hilfsfunktionen für SRF02 ----------


Function Srf02_firmware(byval Slaveid As Byte) As Byte
Local Firmware As Byte
Local Slaveid_read As Byte

Slaveid_read = Slaveid + 1

I2cstart
I2cwbyte Slaveid
I2cwbyte 0 'Leseregister festlegen
I2cstop

I2cstart
I2cwbyte Slaveid_read
I2crbyte Firmware , Nack
I2cstop

Srf02_firmware = Firmware
End Function



Function Srf02_entfernung(byval Slaveid As Byte) As Integer
Local Lob As Byte
Local Hib As Byte
Local Firmware As Byte
Local Temp As Byte
Local Slaveid_read As Byte

Slaveid_read = Slaveid + 1

'Messvorgang in starten
I2cstart
I2cwbyte Slaveid
I2cwbyte 0
I2cwbyte 81 'in Zentimetern messen
I2cstop


Warteaufmessung:
Waitms 1
Firmware = Srf02_firmware(slaveid)
If Firmware = 255 Then Goto Warteaufmessung

I2cstart
I2cwbyte Slaveid
I2cwbyte 2 'Leseregister festlegen
I2cstop


I2cstart
I2cwbyte Slaveid_read
I2crbyte Hib , Ack
I2crbyte Lob , Nack
I2cstop


Srf02_entfernung = Makeint(lob , Hib)
End Function


Sub Anhalten()
I = 0
A = 0

Ocr2a = 0 'Links
Ocr2b = 0 'Links
Ocr0a = 0 'Rechts
Ocr0b = 0 'Rechts

End Sub

Sub Ruckwarts()

I = 0
A = 0
Do
Ocr2a = I 'Links
Ocr2b = 0 'Links
Ocr0a = 0 'Rechts
Ocr0b = A 'Rechts

Waitms 500
I = I + 5
A = A + 8
Loop Until I > 70


End Sub

damfino
21.05.2012, 20:35
Hi,
Ich programmier zwar in C, aber eine wait Funktion hat in der Hauptschleife nichts verloren. Damit steht das ganze Programm und es ist daher auch nicht möglich inzwischen die Sensoren abzufragen.
Hab selber grad eine Schaltung und Programm für 8 SRF02 gebastelt, da verwende ich einen Timer mit 10ms Intervall und Zählvariable um bei 0 einen SRF02 zu starten und nach 70ms (warten bis Zählvariable auf 7 =>70ms steht) das Ergebnis auszulesen. Laut Doku braucht der SRF02 maximal 65ms um ein Ergebnis zu haben, daher spare ich mir die laufende Abfrage ob der Sensor bereit ist und warte stattdessen einfach die Zeit ab.
LG!

Alpha2000
21.05.2012, 23:39
ok ich weis wie du es meinst ist ja klar bei den 500ms macht das ganze program ja nix

aber wen ich diesen part irgendwie in eine funktion oder sub reinpacke dan wird er doch trozdem beim aufruffen dieser funktion erstmal 500ms warten und so lange einfach nicht in die hauptrutine zuruckspringen oder? sehe ich das falsch?

und wen ich diese 500ms nicht abwarte dan beschleunigt das fahrzeug zu schnell

damfino
23.05.2012, 20:27
Du brauchst einen Timer, der langsam eine Variable hochzählt. Am einfachsten einen Timer mit einen Interrupt alle 10ms. Dann in der Hauptschleife einfach If timer> 50 then I=i+5 .... und auch timer =0 setzen. Damit wird nur alle 500ms die Funktion aufgerufen und in der Zwischenzeit kann das Programm noch viele andere Sachen erledigen.
Hier als Beispiel eine Funktion die alle 250ms aufgerufen wird.


if (timecount >=25) // Timer Interrupt alle 10ms
{
timecount=0; // Timer gleich wieder auf 0 setzen damit das Intervall eingehalten wird

if (drehzahl_ist<drehzahl_soll) // Geschwindigkeitsregelung
{speed_li=speed_li-16;speed_re=speed_re-16;

if (drehzahl_ist<=(drehzahl_vmin))
{speed_li=speed_min;speed_re=speed_min;}


}

Alpha2000
27.05.2012, 13:36
Hi

Also jetzt verstehe ich was du meinst. ok habe jetzt auch ein timer implementiert



Config Timer1 = Timer , Prescale = 8 'Konfiguriere Timer1
Enable Timer1 'schalte den Timer1 ein
On Timer1 Isr_von_timer1 'verzweige bei Timer1 überlauf zu Isr_von_Timer1
Enable Interrupts
Load Timer1 = 3125 'Timer1 wert der vorgeladen wird


So das ganze geht wie du sagtest alle 10 ms loss
er zahlt 2 werte hoch der eine bis 7 für den ultraschall sensor der dan seine messung ausspuckt und entscheidet ob er ffährt und er andere bis 50 um zu beschleunigen
getestet hab ich es jetzt nochnicht da die battereieen leer sind aber beim ersten test mit programmer cabel dran geht das program schonmal ganz gut.

THX erstmal für die hilfe

Alpha2000
28.05.2012, 10:23
Eine frage Hätte ich noch

undzwar bin ich jetzt dabei ihm das drehen beizubringen daher soll er schauen ob der gegenstand noch im weg ist oder nicht.
er soll aber erst wen er sich gedreht hat wieder schauen ist noch was im weg oder nicht bevor er einfach lossfahrt daher soll er erstmal warten
und er soll auch erst drehen wen der gegenstand länger da ist

giebt es da eine andere möglichkeit als wait um das hinzubekommen? hab es schon mit einem zahler versucht aber das hat nicht so geklapt ist immer gleich wen er sich ein stuck bewegt hat losgebrettert oder hat sich bloss 1 milimeter bewegt

Mein derzeitiger code ist



$prog &HFF , &HF6 , &HD9 , &HFC 'Standard Fusebits für Orangutan SV-328

'Die üblichen Definitionen bei Standardprogrammen für Orangutan B-328
$regfile = "m328pdef.dat"
$crystal = 20000000 'Quarzfrequenz
$hwstack = 32
$framesize = 64
$swstack = 32
' ------ Anwendungsspezifische Configurationen ---------

Declare Function Srf02_firmware(byval Slaveid As Byte) As Byte
Declare Function Srf02_entfernung(byval Slaveid As Byte) As Integer
Declare Sub Fahren()
Declare Sub Anhalten()
Declare Sub Ruckwarts()
Declare Sub Drehen()

'Ports benennen
Motor1a Alias Portd.6
Motor1b Alias Portd.5
Motor2a Alias Portd.3
Motor2b Alias Portb.3

Config Pind.1 = Output
Config Pinb.3 = Output
Config Pind.3 = Output
Config Pind.5 = Output
Config Pind.6 = Output

Config Scl = Portd.2 'Gelb Ports fuer IIC-Bus
Config Sda = Portd.0 'Lila

Config Pind.1 = Output
Red_led Alias Portd.1

Const Srf02_slaveid = &HE0 'Standard I2C Adresse von SRF02


'Variablen
Dim I As Integer
Dim A As Integer
Dim I1 As Integer
Dim A1 As Integer

Dim Entfernung As Integer
Dim V As Integer

Dim X As Byte
Dim T1 As Byte
Dim T2 As Byte
Dim T3 As Byte


' PWM Register setzen
' see the ATmega48/168/328P datasheet for detailed register info
' configure for inverted PWM output on motor control pins
Tccr0a = &HF3
Tccr2a = &HF3
' use the system clock / 8 (2.5 MHz) as the timer clock
Tccr0b = &H02
Tccr2b = &H02

Config Timer1 = Timer , Prescale = 8 'Konfiguriere Timer1
Enable Timer1 'schalte den Timer1 ein
On Timer1 Isr_von_timer1 'verzweige bei Timer1 überlauf zu Isr_von_Timer1
Enable Interrupts
Load Timer1 = 3125 'Timer1 wert der vorgeladen wird

Main:

'Warte 3 Sekunden
I2cinit
V = 0
I = 0
A = 0
T1 = 0
T2 = 0
T3 = 0

Do
' Messen
If T1 >= 7 Then
T1 = 0
Entfernung = Srf02_entfernung(srf02_slaveid)
End If

'Fahren oder nicht
If Entfernung >= 40 Then

Fahren

Else

Anhalten

End If
'Beschleunigen

If T2 >= 50 Then
T2 = 0
If I < 50 Then
I = I + 5
A = A + 6
End If
End If


Loop

End

Isr_von_timer1: 'ISR von Timer1
Load Timer1 = 3125
T1 = T1 + 1
T2 = T2 + 1
T3 = T3 + 1
Return


'------------- Hilfsfunktionen für SRF02 ----------


Function Srf02_firmware(byval Slaveid As Byte) As Byte
Local Firmware As Byte
Local Slaveid_read As Byte

Slaveid_read = Slaveid + 1

I2cstart
I2cwbyte Slaveid
I2cwbyte 0 'Leseregister festlegen
I2cstop

I2cstart
I2cwbyte Slaveid_read
I2crbyte Firmware , Nack
I2cstop

Srf02_firmware = Firmware
End Function



Function Srf02_entfernung(byval Slaveid As Byte) As Integer
Local Lob As Byte
Local Hib As Byte
Local Firmware As Byte
Local Temp As Byte
Local Slaveid_read As Byte

Slaveid_read = Slaveid + 1

'Messvorgang in starten
I2cstart
I2cwbyte Slaveid
I2cwbyte 0
I2cwbyte 81 'in Zentimetern messen
I2cstop

I2cstart
I2cwbyte Slaveid
I2cwbyte 2 'Leseregister festlegen
I2cstop


I2cstart
I2cwbyte Slaveid_read
I2crbyte Hib , Ack
I2crbyte Lob , Nack
I2cstop


Srf02_entfernung = Makeint(lob , Hib)
End Function

' Richtung angeben
Sub Anhalten()

I = 0
A = 0

Ocr2a = 0 'Links
Ocr2b = 0 'Links
Ocr0a = 0 'Rechts
Ocr0b = 0 'Rechts

V = V + 1

If V = 1000 Then
Toggle Red_led
V = 0

End If

Return


End Sub

Sub Ruckwarts()

Ocr2a = I 'Links
Ocr2b = 0 'Links
Ocr0a = 0 'Rechts
Ocr0b = A 'Rechts



End Sub

Sub Fahren()

If T3 >= 7 Then
T3 = 0
If Entfernung >= 40 Then
V = 0
Ocr2a = 0 'Links
Ocr2b = I 'Links
Ocr0a = A 'Rechts
Ocr0b = 0 'Rechts
End If
End If
Return
End Sub