Archiv verlassen und diese Seite im Standarddesign anzeigen : 3d Sensorboard CHR-6d Datenformat und Uart Geschwindigkeit
Hallo,
ich habe ein 3D Sensorboard CHR-6d
http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=71&products_id=221
Mit der software über meinen PC kann ich alle Werte sehen.
Wie sehen die Empfangenen Daten aus? Laut Datenblatt müssten die Daten Hexadezimal ausgegeben werden.
Das Hyper Termnal macht bei mir deshalb nur Hyroglyphen.
Hat jemand einen Bascom Codeschnipsel für mich, um diese Daten in normale ASCI Zeichensätze umzuwandeln und in verschiedene Variablen zu schreiben?
Vielen Dank Im vorraus.
Um die UART mit 115200 Baut zu betreiben benötigt man einen Quarz zB. einen 7,3728 MHz oder einen 18,432 MHz Quarz.
Meine neue Erkentnis ist, das das Modul binär sendet.
Wäre schön, wenn hier jemand seine Erfahrungen mit dem Moodul posten würde.
Guten morgen,
ich habe dieses Board auch hier. Funktioniert denn das alles mit dem mitgelieferten Programm?
Peter
Die Übertragung per UART ist immer binär, eine Abfolge von H und L - Pegeln, die für 0 und 1 als Bits stehen und die dann in der Regel ein Byte werden, dass dann beim AVR im UDR-Register landet.
im Datenblatt:
http://www.pololu.com/file/0J276/chr6d_datasheet.pdf
Seite 7 steht wie der Sensor seine Daten übermittelt, nämlich als Abfolge von mehreren Bytes als Message, die mit der Zeichenfolge ASCII "s" "n" und "p" beginnen.
http://www.torsten-horn.de/techdocs/ascii.htm
sprich im UDR-Register tauchen nacheinander die Bytes / Zeichen
"s" / 115
"n" / 110
"p" / 112 auf
dann dahinter die Daten.
Wie im Datenblatt beschrieben.
Hi,
Mit dem Programm kann ich alle achsen sehen.
Mit meinem alten xp Rechner funktionierte es nicht, da kam eine Fehlermeldung. Das hat mit directx und Java zu tun, soweit ich das verstanden habe.
Mit meinem Notebook mit windows 7 funktionierte es sofort.
Ich benutzte von myavr das uart to usb Modul.
Per Terminalprogramm bekam ich nur Hiroglyphen. Mit dem Serial Programm von Robotikhardware, das gleiche. Wenn ich auf Hex stelle, dann Zeigt er Hex werte an, ob die stimmen weiss ich nicht.
Es scheint, als ob das Terminalprogramm nicht weis, wann ein Datenpaket zu ende ist und wann das neue anfängt.
Es werden wohl auf keinen Fall Achsinformationen wie roll=WERT, accZ= WERT ausgegeben, sondern nur die Werte hintereinander weg.
hi Vitis,
danke für deine Nachricht.
Das eine UARt nur Binär senden kann ist ja logisch wo du mich mit der Nase drauf gestossen hast. O:)
Warum kann mann diese Abfolge dann nicht im Terminalprogramm sehen?
Da die Paketlänge vom Standart abweicht und von den gesendeten Kanälen abhängig ist. (Die Kanäle können mit dem Tool von CH Robotics einzeil abgeschaltet werden.)
Die Paketlänge besteht aus 7 + Gesendete Kanäle Bytes.
Somit ist eine klare Anzeige über ein Terminalprogramm nicht möglich.
Bitte berichtigt mich, wenn ich was falsches geschrieben habe.
Es soll ja später für alle eine korrekte Ausarbeitung sein.
Hier mal mein Code für das einlesen Per UART und Aufteilen des Strings in Bytes.
$regfile = "m8def.dat"
$crystal = 7372800
$baud = 115200
Dim E As String * 13 'Länge des Strings hier einstellen. Abhängig von den gesendeten Kanälen.
Dim Gyroz As String * 1
Dim Gyroy As String * 1
Dim Gyrox As String * 1
Dim Accz As String * 1
Dim Accy As String * 1
Dim Accx As String * 1
Dim Anfang As String * 1
On Urxc Onrxd 'Interrupt auslösen, wenn volsändiges Zeichen geladen.
Enable Urxc
Enable Interrupts
'------------------------------------------------------------------------
Do
Anfang = Left(e , 1) '1. Byte lesen
If Anfang = "115" Then 'Anfang des Datensatzes abwarten,damit nicht mittendrin in den String geschrieben wird.
E = ""
End If
If Len(e) > 12 Then 'wenn kompletter Datensatz geschickt, dann in einzelne Variablen aufteilen.
Gosub Werte
End If
Loop
Onrxd:
E = E + Chr(udr) 'neu empfangenes Byte anhängen
Return
Werte:
Gyroz = Mid(e , 5 , 1) 'String e wird in die einzelnen Werte verteilt.
Gyroy = Mid(e , 6 , 1)
Gyrox = Mid(e , 7 , 1)
Accz = Mid(e , 8 , 1)
Accy = Mid(e , 9 , 1)
Accx = Mid(e , 10 , 1)
E = ""
Return
End
Warum kann ich den auseinandergeschnittenen String nicht als Byte Dimensionieren? z.B: Gyroz?
Ist das abwarten bis ein p(115) gesendet wird so richtig?
If Anfang = "115" Then
E = ""
Wenn jemand etwas auffällt, bitte Posten O:)
Warum geht beim Nachricht schreiben der Scrollbalken in die Mitte dier Nachricht wenn die Nachrichtenbox voll geschrieben ist?
Das nervt gewaltig :evil:
Habs rausgefunden.
Internet Explorer 8 nur in der Kompatibilitätsansicht verwenden.
das wird so nicht funktionieren, da ja die Datenbytes alles Mögliche enthalten können, unter Anderem auch den Binärwert von s und p.
Das wird nur gehen wenn Du nen Ringpuffer verwendest, der mindestens 2mal die Paketlänge lang ist und dann quasi ne maske darüber schiebst.
Sprich erst schiebst Du "snp" über den puffer, wenn da eine Übereinstimmung ist wertest Du das Type-byte aus, ob Du dieses Paket überhaupt haben willst, dann liest Du die Paketlänge aus und hüpfst die angegebene Paketlänge über den Buffer und bildest die 2 angehängten checksummenbytes aus um das Paket auf Richtigkeit zu prüfen.
Dann und nur dann ist das ne gültige Message.
schau Dir mal Overlayvariablen und Array an.
du schreibst dann per urxc in den array und zählst den pointer hoch
also pseudocode
dim puffer(40) as byte
dim pufferstring as string*39 at puffer overlay
:uartempfang
incr pufferpointer
puffer(pointer)=udr
if pufferpointer>39 then pufferpinter=0
return
:auswertung
For Zaehler = 1 To 40
Zeichenpointer=Zaehler
If Puffer(zeichenpointer) = "s" Then
Incr Zeichenpointer
If Zeichenpointer > 40 Then
Zeichenpointer = Zaehler - 40
endif
If Puffer(zeichenpointer) = "n" Then
Incr Zeichenpointer
If Zeichenpointer > 40 Then
Zeichenpointer = Zeichenpointer - 40
End If
If Puffer(zeichenpointer) = "p" Then
Snp_erkannt_flag = Zeichenpointer
Else
Snp_erkannt_flag = 0
End If
else
Snp_erkannt_flag = 0
End If
else
Snp_erkannt_flag = 0
End If
Next
If Snp_erkannt_flag > 0 Then
Gosub Weiter_zur_auswertung
End If
return
irgendwie so halt
return
Ich benutze in einem Array 2 Zeiger. Den ersten Zeiger für aus dem UDR Register zu speichern und den 2. Zeiger um eine For next schleife zu benutzen um den Datensatzanfang zu finden. Ist der Datensatzanfang gefunden werden die Nachfolgenden 6 Bytes ausgelesen.
Wenn das Hauptrogramm beim USART Interrupt für ein neu angekommenes Zeichen anhält, kann es sein das sich das Schreiben und das Lesen im Array überschneidet, so das Datenschrott ausgelesen wird?
Im Prinzip ja, aber es wird kein Schrott heraus kommen, da ja der Pointer beim Speichern weiter läuft und der Interrupt die Programmausführung unterbricht.
Ausserdem macht es Sinn das Array nicht ständig zu prüfen sondern n Flag im URXC-Interrupt zu setzen und erst bei gesetztem Flag den Eingang zu prüfen in der Mainloop.
Wenn tatsächlich Datenmüll dabei raus kommt macht das garnix, weil ja die Prüfsumme nicht stimmt.
Du hast mich auf eine tolle Idee gebracht. Ich weiss ja aus wieviel bytes ein Datensatrz besteht. Durch den Flag aus dem URXC lasse ich eine anderes Byte hochzählen, bis die Anzahl der empfangenen Bytes eine Datensatzlänge entspricht.
Erst dann lese ich aus.
super, danke.
im prinzip kannst du das so machen, aber irgendwann wird mal der Datenbereich der Bytefolge "snp" entsprechen und die Geschichte kommt aus dem Tritt.
ich fürchte Du wirst schlussendlich nicht um die komplette prüfung herum kommen
kann mir jemand sagen wie die beiden Chk Bits errechnet werden?
Die Summe aller Bytes ohne den beiden Chk Bytes?
Wie ist der Inhalt der beinden Chk Bytes aufgeteilt?
Werden die chk Bytes addiert?
Achtung.
Bei der neuen Firmwareversion ist ein Kalman Filter vorhanden. Erst dann können Pich und Roll ausgelesen werden.!!!
Datenblatt wurde auch geändert!!!!
Mit der Imu Software zeigt mir der roll Wert bei liegender Platine (IC´s oben) einen Winkelwert von um die 200 an. Bei einer Nick Bewegung an einer bestimmten Stelle zwichen ein paar Grad, haut der Wert auf 40. Icht meine Platine defekt? Habe daraufhin das Firmwareupdate 2.0 installiert. Feher ist der Gleiche geblieben.Auch wenn ich die 200 als Null Wert nehme, ist die Veränderung zur Lage nicht richtig.
Der nick Wert liegt um die Null und zeigt recht genau die Winkelposition an. So sollte es auch sein. Kann ich in diesem Programm den roll Wert auch auf null setzen ?
Bin am verzweifeln.
Habe einen neuen Thread im Senor Bereich aufgemacht, da das jetzige Problem ja nichts mit Bascom zu tun hat.
Jetzt habe ich mal ein Mini Programm geschrieben, das mir die über UART empfangenen Daten rx über meinen ATMEGA über tx an ein Terminalprogramm weitergibt.
$regfile = "m168def.dat"
$crystal = 18432000
$baud = 115200
Dim Rxdflag As Bit
On Urxc Onrxd 'Interrupt auslösen, wenn volsändiges Zeichen geladen.
Enable Urxc
Enable Interrupts
Do
If Rxdflag = 1 Then 'flagauswertung bei empfangenen USART Byte
Rxdflag = 0
Print Udr
End If
Loop
Onrxd:
Rxdflag = 1
Return
End
Bekomme gerade aus meinem Atmega werte, die so nicht im CHR Datenblatt stehen.
Wenn ich meine Werte aus der udr einfach über die uart wieder ausgebe mit allen aktivierten achsen dann kommt das hier bei mir raus.
112
115
110
112
202
112
115
110
112
185
112
115
110
112
253
112
115
110
112
247
112
115
110
112
57
112
115
110
112
183
112
115
110
112
192
112
115
110
112
209
112
115
112, 115,110 ist laut Dateblatt "snp" der Datensatzanfang.
Danach kommen aber nur 2 Werte,dann wieder der neue Datensatzanfang.
Laut Datenblatt müsste snp, PT,N,alle Achsen also 8,und 2 Check Bytes gesendet werden.
merkwürdig...
Was mache ich falsch ?
kann mir keiner einen Tipp geben?
habe jetzt ein neues Programm mit overlay.
Wie suche ich im array jetzt den Datensatzanfang s n p ?
Schift funktioniert nicht.
Wenn ich den dsz verändere, veränder ich auch die Speicherstelle des neu empangenen Bytes.
Wie kann ich also meine overlay Maske auf dem String verschieben?
$regfile = "m168def.dat"
$crystal = 18432000
$baud = 115200
Dim Z As Byte
Dim I As Byte
Dim S As String * 24
Dim B(25) As Byte At S Overlay
Dim Dsz As Byte
Dim Check As Integer
Dim Ss As Byte At S(1) Overlay
Dim Nn As Byte At S(1) + 1 Overlay
Dim Pp As Byte At S(1) + 2 Overlay
Dim Pt As Byte At S(1) + 3 Overlay
Dim Num As Byte At S(1) + 4 Overlay
Dim Pitch As Integer At S(2) + 5 Overlay
Dim Roll As Integer At S(2) + 7 Overlay
Dim Gyroz As Integer At S(2) + 9 Overlay
Dim Chk As Integer At S(2) + 11 Overlay
On Urxc Onrxd 'Interrupt auslösen, wenn volsändiges Zeichen geladen.
Enable Urxc
Enable Interrupts
Config Lcd = 16 * 3 , Chipset = Dogm163v5
Config Lcdbus = 4 'configure lcd screen
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portd.7 , Db6 = Portd.6 , Db7 = Portd.5 , E = Portd.2 , Rs = Portd.3
Waitms 100
Initlcd
Waitms 100
Display On
Cursor Off Noblink
Cls
Do
'Check = Ss
'Check = Check + Nn
'Check = Check + Pp
'Check = Pt
'Check = Check + Num
'Check = Check + Pitch
'Check = Check + Roll
'Check = Check + Gyroz
If Dsz > 23 Then
'If Ss = 115 And Nn = 110 And Pp = 112 And Chk = Check Then
If Ss = 115 And Nn = 110 And Pp = 112 Then
Dsz = 0
Gosub Werteschreiben
Else
Shift S , Right ,1
End If
End If
Loop
Onrxd:
Incr Dsz
B(dsz) = Udr
Return
Werteschreiben:
Cls
Locate 1 , 1 : Lcd "gyroz= " ; Gyroz
Locate 2 , 1 : Lcd "Pitch= " ; Pitch
Locate 3 , 1 : Lcd "roll= " ; Roll
Return
End
schaue Dir einmal den INSTR Befehl an.
Gruß Richard
schaue Dir einmal den INSTR Befehl an.
Gruß Richard
Hallo Richard,
habe den befehl eingebunden.
Funktioniert aber leider so nicht.
Vitis hat mir noch den Tipp gegeben ein 2. overlay array einzubinden, um den gefundenen Datensatz komplett im 2. overlay zu zertrennen.
Das habe ich nicht hinbekommen.
Hier mal der neue Code:
$regfile = "m168def.dat"
$crystal = 18432000
$baud = 115200
Dim Z As Byte
Dim I As Byte
Dim S As String * 24
Dim B(25) As Byte At S Overlay
Dim Dsz As Byte
Dim Check As Integer
Dim Pos As Byte
Dim C As Byte
Dim D As Byte
Dim E As Byte
Dim F As Byte
'Dim Pitch As Integer At S(2) + C Overlay
'Dim Roll As Integer At S(2) + D Overlay
'Dim Gyroz As Integer At S(2) + E Overlay
'Dim Chk As Integer At S(2) + F Overlay
On Urxc Onrxd 'Interrupt auslösen, wenn volsändiges Zeichen geladen.
Enable Urxc
Enable Interrupts
Config Lcd = 16 * 3 , Chipset = Dogm163v5
Config Lcdbus = 4 'configure lcd screen
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portd.7 , Db6 = Portd.6 , Db7 = Portd.5 , E = Portd.2 , Rs = Portd.3
Waitms 100
Initlcd
Waitms 100
Display On
Cursor Off Noblink
Cls
Do
Zurueck:
If Dsz > 23 Then
Cls
Dsz = 0
Pos = Instr(s , "snp")
C = Pos + 6
D = Pos + 8
E = Pos + 10
F = Pos + 12
Dim Pitch As Integer At S(2) + C Overlay
Dim Roll As Integer At S(2) + D Overlay
Dim Gyroz As Integer At S(2) + E Overlay
Gosub Werteschreiben
End If
Loop
Onrxd:
Incr Dsz
B(dsz) = Udr
Return
Werteschreiben:
If Pos = 0 Then 'wenn pos =0 dann wurde snp nicht gefunden
Goto Zurueck
End If
Cls
Locate 1 , 1 : Lcd "Pitch= " ; Pitch
Locate 2 , 1 : Lcd "roll= " ; Roll
Locate 3 , 1 : Lcd "gyroz= " ; Gyroz
'Lcd "pos= " ; Pos
Return
End
Kann den code mal jemand für mich berichtigen?
So gibt mir das Display für alle 3 Werte 28275 aus mit ein paar Störungen zwischendurch.
Dim in der Programmschleife ist ja auch nicht so prickelnd oder?
Ich hätte nicht gedacht, das ich an dieser Sache so hängen bleibe.
das wird schon nix werden wegen dem Goto Zurueck da läuft Dir der Stack über weil Du ja per Gosub in die Subroutine springst.
Verbanne Goto aus dem Sprachschatz, das ist wirklich nur in ganz ganz wenigen Ausnahmen sinnig gebrauchbar.
Die DIM's gehören an den Anfang des Programms, das wird vom Compiler nur einmal gemacht, die IF davor wird niemals was ergeben zur Redimmensionierung der Variablen. Das ginge nur, wenn Du direkt auf das S-RAM per adressierung zugreifst.
Den Code berichtigen liefe auf das Schreiben eines neuen Codes hinaus ... mir persönlich zu viel Arbeit.
Mein Tip: geh nochmal ganz zum Anfang, besorge Dir ein gutes Buch über Bascom Programmierung und arbeite Dich dort Schritt für Schritt durch Programmstrukturen und Programmabläufe. Sorry, klingt hart, ist aber herzlich gemeint. Programmieren ist kein Rätselraten, sondern harte Arbeit vor allem am Anfang.
Goto sollte man verbieten, Gosub /return oder Call/return ist
allemal besser.Zuweisungen wie config oder Dim u.s.w. gehören immer ganz am Anfang, der Compieler reserviert da einfach nur Speicherplatz für die Variablen. Wenn Du diesen Speicherplatz später veränderst (wenn das überhaupt geht), überschreibst du vorher zugeordnete Adressen b.z.w. deren Inhalt!!!
Gruß Richard
Hi Vitis / Richard, okay goto streiche ich von meinem Befehlssatz.
Ich habe das Bascom AVR Buch von Roland Walter. Über sein Beispiel habe ich auch das Overlay Array aufgebaut. Ich habe das Buch bestimmt schon 4 x gelesen und auch fast alles verstanden. Ist sozudagen meine Bettlektüre bei jedem neuen Projekt, das ich starte.
Die geringe Beteiligung in diesem Thread durch andere Forumsmitglieder zeigt mir, das entweder dieses Thema (Overlay und bytes aus Strings in andere Variablen, Maskierung) bei vielen noch nicht so klar ist / nicht verstanden wurde (wie bei mir) oder
die Leute keine Lust haben zu antworten (Das ich mir nicht vorstellen kann)
Wenn ich fertig bin, werde ich auf jeden Fall den funktionierenden Code hier reinstellen, damit andere auch was davon haben.
Einfach nur die komplette Lösung bekomen behindert bei den meisten Leuten den Lernprozess. Ich selber will es ja auch verstehen.
Deshalb bin ich für jeden Tip dankbar.
Diese ganze STR "Sch****" ist auch zum Mäusemelken. :-(
Mit den Overlay habe ich mich auch noch nicht richtig befasst, ist auch irgendwie dämlich beschrieben. Ich teste neues immer möglichst klein gehalten bis ich den Sinn (hoffentlich) verstanden habe. Erst danach setze ich das zu einem Programm zusammen, ist übersichtlicher. :-)
Gruß Richard
ich hänge heute auch schon 4 studen dran und habe es ohne overlay zu Fuss nochmal versucht mir die einzelnen strings in bytes auf mein Display auszugeben.
nur mal ein auszug:
Pos = Instr(empfang , "snp")
Datensatz = Mid(empfang , Pos , 15) 'snp Datensatz 15er Länge komplett in einem String
Cls
astring = Mid(datensatz , 1 , 1)
Bb = astring
Locate 1 , 1 : Lcd Bb
aus dem array "empfang" den Anfang des Datensatzes finden, dann in einen neuen kleineren String "datensatz"übernehmen.
dann mit MID ein Byte in Astring übernehmen.
Astring in ein Byte umwandeln und ausgeben.
Ich habe so per Hand 8 werte auf mein Display gegeben, die sich aber nicht merklich ändern bei Bewegung der Platine.
Der 10. Wert ändert sich von 81 auf was anderem im Sekundentakt, das wars.
Ist es richtig das ich mit makeint aus 2 Bytes ein Integer zur anzeige machen kann?
So endlich gute Neuigkeiten. \:D/
Ich habe den Modus von Dauersenden (Broadcast mode) auf senden bei Nachfrage (Silent Mode) geändert.
Jetzt zeigt mit das Terminalprogramm auch alle bytes wie beschrieben an.
@Richard klein anfangen war ein guter Tipp.
Das Get_Data Packet, das geschickt werden muss, schicke ich mit printbin und sieht so aus:
115,110,112,1,0,1,82
s,n,p,PT,N,chksum,chksum
Im Datenblatt steht PT=0x01 (Mit dem Windows Rechner von Hex 01 nach Dez)
Die Checksum wird so errechnet: alle Werte addieren, die letzten(linken) 8 bit sind das 1. Checksum Byte und die anderen 8 Bit das 2. checksum Byte.
In diesem Fall 115+110+112+1=338
Zur Verdeutlichung:
338 sind Binär 1 01010010 = Letzte Byte 00000001 also 1= Dez 1 und
in das erste Byte 01010010 also 1010010 =Dez 82
Jetzt weiss ich wenigstens schonmal was da ankommt. Der Datensatz unterscheidet sich um 2 Bytes von der größeren chr6dm Platine!!!
Es muss ein Terminalprogramm verwendet werden, das auch dezimal ausgeben kann, sonst sieht man nur snp und danach Hyroglyphen.
Ich nehme das von Robotikhardware, war auf einer CD beim Funkboard dabei.
Hier meine Befehlsliste mit den Befehlen, die ich benötige.
Hier etwas neues.
Ich lasse erst nach Aufforderung senden.
Die Werte sehen auf meinem Display schon gut aus.
nur wenn der negative Wert zum ositiven Wert umschlägt ist er plötzlich sehr groß, kippe ich die Platine weiter sieht es wieder besser aus.
Mache ich da noch was mit den zusammengeführten einzelstrings was falsch?
Es soll einen complement Integer ergeben.
Hier mein Code:
$regfile = "m168def.dat"
$crystal = 18432000
$baud = 115200
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
Dim Z As Byte
Dim I As Byte
Dim Empfang As String * 14
Dim Nick As Integer
Dim Nicka As String * 1
Dim Nickb As String * 1
Dim Roll As Integer
Dim Rolla As String * 1
Dim Rollb As String * 1
Dim Gyro As Integer
Dim Gyroa As String * 1
Dim Gyrob As String * 1
'Dim Gyroc As String * 1
'Dim Roll As Integer
'Dim Gyro_z As Integer
On Urxc Onrxd 'Interrupt auslösen, wenn volsändiges Zeichen geladen.
Enable Urxc
Enable Interrupts
Config Lcd = 16 * 3 , Chipset = Dogm163v5
Config Lcdbus = 4 'configure lcd screen
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portd.7 , Db6 = Portd.6 , Db7 = Portd.5 , E = Portd.2 , Rs = Portd.3
Waitms 100
Initlcd
Waitms 100
Display On
Cursor Off Noblink
Cls
Do
Waitms 150
Printbin 115 ; 110 ; 112 ; 1 ; 0 ; 1 ; 82 'get data gesendet 115,110,112,176,1 =data complete
' Printbin 115 ; 110 ; 112 ; 3 ; 0 ; 1 ; 84 'GET_ACCEL_BIAS
If Len(empfang) > 13 Then
Cls
Nickb = Mid(empfang , 7 , 1)
Nicka = Mid(empfang , 8 , 1)
Nick = Makeint(nicka , Nickb) 'Aus beiden Strings ein Integer machen
Locate 1 , 1 : Lcd "Nick= " ; Nick
Rollb = Mid(empfang , 9 , 1)
Rolla = Mid(empfang , 10 , 1)
Roll = Makeint(rolla , Rollb)
Locate 2 , 1 : Lcd "Roll= " ; Roll
Gyrob = Mid(empfang , 11 , 1)
Gyroa = Mid(empfang , 12 , 1)
Gyro = Makeint(gyroa , Gyrob )
Locate 3 , 1 : Lcd "Gyro= " ; Gyro
Empfang = ""
End If
Loop
Onrxd:
Empfang = Empfang + Chr(udr)
Return
End
probier mal das:
Dim Empfang As String * 14
dim Nick as integer at Empfang+7 overlay
dim Roll as integer at Empfang+9 overlay
dim Gyro as integer at Empfang+11 overlay
und dann:
Cls
Locate 1 , 1 : Lcd "Nick= " ; Nick
Locate 2 , 1 : Lcd "Roll= " ; Roll
Locate 3 , 1 : Lcd "Gyro= " ; Gyro
ohne die makeint-geschichte dazwischen ... sollte aufs gleiche ergebnis heraus kommen nur praktisch ohne Rechenzeit und stringkopiererei
der Gag bei Overlayvariablen ist, dass sie auf die gleiche Speicheradresse verweisen, auf die bereits eine Variable verweist.
Warum das von Vorteil ist? Der Code wird kleiner und daher auch schneller.
In Deinem Beispiel bremst das LCD die Geschichte noch aus, aber Du wirst das Ding ja auch für was Anderes verwenden wollen und da können dann µs an Ausführungszeit schon entscheidend werden.
Beispiel:
dim irgendeinstring as string * 5
dim eine_byte_variable as byte at irgendeinstring+3 overlay
an der dritten Stelle des Strings kann ich nun auch per eine_byte_variable direkt auf das Byte zugreifen. Damit ändert sich natürlich der String an der Stelle. Andersherum aber auch, wenn der String sich ändert wird auch das byte geändert.
irgendeinstring="xx1xx"
dann steht in eine_byte_variable das ASCII-Zeichen "1", also der Bytewert 49
schreiben wir nun
eine_byte_variable=50
dann steht in dem String nun "xx2xx"
Die Oberlayvariablen sind so ziemlich das Genialste an Bascom überhaupt.
Wie man in Deinem Beispiel sieht. Man kann den String einfach aneinanderreihen
und dann die beliebigen Elemente herauspicken praktisch ohne Code.
Anderes Beispiel.
Ich verwende in einer Anwendung einen externen AD-Wandler mit 16 Bit.
Diese 16 Bit überträgt er als 2 Bytes.
Ich gehe nun hin und schreibe die 2 Bytes ins S-RAM und lege eine Word-Variable
als Overlay drüber.
Nun kann ich an jeder Programmstelle direkt mit der Word-Variable arbeiten
ohne vorher jedes mal die Bytes zusammen zu setzen.
Hi Vitis, okay jetzt habe ich die overlay Geschichte richtig verstanden.
Jetzt, wo ich den Datensatzanfang immer an gleicher Stelle habe, ist es ja auch so zu verwenden.
Nur zum weiteren Verständnis als der Datensatz im doppelt so großen Array irgendwo stand und ich
dim Nick as integer at Empfang+7 overlay +korrektur
berechnen musste, würde denn der Korrekturwert trotzdem richtig übernommen, da er sich ja pro Datensatzanfangsuche ändert und nur am Anfang des Programmes einmal der Speicher dimensioniert wird?
Ich habe mir nen Wolf gesucht, wie ich das Integer am besten befülle.
Werden im Integer die Bytes komplementär in richtiger reihenfolge geschrieben? Wäre ja blöd wenn nicht. Ich werde es auf jeden Fall morgen ausprobieren.
Danke, dachte du hättest mich als hoffnungslos abgeschrieben, nach der Kauf dir nen Buch Aufforderung von dir.
mit dem doppelten array war der Empfangspuffer gemeint.
Meine Intension war, die Zeichenfolge zu suchen und bei korrekter Syntax die Message kopieren in ein zweites Array. Daraus ergibt sich dann, dass die entsprechenden Nutz-Werte immer an der gleichen stelle stehen. So kannst Du mit den Overlays die Werte direkt verarbeiten.
Zur Buchempfehlung ... naja, das Programm oben war einfach Murks, sorry.
Wenn ich in 5 Zeilen Code nen goto sehr gehn bei mir die Lichter aus.
Morgen Vitis,
habe jetzt das Programm mit overlay geschrieben.
Ich habe große Sprünge in der Ausgabe, deren Abhängigkeit ich nicht zuweisen kann. Ich vermute das Die Bytes falsch herum in das Integer geschrieben werden. Ich habe testweise aus dem Integer ein byte gemacht, um mir den Einzelnen Wert in Abhängikeit des Winkels anzusehen.
Das 7. Byte ist das Hibye, das 8. das lowbyte. Das Lowbyte wird mir am Display in Abhängikeit des Winkels schön angezeigt.
Da muss ich nochmal schauen.
Gibt es da einen Trick, die Bytes zu drehen?
Ich werde heute Abend mal versuchen in 2 Bytes zu schreiben und das
Highbyte *1000+lowbyte in ein integer schreiben.
funkheld
30.09.2010, 09:40
Ihr müsst ziemlich genau die 3,3 Volt einhalten, sonst haut es nicht hin.
Auch die 115000baud sind sehr kritisch.
Vielleicht lässt sich am Gerät die baudweite runterregeln per software.
3,3 Volt sind per Spannungsregler und 4 Kondensatorern gegen schwingen bei mir verbaut. Der Mega 168 läuft auf 5 Volt. Die CHR Platine soll 5 Volt kompatibel sein. Ich benutze einen externen Quarz 18, xxxMhz mit 0% Error Rate für diese hohe Baud Rate. Meinst du der Mega schafft es nicht fehlerfrei durch den Interrupt ausgelöste Berechnungen bis zum nächsten Interrupt abzuschließen?
funkheld
30.09.2010, 12:35
Veruch mal eine weile mit normalen Printbefehlen in dieser Geschwindigkeit (115000)TextDaten zu übertragen/einzulesen um zu sehen, wie die aussehen.
funkheld
30.09.2010, 12:37
...Das Lowbyte wird mir am Display in Abhängikeit des Winkels schön angezeigt....
und wenn du 343 Grad hast, wo bleibt der Rest?
Die Printbefehle sehen normal aus. Es Ist ja nur snp zu lesen und dann kommen irgendwelche Zeichen (weil ASCII). Die Zeichenlänge ist annähernd gleich.
Der Filter kann nur bis unter 90 " verwendet werden.
Die Einzelbytes habe ich mir angeschaut, um zu sehen, ob sich der Wert wenn auch nur eingeschränkt richtig sichtbar ist. Und das ist er, man kann ihn schön bis 255 hochzählen lassen. Somit gibt es kein Array Speicherprobblem wegen zu hoher datenrate/zu langsame Verarbeitung.
Die Printbefehle sehen normal aus. Es Ist ja nur snp zu lesen und dann kommen irgendwelche Zeichen (weil ASCII). Die Zeichenlänge ist annähernd gleich.
Der Filter kann nur bis unter 90 " verwendet werden.
Die Einzelbytes habe ich mir angeschaut, um zu sehen, ob sich der Wert wenn auch nur eingeschränkt richtig sichtbar ist. Und das ist er, man kann ihn schön bis 255 hochzählen lassen. Somit gibt es kein Array Speicherprobblem wegen zu hoher datenrate/zu langsame Verarbeitung.
Lade Dir mal H-Term herunter, das Terminal Programm kann alles anzeigen, benutze ich nur noch vor allem wenn ich nicht genau weiß was da so kommt. :-)
Gruß Richard
Hi Richard,
Ich habe ein gutes Terminalprogramm, wo ich mir die Daten in Dezimal anzeigen Lasse.
Das gesendete Paket besteht aus folgendem:
s,n,p,PT,N,D1,D2a,D2b,D3a,D3b,D4a,D4b,checksuma,ch ecksumb
......I...I..I...I.....I.............I............ .I............ I 2 checksum Bytes
......I...I..I...I.....I.............I............ .I GyroZ als 2 Byte komplementär Integer
......I...I..I...I.....I.............I roll als 2 Byte komplementär Integer
......I...I..I...I.....I Pitch als 2 Byte komplementär Integer
......I...I..I...I ein byte mit Infomationen, welche Kanäle gesendet werden(gleich)
......I...I..I Anzahl Daten Bytes
......I...I Paketart( Send Data)
......I snp SNP Datensatzanfang
Es wird auch immer in gleicher länge gesendet.
Mein Problem, denke ich könnten falsch zusammengesetzte Integer sein.
Die Bytes müssen ja folgendes ergeben.
höchstwertige Bit
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 = = 127 127
0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 = = 126 126
0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 = = 2 2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 = = 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 = = 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 = = −1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 = = −2 -2
1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 = = −127 -127
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 = = −128 -128
8-bit two's-complement integers 8-Bit-Zweierkomplement-Zahlen Contents
Mit dem Befehl:
dim Nick as integer at Empfang+7 overlay
gebe ich an ab 7. Stelle bis zur 8. den wert in ein Integer zu schreiben.
Kann ich die Byte Reihenfolge ändern?
Ich werde mich heute Abend nochmals an das Problem begeben.
Kann ich die Byte Reihenfolge ändern?
In Bascom gibt es dafür den SWAP Befehl, den gibt es auch in den meisten Asembler und in C soltte er auch vorhanden sein.
Gruß Richard
Der Swap Befehl funkrioniert nur mit 2 Variablen.
Dann müsste ich wieder 2 Bytes auslesen und diese in ein integr bringen.
Beim Auslesen des Byte overlays gleich in ein Integer wäre besser.
Der Swap Befehl funkrioniert nur mit 2 Variablen.
Dann müsste ich wieder 2 Bytes auslesen und diese in ein integr bringen.
Beim Auslesen des Byte overlays gleich in ein Integer wäre besser.
Ist ja auch sinnvoll. wenn Dein Artty lobyte,hbyte,lobyte,hbyte....
enthält und Du das ganze Arry Swappen würdest/könntest dann ist die komplette Reihenvolge "falsch herum".
Mit
Arry =a
swap a(1),a(2)
swap a(3), a(4)
Und danach als word overlay auslesen sollte es gehen? Kann das zur Zeit nicht testen, linux und Bascom mögen sich nicht so.....
Gruß Richard
Hi Richard,
supi klappt so.
Jetzt geht alles.
\:D/ \:D/\:D/\:D/\:D/\:D/\:D/\:D/\:D/\:D/\:D/\:D/
code folgt in Kürze.
kann auch sein, dass ich mich beim Übersetzen der mid-Befehle um ne Steller vertan hab, schonmal probiert die overlays eine Stelle nach rechts oder links zu schieben?
also die overlay +x um 1 zu erhöhen oder erniedrigen?
hi Vitis,
ja es muss um eine Stelle nach vorn (links) verschoben werden.
DerString geht von 1 bis x
Das Byte von 0 bis x
Ich habe immer wieder den Datensatz am PC mit dem Wert im Display verglichen. Dann kam ja noch das erste Datenbyte dazwischen, das nur die Aktiven Kanäle beinhaltet. Das war im Datenblatt sehr schwer zu erkennen.
Deshalb bekam ich nur Müll angezeigt.
Danach bekam ich in eine Kipprichtung die Werte anscheinend richtig und in der anderen Richtung kurz unter 0 gleich 32000 angezeigt.
Das swappen der Bytes war die Lösung.
Habe gleich die neue Jeti Fernsteuerung mit Telemetriesensor bestellt. Jetzt geht es mit Summensignal auswerten weiter. Der Empfänger kann mir dann auch Daten wie Akkuspannung, aktuelle Stromstärke und entnommene mAh zur Fernsteuerung auf ein Display zurücksenden.
Guten morgen,
micro99, du wolltest doch deinen Code hier veröffentlichen.
Ich möcht mir den Code einmal anschauen, da ich an einer Kamerasteuerung mit diesem Modul arbeite. Wäre nett von dir.
Peter
Hallo,
jetzt schlage ich mich mit diesem Sensor rum und habe meine Probleme damit. Der Datensatzanfang soll ja mit snp, in dez. 115 110 112, beginnen. Diesen Datensatzanfang gibt es aber nicht bei mir. Bei mir erscheint immer 115 110 187. Die 187 ist falsch.
18997
Kennt jemand von euch dieses Problem bzw. kann mir jemand einen Tip geben, was hier falsch läuft?
Schönen Abend noch
Peter
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.