Archiv verlassen und diese Seite im Standarddesign anzeigen : RS485 Empfang ohne Input/waitkey, und mit 0Byte
Lucky1001
18.12.2010, 14:41
Hallo, ich bin neu hier im forum, und habe auch erst gerade mit Bascom angefangen
Mein Projekt:
Ich möchte 30 Ladegeräte per RS485 Steuern/Abfragen
Die Geräte werden den Kommando K01 M(CR/LF) für Gerät 1 nach Messwerten gefragt, die Antwort ist denn ein 18 Zeichen langen string, der mit P01 ... anfängt.
Desweitern gibt es noch ander Kommandos, die aber erstmal nicht wichtig sind, es geht mir jetzt nur darum die Kommunikation herzustellen
also z.b.
Sende: K01 M(CR/LF)
Antwort: P01 VT-EEE-EEE-EEE(CR/LF)
Das Problem:
Es muss sichergestellt sein, das wenn ein Gerät gefragt wurde, und es nicht, oder Falsch antwortet (was durchaus vorkommen kann, z.b. Defekter Optokoppler im Gerät), das Programm nicht stehen bleibt, sondern das nächste Gerät abfragt.
Deshalb kommen wohl INPUT und WAITKEY nicht infrage weil sie warten würden, und INKEY wegen der 0 auch nicht ?! (wenn falsch bitte korrigieren)
Ich habe bereits eine LabView Anwendung geschrieben die die Geräte effizient Steuert/Abfragt, doch einige bereiche sollen jetzt in den Atmega ausgelagert werden um einen Ausfall das PCs mittelfristig zu überbrücken
Ich habe übrigens die möglichkeit die Aktivität auf dem Bus mit zu Logger und im Terminal zu sehen
Mein bisheriger code funktioniert, aber ich weis nicht wie ich die antwort anders empfangen könnte.
$regfile = "M88def.dat"
$crystal = 1000000
$hwstack = 100
$swstack = 100
$framesize = 100
Config Com1 = 4800 , Synchrone = 0 , Parity = Even , Stopbits = 1 , Databits = 7 , Clockpol = 0
Config Print = Portd.2 , Mode = Set
Config Pind.2 = Output
Led1 Alias Portb.0
Config Led1 = Output
Led2 Alias Portd.7
Config Led2 = Output
Led3 Alias Portd.4
Config Led3 = Output
Taster1 Alias Pind.5
Config Taster1 = Input
Taster2 Alias Pind.6
Config Taster2 = Input
Dim Test As String * 20
Do
Gosub Mess
If Len(test) = 19 Then
Led2 = 1
Else
Led2 = 0
End If
Loop
Mess:
Waitms 5
Print "K02 M"
Input Test Noecho
Return
schonmal vielen dank für eure Antworten ;-)
Wenn du von einem Gerät daten kriegst oder auch nicht, würde ich empfehlen,
1) mit "config serialin=buffered, .... " (-->bascom help) den Empfang asynchron (mit Interrupt) zu machen
2) parallel dazu einen Timer laufen zu lassen. Durch ein Zeitfenster kannst du erkennen, ob irgendein Gerät offensichtlich keine oder eine verstümmelte Antwort liefert
Hallo, ich bin neu hier im forum, und habe auch erst gerade mit Bascom angefangen
Mein Projekt:
Ich möchte 30 Ladegeräte per RS485 Steuern/Abfragen
Die Geräte werden den Kommando K01 M(CR/LF) für Gerät 1 nach Messwerten gefragt, die Antwort ist denn ein 18 Zeichen langen string, der mit P01 ... anfängt.
Desweitern gibt es noch ander Kommandos, die aber erstmal nicht wichtig sind, es geht mir jetzt nur darum die Kommunikation herzustellen
also z.b.
Sende: K01 M(CR/LF)
Antwort: P01 VT-EEE-EEE-EEE(CR/LF)
Das Problem:
Es muss sichergestellt sein, das wenn ein Gerät gefragt wurde, und es nicht, oder Falsch antwortet (was durchaus vorkommen kann, z.b. Defekter Optokoppler im Gerät), das Programm nicht stehen bleibt, sondern das nächste Gerät abfragt.
Deshalb kommen wohl INPUT und WAITKEY nicht infrage weil sie warten würden, und INKEY wegen der 0 auch nicht ?! (wenn falsch bitte korrigieren)
Ich habe bereits eine LabView Anwendung geschrieben die die Geräte effizient Steuert/Abfragt, doch einige bereiche sollen jetzt in den Atmega ausgelagert werden um einen Ausfall das PCs mittelfristig zu überbrücken
Ich habe übrigens die möglichkeit die Aktivität auf dem Bus mit zu Logger und im Terminal zu sehen
Mein bisheriger code funktioniert, aber ich weis nicht wie ich die antwort anders empfangen könnte.
$regfile = "M88def.dat"
$crystal = 1000000
$hwstack = 100
$swstack = 100
$framesize = 100
Config Com1 = 4800 , Synchrone = 0 , Parity = Even , Stopbits = 1 , Databits = 7 , Clockpol = 0
Config Print = Portd.2 , Mode = Set
Config Pind.2 = Output
Led1 Alias Portb.0
Config Led1 = Output
Led2 Alias Portd.7
Config Led2 = Output
Led3 Alias Portd.4
Config Led3 = Output
Taster1 Alias Pind.5
Config Taster1 = Input
Taster2 Alias Pind.6
Config Taster2 = Input
Dim Test As String * 20
Do
Gosub Mess
If Len(test) = 19 Then
Led2 = 1
Else
Led2 = 0
End If
Loop
Mess:
Waitms 5
Print "K02 M"
Input Test Noecho
Return
schonmal vielen dank für eure Antworten ;-)
Lese einmal......
http://www.rowalt.de/mc/avr/avrboard/06/avrb06.htm
Gruß Richard
Lucky1001
18.12.2010, 20:42
Danke euch beiden für die Antworten !
@PicNick, das mit dem Timer ist eine gute idee ! habe das jetzt mit eingebaut, und scheint auch zu laufen :-D
@Richard, das habe ich schon versucht (hab das buch von Roland Walter hier)
aber leider hatte ich damit keinen erfolg, wenn ich das so einbaue, wird mein ausgehenden string verstümmelt, es fehlen dann CR/LF ! vielleicht liegt es daran das ja ein Interrupt ausgelöst wird wenn der sendebefehl noch nicht ganz raus ist. Zur info, ich Arbeit mit R485 in Half Duplex
ich habe jetzt mal folgendes probiert, scheint soweit auch zu laufen, jedenfalls hängt das Programm micht mehr wenn keine Antwort kommt
$regfile = "M88def.dat"
$crystal = 1000000
$hwstack = 100
$swstack = 100
$framesize = 100
Config Com1 = 4800 , Synchrone = 0 , Parity = Even , Stopbits = 1 , Databits = 7 , Clockpol = 0
Config Print = Portd.2 , Mode = Set
Config Pind.2 = Output
Config Timer0 = Timer , Prescale = 1024
'Enable Timer0
'Enable Interrupts
'On Timer0 Ontimer0
Led1 Alias Portb.0
Config Led1 = Output
Led2 Alias Portd.7
Config Led2 = Output
Led3 Alias Portd.4
Config Led3 = Output
Taster1 Alias Pind.5
Config Taster1 = Input
Taster2 Alias Pind.6
Config Taster2 = Input
'-----------------------Dim's--------------------------------------------------
Dim Test As String * 20
Dim A As Byte
Dim Kreisz As Byte
Dim Adresse As String * 2
'----------------------Haubtschleife-------------------------------------------
Do
For Kreisz = 1 To 10 Step 1
Adresse = Str(kreisz)
Adresse = Format(adresse , "00")
If Len(test) >= 18 Then
Test = ""
Led2 = 1
Else
Led2 = 0
End If
Gosub Mess
Next Kreis
Loop
'------------------Messwerte anfordern-----------------------------------------
Mess:
Waitms 100
Print "K" ; Adresse ; " " ; "M"
Do
A = Ischarwaiting()
If A = 1 Then
Led1 = 1
A = Inkey()
Test = Test + Chr(a)
End If
Loop Until Len(test) >= 18 Or Timer0 = 200
Led1 = 0
Timer0 = 0
Return
Hallo,
hab grad den thread gelesen.
Mir fällt dazu folgendes ein:
Anstelle eines Timers kann auch das Statement $TIMEOUT verwendet werden. Einfach mal in der Basdcom-Hilfe dazu schauen.
Mitch.
ach so, einen Tip hab ich auch noch, anstatt eines Max485 oder LTC485, die man
aktiv zwischen Senden und Empfangen umschalten muss kann man auch
sehr oft aus dem CAN-Netz den PCA82C250 nehmen, da hat man die
Umschalterei aus dem Kreuz.
edit:
Die config Print Geschichte ist ganz nett, hab aber schon öfter festgestellt,
das beim Senden mitunter zu schnell zurück geschaltet wird, wodurch das
letzte Byte verstümmelt wird.
Das letzte Byte wird nicht verstümmelt, wenn man das Bit TXC im Register UCSRA abfrägt, ob der Transfer complet ist. Und erst dann wieder auf Empfang geht.
Das letzte Byte wird nicht verstümmelt, wenn man das Bit TXC im Register UCSRA abfrägt, ob der Transfer complet ist. Und erst dann wieder auf Empfang geht.
nix anderes passiert wenn man die config print anweisung verwendet.
aber je nach terminierung des bus kann ein zu schnelles freigeben
beim empfänger als bitfehler ... framing error ankommen.
ein paar µs wartezeit kann da wunder wirken.
Cool, den kannte ich nicht nicht.
Config Print muss ich mir merken!
Is doch mal ein schöner Tipp am Rande.
Lucky1001
23.12.2010, 13:48
Danke für eure hilfe,
Ich habe alle drei möglichkeiten ausprobiert, also mit timer, Timeout und interrupt, habs jetzt aber beim timer belassen, damit läuft es bis jetzt ganz gut !
ich habe hab noch eine andere frage:
Ich möchte den wert einer Integer Variable als HEX senden
die Variable hat dezimal den wert 2400 also in HEX 960 !
wenn ich es so schreibe, wird 0960 satt nur 960 gesendet, was der empfäger nicht versteht. wie kann man es anstellen das wirklich nur 960 ohne 0 gesendet wird ? mir würde nur einfallen den HEX wert in einen String zu wandeln und den zu stutzen, aber geht das nicht auch anders ?
Steuern:
Prozedur = Lad
S_adresse = "02"
Real_soll_u = 12
Real_soll_i = 1
Soll_u = Real_soll_u * 200
Soll_i = Real_soll_i * 80
Print "K" ; S_adresse ; " " ; Prozedur 'Prozedur Senden
Waitms 100
Print "K" ; S_adresse ; " " ; "U" ; Hex(soll_u) 'Spannung Senden
Waitms 100
Print "K" ; S_adresse ; " " ; "I" ; Hex(soll_i) 'Strom Senden
Waitms 100
Print "K" ; S_adresse ; " " ; "S" 'Sollwert Anfordern
Lucky1001
25.12.2010, 12:13
keiner ne idee?, kann ich mir nicht vorstellen O:)
und woher weis der Empfänger, dass nur 3 Zeichen den Wert darstellen?
Was ist, wenn ich 5000 als Wert übertrage? Das wäre Hex 1388. Woher weis das jetzt der Empfänger, dass 4 Zeichen den Wert darstellen und nicht 3?
Bist du sicher, dass als ACII übertragen wird und das in Hex-Schreibweise?
Ich kenne dein Protokoll nicht, deshalb ist das schwierig. Was wird als Endekennung für eine Übertragung verwendet?
Woher weis der Empfänger ob ein Sollwert oder etwas anderes kommt?
und woher weis der Empfänger, dass nur 3 Zeichen den Wert darstellen?
Was ist, wenn ich 5000 als Wert übertrage? Das wäre Hex 1388. Woher weis das jetzt der Empfänger, dass 4 Zeichen den Wert darstellen und nicht 3?
Bist du sicher, dass als ACII übertragen wird und das in Hex-Schreibweise?
Ich kenne dein Protokoll nicht, deshalb ist das schwierig. Was wird als Endekennung für eine Übertragung verwendet?
Woher weis der Empfänger ob ein Sollwert oder etwas anderes kommt?
Wenn ich so nen Käse lese ...
ACII übertragen wird und das in Hex-Schreibweise? ......
Es werden Bytes übertragen, das sind 8 Bit, in welcher Art die dargestellt werden ist doch komplett wurst. Ob sich der ANwender die Bytes als Bitfolge, oktal, dezimal, sedezimal oder als ASCII-String anzeigen lässt hat mit den übertragenen Bit und Byte nix zu tun.
Wenn der TO im Hyperterminal oder was weiß ich in welcher Terminalsoftware einen lesbaren Text erhält, der einigermaßen sinnig und schlüssig lesbar ist, dann wird das Übertragungsprotokoll mit hoher Wahrscheinlichkeit Klartext sein und keine Hex-Darstellung von Bytewerten eines Strings ....
[quote=Mitch64]
Wenn ich so nen Käse lese ...
ACII übertragen wird und das in Hex-Schreibweise? ......
Na ja, eine DWort Variable hat bei kleineren Werten in Hex halt führende Nullen. Wenn die nicht mit übertragen werden sollen muß man das DWort halt in Einzel Bytes zerlegen und führende "0" werte beim Übertragen überspringen. Wozu das auch immer gut sein soll? Ohne führende "0" kann man schnell vermuten das es sich um eine dezimal zahl handelt....
Gruß Richard
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.