PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RN-Control über RS232 mit PC komunizieren lassen (Vistual Basic)



robonooby
12.03.2011, 09:11
Hallo
ich hab mal ne frage. Hab mir jetzt die RN-Control bestellt und warte sehnsüchtig auf die Lieferung :)
nun möchte ich schonmal wissen ob es möglich ist über die RS232 Schnittstelle Daten zwischen der RN-Control und dem PC auszutauschen.
Konkret:
Ich will dass die RN-Control die Abstände der Sensoren an den PC weitergibt, daraufhin sollen diese am PC in meinem Programm, welches ich unter VB geschrieben hab, angezeigt werden.
Umgedreht sollen Befehle zum beispiel Motordrehzahl und Drehrichtung vom PC Programm an die RN Conrol gesendet werden und diese setzt das dann um.

Geht das? wenn ja wie? hat jemand vielleicht dazu nen beispielcode.

Frank
12.03.2011, 09:28
Ja das geht natürlich. Du brauchst nur RS232 Kabel und kannst dann Daten hin und herschicken. Wenn du keine serielle Schnittstelle hast, brauchst du zusätzlich USB-RS232 kabel, z.B. dies http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=73&products_id=230
Du musst dann halt für PC und für RN-Control ein kleines Programm schreiben das bei bestimmten Daten irgend was bestimmtes macht.

Wie Daten gesendet und mit PC empfangen werden, ist in den mitgelieferten Beispielen schon zu ersehen. Wie Daten vom PC zu RN-Control gesendet werden, dazu musst du hier in den Beiträgen und in RN-Wissen etwas stöbern.

Hilfreich beispielsweise:
http://www.rn-wissen.de/index.php/Joystick_am_PC_zur_Kontrolle_eines_Roboters
und
http://www.rn-wissen.de/index.php/Windows_Programm_zum_Steuern_des_AVR's#Weitergehen de_Tipps

robonooby
13.03.2011, 16:18
danke
das ist schonmal sehr hilfreich. denk damit werd ich jetzt klar kommen. ist ja eigentlich recht einfach. habs mir schwiriger vorgestellt^^
dann freu ich mich auf die RN Control :-)

robonooby
20.03.2011, 18:19
so ich hab das jetzt mal ausprobiert was im Wiki stand
aber irgendwie will der nicht so wie ich will^^

Also was ich machen will, ist Daten zwischen RN-Control und PC austauschen.
Also die RN-Control bekommt vom PC steuerbefehle und der PC bekommt Sensor werte von der RN-Control
und das alles soll per RS232 ausgetauscht werden.

Ich hab es jetzt hinbekommen dass die RN-Control daten an PC sendet aber in meinem Programm kommen die nur gestückelt oder nur teilweise an.
in Bascom kommt alles richtig an. Also muss das ja wohl an meinem Programm liegen aber ich find den Fehler nicht. Hab soweit alles so eingestellt wie in Bascom, also die Schnittstelleneinstellungen (Bautrate, Com1, usw)

und wenn ich vom PC an die RN-Control Daten senden will ging das bisher noch gar nicht. die pipst dann nur komisch.

Kann mir da jemand helfen?

Hier mal nen Ausschnitt aus dem Quellcode:
VB-Net:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim Licht, BlLicht, IRLicht As Integer
Dim DatenSenden As Boolean
Dim DatenEmpfangen As String
Dim AusgabeArr() As String

IRAbstand1 = 0
IRAbstand2 = 0
UAbstand1 = 0
UAbstand2 = 0
DatenSenden = False

MotorL = CInt(MoDrehzahl * MotorL / 100)
MotorR = CInt(MoDrehzahl * MotorR / 100)

If MotorL < 0 Then
prbUKetteL.Value = MotorL * (-1)
Else
prbUKetteL.Value = MotorL
End If

If MotorR < 0 Then
prbUKetteR.Value = MotorR * (-1)
Else
prbUKetteR.Value = MotorR
End If

Licht = Scheinwerfer
BlLicht = Blinklicht
IRLicht = IRStrahler
DatenEmpfangen = ""

'Daten vom COM Port empfangen
If SerialPort1.BytesToRead > 0 Then
Do
rtbFehlermeldungen.AppendText(Chr(SerialPort1.Read Byte)) 'Hier ist der Fehler. Man kann ja nicht zweimal Daten auslesen wenn sie schon ausgelesen sind^^
rtbFehlermeldungen.ScrollToCaret()
DatenEmpfangen = DatenEmpfangen & Chr(SerialPort1.ReadByte) & ";"
If SerialPort1.BytesToRead = 0 Then
Exit Do
End If
Loop
If chbRNSenden.Checked = True Then


'Werte aus Ausgabe Array den einzelnen Variablen zuordnen
IRAbstand1 = CInt(AusgabeArr(1))
IRAbstand2 = CInt(AusgabeArr(2))
UAbstand1 = CInt(AusgabeArr(3))
UAbstand2 = CInt(AusgabeArr(4))
Batteriestatus = CShort(AusgabeArr(5))
lblTempA.Text = AusgabeArr(6)
lblTempI.Text = AusgabeArr(7)
rtbFehlermeldungen.Text = rtbFehlermeldungen.Text & vbNewLine & AusgabeArr(0)

DatenSenden = True
End If
End If

AusgabeArr = message.Split(CChar(";")) 'empfangenen Text trennen und in ein String-Array speichern

If DatenSenden = True Then
'Daten über den COM Port RS232 an die RN-Control senden:
If SerialPort1.IsOpen Then 'folgenden Code nur ausführen wenn auch eine Verbindung besteht
SerialPort1.Write("Motorr" + (MotorR).ToString + Chr(13)) 'per RS232 die aktuelle Motordrehzahl für Rechten Motor senden ' " CHr(13) =Enter drücken"
SerialPort1.Write("Motorl" + (MotorL).ToString + Chr(13)) 'per RS232 die aktuelle Motordrehzahl für Linken Motor senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("Licht" + (Licht).ToString + Chr(13)) 'per RS232 der Scheinwerfer an aus senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("BlLicht" + (BlLicht).ToString + Chr(13)) 'per RS232 das Blinklicht an aus senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("IRLicht" + (IRLicht).ToString + Chr(13)) 'per RS232 der IR-Strahler an aus senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("SchildH" + (SchildPosH).ToString + Chr(13)) 'per RS232 das SchildHorizontal senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("SchildV" + (SchildPosV).ToString + Chr(13)) 'per RS232 der Schild Vertikal senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("Kamerapos" + (KameraPosition).ToString + Chr(13)) 'per RS232 der Schild Vertikal senden ' " CHr(13) =Enter drücken"

End If
DatenSenden = False
End If

lblIRAbstand1.Text = IRAbstand1 & " cm"
lblIRAbstand2.Text = IRAbstand2 & " cm"
lblUAbstand1.Text = UAbstand1 & " cm"
lblUAbstand2.Text = UAbstand2 & " cm"

KameraPosition = 0
SchildPosH = 0
SchildPosV = 0
MotorL = 0
MotorR = 0
End SubQuellcode RN-Control (Bascom)

'Microcontroller Einstellungen Definieren.
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000
$baud = 9600

...

'Hauptprogramm
Do
Taste = Tastaturabfrage()
If Taste <> 0 Then
Select Case Taste
Case 1
Empfangstatus = 0
Case 2
Empfangstatus = 1
Case 3

Case 4

Case 5
Print "Programm wurde abgebrochen"
Sound Portd.7 , 800 , 400
Exit Do
End Select
End If

Fehlermeldung = "Dies Ist Ein Test"
Irabstand1 = 20
Irabstand2 = 10
Uabstand1 = 500
Uabstand2 = 100
Batteriespannung
Batteriestatus = Spannung
Temperatura = 2
Temperaturi = 20

If Empfangstatus = 1 Then
Print Fehlermeldung
Print Irabstand1
Print Irabstand2
Print Uabstand1
Print Uabstand2
Print Batteriestatus
Print Temperatura
Print Temperaturi
Empfangstatus = 1 'Normal 0 aber zu testzwecken auf 1 umgestellt.
End If

If Empfangstatus = 0 Then
Data_available = Ischarwaiting()
If Data_available > 0 Then 'Wenn Daten da sind, dann...
Input "" , Inputstring
Motorr_empfangen = Instr(inputstring , "Motorr") 'Gibt den Motorwert des Substrings "Motorr" aus oder NULL wenn nicht gefunden
Motorl_empfangen = Instr(inputstring , "Motorl") 'Gibt den Motorwert des Substrings "Motorl" aus oder NULL wenn nicht gefunden
Empfangstatus = 1
End If

If Motorr_empfangen = 1 Then
Motorr_wert_string = Mid(inputstring , 2) 'Die erste stelle des Strings (Das Motorr) abschneiden
Motorr_wert_integer = Val(motorr_wert_string) 'String in Integer konvertieren
End If

If Motorl_empfangen = 1 Then
Motorl_wert_string = Mid(inputstring , 2) 'Die erste stelle des Strings (Das Motorr) abschneiden
Motorl_wert_integer = Val(motorl_wert_string) 'String in Integer konvertieren
End If
End If

Motorr = Motorr_wert_integer
Motorl = Motorl_wert_integer

Motorschalten

Ausgabe1 = Motorr * 4
Ausgabe2 = Motorl * 2

Motorr = 0
Motorl = 0
Sound Portd.7 , 10 , Ausgabe1
'Sound Portd.7 , 10 , Ausgabe2
Waitms 900
Loop
End

Neutro
20.03.2011, 18:59
Hast du die Fuse Bits auf externen Quarz umgestellt?
Falls nicht kommt da meistens nur irgendein Daten /Sonderzeichen Müll bei raus. Hast du das schon mal mit dem Bascom Terminal ausprobiert?

Gruß
Neutro

Edit: Wo liest du in deinem Bascom Prog. denn Die Daten die von der RS232 kommen ein? ich finde dairgendwie nix....:confused:

robonooby
20.03.2011, 19:24
ja das müsste umgestellt sein. also hab das so eingestellt wie im handbuch beschrieben.
Aber im Bascom Terminal kommt wie gesagt alles wunderbar an. Nur in meinem Programm eben nicht. da kommt nur zerhacktes an. also alles durcheinander und nicht so wie ichs gesendet hab. Zb bei "Dies Ist Ein Test" kommen nur buchstaben an. aber net alles.

direkt nachdem ich die anderen Daten versendet habe. also direkt unten drunter. wobei das durch ne if abfrage gesichert ist. also erst wenn alles erfolgreich weggesendet wurde geht er in empfang. wobei ich hier in dem oben Beispiel das erstmal deaktiviert hab. Sollang er nicht richtig sendet brauch ich auch nix empfangen^^

Edit: der Timer steht auf 1ms im PC-Programm
der Serial Port im PC-Programm hat folgende Eigenschaften:
Baudrate 9600
DataBits 8
DiscardNull: falls
DtrEnable False
Generate Merr True
Handshake None
Parity None
Parity Replace 63
Port Name COM1
ReadBufferSize 4096
ReadTimeout -1
RecivedByte 1
RtsEnable False
StoptBits one
WriteBufferSize 2048

Neutro
21.03.2011, 15:53
Vielleicht ist die 1ms etwas zu klein bemessen, vergrößere den Wert doch mal auf 100ms und schau was dann so rauskommt.

robonooby
21.03.2011, 15:57
hmm hab ich auch schon probiert^^
also erst auf 250ms dann mal 1000ms aber beides nicht so das wahre. keine veränderung. aber normal wär das ja auch unlogisch weil der empfängt ja erst alles bevor er die schleife wieder von neuem anfängt wenn ich das richtig in erinnerung hab.
genauso beim senden.

EDIT:
hier mal das was ankommt:

De s i et
0
0
0
10
1

2
Porm ud berce
und das soll ankommen:


"Dies Ist Ein Test"
20
10
500
100
11
2
20
Programm abgebrochen

robonooby
21.03.2011, 18:22
EDIT: hab meinen Fehler gefunden.
ISt sogar eigentlich nen seehr dummer fehler^^

trotzdem danke

Neutro
21.03.2011, 20:09
Jetzt musst du aber auch schon sagen was es war, vielleicht ist es auch für andere
hilfreich.
Aber schön das es jetzt geht. Hattest du die Masse (GND) vergessen?

robonooby
22.03.2011, 14:51
ja natürlich sag ich noch was falsch war. aber es war auf jedenfall nicht GND^^

hab das oben im Quellcode schon angedeutet.
ich hab den Fehler gemacht in der Zeile:

rtbFehlermeldungen.AppendText(Chr(SerialPort1.Read Byte)) 'Hier ist der Fehler. Man kann ja nicht zweimal Daten auslesen wenn sie schon ausgelesen sind^^
rtbFehlermeldungen.ScrollToCaret()
DatenEmpfangen = DatenEmpfangen & Chr(SerialPort1.ReadByte) & ";"einmal den SerialPort auszulesen und direkt ins Fenster zu schreiben
und dann gleich nochmal auszulesen um die werte in die variable zu schreiben.
somit hat er das erste zeichen ausgegeben das zweite in die variable geserzt und das dritte wieder ausgegeben und so weiter^^

also eigentlich nen dummer fehler.

Ich hab das jetzt so gelöst: (wobei das einlesen in die RN-Control noch nicht 100%ig funktioniert da noch Fehlermeldungen kommen)

Code vom PC Programm:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim Licht, BlLicht, IRLicht As Integer
Dim DatenSenden As Boolean
Dim DatenEmpfangen As String
Dim AusgabeArr() As String

'IRAbstand1 = 0
'IRAbstand2 = 0
'UAbstand1 = 0
'UAbstand2 = 0
DatenSenden = False

MotorL = CInt(MoDrehzahl * MotorL / 100)
MotorR = CInt(MoDrehzahl * MotorR / 100)

If MotorL < 0 Then
prbUKetteL.Value = MotorL * (-1)
Else
prbUKetteL.Value = MotorL
End If

If MotorR < 0 Then
prbUKetteR.Value = MotorR * (-1)
Else
prbUKetteR.Value = MotorR
End If

Licht = Scheinwerfer
BlLicht = Blinklicht
IRLicht = IRStrahler
DatenEmpfangen = ""

'Daten vom COM Port empfangen
If SerialPort1.BytesToRead > 0 Then
Do
'DatenEmpfangen = SerialPort1.ReadLine
DatenEmpfangen = DatenEmpfangen & SerialPort1.ReadLine '& ";"

If SerialPort1.BytesToRead = 0 Then
Exit Do
End If
Loop
rtbFehlermeldungen.Text = rtbFehlermeldungen.Text & vbNewLine & DatenEmpfangen

AusgabeArr = DatenEmpfangen.Split(CChar(";")) 'empfangenen Text trennen und in ein String-Array speichern

If CDbl(AusgabeArr(0)) = 1 Then
If CDbl(AusgabeArr(9)) = 23 Then
'Werte aus Ausgabe Array den einzelnen Variablen zuordnen
IRAbstand1 = CInt(AusgabeArr(2))
IRAbstand2 = CInt(AusgabeArr(3))
UAbstand1 = CInt(AusgabeArr(4))
UAbstand2 = CInt(AusgabeArr(5))
Batteriestatus = CShort(AusgabeArr(6))
lblTempA.Text = AusgabeArr(7)
lblTempI.Text = AusgabeArr(8)
rtbFehlermeldungen.Text = rtbFehlermeldungen.Text & vbNewLine & AusgabeArr(1)
Else
MessageBox.Show("Der Startpunkt war falsch", "Warnung", MessageBoxButtons.OK)
End If
End If
DatenSenden = True
End If


If DatenSenden = True Then
'Daten über den COM Port RS232 an die RN-Control senden:
If SerialPort1.IsOpen Then 'folgenden Code nur ausführen wenn auch eine Verbindung besteht
SerialPort1.Write("Motorr" + (MotorR).ToString + Chr(13)) 'per RS232 die aktuelle Motordrehzahl für Rechten Motor senden ' " CHr(13) =Enter drücken"
SerialPort1.Write("Motorl" + (MotorL).ToString + Chr(13)) 'per RS232 die aktuelle Motordrehzahl für Linken Motor senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("Licht" + (Licht).ToString + Chr(13)) 'per RS232 der Scheinwerfer an aus senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("BlLicht" + (BlLicht).ToString + Chr(13)) 'per RS232 das Blinklicht an aus senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("IRLicht" + (IRLicht).ToString + Chr(13)) 'per RS232 der IR-Strahler an aus senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("SchildH" + (SchildPosH).ToString + Chr(13)) 'per RS232 das SchildHorizontal senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("SchildV" + (SchildPosV).ToString + Chr(13)) 'per RS232 der Schild Vertikal senden ' " CHr(13) =Enter drücken"
'SerialPort1.Write("Kamerapos" + (KameraPosition).ToString + Chr(13)) 'per RS232 der Schild Vertikal senden ' " CHr(13) =Enter drücken"

End If
DatenSenden = False
End If

lblIRAbstand1.Text = IRAbstand1 & " cm"
lblIRAbstand2.Text = IRAbstand2 & " cm"
lblUAbstand1.Text = UAbstand1 & " cm"
lblUAbstand2.Text = UAbstand2 & " cm"
prbBatterie.Value = Batteriestatus

KameraPosition = 0
SchildPosH = 0
SchildPosV = 0
MotorL = 0
MotorR = 0
End SubProgramm der RN-Control:

Do
Taste = Tastaturabfrage()
If Taste <> 0 Then
Select Case Taste
Case 1

Case 2

Case 3

Case 4

Case 5
Print "Programm wurde abgebrochen"
Sound Portd.7 , 800 , 400
Exit Do
End Select
End If

Fehlermeldung = "Dies ist Ein Test"
Irabstand1 = 20
Irabstand2 = 10
Uabstand1 = 500
Uabstand2 = 100
Batteriespannung
Batteriestatus = Spannung
Temperatura = 2
Temperaturi = 20

If Empfangstatus = 1 Then
Print 1 ; ";" ; Fehlermeldung ; ";" ; Irabstand1 ; ";" ; Irabstand2 ; ";" ; Uabstand1 ; ";" ; Uabstand2 ; ";" ; Batteriestatus ; ";" ; Temperatura ; ";" ; Temperaturi ; ";" ; 23
Empfangstatus = 0
End If


'Input "" , Empfang1 'Einlesen der Daten die vom RS232 Port gesendet wurdne
'Input "" , Empfang2
If Empfangstatus = 0 Then
Data_available = Ischarwaiting()
If Data_available > 0 Then 'Wenn Daten da sind, dann...
Input "" , Inputstring
Motorr_empfangen = Instr(inputstring , "Motorr") 'Gibt den Motorwert des Substrings "Motorr" aus oder NULL wenn nicht gefunden
Motorl_empfangen = Instr(inputstring , "Motorl") 'Gibt den Motorwert des Substrings "Motorl" aus oder NULL wenn nicht gefunden
Empfangstatus = 1
End If

If Motorr_empfangen = 1 Then
Motorr_wert_string = Mid(inputstring , 2) 'Die erste stelle des Strings (Das Motorr) abschneiden
Motorr_wert_integer = Val(motorr_wert_string) 'String in Integer konvertieren
End If

If Motorl_empfangen = 1 Then
Motorl_wert_string = Mid(inputstring , 6) 'Die erste stelle des Strings (Das Motorr) abschneiden
Motorl_wert_integer = Val(motorl_wert_string) 'String in Integer konvertieren
End If
Print Motorl_wert_string
Print Motorl_empfangen
Empfangstatus = 1
End If


Motorr = Motorr_wert_integer
Motorl = Motorl_wert_integer

Motorschalten

Ausgabe1 = Motorr * 4
Ausgabe2 = Motorl * 2

Motorr = 0
Motorl = 0
Sound Portd.7 , 10 , Ausgabe1
'Sound Portd.7 , 10 , Ausgabe2
Waitms 1
Loop
End

robonooby
26.03.2011, 14:37
so ich hab immer noch nen Problem^^
und zwar will das nicht so recht mit dem Übertragen von Daten vom PC auf die RN-Control funktionieren.
ich hab jetzt auch erstmal nen unabhängiges Programm geschrieben und genau diesen Code von dem Joystick Tutorial (http://www.rn-wissen.de/index.php/Joystick_am_PC_zur_Kontrolle_eines_Roboters) eingefügt. aber irgendwie kommen die daten net richtig an bzw nur teilweise.
ich weis aber auch nicht woran es liegen könnte.
wenn ich zum Beispiel den Wert X5000 an die RN Control Sende kommt nur 5 an
bei X1000 nur ne 1

kann mir da jemand helfen. wie gesagt ich habs eins zu eins von dem tutorial übernommen, nur dass ich die werte die er senden sollt über ein Textfeld manuell eingebe und dass er dies mit einem timer alle paar ms sendet bzw immer dann wenn nen button gedrückt wird.