- Akku Tests und Balkonkraftwerk Speicher         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 25

Thema: Stringkette bestimmter Länge über UART empfangen

  1. #11
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    12.02.2006
    Beiträge
    164
    Anzeige

    Praxistest und DIY Projekte
    ohhm das was ich verwende nennt sich eSLIP und war irgendwie mal der vorgänger von tcp/ip oder sowas (würde mir sowas nie selbst ausdenken, zuwenig drin in der birne)

  2. #12
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    ..zuwenig drin in der birne..
    *hehe* diese Sachen kann keiner erfinden.
    Die gibt's alle schon, da sind wir noch am Schnuller gehangen
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #13
    Erfahrener Benutzer Roboter Experte Avatar von marvin42x
    Registriert seit
    02.08.2005
    Ort
    Berlin
    Alter
    75
    Beiträge
    703
    Das besagte Netzwerkprojekt kann man sich hier etwas näher ansehen.
    http://www.marvins-lab.roboterbastler.de
    Hier entsteht eine Dokumentation die aber jetzt bereits einiges erhellendes zu bieten hat.

    Netter Gruß

    Ps. Sorry, bisschen Schleichwerbung muss schon sein
    Die ersten zehn Millionen Jahre waren die schlimmsten. Und die zweiten Zehn Millionen Jahre, die waren auch die schlimmsten.url

  4. #14
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    56
    Beiträge
    112

    Re: Stringkette bestimmter Länge über UART empfangen

    Zitat Zitat von Foooob

    Sobald das erste Zeichen reinflattert soll der AVR dieses entgegennehmen und so lange warten bis die übrigen 5 Zeichen ebenfalls gespeichert sind. Erst dann soll er den String auswerten. Und erst wenn dieser String ausgewertet ist soll der nächste entgegengenommen werden.

    Ich scheitere momentan vor allem daran, dass der AVR wirklich so lange wartet, bis er einen 6-stelligen String hat.
    .
    .
    .
    Hallo,

    mit nachfolgendem Code wartet der AVR zunaechst auf ein bestimmtes Zeichen oder eine Zeichenfolge. In meinem Beispiel horcht der AVR auf ein "a".
    Anschliessend liest der AVR die naechsten anstehenden Zeichen ein und speichert diese in die Stringvariable "zeichen".
    Das ganze ist eine Endlosschleife. Mit diesem Programmschnipsel habe ich erfolgreich in einem anderen Projekt die Daten einer GPS-Mouse (Koordinaten, Geschwindigkeit usw. ) eingelesen.
    Der Code basiert auf einem Beispiel aus dem Buch von Claus Kuehnel "Programmieren der AVR-Risc...") - na, kennt hier ja jeder...

    Code:
    $lib "glcdKS108.lib"
    $regfile = "m32def.dat"
    $crystal = 16000000
    $hwstack = 32
    $swstack = 20
    $framesize = 40
    $baud = 4800
    Config Graphlcd = 128 * 64sed , Dataport = Portc , Controlport = Portb , Ce = 1 , Ce2 = 0 , Cd = 4 , Rd = 3 , Reset = 2 , Enable = 5
    Config Serialin = Buffered , Size = 10
    Declare Function Read_string(byval T As Byte) As String
    Declare Sub Wait_for_string(byval S As String)
    Enable Interrupts
    Dim Zeichen As String * 6
    
    Setfont 6x8font
    Cls
    Lcdat 1 , 1 , "wait_for_string"
    
    Do
     Print "test"
     Call Wait_for_string( "a")
     
    'Zeichen = Read_string(8)
    
     Print "Alles wird gut"
     Lcdat 3 , 1 , "Zeichen a empfangen"
     waitms 500
    Loop
    
    End
    
    Sub Wait_for_string(byval S As String) As String
    Local Ii As Byte
    Local Cc As Byte
     Ii = 1
     M1:
     Cc = Waitkey()
     If Cc <> Mid(s , Ii , 1) Then
     Goto M1
     Else
      Incr Ii
     If Ii > Len(s) Then Goto M2
      Goto M1
     End If
    M2:
    End Sub
    
    Function Read_string(byval T As Byte) As String
     Local Cc As Byte
     Local Ss As String * 10
     Ss = ""
     Do
      Cc = Waitkey()
      Ss = Ss + Chr(cc)
     Loop Until Cc = ","
     Read_string = Left(ss , T)
    End Function
    
    $include "6x8font.font"

    Screenshot: http://www.elektronik-web.de/atmel/r...tforstring.gif

    Drahtigel: http://www.elektronik-web.de/atmel/roboternetz/wfs.jpg

    Vielleicht hilft es ja etwas weiter...

    Mit freundlichen Gruessen
    Digitali

  5. #15
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.03.2005
    Ort
    Ulm
    Alter
    36
    Beiträge
    519
    Danke für die Hilfe!
    Ich bin gerade dabei einen Code zu schreiben. Mir kamen auch einige gute Ideen dazu.

    Habe noch eine kurze (recht primitive Frage)
    Gibts in Bascom kein Ungleich??

    Ich würd gern ´ne While-Schleife machen bei der geprüft werden soll ob Udr ungleich "Y" ist, also sowas hier

    Code:
    While Udr ! "Y"
    ....
    Wend
    Aber weder ! noch not oder != funktionieren.
    Kennt sowas Bascom nicht? Kann doch nicht sein oder??

  6. #16
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    56
    Beiträge
    112
    In der Bascom-Hilfe unter Stichwort "Language Fundamentals" gefunden:


    ----schnipp----

    Relational Operators

    = Equality X = Y
    <> Inequality X <> Y
    < Less than X < Y
    > Greater than X > Y
    <= Less than or equal to X <= Y
    >= Greater than or equal to X >= Y

    ----schnapp----

  7. #17
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.03.2005
    Ort
    Ulm
    Alter
    36
    Beiträge
    519
    @ digitali
    Vielen Dank für die Hilfe!
    Deinen Code weiter oben habe ich mal analysiert und versucht nachzuvollziehen. Man! Der verwendet Schlüsselwörter die ich noch gar nicht kannte aber die einem das Leben echt vereinfachen ;-)

    Ich habe aber noch einige Fragen zu denen ich unter anderem auch in der Bascom-Hilfe und im Datasheet nix fand.

    1. Config Serialin = Buffered , Size = 10
    Ich schätze mal hier setzt du den Eingangspuffer für die RS-232 auf 10 Bytes. Ich dachte der ist bei jedem Mega fest eingestellt und kann nicht verändert werden? Oder etwa doch?

    2. Zeichen = Read_string(8)
    Darfste ja eigentlich nicht auskommentieren. Aber ganz eine andere Frage: Was bewirkt diese Zeile? Sie ruft die Funktion read_string auf und übergibt ihr den Parameter für die Länge des Strings (hier 8), richtig?
    Und die Zeile: Read_string = Left(ss , T) ist dann der Rückgabewert der Funktion read_string als String? Und dieser Rückgabewert ist dann gleich dem String Zeichen??
    Wieso ist dann aber Zeichen 6 Stellen lang? Müsste es nicht 8 sein? Da wir ja den String Ss bis zum 8. Zeichen von links "ausschneiden".

    3. Du schreibst Cc = ","
    Das heist das Komma ist das Endezeichen? Hier verwendest du aber im Gegensatz zu der Zeile weiter oben nicht das Chr(), also Chr(Cc) = "," Wenn ich auf ein Endezeichen im ASCI-Standard warte könnte/sollte/müsste ich dann Chr(Cc) = "," schreiben?

    Man, ich hätte glaub echt gleich von Anfang an die Dinger mit C programmieren sollen. Ich tu mir teilweise immer noch sehr schwer mit BASIC weil ich sonst immer nur mit C und C++ zu tun hab.

    EDIT: Ich habe das Programm auf mein Board angepasst aber noch nicht getestet, da ich erst den Code verstehen will.

  8. #18
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    56
    Beiträge
    112
    Zitat Zitat von Foooob
    @ digitali
    Vielen Dank für die Hilfe!
    Deinen Code weiter oben habe ich mal analysiert und versucht nachzuvollziehen. Man! Der verwendet Schlüsselwörter die ich noch gar nicht kannte aber die einem das Leben echt vereinfachen ;-)

    Ich habe aber noch einige Fragen zu denen ich unter anderem auch in der Bascom-Hilfe und im Datasheet nix fand.

    1. Config Serialin = Buffered , Size = 10
    Ich schätze mal hier setzt du den Eingangspuffer für die RS-232 auf 10 Bytes. Ich dachte der ist bei jedem Mega fest eingestellt und kann nicht verändert werden? Oder etwa doch?
    Also in der Basom-Hilfe Stichwort "config serialin" steht nichts von einem fest eingestellten Wert. Im Original-Programm stand der Wert auf 100.

    Zitat Zitat von Foooob
    2. Zeichen = Read_string(8)
    Darfste ja eigentlich nicht auskommentieren. Aber ganz eine andere Frage: Was bewirkt diese Zeile? Sie ruft die Funktion read_string auf und übergibt ihr den Parameter für die Länge des Strings (hier 8), richtig?
    Und die Zeile: Read_string = Left(ss , T) ist dann der Rückgabewert der Funktion read_string als String? Und dieser Rückgabewert ist dann gleich dem String Zeichen??
    Wieso ist dann aber Zeichen 6 Stellen lang? Müsste es nicht 8 sein? Da wir ja den String Ss bis zum 8. Zeichen von links "ausschneiden".
    Ich hatte es auskommentiert, weil ich keine weiteren Zeichen nach dem Empfang von "a" eingelesen hatte. Wollte nur ad hoc zeigen, dass zumindest das wait_for_string so schon mal funktioniert.
    Die Funktion read_string habe ich so aus dem Beispiel uebernommen und deren Werte auf die Schnelle nicht weiter angepasst. Sie liest dann die nachfolgenden 8 Werte ein und uebergibt diese der Stringvariable (die ich haette mit der Laenge 8 deklarieren muessen) "Zeichen".

    Zitat Zitat von Foooob
    3. Du schreibst Cc = ","
    Das heist das Komma ist das Endezeichen? Hier verwendest du aber im Gegensatz zu der Zeile weiter oben nicht das Chr(), also Chr(Cc) = "," Wenn ich auf ein Endezeichen im ASCI-Standard warte könnte/sollte/müsste ich dann Chr(Cc) = "," schreiben?
    Das Beispiel stammt, wie gesagt, aus einem Programm welches den Datenstrom einer GPS-Mouse einliest. Die einzelnen Werte innerhalb eines Datensatzes werden immer mit einem "," getrennt.
    Beispiel:
    $GPRMC,213926.206,V,0000.0000,N,00000.0000,E,,,140 606,,*18


    Mit freundlichen Gruessen
    Digitali

  9. #19
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.03.2005
    Ort
    Ulm
    Alter
    36
    Beiträge
    519
    Ich habe es gerade ausprobiert! Es funktioniert super!!
    Ich habs eben auch mit großen Datenmengen probiert. Bei ´nem Puffer von 10 Bytes hat er hin und wieder noch einen Fehler reingehaun. Jetzt hab ich den Puffer auf 100 gesetzt und die Sache klappt 1A, er verschluckt auch nichts mehr.

    Vielen Dank für den Code und die Erklärung zu meinen Fragen!

  10. #20
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    21.03.2005
    Ort
    Ulm
    Alter
    36
    Beiträge
    519
    Jetzt muss ich doch nochmal auf was zurückkommen...

    Ich würde das ganze gern als Interrupt ausführen, aber das funktioniert nicht, nur frage ich mich wieso....

    Wenn ich den Code nun so schreibe:

    Code:
    $regfile = "m128def.dat"                                    'ATmega128
    $crystal = 11059200                                         'Quarz: 11059200 Hz
    $hwstack = 32                                               'Hardware Stack
    $swstack = 32                                               'Software Stack
    $framesize = 32                                             'Framesize
    $baud = 9600
    
    Config Serialin = Buffered , Size = 100
    Declare Function Read_string(byval Stringlaenge As Byte) As String
    Declare Sub Wait_for_string(byval S As String)
    
    Dim Zeichen As String * 8
    
    Config Lcd = 20 * 4a , Chipset = Ks077
    Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Porta.4 , Rs = Porta.5
    Config Lcdbus = 4
    Waitms 100
    Initlcd
    Cursor Off
    
    Do
    
     Call Wait_for_string( "y")
     Zeichen = Read_string(6)
    
     Locate 2 , 1
     Lcd Zeichen
     Locate 3 , 10
     Lcd "Hallo"
    
    Loop
    
    '***BEGIN***********AUSLESEN DER RS-232********************
    Sub Wait_for_string(byval S As String) As String
    Local Startpunkt As Byte
    Local Empfangen As Byte
     Startpunkt = 1
    M1:
     Empfangen = Waitkey()
     If Empfangen <> Mid(s , Startpunkt , 1) Then
      Goto M1
    
     Else
      Incr Startpunkt
    
        If Startpunkt > Len(s) Then Goto M2
    
      Goto M1
     End If
    M2:
    End Sub
    
    Function Read_string(byval Stringlaenge As Byte) As String
     Local Empfangen As Byte
     Local Ss As String * 10
     Ss = ""
     Do
      Empfangen = Waitkey()
      Ss = Ss + Chr(empfangen)
     Loop Until Empfangen = ","
     Read_string = Left(ss , Stringlaenge)
    End Function
    '***ENDE***********AUSLESEN DER RS-232********************
    
    End
    Dann funktioniert das Auslesen der RS-232 problemlos, allerdings wartet mein Programm dann logischerweise immer an der Stelle Call Wait_for_string( "y") bis ein String reingeflattert kommt. Erst dann würde er das "Hallo" anzeigen.
    Das will ich jedoch nicht und so habe ich mir gedacht das einfach in einen Interrupt zu legen, der dann so ausschaut:

    Code:
    $regfile = "m128def.dat"                                    'ATmega128
    $crystal = 11059200                                         'Quarz: 11059200 Hz
    $hwstack = 32                                               'Hardware Stack
    $swstack = 32                                               'Software Stack
    $framesize = 32                                             'Framesize
    $baud = 9600
    
    Config Serialin = Buffered , Size = 100
    Declare Function Read_string(byval Stringlaenge As Byte) As String
    Declare Sub Wait_for_string(byval S As String)
    
    Dim Zeichen As String * 8
    
    On Urxc
    Enable Urxc
    Enable Interrupts
    
    Config Lcd = 20 * 4a , Chipset = Ks077
    Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Porta.4 , Rs = Porta.5
    Config Lcdbus = 4
    Waitms 100
    Initlcd
    Cursor Off
    
    Do
    
     Locate 2 , 1
     Lcd Zeichen
     Locate 3 , 10
     Lcd "Hallo"
    
    Loop
    
    '***BEGIN***********AUSLESEN DER RS-232********************
    Sub Wait_for_string(byval S As String) As String
    Local Startpunkt As Byte
    Local Empfangen As Byte
     Startpunkt = 1
    M1:
     Empfangen = Waitkey()
     If Empfangen <> Mid(s , Startpunkt , 1) Then
      Goto M1
    
     Else
      Incr Startpunkt
    
        If Startpunkt > Len(s) Then Goto M2
    
      Goto M1
     End If
    M2:
    End Sub
    
    Function Read_string(byval Stringlaenge As Byte) As String
     Local Empfangen As Byte
     Local Ss As String * 10
     Ss = ""
     Do
      Empfangen = Waitkey()
      Ss = Ss + Chr(empfangen)
     Loop Until Empfangen = ","
     Read_string = Left(ss , Stringlaenge)
    End Function
    '***ENDE***********AUSLESEN DER RS-232********************
    
    Onrxd:
     Call Wait_for_string( "y")
     Zeichen = Read_string(6)   
    Return
    
    End
    Nun zeigt mein AVR das "Hallo" an, allerdings wertet er keine Zeichenkette von der UART aus....nur wieso??? Denn das interessante kommt jetzt, wenn ich die Zeile Zeichen = Read_string(6) (und nur diese) wieder oben in Do...Loop reinhaue sieht man wieder dass er auf das Interrupt (korrekt) reagiert.

    Code:
    $regfile = "m128def.dat"                                    'ATmega128
    $crystal = 11059200                                         'Quarz: 11059200 Hz
    $hwstack = 32                                               'Hardware Stack
    $swstack = 32                                               'Software Stack
    $framesize = 32                                             'Framesize
    $baud = 9600
    
    Config Serialin = Buffered , Size = 100
    Declare Function Read_string(byval Stringlaenge As Byte) As String
    Declare Sub Wait_for_string(byval S As String)
    
    Dim Zeichen As String * 8
    
    On Urxc
    Enable Urxc
    Enable Interrupts
    
    Config Lcd = 20 * 4a , Chipset = Ks077
    Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Porta.4 , Rs = Porta.5
    Config Lcdbus = 4
    Waitms 100
    Initlcd
    Cursor Off
    
    Do
     Zeichen = Read_string(6)  
    
     Locate 2 , 1
     Lcd Zeichen
     Locate 3 , 10
     Lcd "Hallo"
    
    Loop
    
    '***BEGIN***********AUSLESEN DER RS-232********************
    Sub Wait_for_string(byval S As String) As String
    Local Startpunkt As Byte
    Local Empfangen As Byte
     Startpunkt = 1
    M1:
     Empfangen = Waitkey()
     If Empfangen <> Mid(s , Startpunkt , 1) Then
      Goto M1
    
     Else
      Incr Startpunkt
    
        If Startpunkt > Len(s) Then Goto M2
    
      Goto M1
     End If
    M2:
    End Sub
    
    Function Read_string(byval Stringlaenge As Byte) As String
     Local Empfangen As Byte
     Local Ss As String * 10
     Ss = ""
     Do
      Empfangen = Waitkey()
      Ss = Ss + Chr(empfangen)
     Loop Until Empfangen = ","
     Read_string = Left(ss , Stringlaenge)
    End Function
    '***ENDE***********AUSLESEN DER RS-232********************
    
    Onrxd:
     Call Wait_for_string( "y")
    Return
    
    End
    Nun nimmt er Strings von der RS-232 entgegen und gibt diese auch (fast) korrekt aus, allein das Startzeichen ("y") lässt er noch stehen aber das wäre ja nicht so wild. Nur dumm dass er jetzt erst wieder auf einen Rückgabewert der Funktion Read_string wartet und vorher nichts anderes macht.

    Aber mein Verstand steigt schon beim 2. Codebeispiel aus. Wieso führt der AVR beim Interrupt das nicht wie gewüscht aus? Ich habe doch die 2 auszuführenden Anweisungen lediglich vom Hauptprogramm ins Interrupt gelegt??

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress