SIM800L Handling

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Im serial0charmatch dimensionierst du eine globale Variable vom Typ String, Länge 30 Bytes, jedes mal.
      Das ist sinnlos, entweder lokal oder im Heeader global.

      Dann ist (mir) nicht klar, was Input verlangt. Ist es ein CR, ist es ein CR/LF? Bei nur CR steht das LF dann im nächsten Paket.

      Wenn du Softserial im Interrupt benutzt, ist dein ganzes Programm in der Zeit blockiert.
      Wenn ich die PC-Ausgabe richtig interpretiere, kommt da ein CR/LF - OK - CRLF hintereinander.
      Mit dem Softserial an dieser Stelle verschluckst du die Daten.
    • Pac-Man wrote:

      die I/O sind TTL tolerant
      In meinem Datenblatt zum SIM800L steht
      Power Supply: 3.4V bis 4.4V
      Nur wenn deine Stromversorgung in diesem Bereich liegt und auch die Periferie dementsprechend korrekt ist kann man davon ausgehen, dass das auch ordnungsgemäß funktioniert.
      Wenn du aber an den I/O-Ports eine andere Spannung anlegst (irgendwie mußt du ja deinen PC mit der Schaltung verbinden und diese Leitung mit höherer Spannung betrieben wird, kann das den Chip zumindest verwirren.
      Und selbst wenn der SIM800-Chip auf einem Modul mit Spannungsregler betrieben wird (ob es solche Module jetzt auch mit den SIM800 gibt weiß ich nicht) sind die I/O-Ports immer noch nicht wirklich in der Lage mit mehr als der maximalen UB umgehen zu können.

      Pac-Man wrote:

      Ja, genau. Aber wo kommen diese Zeichen her?
      Ganz einfach: Das Modul will den Text ERROR senden (tut das wohl auch), irgendetwas passt aber nicht an den Ausgängen oder die Baudrate passt nicht usw.
      und dein Terminalprogramm empfängt zumindest das erste Zeichen falsch und zeigt den Text dann eben so an wie es angezeigt wird.
      Ich habe jetzt nicht nachgesehen, meine mich aber zu erinnern, dass auch dieses Modul so etwas wie "AutoBaud" kann. Eventuell verschluckt sich ja da was.
      Auf der sicheren Seite ist man, mit einer fest eingestellten Baudrate korrekter Versorgungsspannung und auch korrekter Pegelanpassung.
    • Michael wrote:

      Das ist sinnlos, entweder lokal oder im Heeader global.
      Local geht nicht. Da kommt die Meldung:

      Error : 114 Line : 139 LOCAL only allowed in SUB or FUNCTION [INCOMING_DATA AS STRING * 30] , in File : C:\Users\Martin\BASCOM\Projekte\test1.bas
      Error : 31 Line : 140 Invalid data type [[0015] 0] , in File : C:\Users\Martin\BASCOM\Projekte\test1.bas


      Hab es jetzt mal in den Header verschoben.


      Michael wrote:

      Wenn ich die PC-Ausgabe richtig interpretiere, kommt da ein CR/LF - OK - CRLF hintereinander.
      Sehe ich auch, sollte ja so nicht sein.

      Mal grundsätzliche Frage zu Serial0charmatch:

      Der MC sammelt Daten die über Rx rein kommen und springt bei Bytematch = 13 zum Label Serial0charmatch:
      Dort lese ich dann alles mit "Input Incoming_data Noecho" was er empfangen hat aus. Ist das so richtig? Wie lösche ich dann den Puffer wieder? Mit Incoming_data=""?


      Zitronenfalter wrote:

      Ganz einfach: Das Modul will den Text ERROR senden (tut das wohl auch), irgendetwas passt aber nicht an den Ausgängen oder die Baudrate passt nicht usw.
      Das Modul sendet ERROR, der PC empfängt es auch richtig und zeigt es an. Die Frage ist ob der MC das richtig empfängt und dann Müll sendet oder ob er es schon falsch empfängt und dann eben diesen falsch empfangenen Müll weiter sendet.

      Die Baudrate ist bei allen drei Komponenten fest auf 9600. Deswegen hab ich ja den PC und den MC über die Dioden gekoppelt damit ich sehen kann was das Modul sendet. Das Modul sendet immer einwandfrei und der PC empfängt auch immer einwandfrei. Beim MC denke ich dass er schon Mist empfängt. Ich habe mal folgendes gemacht:


      Source Code

      1. 'Timer
      2. Anzeigen: 'Betriebsanzeige
      3. Timer1 = 34286 '49111 'Timer auf 1 sekunde
      4. Incr Sekunden
      5. Gosub Betriebszustandsanzeige
      6. Return
      7. Sub Betriebszustandsanzeige
      8. Toggle Led_0
      9. Print #2 , "Hi"
      10. End Sub
      Display All
      Mit dem Ergebnis dass ich jede Sekunde ein "Hi" empfange und das ohne irgendwelche Steuerzeichen sondern so wie es sein muss.

      Deswegen vermute ich das Problem bei Serial0charmatch:

      Gruß, Martin
    • Pac-Man wrote:

      '##################################### Serielle Kommunikation ####################################



      'Achtung!!!! Die Gegenseite darf nur CR anhängen!!!!!
      Serial0charmatch:
      Led_4 = 1
      Dim Incoming_data As String * 30
      Input Incoming_data Noecho 'Daten vom Buffer auslesen,

      Print #2 , Incoming_data

      Return
      Ist so deine Empfangsroutine?

      Ist es nicht so, dass bei einem Char-Match beim Empfang das Label Serial0CharMatch von Maschinensprache her aufgerufen wird?
      Da kann man nicht einfach mit Basic weiter machen. Man muss, da es sich um eine Unterroutine der ISR handelt, und man sich somit noch in der ISR befindet, die Register sichern und wiederherstellen, die man verändert.

      Die Befehle Pushall und PopAll könnten helfen.
      Und wie die Vorredner schon angemerkt haben, kann man in einem Unterprogramm, das keine Sub oder Funktion ist, keine Dim-Anweisungen schreiben. Und Local geht nur in Sub/Functionen.
      Print #2 geht an der Stelle auch nicht, da man in einer ISR ist.

      Dim in Header ist verschieben ist an der Stelle gut!

      Da du ja nur den Buffer auslesen willst, kannnst du das auch im Hauptprogramm machen.
      In der ISR also nur ein Flag setzen Etwa: Flag_NewData=True
      und das im Hauptprogramm abfragen.
      If Flag_NewData=True then
      Input Incoming_data Noecho 'Daten vom Buffer auslesen,
      Print #2 , Incoming_data
      Flag_NewDate=False
      End If
    • Pac-Man wrote:

      Wie lösche ich dann den Puffer wieder?
      Gar nicht. Er ist als Ring ausgelegt und braucht nicht weiter beachtet zu werden. Mit dem Input "merkt" er sich bis wohin gelesen wurde und gibt beim nächsten Input die darauf gefolgten Daten aus.
      Das Dim steht an seltsamer Stelle wird aber von Bascom so umgesetzt als würde es oben stehen.
      Hätte eine Lokale Variable dort einen Vorteil?
      Das Ganze "verschluckt sicht" an den beiden CR
      Nach dem ersten wird die Serial0charmatch: aufgerufen während das nächste schon kommt das dann aber nicht als solches erkannt werden kann.
      Weshalb Bytematch 13 ? Wäre 10 nicht besser allein schon das er arbeiten kann ohne das ein Zeichen dazwischen funkt?
      @mitch wäre ein Bytematch nosave möglich? Hier sichert er die Register und weigert sich ein nosave zu akzeptieren.
    • Pluto25 wrote:

      @mitch wäre ein Bytematch nosave möglich? Hier sichert er die Register und weigert sich ein nosave zu akzeptieren.
      Bei Bytematch wird die Routine direkt aus der ISR (von MCS.lib) as angesprugnen. Das ist mit Nosave dahingehend vergleichbar, weil keine register gesichert sind.
      Wenn man in der Routine serial0Bytematch, die ja von der ISR aufgerufen wird, in Basic was machen will, muss man vorher die Register sichern und danach wieder herstellen.

      Aber das funktioniert dann trotzdem nicht mit Print #2 in der isr.
      denn während der Print ausgeführt wird, kommen die nächsten bytes an, die aber unter den Tisch fallen, weil die ISR ja mit dem Print2 beschäftigt ist.

      Wenn ich solche Dinge mache, dann verwende ich immer einen Empfangsbuffer.
      Das Charmatch oder Bytematch kann man ja trotzdem machen, ist aber oft gar nicht nötig.

      Man prüft in der Hauptschleife einfach mit IsCharWaiting() ab, ob ein Zeichen bereits im Empfangsbuffer liegt.
      Und wenn ja, kann man einfach mit Input strVariable abfragen.

      ' Hauptschleife
      Do
      If IsCharWaiting()=True then
      Input strVariable
      End If
      Loop
    • Moin, weiß jetzt nicht was ich sagen soll. Hab gestern Nacht Eure Nachrichten gelesen. War recht spät. Hab dann nochmal die Tasten betätigt und war alles so wie vorher. Heute früh, Tasten betätigt und die Daten kommen so wie sie sein sollen. Keine Steuerzeichen mehr. Alles perfekt. MC und SIM800 waren die ganze Nacht in Betrieb. Selbst nach mehreren Resets und Powerdowns funktioniert es problemlos. Verstehe ich nicht.


      Mitch64 wrote:

      Da du ja nur den Buffer auslesen willst, kannnst du das auch im Hauptprogramm machen.
      Hab ich nach Deinem Vorschlag gemacht.


      Source Code

      1. Do
      2. Debounce Handlebar_1 , 1 , Taster_1 , Sub
      3. Debounce Handlebar_2 , 1 , Taster_2 , Sub
      4. Debounce Handlebar_3 , 1 , Taster_3 , Sub
      5. If Flag_newdata = 1 Then
      6. Led_4 = 1
      7. Input Incoming_data Noecho 'Daten vom Buffer auslesen,
      8. Print #2 , Incoming_data ;
      9. Flag_newdata = 0
      10. End If
      11. Loop
      12. Serial0charmatch:
      13. Flag_newdata = 1
      14. Return
      Display All
      Läuft und ich werde mich mal weiter mit dem Modul beschäftigen.
    • Pluto25 wrote:

      Mitch64 wrote:

      in Basic was machen will, muss man vorher die Register sichern
      wozu ? Sie wurden gesichert, werden in der Isr nicht mehr benötigt und wiederhergestellt nach dem Return aus dem serial0Bytematch
      Darum: Siehe Bascom-Hilfe
      (Außerdem habe ich es oben schon 2x erklärt.)

      The optional BYTEMATCH can be used to monitor the incoming data bytes and call a label when the specified data is found. This label is a fixed label as mentioned in the table above. The label is called after the data is stored in the buffer.
      This way you can determine the start of a serial stream when you work with a unique header byte. Or you can determine when the data is received into the buffer when you work with a unique trailer byte.
      While bytematch allows you to trap the incoming data bytes, take care that you do not delay the program execution too much. After all the serial input interrupt is used in order not to miss incoming data. When you add delays or code that will delay execution too much you might loose incoming data.
      When using the BYTEMATCH option, you must preserve the registers you alter. If you do not know which one, use PUSHALL and POPALL.
      When using BYTEMATCH and CTS/RTS, do not print data in the bytematch routine to the same UART. This can disturb the communication when the output buffer becomes full.
      To clear the buffer, use CLEAR SERIALIN. Do not read and write the internal buffer variables yourself.
    • Weiter unten stehen Beispiele ohne Register (doppelt) zu sichern, sogar mit einem Print darin. Es funktioniert problemlos:

      Source Code

      1. Serial0ByteReceived:
      2. inputbin a
      3. Printbin #2, a
      4. Return
      hiermit habe ich eben 28k fehlerfrei übertragen. Im Moment laufen 760k drüber.
      Würde mehr als ein Byte gesendet könnte er sich natürlich "verhaspeln"
      Wieviel kann Hterm aufnehmen?
    • Hallo Pluto,
      ein Gegenbeispiel, wo es scheinbar funktioniert, ist ja kein Beweis, dass der Kommentar in der Hilfe nicht stimmt. Wenn du eine leere Mainloop hast dann kannst du in der ISR einen ganzen Roman schreiben, ohne dass da etwas passieren kann.
      Und nein, nach dem Return werden nicht alle Register gepoped, sondern nur die, die der Compiler für seine URXC ISR genutzt hat (R16,R23-R27). Dein Inputbin und Printbin nutzen noch R18 und R19. Die werden nicht gesichert.
    • Also zum streamen ist es nicht nützlich. :D Nach fast drei Stunden (fast 10 MB ohne Bytefehler) reicht es für gut 1,5 min Video. ;(
      Das ganze ist recht belastend so das die Main kaum dazu kommt ihre Arbeit zu verrichten. Hier hat sie es jedoch auch fehlerlos vollbracht. Jedoch eher zufällig. (R18/19)
      Da liegt Franz richtig :

      Franz wrote:

      nicht alle Register gepoped, sondern nur die, die der Compiler für seine URXC ISR genutzt hat
      Sollte diese "Unart" wirklich in einem Projekt genutzt werden muß das berücksichtigt werden.
      Für Testläufe ist es jedoch recht nützlich zu sehen was der Avr empfangen hat.
      Da wäre es auch nicht schlecht wenn das Pushpop 18/19 im Bascom Beispiel eingefügt wäre. (Oder ihr empfohlenes Pushpopall)
      Aber dort senden sie auch auf den selben Kanal wo weiter oben vor gewarnt wurde.

      Ich habs mal eingefügt: mit pushpop all schmiert er nach einigen hundert byte ab. a_28_2c02f089
      Mit R18/19 hat er die 22k richtig übertragen. :)

      The post was edited 1 time, last by Pluto25 ().

    • Hallo,

      habe das Programm jetzt umgeschrieben. Arbeite mit URXC. Soweit funktioniert es ja aber ich bin mir nicht sicher ob es so auch wirklich korrekt ist. Könnte bitte jemand mal drüber schauen ob ich wieder Mist gebaut hab? Die Vergangenheit hat mich gelehrt dass etwas nicht richtig sein muss obwohl es funktioniert.

      Gruß, Martin
      Files
      • test2.bas

        (8.11 kB, downloaded 7 times, last: )
    • Pac-Man wrote:

      wieder Mist
      Wenns läuft kanns kein großer Mist sein.
      Ein (fast) Ring wirds mit if n>=51 then n=0. Sollte kein 13 kommen läuft er sonst über und überschreibt die nachfolgenden Variablen. Auch möglich wäre if n>=51 then n=50 . Damit bleibt das zuerst gesendete erhalten.
      Schöner ist es b nicht größer als S zu maschen denn b(51) ist das Signaturbyte vom String wenn dort was anderes als 0 steht verhält sich der String seltsam.
      Weshalb 13 nicht 10?
      Die empfangenen Daten werden keine 0 enthalten? Anderenfalls wird S nur bis zu der 0 angezeigt;bzw es wird auch altes angezeigt weil die 0 nicht mitwandert:
      Beim s="" wird sie an erster Stelle gesetzt. Kommen nun Daten ist sie weg und S wird bis zur nächsten 0 angezeigt. Enthält also neben den neuen auch alte Daten. Ein b(n)=0 in der Hauptschleife vor dem Print wird das verhindern. (Damit verschwindet auch die 13 die beim Empangsgerät für Verwirrung sorgen könnte (13,13,10)
      Wenn nicht akuter Speichermangel besteht würde ich auf dim ... as Bit verzichten und stattdessen ein byte dimmen. Seine Abarbeitung ist schneller und es bleibt die Möglichkeit es zu gewichten.

      The post was edited 3 times, last by Pluto25 ().

    • Hi, danke für das Feedback.

      Pluto25 wrote:

      Schöner ist es b nicht größer als S zu maschen denn b(51) ist das Signaturbyte vom String wenn dort was anderes als 0 steht verhält sich der String seltsam.
      Ok, verstanden


      Pluto25 wrote:

      Weshalb 13 nicht 10?
      Bei 10 findet meine "Sub Auf_string_warten" nichts. Ist die überhaupt richtig so? Hab mir da einen abgebrochen...

      Source Code

      1. Sub Auf_string_warten(suchstring , Wartezeit , Fehler)
      2. Local Position As Integer
      3. Sekunden = 0 : Position = 0
      4. Do
      5. If Flag_gefunden = 1 Then
      6. Position = Instr(s , Suchstring)
      7. N = 0 : Flag_gefunden = 0 : S = ""
      8. End If
      9. If Sekunden > Wartezeit Then
      10. Flag_fehler = 1
      11. Call Fehler_behandeln(fehler)
      12. N = 0 : Flag_gefunden = 0 : S = ""
      13. Exit Sub
      14. End If
      15. Loop Until Position <> 0
      16. End Sub
      Display All

      Gibt es in Bascom so was wie "xxxx.contains(yyy)" nicht? Muss man das zu Fuß machen?


      Pluto25 wrote:

      Die empfangenen Daten werden keine 0 enthalten?
      Ich denke nicht. Das SIM800l betreibe ich im Text Modus. Sollte ich vorbauen z.B. mit "If UDR=0 then UDR=1" in der ISR?


      Pluto25 wrote:

      Ein b(n)=0 in der Hauptschleife vor dem Print wird das verhindern.

      Source Code

      1. Do
      2. Debounce Handlebar_1 , 1 , Taster_1 , Sub
      3. Debounce Handlebar_2 , 1 , Taster_2 , Sub
      4. Debounce Handlebar_3 , 1 , Taster_3 , Sub
      5. If Flag_gefunden = 1 Then
      6. 'For N = 0 To 50
      7. ' B(n) = 0
      8. 'Next N
      9. Print #2 , "Empfangen" ; S
      10. N = 0
      11. Flag_gefunden = 0
      12. S = ""
      13. End If
      14. Loop
      Display All
      Meinst Du so? Dann kann ich aber nichts mehr vom Modul Empfangen. Ich lösche ja die Nachricht vor dem Print.

      Warum finde ich damit

      Source Code

      1. If Flag_fehler = 0 Then Call Auf_string_warten( ">" , 2 , "Keine Antwort auf >")
      das ">" Zeichen nicht? Ich habe es so gelöst dass ich eben warte und hoffe das es kommt.

      Muss ich grundsätzlich auf eine Antwort vom Modul warten

      Source Code

      1. Print "AT" ; Chr(13); 'modul erreichbar?
      2. Call Auf_string_warten( "OK" , 1 , "Keine Antwort auf AT")
      oder kann ich einfach davon ausgehen dass bei bestimmten AT Kommandos auch die entsprechende Antwort kommt? Ich habe das Gefühl dass ich es zu kompliziert mache.

      Gruß, Martin
    • Pac-Man wrote:

      Sollte ich vorbauen z.B. mit "If UDR=0 then UDR=1" in der ISR?
      Wenn eine 0 nur druch einen Fehler entstehen kann ist das unnötig (Die Sendung wäre unbrauchbar, da ist es auch egal ob sie vielleicht länger war.)

      Pac-Man wrote:

      Ich lösche ja die Nachricht vor dem Print.
      Klar, nur eine 0 bei n. N ist die Position der 13. Sie ist das letzte Zeichen das empfangen wurde. Angenommen das Modul sendet (als erstes) "Hallo, ich bin wach[13]" dann ist das der innhalt von s und n=20
      Dann antwortet es "OK[13]" aber s wird "OK[13]lo, ich bin wach[13]" und n ist 3

      Pac-Man wrote:

      das ">" Zeichen nicht?
      findet es. Es sei denn keine 13 folgt. Was genau sendet das Modul?
      Ich hab sein Datenblatt mal überflogen: Es sendet > alleine als Meldung "kann weiter gehen"
      Das kann in der Onrxd abgefangen werden (Dim bereit as byte) if udr=$3e then bereit=1

      Pac-Man wrote:

      bei bestimmten AT Kommandos auch die entsprechende Antwort kommt?
      Meistens. Der Avr kann nicht alle Befehle und die entspechenden Antworten kennen. Aber er sollte schon (ab und zu :D ) auf das Mudul hören um zu wissen wies ihm geht. Würde alles in einem Rutsch ausgegeben wäre es kaum möglich den Fehler zu finden wenns dann nicht funktioniert. Selbst wenn das Modul zuhört während es spricht bezweifle ich das es auch alle Befehle richtig ausführt wenn es noch auf den "vorletzten" antworten muß.

      The post was edited 1 time, last by Pluto25 ().

    • Pac-Man wrote:

      Muss ich grundsätzlich auf eine Antwort vom Modul warten
      oder kann ich einfach davon ausgehen dass bei bestimmten AT Kommandos auch die entsprechende Antwort kommt? Ich habe das Gefühl dass ich es zu kompliziert mache.
      Hallo Martin,
      ich habe mit meinem SIM800 auch so angefangen wie du es jetzt machst. Teilweise auf Antworten warten, aber auch einfach ignorieren.
      Bei mir ist es die Überwachungsanlage fürs Haus und sie läuft immer und soll auf jede Menge Dinge reagieren und mich per SMS informieren.
      Je mehr Funktionalität ich integriert hatte umso komplexer wurde die Steuerung und sicherstellen, dass das Programm nicht etwas übersieht oder in eine Schleife gerät.

      Daraufhin habe ich dann das komplette Programm umgestellt.
      Es arbeitet jetzt als meine Implementierung eines Event Handlers mit einer klaren Trennung zwischen Erzeugen von Befehlen an das SIM Modul und Auswerten der Antworten.
      Ich bin nicht sicher, ob ich tatsächlich alle Antworten auswerte aber es sind schon ziemlich viele.
      Mit der jetzigen Konstruktion ist es wesentlich einfacher, Erweiterungen vorzunehmen ohne den Rest zu beeinflussen. Das war vorher kaum zu überschauen.
      Musst du dir mal überlegen, ist anfangs aufwendiger aber mit größer werdendem Programm sicherlich einfacher.

      Das gleiche Konzept übernehme ich jetzt für die Kommunikation mit einem HC-05, da das dort sehr ähnlich läuft.
      So hat sich die Entwicklung dann auch gelohnt.

      Viel Erfolg
      Franz
    • Pluto25 wrote:

      Es sendet > alleine als Meldung "kann weiter gehen"
      Das kann in der Onrxd abgefangen werden (Dim bereit as byte) if udr=$3e then bereit=1
      :thumbup: Mist, da hätte ich selbst drauf kommen können.



      Pluto25 wrote:

      Angenommen das Modul sendet (als erstes) "Hallo, ich bin wach[13]" dann ist das der innhalt von s und n=20
      Dann antwortet es "OK[13]" aber s wird "OK[13]lo, ich bin wach[13]" und n ist 3
      Verstehe. Dann würde ich beim Durchsuchen eventuell den Suchstring bei einer alten Nachricht finden.
      Kann ich das auch so lösen?

      Source Code

      1. Onrxd:
      2. If N > 51 Then N = 0
      3. Incr N
      4. B(n) = Udr
      5. If Udr = $3e Then Flag_text_senden = 1
      6. If Udr = 13 Then
      7. Flag_gefunden = 1
      8. B(n) = 0
      9. End If
      10. Return
      Display All
      Oder muss es jedes mal in S gemacht werden nachdem If Flag_gefunden=1 ?
      Muss das S="" dann überhaupt sein?



      Pac-Man wrote:

      Gibt es in Bascom so was wie "xxxx.contains(yyy)" nicht? Muss man das zu Fuß machen?
      Ich gehe mal davon aus dass es so was nicht gibt.

      Danke Pluto für Deine Hilfe!

      The post was edited 1 time, last by Pac-Man ().