French [RESOLU]Dialogue Android/Arduino sous B4A

Discussion in 'French Forum' started by Bricopin, Dec 11, 2018.

  1. Bricopin

    Bricopin Member Licensed User

    Bonjour,
    Un projet simple qui me permet de dialoguer avec un Arduino.
    Tout fonctionne parfaitement (je transmet et reçoit mes données)
    Le seul problème est que les données reçues ne sont pas toujours complètes.
    Je dois recevoir une trame de 24 caractères (en fait 24 chiffres).
    Des fois je reçois les 24 chiffres, des fois une dizaine, des fois 5, des fois 1, etc...
    Je n'ai aucune erreur de fonctionnement.
    Ou est mon erreur ?
    Cordialement

    Code:
    Sub Activity_Create(FirstTime As Boolean)
        
    Activity.LoadLayout("accueil")
        MyDeviceName = 
    "linvor"
        
    ToastMessageShow("Trying to connect to " & MyDeviceName, True)
        Timer1.Initialize(
    "timer1",50000)
        Timer1.Enabled = 
    False
        
        
    Try
            BT.Initialize(
    "BT")
            Serial1.Initialize(
    "Serial1")
        
    Catch
            
    ToastMessageShow("No BlueTooth Device visible..."True)
        
    End Try
        
    End Sub

    Sub Activity_Resume
        
    Try
            
    If BT.IsEnabled = False Then
                BT.Enable
            
    Else
                
    'connect to SK
                BTConnectToDevice
            
    End If
        
    Catch
        
    End Try
    End Sub

    Sub BT_StateChanged(NewState As Int,OldState As Int)
        
    If NewState = BT.STATE_ON Then
            BTConnectToDevice
            
    Log("BT Connect")
        
    Else
            Serial1.Disconnect
            Timer1.Enabled = 
    False
            
    Log("BT Disconnect")
        
    End If
    End Sub

    Sub BTConnectToDevice
        
    Dim PairedDevices As Map
        PairedDevices = Serial1.GetPairedDevices
        
    Try
            Serial1.Connect3(PairedDevices.Get(MyDeviceName),
    1)
        
    Catch
            
    ToastMessageShow("Device not available",True)
        
    End Try
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)

    End Sub

    'Sub mnuConnect_Click
    '    Dim PairedDevices As Map
    '    PairedDevices = Serial1.GetPairedDevices
    '    Dim l As List
    '    l.Initialize
    '    For i = 0 To PairedDevices.Size - 1
    '        l.Add(PairedDevices.GetKeyAt(i))
    '    Next
    '    Dim res As Int
    '    res = InputList(l, "Choose device", -1)             
    '    If res <> DialogResponse.CANCEL Then
    '        Serial1.Connect(PairedDevices.Get(l.Get(res)))
    '    End If
    'End Sub

    Sub Serial1_Connected (Success As Boolean)
        
    If Success = True Then
            
    ToastMessageShow("Bluetooth connected to " & Serial1.Address, False)
            AStreams.Initialize(Serial1.InputStream,Serial1.OutputStream,
    "AStreams")
            Timer1.Enabled = 
    True
        
    Else    'disconnected
            ToastMessageShow("Connection to " & Serial1.Address & _
                            
    " broken!"True)
            Timer1.Enabled = 
    False
            connected = 
    False
        
    End If
    End Sub

    Sub AStreams_NewData (Buffer () As Byte)
        msg = 
    BytesToString (Buffer, 0 , Buffer.Length, "UTF8" )
        
    ToastMessageShow (msg, False )
    End Sub
     
  2. klaus

    klaus Expert Licensed User

    Est-tu sûr que les données sont parties?
    Dans la routine AStreams_NewData essaies de remplacer ToastMessageShow (msg, False ) par Log(msg) pour voir si les données arrivent en plusieurs fois ou si elles sont incomplètes.
    J'avais vu une fois, mais je ne me rappelle plus exactement où, une solution qui regroupe plusieurs arrivées de données pour être sûr qu'elles soient complètes.
     
  3. Bricopin

    Bricopin Member Licensed User

    Bonjour Klaus,
    Le problème est identique avec Log(msg) mais me permet de mieux voir ce qui se passe.
    La trame (en fait il y a 25 chiffres) arrive une fois complète (25) , puis ensuite en 2 fois (Exemple 9+16, puis 4+21, puis 1+24) et ça boucle.
    Oui les données sont bien envoyées en totalité (je le vérifie avec le moniteur série de l'Arduino).
    Qui plus, j'avais déjà développé cette appli avec WinDev mobile et elle fonctionnait parfaitement.
    JPR
     
  4. klaus

    klaus Expert Licensed User

    C'était le but.
    Regardes cette Class: AsyncStreamText.
    Dans cette Class, il y a une routine qui réassemble des messages partiels.
    Si l'Arduino envoie un caractère spécifique à la fin du message, la Class ci-dessus devrait résoudre le problème.
    Si non, tu pourrais modifier la routine pour attendre que le message soit complet et le reconstituer.

    J'ai utilisé cette Class dans le projet exemple HC05DataLogger qui figure dans le B4R Example Projects Booklet.
     
    Last edited: Dec 12, 2018
  5. Bricopin

    Bricopin Member Licensed User

    Bonjour à tous,
    Je n'ai pas utilisé cette classe et j'ai préféré ajouter une routine qui vérifie que le message soit complet.
    La routine éffectue bien son travail mais dans la mesure ou les messages tronqués sont très nombreux, le déroulement du programme s'en trouve fortement ralenti.
    J'ai donc changé de programme et le nouveau fonctionne parfaitement.
    J'ai juste un petit soucis, bien que ce ne soit ni dramatique ni bloquant.
    Le programme démarre le mode BT sur le smartphone, mais ne le supprime pas lorsque je quitte le programme.
    Y a t'il une commande spécifique .
    JPR
    C
    Code:
    Sub Activity_Create(FirstTime As Boolean)
        
    Activity.LoadLayout("accueil")
        MyDeviceName = 
    "linvor"
        
    ToastMessageShow("Trying to connect to " & MyDeviceName, True)
        
        
    If FirstTime Then
            Serial1.Initialize(
    "Serial1")           
            Timer1.Initialize(
    "Timer1"500)       
            
    'Timer2.Initialize("Timer2", 100)       
        End If
        
    Try
            BT.Initialize(
    "BT")
            Serial1.Initialize(
    "Serial1")
        
    Catch
            
    ToastMessageShow("No BlueTooth Device visible..."True)
        
    End Try
    End Sub

    Sub Activity_Resume
        pw.KeepAlive(
    True)        'pour eviter mise en veille : avec bibliotheque "phone"
        Try
            
    If BT.IsEnabled = False Then
                BT.Enable
            
    Else
                BTConnectToDevice
            
    End If
        
    Catch
        
    End Try
    End Sub

    Sub BTConnectToDevice
        
    Dim PairedDevices As Map   
        PairedDevices = Serial1.GetPairedDevices
        
    Try
            Serial1.Connect3(PairedDevices.Get(MyDeviceName),
    1)
        
    Catch
            
    ToastMessageShow("Device not available",True)
        
    End Try
    End Sub

    Sub Serial1_Connected (Success As Boolean)
        
    If Success Then
            
    ToastMessageShow("Bluetooth connected to " & Serial1.Address, False)   
            TextReader1.Initialize(Serial1.InputStream)
            TextWriter1.Initialize(Serial1.OutputStream)
            Timer1.Enabled = 
    True
            
    'Timer2.Enabled = True
            connected = True
        
    Else
            
    ToastMessageShow("Connection to " & Serial1.Address & _
                            
    " broken!"True)
            connected = 
    False
            Timer1.Enabled = 
    False
            
    'Timer2.Enabled = False
            Msgbox(LastException.Message, "Error connecting.")
        
    End If
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        
    End Sub

    Sub BT_StateChanged(NewState As Int,OldState As Int)
        
    If NewState = BT.STATE_ON Then
            BTConnectToDevice
            
    Log("BT Connect")
        
    Else
            Serial1.Disconnect
            Timer1.Enabled = 
    False
            
    Log("BT Disconnect")
        
    End If
    End Sub


    Sub Timer1_Tick
        
    If connected Then
            
    If TextReader1.Ready Then   
                msg = TextReader1.ReadLine   
                trames = (msg)
            
    End If
        
    End If
    End Sub
    i-joint listing nouveau programme
     
  6. klaus

    klaus Expert Licensed User

    Qu'est-ce que tu as changé? Ça pourrait être intéressant pour d'autres utilisateurs.
    Quelle Library utilises-tu pour Bluetooth?
    As-tu essayé BT.Disconnect ?
     
  7. Bricopin

    Bricopin Member Licensed User

    Bonjour à tous,
    La librairie Serial Ver 1.26 .
    Dans le premier programme j'utiliise AsyncStream.
    Dans le second j'utilise TextReader.
    Je me suis servi de plusieurs programmes disponibles sur le forum.
    J'ai fait un mix avec les différents éléments pour obtenir ce que je voulais à savoir :
    - Connexion automatique du Bluetooth du smartphone.
    - Connexion a un module Bluetooth unique (avec son nom en dur dans le programme).
    - Récupération au fil de l'eau de la trame transmise par l'Arduino.
    - Émission de commande en direction de l'Arduino.
    - Déconnexion automatique du Bluetooth à la fermeture du programme.
    JPR
     
    klaus likes this.
  8. Bricopin

    Bricopin Member Licensed User

    Bonjour à tous,
    Voici le programme
    JPR

    Code:
    Sub Activity_Create(FirstTime As Boolean)
        
    Activity.LoadLayout("accueil")
        myvar = (msg)
        MyDeviceName = 
    "linvor"
        
    ToastMessageShow("Trying to connect to " & MyDeviceName, True)
        
    If FirstTime Then
            Serial1.Initialize(
    "Serial1")           
            Timer1.Initialize(
    "Timer1"500)
            Timer1.Enabled = 
    False       
            Timer2.Initialize(
    "Timer2"500)
            Timer2.Enabled = 
    False
        
    End If
        
    Try
            BT.Initialize(
    "BT")
            Serial1.Initialize(
    "Serial1")
        
    Catch
            
    ToastMessageShow("No BlueTooth Device visible..."True)
        
    End Try
    End Sub

    Sub Activity_Resume
        pw.KeepAlive(
    True)        'pour eviter mise en veille : avec bibliotheque "phone"
        Try
            
    If BT.IsEnabled = False Then
                BT.Enable
            
    Else
                BTConnectToDevice
            
    End If
        
    Catch
        
    End Try
    End Sub

    Sub BT_StateChanged(NewState As Int,OldState As Int)
        
    If NewState = BT.STATE_ON Then
            BTConnectToDevice
            
    Log("BT Connect")
        
    Else
            Serial1.Disconnect
            Timer1.Enabled = 
    False
            Timer2.Enabled = 
    False
            
    Log("BT Disconnect")
        
    End If
    End Sub

    Sub BTConnectToDevice
        
    Dim PairedDevices As Map   
        PairedDevices = Serial1.GetPairedDevices
        
    Try
            Serial1.Connect3(PairedDevices.Get(MyDeviceName),
    1)
        
    Catch
            
    ToastMessageShow("Device not available",True)
        
    End Try
    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        
    If UserClosed  Then
            pw.ReleaseKeepAlive        
    'pour eviter mise en veille : avec bibliotheque "phone"
        End If
    End Sub

    Sub Serial1_Connected (Success As Boolean)
        
    If Success = True Then
            
    ToastMessageShow("Bluetooth connected to " & Serial1.Address, False)   
            TextReader1.Initialize(Serial1.InputStream)
            TextWriter1.Initialize(Serial1.OutputStream)
            Timer1.Enabled = 
    True
            Timer2.Enabled = 
    True
            connected = 
    True
        
    Else
            
    ToastMessageShow("Connection to " & Serial1.Address & _
                            
    " broken!"True)
            Timer1.Enabled = 
    False
            connected = 
    False
            Timer2.Enabled = 
    False
            
    Msgbox(LastException.Message, "Error connecting.")
        
    End If
    End Sub

    Sub Timer1_Tick
        
    If connected Then
            
    If TextReader1.Ready Then   
                msg = TextReader1.ReadLine
                Trames = (msg)
                msg = (
    "")
            
    End If
        
    End If
    End Sub

    Sub Timer2_Tick
        
    'Log (Trames)
        EditText1.text = (Trames)
        Trames = (
    "")
    End Sub

    Sub btEntrer_Click
        
    Activity.LoadLayout("nivstab")

    Sub BtStopNivStab_Click        ' Choix "z" = Arret de la fonction en cours
        TextWriter1.WriteLine("z")
        TextWriter1.Flush
    End Sub
     
  9. Bricopin

    Bricopin Member Licensed User

    Bonjour à tous,
    Mon projet est constitué de plusieurs activity.
    Je récupère en permanence les données provenant de l'Arduino dans une variable (trames).
    Ces données me servent à effectuer différentes actions.
    Quels est la bonne manière de transferer cette variable dans les autres activity.
    J'ai fais des essais (statsub, callsub, callsubdelayed, etc) grâces aux messages récupérés sur le forum mais ça ne fonctionne pas.
    JPR
     
    Last edited: Jan 14, 2019
  10. Serge Bertet

    Serge Bertet Member Licensed User

    Je fais la même chose que toi mais en wifi, les infos viennent d'autres téléphones.
    J'ai mis tout le code wifi dans le service starter avec timers, buffers, etc.
    Quand il y a des données je propage les infos à l'activité qui est ouverte.
    Code:
    ' Propager l'info à toutes les activités (sauf "play vidéo" et "play image").
        If SubExists(PrefTools, "FileReceived"Then CallSub(PrefTools, "FileReceived")
        
    If SubExists(Main, "FileReceived"Then CallSub(Main, "FileReceived")
        
    If SubExists(preferences, "FileReceived"Then CallSub(preferences, "FileReceived")
     
  11. Bricopin

    Bricopin Member Licensed User

    Bonjour,
    Merci, je fais un essai des que possible.
    JPR
     
  12. Bricopin

    Bricopin Member Licensed User

    Bonjour à tous,
    J'ai fais un essai avec la proposition d'Electrizay (merci à lui) mais en définitive j'ai opté pour une autre solution.
    En fait je charge dans "Activity_Create" toutes mes Layout avec LoadLayout("xxxxx") et je n'ai plus qu'à les rendre visibles ou pas suivant le besoin.
    De ce fait, ma variable "trames" est en permanence disponible.
    Comme mes différentes Layout possédaient des éléments similaires, cela me simplifie le travail dans la mesure ou je définie tous mes éléments identiques seulement dans la 1er Layout et je "colle " ensuite les autres Layout par dessus, c'est bien plus pratique.
    Ayant trouvé une solution satisfaisante je passe ce post en résolu .
    J'ai d'autres questions, j'ouvrirais donc de nouveaux posts au fur et à mesure.
    JPR
     
    Last edited: Jan 16, 2019
  13. klaus

    klaus Expert Licensed User

    Juste une précision:
    Le fait de charger un Layout ne signifie pas charger une nouvelle Activity!
    Les Layouts sont indépendants des Activities!
    Dans ton cas, tu n'as qu'une Activity, mais to jongles avec différents Layouts.

    Pour voir la différence, tu peux regarder ce thread: Different examples with two layouts.
     
  14. Bricopin

    Bricopin Member Licensed User

    Bonjour,
    Oui, je n'ai pas employé les bons termes.
    J'ai modifié mon post précédents afin qu'il soit compréhensible.
    JPR
     
    klaus 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