PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : RS232 mit Variablen als Long-drehe hier noch durch



m@rkus33
18.01.2006, 11:54
Hallo zusammen,

ich drehe bald am Rad. Folgendes Problem:

Ich muss von einem Mega8 auf einen anderen über RS232 permanent Daten übertragen. Das Ganze wird als Array mit Starbit, 5 Nutzdatensätze, Checksum übertragen.

Das Problem ist: Die Nutzdatensätze können nicht alle als Byte definiert werden, da die Wertegrößen teilweise im Tausender Bereich liegen. Also sind die 5 Datensätze gemischt mit "Byte" und "Long" definiert.

Ich bekomme zwar die Daten gesandt, aber am Empfänger nicht ausgewertet. Habe schon etliche Versuche auch mit Hilfe mit veränderungen hinter mir. Nix geht.

Hier mal der Sendercode:




$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600

Dim Tank As Byte
Dim Eu As Word
Dim Tanum As Long
Dim Dfmimpulse As Long

Dim Stb As Byte
Dim C As Long
Dim B(5) As Long
Dim D As Long

'-----------------------------------------------------------------
'hier ist die Do-Loop mit dem Sammeln und schreiben der Daten
'sind alle Daten abgefragt folgt der Sprung ins Sub "Datensenden"
'-----------------------------------------------------------------


'------------------------------
'Sub Datensenden
'------------------------------

Datensenden:

Stb = 15 'Starbyte
C = 0
B(1) = Tank 'Wert von 1 - 20
B(2) = Eu 'Wert vom ADC 0-1023
B(3) = Tanum 'Wert von 0 - 10.000
B(4) = 55 'Testwert
B(5) = Dfmimpulse 'Wert von 0 - 90.000

For D = 1 To 5
C = C Xor B(d)
Next
Printbin Stb ; B(1) ; C

Waitms 250



Return



Und hier der Empfänger:




$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600

'----------------------------------------
'Hauptschleife Abfrage RS232
'---------------------------------------

D = 0
C = 0

Do


If Ischarwaiting() = 1 Then Gosub Empfang
If D = 7 Then Gosub Auswertung

'-------------------------------------
'Hier werden die Daten bearbeitet und am LCD visualiesiert
'--------------------------------------------

D = 0
C = 0



Loop

'----------------------------------------
'Subroutinen für RS232
'---------------------------------------

Empfang:
A = Inkey()
If D > 0 Then Goto Empfang2
If A = 15 Then Incr D
Return

Empfang2:
If D < 6 Then B(d) = A
C = C Xor A
Incr D
Return

Auswertung:
If C <> 0 Then
D = 0
C = 0
Return
End If

B(1) = Tank
B(2) = Euneu
B(3) = Tvnum
B(4) = Gosetup
B(5) = Dfmimpulse

D = 0
C = 0
Return




Was ist denn hier noch machbar? Gerade das Problem mit den Variablen die nicht als "Byte" definiert sind?


Gruß
Markus

Vitis
18.01.2006, 12:15
also im prinzip kannste keine pakete die länger als 8 Bit sind
einfach so per UART übertragen, das gibt die nicht her.
Du kannst aber deine Zahlenwerte zerlegen in Byte-Werte.

ich hab das bei mir mal so gelöst, indem ich ne bytevariable mit nem
integer-wert gleichgesetzt habe, dadurch wurden die unteren 8 Bit
in die bytevariable übernommen, der Wert verschickt, beim empfänger
ebenfalls erst in ne Bytevariable, dann in integervariable.
Dann die sender-integer-variable 8bit nach rechts geschoben (shift right),
wieder die unteren 8bit in bytevariable, verschicken, empfängerseitig
dann shift left 8 schritte, und die beiden byte dann in einer variable
zusammenführen ...

so gehts mit allen zahlenwerten, die nicht byteformat sind.
zerlegen, verschicken und wieder zusammensetzen.

m@rkus33
18.01.2006, 12:30
Hallo Vitis,

...ah ja...

Klingt logisch. Da ich aber Neuling auf dem ganzen Gebiet bin hab ich ehrlich keine Ahnung wie ich sowas realisiere. :-k Also das Zerlegen von Long-Variablen in Byte-Werte zerlegen und wieder zusammenführen.

Kannst Du mir mal ein Beispiel gegen? Wäre supernett.

Gruß
Markus

m@rkus33
18.01.2006, 19:00
also ich habe selber auch noch gesucht.

Frage: Wenn ich beim Sender das so mache wie hier und mit Starbyte und Checksum arbeite funktioniert das so?




$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600

Dim Header As Byte at &H0060 'feste SRAM Adresse zuweisen
Dim Tank As Byte at &H0061
Dim Eu As Word at &H0062
Dim Tanum As Long at &H0064
Dim Gosetup As Byte at &H0068
Dim Dfmimpulse As Long at &H0069

Dim Stb As Byte 'Startbyte
Dim C As Byte 'Checksum
Dim B(12) As Byte At Header Overlay 'der Bytestream der 12 Bytes
Dim D As Byte 'Zähler


'----------------
'Hauptschleife Daten sammeln, wenn alle da dann Sub und senden
'---------------------------

Datensenden:



Stb = 15
C = 0
B(12)
For D = 1 To 12
C = C Xor B(d)
Next
Printbin Stb ; B(12) ; C


Return


Beim Sender hab ich es so gedacht. Nur wie bekomme ich die Einzelnen Variablen wieder aus dem Byte- Stream raus??

Empfänger:




$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600
Dim Tank As Byte
Dim Eu As Word
Dim Tanum As Long
Dim Gosetup As Byte
Dim Dfmimpulse As Long

Dim A As Byte
Dim C As Long
Dim B(12) As Byte
Dim D As Byte

Do

If Ischarwaiting() = 1 Then Gosub Empfang
If D = 7 Then Gosub Auswertung
D = 0
C = 0

Loop


'----------------------------------
'Sub
'-----------------------------------
Empfang:
A = Inkey()

Locate 4 , 12
Lcd Chr(3)

If D > 0 Then Goto Empfang2
If A = 15 Then Incr D
Return

Empfang2:
If D < 13 Then B(d) = A
C = C Xor A
Incr D
Return

Auswertung:
If C <> 0 Then
D = 0
C = 0
Return
End If


????= Tank
???? = Euneu
???? = Tvnum
???? = Gosetup
???? = Dfmimpulse

D = 0
C = 0
Return





Das ausdrönseln der einzelnen Variablen aus dem Stream ist mir nicht klar.

Gruß
Markus

Vitis
18.01.2006, 21:49
such mal in der Bascom Hilfe nach SHIFT, LOW, HIGH, MAKEINT, MAKEBCD etc.

Du has mit den Long-Variablen nicht unbedingt ne gute Wahl getroffen
gehts nicht evtl. auch mit Integerwerten ?

m@rkus33
18.01.2006, 22:06
Ich werde mir das die Befehle mal anschauen.

Leider komm ich um die Long- Variablen nicht rum :(

Gruß
Markus

Rage_Empire
19.01.2006, 07:08
Zerleg doch dein Long in Bytes. Das kannst du ganz einfach mit "DIM.....at...overlay" Dann schickst du die Bytes rüber und dein Empfänger baut diese dann wieder zu Long.
Wir arbeiten nun mal mit 8-Bit systemen, da muß man sich eben was einfallen lassen ;-)

super_castle
19.01.2006, 07:16
schick alles als string rüber und zerlege es dann beim anderen avr, ist einfacher.

Castle

Rage_Empire
19.01.2006, 08:50
Einfacher vieleicht, weiß aber nicht wie es mit Resourcenverbrauch bei dieser Methode aussieht. Wenn du ein EEProm beschreiben willst, kannst du auch nicht alles in Strings umsetzen. Und zu dem braucht die Übertragung viel länger, wenn du alles in strings sendest, da du pro ziffer schon 8bit senden mußt.

Kann dir hierzu heute Abend evtl. einen Source geben.

m@rkus33
19.01.2006, 12:18
Hallo Rage_Empire

das mit Overlay.... ist das so wie in meinem Code oben bei Sender richtig?

Hab ich das so richtig verstanden??

Gruß
Markus

Vitis
19.01.2006, 13:03
Der Overlay ist im Prinzip recht simpel.
du definierst mehrere Variablen auf einen Speicherbereich.
Bildhaft wär in etwa so, wie wenn du in excel mehrere Zellen
verbindest auf eine Zelle zusammen.
Das wääre dann deine Long-Variable.
Nun legst du eine Maske aus x Zellen über deine verbundene Zelle.
Du kannst nachwievor den Inhalt der verbundenen Zelle als
ganzes betrachten aber in der Maske ist der Inhalt auf x Zellen
aufgeteilt, du kannst also jede ienzelne Zelle für sich auslesen
in Deinem Fall als Bytewert und den dann verschicken ...
hmmm ...

|--------------1 Longvariable ---------------|
Bytevaraiablen:
|---- 1 ----|---- 2 ----|---- 3 ----|---- 4 ----|

so in etwa. Wichtig dabei ist, das die Inhalte zusammengesetz den
eigendlichen Wert ergeben

Sorry, an der Overlay hab ich glatt nicht mehr gedacht, is aber n super tip!

Rage_Empire
19.01.2006, 13:04
Ja, aber du kannst es einfacher machen:

dim variable as long
dim bytes(4) as byte at variable overlay

und schon hast du alle 4 bytes im Arry.....dann noch:

for i=1 to 4
printbin bytes(i)
next i


und du sendest diese.....so ungefähr könnte man das machen.