German Paket Daten sammeln

Discussion in 'German Forum' started by MarkusR, Apr 11, 2019.

Tags:
  1. MarkusR

    MarkusR Well-Known Member Licensed User

    Irgendwie habe ich hier ein Denkfehler drin.

    Ich sammle Daten die aufeinanderfolgend rein kommen. (Serielle Schnittstelle)
    Eine Datenzeile besteht aus start tab wert new line
    Dieses Reihen möchte ich in eine Liste außer dieses New Line Zeichen sammeln.
    Beim verarbeiten gehe ich dann die Reihen durch und zerlege die nach Tab Zeichen
    und übertrage die Werte in eine Struktur.

    Manchmal kommt es vor das ich kein gültigen Wert habe wenn ich die Liste verarbeite, das verstehe ich nicht.

    Die andere Seite auf dem Arduino macht das hier:
    Code:
    String row = "start\t" + String(valuea);
    bt.println(row);
    Meine Klasse die die Daten sammeln soll und als Zeilen in die Liste fügt.
    Code:
    Sub Class_Globals

        
    Dim InputBuffer As String
        
    Public List As List
      
    End Sub

    'Initializes the object. You can add parameters to this method if needed.
    Public Sub Initialize
      
        InputBuffer = 
    ""
      
        
    List.Initialize
        
    List.Clear
      
    End Sub

    Public Sub Collect(Data As String)
      
        
    'Log("Collect: '" & Data & "'")
      
        InputBuffer = InputBuffer & Data

        
    Dim x,x1,x2 As Int
        x = InputBuffer.IndexOf(
    "start")
        
    If x > 0 Then InputBuffer = InputBuffer.SubString(x) 'mit start fängt die reihe an
      
        
    If InputBuffer.StartsWith("start") = False Then InputBuffer="" 'ungültiger anfang

        x1 = InputBuffer.IndexOf(
    "start")
        x2 = InputBuffer.IndexOf(
    CRLF)

        
    If x1>=0 And x2 > x1 Then 'mindestens eine reihe mit start und chr(10)
      
         
    Dim Row As String = InputBuffer.SubString2(0,x2) 'bis ohne Zeilenumbruch merken
         List.Add(Row)
      
         InputBuffer = InputBuffer.SubString(x2+
    1'kürzen vorne was ausgelesen wurde weg
      
         Collect(
    ""'das soll den Rest zerlegen 
        End If

    End Sub

    Public Sub Test
      
        Collect(
    "234234")
        Collect(
    "start" & TAB)
        Collect(
    "123")
        Collect(
    CRLF)
        Collect(
    "start" & TAB)
        Collect(
    "456" & CRLF)
        Collect(
    "start" & TAB)
      
        
    For Each Row As String In List
            
    Log(Row)
        
    Next

        InputBuffer = 
    ""
        
    List.Clear
          
    End Sub
     
    Last edited: Apr 11, 2019
  2. DonManfred

    DonManfred Expert Licensed User

    Was ist bei deinem Test das "erwartete" Ergebnis? log

    Code:
    Logger connected to: 988ad036525346515630
    --------- beginning of main
    --------- beginning of system
    *** 
    Service (starter) Create ***
    ** 
    Service (starter) Start **
    ** 
    Activity (main) Create, isFirst = true **
    ** 
    Activity (main) Resume **
    start    
    123
    start    
    456
    ** 
    Activity (main) Pause, UserClosed = false **
    ** 
    Activity (main) Resume **
    Ich habe zu collect hinzugefügt

    Code:
    Public Sub Collect(Data As String)
     
        
    'Log("Collect: '" & Data & "'")
     
        InputBuffer = InputBuffer & Data
        InputBuffer = InputBuffer.Replace(
    Chr(13)&Chr(10),CRLF' Neu
        Dim x,x1,x2 As Int
        x = InputBuffer.IndexOf(
    "start")
        
    If x > 0 Then InputBuffer = InputBuffer.SubString(x) 'mit start fängt die reihe an
     
        
    If InputBuffer.StartsWith("start") = False Then InputBuffer="" 'ungültiger anfang

        x1 = InputBuffer.IndexOf(
    "start")
        x2 = InputBuffer.IndexOf(
    CRLF)

        
    If x1>=0 And x2 > x1 Then 'mindestens eine reihe mit start und chr(10)
     
            
    Dim Row As String = InputBuffer.SubString2(0,x2) 'bis ohne Zeilenumbruch merken
            List.Add(Row)
     
            InputBuffer = InputBuffer.SubString(x2+
    1'kürzen vorne was ausgelesen wurde weg
     
            Collect(
    ""'das soll den Rest zerlegen
        End If

    End Sub
     
    MarkusR likes this.
  3. pucki

    pucki Active Member Licensed User

    Kleine Frage zum Arduino. Das BT lässt vermuten das du ein Bluetooth-Modul benutzt. Welches ist das, und wie steuerst du es an.
    Und ich würde auch gerne wissen wie du es auf der Android-Seite ansteuerst.

    @manfred. Ist es mit B4a möglich, irgendwie die Daten des Songs der gerade von einer ANDEREN APP gespielt wird auszulesen und an ein Bluetooth-Modul zu senden.
    Ich frage deshalb, weil ich gerne wissen will, welcher Song von wem gerade läuft OHNE auf mein Handy zu schauen.

    Gruß

    Pucki
     
  4. OliverA

    OliverA Well-Known Member Licensed User

    Code:
    'Based on @DonManfred's update:
    Public Sub Collect(Data As String)
       
    'Log("Collect: '" & Data & "'")
       InputBuffer = InputBuffer & Data
       InputBuffer = InputBuffer.Replace(
    Chr(13)&Chr(10),CRLF' Neu
       'Brauchen kein x
       Dim x1,x2 As Int
       
    'Add & TAB to all the IndexOf("start") methods
       x1 = InputBuffer.IndexOf("start" & TAB)
       
    If x1 <> -1  Then ' Wir haben einen start gefunded
           x2 = InputBuffer.IndexOf2(CRLF, x1)
           
    If x2 <> -1 Then ' Wir haben ein ende gefunden
               Dim row As String = InputBuffer.SubString2(x1,x2) 'bis ohne Zeilenumbruch merken
               'Leeren start ausschliessen (start\t ohne CRLF)
               x1 = row.LastIndexOf("start" & TAB)
               
    If x1 > 0 Then
                   row = row.SubString(x1)
               
    End If
               
    List.Add(row)
               InputBuffer = InputBuffer.SubString(x2+
    1'kürzen vorne was ausgelesen wurde weg
               Collect(""'das soll den Rest zerlegen
           End If
       
    End If
    End Sub
    Code:
    InputBuffer = ""
     
       
    List.Initialize
       
    List.Clear
       Collect(
    "234234")
       Collect(
    "start" & TAB)
       Collect(
    "123")
       Collect(
    CRLF)
       Collect(
    "start" & TAB)
       Collect(
    "456" & CRLF)
       
    'Start w/o data
       Collect("start" & TAB)
       
    'Split start
       Collect("sta")
       Collect(
    "rt" & TAB)
       Collect(
    "split start" & CRLF)
       
    'Junk
       Collect("st")
       Collect(
    TAB & "123")
       Collect(
    "456" & CRLF)
       
    'Good
       Collect("start" & TAB)
       Collect(
    "good start" & CRLF)
       
    'Trick
       Collect("start" & TAB & "start" & TAB & "trick" & CRLF & "start" & TAB & "treat" & CRLF)
     
       
    For Each Row As String In List
           
    Log(Row)
       
    Next

       InputBuffer = 
    ""
       
    List.Clear
    Code:
    start   123
    start   
    456
    start   split start
    start   good start
    start   trick
    start   treat
     
    MarkusR likes this.
  5. MarkusR

    MarkusR Well-Known Member Licensed User

    danke, das war wohl der Wink in die richtige Richtung. :D
    bin grad noch am testen.
     
  6. MarkusR

    MarkusR Well-Known Member Licensed User

    Android BLE2 Version 1.37 hab ein Beispiel hier im Forum dazu gefunden.

    Arduino IDE
    https://www.arduino.cc/en/Main/Software

    Nutze aber besser Serial1, auf dem Uno Serial aber ohne das es am PC angeschlossen ist weil das der USB Port ist

    Modul: DSD TECH HM-10 Bluetooth 4.0 BLE
    Kostet ~ 9€ bei Amazon.

    Das Modul braucht einen Spannungsteiler den man leicht selber machen kann mit zwei Wiederstände.
    Code:
    Sub Spannungsteiler()

        
    Dim vin,vout,r1,r2 As Float
        
        r1 = 
    1000.0
        r2 = 
    1950.0
        
        vin = 
    5.0
        vout = vin * (r2/ (r1+r2))
        
        
    Log(vout)
        
    End Sub

    Code:
    // Lautstärke
    // * RX 
    is digital pin 10 (connect to TX of other device)
    // * TX 
    is digital pin 11 (connect to RX of other device) (voltage divider 5V to 3.3V)

    int readPinA = A0;
    int readPinD = 
    7;
    int ledPin = 
    2;

    int count=
    0;
    bool alarmflag=
    false;
    unsigned long alarmtime;

    #include <SoftwareSerial.h>
    SoftwareSerial bt(
    1011); // RX Empfang, TX Senden

    void setup() {
      // put your setup code here, 
    to run once:

      
    Serial.begin(38400);
      //
    Serial.begin(115200);

      //pinMode(readPinA,INPUT);
      pinMode(readPinD,INPUT);
     pinMode(ledPin,OUTPUT);

    //
    38400

    //
    115200 ist wohl für softwre serial zu viel

      bt.begin(
    38400);
      //bt.begin(
    115200);
      //
    Serial.begin(115200); //BT Modul hat default 9600

     // AT+BAUD4 stellt 
    115200 Baud ein
      // AT muss OK sagen
      // 
    "AT+BAUD?" Anwort "OK+Get:4"
      //
    0 – 9600
     //
    2 – 38400
     //
    4 – 115200

    }

    void loop() {

      if (1==1) {

        if (bt.available()) {
          Serial.write(bt.read());
        }
        if (Serial.available()) {
          bt.write(Serial.read());
        }
     
      }
     
     
      // put your main code here, to run repeatedly:

     int valuea = analogRead(readPinA);
     int valued=digitalRead(readPinD);

    if (abs(512-valuea)>10)  {
      alarmflag=true;
      alarmtime=millis();
      }

    if (millis() - alarmtime >3000) {alarmflag=false;}

     Alarm(alarmflag);

    String row = "start\t" + String(valuea);

    bt.println(row);

    //delay(20); //irgendwie stört das die Serielle (Software) Übertragung ...

    }

    void Alarm(bool flag)
     {
       if (flag==true)
       {
          digitalWrite(ledPin, HIGH);
       } else {
         digitalWrite(ledPin, LOW);
       }
    }
     
  7. pucki

    pucki Active Member Licensed User

    Vielen Dank für deine Info.

    Gruß

    Pucki
     
  8. MarkusR

    MarkusR Well-Known Member Licensed User

    Jo, aktualisier nochmal die Seite weil ich die Beiträge oft ergänze.
     
  9. MarkusR

    MarkusR Well-Known Member Licensed User

    Das sieht so aus als ob Bytes in der Übertragung verschwinden und dann habe ich zwischen zwei Zahlen einen Zeilenumbruch. Das Log schreibt die Daten wie sie rein kommen.
    Snap_2019.04.11_23h04m18s_002_.png

    Habe nun den Ardunio Mega mit Hardware Serial 1 genutzt. Läuft besser :)
     
    Last edited: Apr 11, 2019
  10. pucki

    pucki Active Member Licensed User

    Ich an deiner Stelle würde ein Back-Protokoll installieren.

    Das heißt z.b. du sendest eine Zahl am Ende der Zelle. Wenn die Zeile analysiert ist, wird diese Zahl zurück geschickt und verglichen. Machen übrigens fast alle Datenübertragungsprotokolle so oder so ähnlich. Oder was meinst du warum du beim Download immer Upload hast. Ohne so was kannst du NIE sicher sein, ob was verschluckt wurde.


    Gruß

    Pucki
     
    MarkusR likes this.
  11. MarkusR

    MarkusR Well-Known Member Licensed User

    jo, tcp braucht sowas nicht, aber eine prüfsumme wäre gut.
    hatte gestern den fall im debug modus das ich den mikro controller aus geschaltet hatte und dann liefen noch minuten daten rein in die b4a app. :D
    Glücklich bin ich mit der übertragung noch nicht.
    Das Projekt was ich grad mache misst Lärmbelästigung per Mikro und Schwellwert.
     
  12. Filippo

    Filippo Expert Licensed User

    Du solltest immer vorher prüfen ob die ganze Zeile in B4a angekommen ist, erst dann kannst du die Zeile teilen.
    Am besten verwendest du die classe von Erel.
     
  13. MarkusR

    MarkusR Well-Known Member Licensed User

    Ja, optimal wäre wenn die Zeile wirklich und richtig angekommen ist.
    Auf der Arduino Seite nutze ich noch kein B4R.
    Vielleicht mache ich son Ping Pong Spiel wie Pucki das mit dem Back-Protokoll erwähnt hat.
    Aber dann bekomme ich bestimmt nicht die Wellenform so gut angezeigt die ich vom Mikro aufnehme.
     
  14. Filippo

    Filippo Expert Licensed User

    Wenn du die classe von Erel verwendest, dann funnktioniert es auch richtig.

    Ich verwende es auch nicht, bin schon seit langem mit Ardiuno gewöhnt.
     
  15. MarkusR

    MarkusR Well-Known Member Licensed User

    Meinst du speziell diesen "prefix" mode?



    Zwei wichtige Befehle die auf dem Ardunio nützlich sind:
     
    Last edited: Apr 12, 2019
  16. thetahsk

    thetahsk Active Member Licensed User

    Überprüfe bitte mal ob dein "sportlicher Spannungsteiler" stabil das BT Modul versorgt. Mit R1=1000 u. R2=1950 fliesen da gerade mal 1.69 mA.
    Das BT Modul wird wahrscheinlich einen deutlich höheren Verbrauch haben. ( 5-30 mA).
    Hast du auch Pegelwandler für die serielle Verbindung eingebaut ?
     
    Last edited: Apr 12, 2019
  17. Filippo

    Filippo Expert Licensed User

    Nein, einfach nur "bt.println(row);".
    Die classe B4a wartet bis ein CRLF kommt und gibt es weiter für weitere prüfungen.
     
  18. MarkusR

    MarkusR Well-Known Member Licensed User

    Hatte ich ja so gemacht. Ich glaube das sich der Ausgangspuffer zu schnell gefüllt hatte und dann können die Bytes nicht raus geschickt werden
    und alles kommt dann zerstückelt an sobald im Puffer wieder Platz ist.

    Edit:
     
    Last edited: Apr 13, 2019
  19. MarkusR

    MarkusR Well-Known Member Licensed User

    Das Modul läuft mit 5V nur die Übertragung vom Arduino TX nach RX hat den Spannungsteiler über 1k & 2k Widerstand.
     
  20. Filippo

    Filippo Expert Licensed User

    Probiere meine modifizierte classe, damit habe ich keine Probleme mehr.
    Ich verwende diese classe in B4a und B4i.

    Code:
    Sub Class_Globals
        
    Private mTarget As Object
        
    Private mEventName As String
        
    Private sb As StringBuilder
        
    Private charset As String = "iso-8859-1"
        
    'Private bc As ByteConverter
    End Sub

    'Initializes the object. You can add parameters to this method if needed.
    Public Sub Initialize(TargetModule As Object, EventName As String)
        mTarget = TargetModule
        mEventName = EventName
        sb.Initialize
    End Sub

    Public Sub NewData (Buffer() As Byte)
        
    'Log("bc.HexFromBytes=" & bc.HexFromBytes(Buffer))
        Dim newDataStart As Int = sb.Length
        sb.Append(
    BytesToString(Buffer, 0, Buffer.Length, charset))
        
    Dim s As String = sb.ToString
        
    Dim start As Int = 0
        
    For i = newDataStart To s.Length - 1
            
    Dim c As Char = s.CharAt(i)
            
    If i = 0 And c = Chr(10Then '\n...
                start = 1 'might be a broken end of line character
                Continue
            
    End If
            
    If c = Chr(10Then '\n
                CallSubDelayed2(mTarget, mEventName & "_NewText", s.SubString2(start, i))
                start = i + 
    1
            
    Else If c = Chr(13Then '\r
                CallSubDelayed2(mTarget, mEventName & "_NewText", s.SubString2(start, i))
                
    If i < s.Length - 1 And s.CharAt(i + 1) = Chr(10Then '\r\n
                    i = i + 1
                
    End If
                start = i + 
    1
            
    End If
        
    Next
        
    If start > 0 Then sb.Remove(0, start)
    End Sub
     
    MarkusR likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice