PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu Code für SRF10



easyprivate
06.01.2009, 15:43
Hi@all!

Hänge am Problem fest wo ich auf eure Hilfe hoffe ;-)

Ziel ist es beim unterschreiten einer bestimmten Entfernung,gemessen durch SRF10, einen Servo in eine bestimmte Position zu bringen...

Als Beispiel mal die Entfernung 30cm....

Hier der Quellcode aus dem Wissensbereich+meiner Ergänzung...


Declare Function Srf10_entfernung(byval Srf10_slaveid As Byte) As Integer
Declare Sub Srf10_reichweite(byval Srf10_slaveid As Byte , Byval Reichweite As Word)
Declare Sub Srf10_verstaerkung(byval Srf10_slaveid As Byte , Byval Srf10_verstaerkung As Byte)
Declare Function Srf10_firmware(byval Srf10_slaveid As Byte) As Byte

$regfile = "m32def.dat"
$framesize = 42
$swstack = 42
$hwstack = 42

$crystal = 16000000 'Quarzfrequenz
$baud = 9600

Config Scl = Portc.0 'Ports fuer IIC-Bus
Config Sda = Portc.1


Dim Entfernung As Integer

Wait 3 'Warte 3 Sekunden
I2cinit
Print "SRF10 Testprogramm "
Print "SRF 10 Firmware Version:" ; Srf10_firmware(&He0)

Srf10_reichweite &HE0 , 1000 'Reichweite in Zentimetern festlegen
Srf10_verstaerkung &HE0 , 10 'Verstärkungsfaktor



Do
Entfernung = Srf10_entfernung(&He0)
Print "Entfernung:" ; Entfernung ; "cm"
Wait 1
Loop

End




Function Srf10_entfernung(byval Srf10_slaveid As Byte) As Integer
Local LoB As Byte
Local Hib As Byte
Local Firmware As Byte
Local Temp As Byte
Local Srf10_slaveid_read As Byte

Srf10_slaveid_read = Srf10_slaveid + 1

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

Warteaufmessung:
Waitms 1
Firmware = Srf10_firmware(&He0)
If Firmware = 255 Then Goto Warteaufmessung

I2cstart
I2cwbyte Srf10_slaveid
I2cwbyte 2 'Leseregister festlegen
I2cstop


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


Srf10_entfernung = Makeint(lob , Hib)
End Function



'Messreichweite in cm festlegen
Sub Srf10_reichweite(byval Srf10_slaveid As Byte , Byval Reichweite As Word)
Local Wert As Word
Local Temp As Byte

Wert = Reichweite / 4 'Ungefähre Registerberechnung
Temp = Low(wert)

I2cstart
I2cwbyte Srf10_slaveid
I2cwbyte 2 'Register
I2cwbyte Temp
I2cstop

End Sub


'Verstärung festlegen
Sub Srf10_verstaerkung(byval Srf10_slaveid As Byte , Byval Srf10_verstaerkung As Byte)
I2cstart
I2cwbyte Srf10_slaveid
I2cwbyte 1 'Register
I2cwbyte Srf10_verstaerkung
I2cstop

End Sub



Function Srf10_firmware(byval Srf10_slaveid As Byte) As Byte
Local Firmware As Byte
Local Srf10_slaveid_read As Byte

Srf10_slaveid_read = Srf10_slaveid + 1

I2cstart
I2cwbyte Srf10_slaveid
I2cwbyte 0 'Leseregister festlegen
I2cstop

I2cstart
I2cwbyte Srf10_slaveid_read
I2crbyte Firmware , Nack
I2cstop

Srf10_firmware = Firmware
End Function



####denke nun müsste folgendes kommen####

Config Servos = 1 , Servo1 = PortA.0 , Reload 10

Config PortA = Output

Enable Interrupts

###hier jetzt ein Befehl der die Distanz <30cm vorm nächsten Schritt abfragt??###

waitms 1000

Servo(1) = 100

loop



Hat jemand einen Tipp??

Gruß,Easy

PicNick
06.01.2009, 16:12
Waitms 1 is ein bisschen knapp. Da is der Schall grad 30 cm in einer Richtung unterwegs. Umdrehen und zurück muss er ja auch noch.
Ich hab jetzt nicht im Kopf, wielange man warten soll, da musst du nachlesen.
Probier mal Waitms 100

Btw: den "i2cstop" zwischen leseregister festlegen und auslesen solltest du ersatzlos streichen

easyprivate
06.01.2009, 17:09
Danke für deine schnelle Antwort.Gut das werde ich berücksichtigen,mein Problem betseht aber eigentlich darin das ich nicht weiß welchen Befehl ich verwenden kann um den Messwert kleiner 30cm zur Einleitung einer Bewegung des Servos zu berücksichtigen...

PicNick
06.01.2009, 17:35
Ich seh im WIKI-Beispiel, dass da auch Waitms 1 steht.
Also, ich weiss nicht, ich lern aber gern dazu.

Was soll denn das Servo machen bei < 30 cm ?

An sich wäre die Abfrage trivialerweise


IF Entfernung < 30
THEN
???? ' ja watten nu ?
END IF


Normalerweise sind Servowerte von 100 bis 200 möglich
Du könntest spasshalber einstellen mit
SERVO[1] = 100 + Entfernung_in_cm
Dann verhält sich das Servo wie ein Zeiger.

Anm: Da du ein Servo sowieso nur alle 20 mS neu einstellen kannst, hast du ja auch mehr Zeit zum Abfragen

easyprivate
06.01.2009, 19:34
Mein Ziel ist es einen Hexa mit Servos anzutreiben... Wenn er sich einem Gegenstand nähert soll er sich bei einer Entfernung kleiner 30cm, 90° zur Seite drehen und weitergehen. Der "Stellwert" sollte nur ein Beispiel sein... Ja laut Wiki steht da wait 1 entspricht einer sekunde,meiner erfahrung nach wäre das dann aber waitms 1000 entspricht einer sekunde, nur wait lässt sich bei mir auch nicht kompilieren... wer weiß wer weiß...

Hast mir auf jedenfall sehr geholfen!!! Danke

holzi
07.01.2009, 05:45
Guten morgen,
Deine 1 s ist viel zu gross. Das kostet doch nur Zeit. Schau mal hier
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=44674&start=22
Hier habe ich eine Erklärung zur Einstellung der Zeit mit dem US geschrieben.
Wenn Dein Servo auf 90 Grad gehen soll, dann benutze doch einfach den Dreisatz.
Beispiel: 150 Servoschritte entsprechen 90 Grad
1 Servoschritt entspricht X Grad
==> X Grad = 90Grad / 150 Servoschritte
Auf diese Art und Weise kannst Du dann jeden beliebigen Winkel ansteuern.

Peter

easyprivate
07.01.2009, 16:19
ja,verstehe eure Bedenken in Sachen Zeit und Winkel des Servos ;-)

Nur besteht mein Problem ausschließlich darin das ich nicht weiß wie ich das ganze im Code umsetzen soll....!!!
Funktioniert es so? Das "Entfernung < 30" kann doch nicht sein oder?


IF Entfernung < 30
THEN
Servo(1) = 100
END IF


Gruß,Easy

PicNick
07.01.2009, 16:22
Na, ist die Frage, was soll sein, wenn die Entfernung >= 30 ist ?


IF Entfernung < 30
then
servo[1] = 100 ' links
ELSE
servo[1] = 150 ' mitte
ENDIF

easyprivate
07.01.2009, 16:34
mensch du bist immer schnell mit antworten ;-)
naja im prinzip bräuchte ich eine schrittkette mit zwei wegen zur abarbeitung...

weg A: Der Bot geht stur gerade aus (servos werden nach und nach abgearbeitet)

weg B: Wenn Entfernung kleiner 30cm unterbricht "weg A" und leitet eine drehung nach links um 90° ein...

Ich weiß nicht wie ichs richtig erklären soll... hoffe du weißt was ich meine ;-)

PicNick
07.01.2009, 17:03
Was ich eben nicht weiss, ist, was denn die Servos normalerweise tun, und auf welche Weise du deine Spinne zum gehen oder drehen bringst.

Angenommen, die hast für jeden Seite der Spinne 3 Servos, dann pendeln die ja alle von 100-200, natürlich zeitlich versetzt, je nach Schrittfolge.
Wenn du nun nach links drehen wolltest, könntest du nun die linken servos z.b. nurmehr von 145-155 oder gar 150-150 bewegen.
Was du (in diesem Fall) bei einer Entfernung < 30 machen würdest, wäre, einfach die LIMITs der Servos zu verändern, bis etwa 90 Grad erreicht sind.

easyprivate
07.01.2009, 19:20
ja genau so möchte ich das machen... nur wie realisiere ich das per code?

Der Befehl um die Entfernung kleiner 30cm einzubinden fehlt mir einfach... Dieses IF Entfernung > 30cm ist ja nicht der "original" Befehl...?!?

oder würde es so gehen:
###"normales gehen"###
IF Entfernung < 30cm (größer)
Then
Servo(1) = 100
Waitms 100
Servo(2) = 100 usw usw usw
END IF

###"drehen"###
IF Entfernung > 30cm (kleiner)
Then
Servo(1) = 166
waitms 100
Servo(2) = usw usw usw
END IF

LOOP

Weiß nur nicht ob so alle Bewegungen ausgeführt werden oder ob nach den ><30cm selektiert wird... :-({|=

PicNick
07.01.2009, 19:36
Wenn die Variable "entfernung" das cm-Ergebnis vomSRF10 enthält, dann ist


IF entfernung > 30
THEN

der "Original" Befehl.

aaaaaaber
Servo(1) = 100
stell das Servo nach links und dort bleibt es einfach stehen.
dadurch dreht sich ja der Hex nicht.
Ich stell mir aber vor, dass sich die Beine bewegen müssen ?

Hast du überhaupt schon ein Programm, mit dem der HEX einfach nur geradeaus geht ?



Btw: kennst du das ?
https://www.roboternetz.de/wissen/index.php/Spinnenbeine#Schrittfolge

easyprivate
08.01.2009, 14:06
Hi! Mit dem Servo(1) = 100 sollte nur ein beispiel sein... Ist im Programm natürlich anders... Ja kenne ich ;-) Werde das ganze mal probieren... Danke ;-)