French AStream_NewData et données non régulières

fgh3966

Active Member
Licensed User
Bonsoir
Le lien est usb vers rs232, aussi c'est une entreprise qui définit le protocole de 19 octet et la valeur de 252 pour synchroniser les données.
Les paquets de 19 octets peuvent arriver toutes les 0.4 ms (vitesse maximum)
Pour afficher les données il faut exécuter quelques calculs afin de les afficher car elles sont encodées pour minimiser le risque d'erreur de transmission et les détecter.
Ce qui compte surtout c'est d'afficher la dernière donnée que l'utilisateur souhaite filtrer, sans aucun oubli de la part du programme.

Si j'ai bien compris le temps que met le smartphone pour afficher les données sous forme de log ou d'affichage et plus long que le temps pour recevoir et les données recues.
Peut être qu'en stockant les données dans un buffer de quelques kilo-octet puis lancer une routine séparée qui calcule, filtre et affiche les données.
Ce serait de la programmation multi tâche.

Qu'en pensez vous ?
 

emexes

Expert
Licensed User
Le lien est usb vers rs232
Y a-t-il une section RS232 dans le lien ? Comme dans 3 fils, pour les données de transmission, les données de réception et la masse électrique commune (plus peut-être quelques fils de contrôle) ? Avec un connecteur D à 9 ou 25 broches.


c'est une entreprise qui définit le protocole de 19 octet et la valeur de 252 pour synchroniser les données.
Je pensais que nous avions découvert qu'il n'y avait pas de 252 dans les données reçues et que le dernier octet des paquets était 249 (hex 0xF9) :

Log output:
1709187211650    19    857F00AA08000F0000122400D2410000F807F9
1709187211682    19    857F00AA0800000000157E00D24100005C00F9
1709187211698    19    857F00AA08000F000018D800D2410000B900F9
1709187211714    19    857F00AA08000000001C3200D34100001800F9
1709187211746    19    857F00AA08000F00001F8C00D34100007500F9
1709187211762    19    857F00AA08000F000022E600D3410000D200F9
1709187211794    19    857F00AA0800000000274000D44100003200F9
1709187211810    19    857F00AA08000F0000299A00D44100008E00F9
1709187211842    19    857F00AA08000F00002CF400D4410000EB00F9
1709187211858    19    857F00AA08000000002F4E00D54100004900F9
1709187211890    19    857F00AA08000F000033A800D5410000A700F9
1709187211906    19    857F00AA0800000000360200D64100000500F9
1709187211922    19    857F00AA0800000000395C00D64100006200F9
1709187211954    19    857F00AA08000F00003DB600D6410000C000F9
1709187211970    19    857F00AA0800000000401000D74100001E00F9
1709187212147    7936


Les paquets de 19 octets peuvent arriver toutes les 0.4 ms
Pourquoi une telle rapidité ? Quelles sont les mesures envoyées ? L'heure ? Un décompte ? Une quantité, comme les volts, les ampères, les kilogrammes ou la température ?


sont encodées pour minimiser le risque d'erreur de transmission et les détecter.
Je me suis demandé si l'avant-dernier octet était une somme de contrôle, mais je me suis dit que notre première étape était de recevoir les données, et que nous pourrions nous préoccuper de la somme de contrôle plus tard.


Ce qui compte surtout c'est d'afficher la dernière donnée que l'utilisateur souhaite filtrer,
sans aucun oubli de la part du programme.
le temps que met le smartphone ... et plus long que le temps pour recevoir et les données recues.
un buffer de quelques kilo-octet puis lancer une routine séparée qui calcule, filtre et affiche les données.
Si les données en série sont continues et plus rapides que ce que le smartphone peut traiter, et que nous ne pouvons pas ignorer les paquets périmés pour n'utiliser que le paquet le plus récent, l'ajout d'une mémoire tampon ne fera que retarder le problème, sans le résoudre.
 

emexes

Expert
Licensed User
Mon deviner est-elle proche de la réalité? Quelles sont les parties que j'ai mal devinées? N'oubliez pas que tout semble être à l'envers depuis l'Australie. 🙃

2024-03-02 B4X Serial Nixie.jpg
 

emexes

Expert
Licensed User
Une photo du matériel, des câbles, etc. disposés sur votre établi serait très utile.

Et il est toujours intéressant de voir les projets des autres. 🍻

Pas de problème si votre établi est un cirque. Un établi occupé est le signe d'un esprit occupé, et un établi vide est le signe de...
 

OliverA

Expert
Licensed User
Longtime User
J'utilise Google Translate, donc je ne sais pas dans quelle mesure cela se traduit. Article original en anglais cité ci-dessous :

Veuillez noter que le sous _NewData est un événement qui s'exécute sur le thread principal. La capture de données via Asyncstream a lieu sur un thread séparé, mais les événements _NewData sont placés dans la file d'attente des événements du thread principal. Par conséquent, si vous effectuez beaucoup de traitements dans _NewData ou dans tout sous-marin directement appelé depuis _NewData, l'exécution des autres événements _NewData sera "bloquée". S'il n'est pas nécessaire de traiter chaque octet reçu via _NewData, vous pouvez alors utiliser _NewData pour simplement capturer et mettre en file d'attente tous les octets reçus, puis utiliser une minuterie pour traiter toutes les données reçues et à une fréquence acceptable (par exemple, toutes les 250 ms). Encore une fois, l'objectif est de terminer le processus dans l'événement Timer le plus rapidement possible afin de permettre à l'application de traiter tous les événements _NewData dans la file d'attente.

Quant aux octets signés/non signés. À moins que vous ayez besoin d'afficher les données ou d'effectuer des opérations autres que le décalage/masquage, vous n'avez pas vraiment besoin de convertir les octets non signés en octets signés. Ainsi, même cette conversion peut être retardée autant que possible.

Using Google Translate, so I do not know how well it translates. Original English post quoted below:

Please note that the _NewData sub is an event that runs on the main thread. Data capturing via Asyncstream does happen on a separate thread, but the _NewData events are placed into the event queue of the main thread. Therefore, if you do a lot of processing in _NewData or any subs that are directly called from _NewData, will "block" other _NewData events from executing. If it is not necessary to process every single byte received via _NewData, then you can use _NewData to just capture and queue all the bytes received and then use a Timer to process any received data and some acceptable frequency (for example, every 250ms). Again, the goal is to complete the process in the Timer event as fast as possible in order to allow the app to process all the _NewData events in the queue.

As to signed / unsigned bytes. Unless you need to display the data, or you need to perform operations besides shifting / masking, you do not really need to convert the unsigned bytes to signed bytes. So even that conversion can be delayed as much as possible.
 

emexes

Expert
Licensed User
Je pense que la première étape consiste encore à clarifier le format du packet.

Log output:
1709187211650    19    857F00AA08000F0000122400D2410000F807F9
1709187211682    19    857F00AA0800000000157E00D24100005C00F9
1709187211698    19    857F00AA08000F000018D800D2410000B900F9
1709187211714    19    857F00AA08000000001C3200D34100001800F9
1709187211746    19    857F00AA08000F00001F8C00D34100007500F9
1709187211762    19    857F00AA08000F000022E600D3410000D200F9
1709187211794    19    857F00AA0800000000274000D44100003200F9
1709187211810    19    857F00AA08000F0000299A00D44100008E00F9
1709187211842    19    857F00AA08000F00002CF400D4410000EB00F9
1709187211858    19    857F00AA08000000002F4E00D54100004900F9
1709187211890    19    857F00AA08000F000033A800D5410000A700F9
1709187211906    19    857F00AA0800000000360200D64100000500F9
1709187211922    19    857F00AA0800000000395C00D64100006200F9
1709187211954    19    857F00AA08000F00003DB600D6410000C000F9
1709187211970    19    857F00AA0800000000401000D74100001E00F9
1709187212147    7936

Le premier octet de chaque paquet est-il toujours 85 ?
Les 2 premiers octets sont-ils toujours 857F ?
Les 3 premiers octets sont-ils toujours 857F00 ?
Les 4 premiers octets sont-ils toujours 857F00AA ?
Les 5 premiers octets sont-ils toujours 857F00AA08 ?
Les 6 premiers octets sont-ils toujours 857F00AA0800 ?
Le dernier octet de chaque paquet est-il toujours F9 ?

Les paquets ont-ils toujours une longueur de 19 octets ?

Combien de mesures y a-t-il dans chaque paquet ?
Les mesures sont-elles de 8 bits chacune, ou de 16 bits, ou... ?
 
Last edited:

fgh3966

Active Member
Licensed User
Bonjour et merci pour vos réponses :) Pour que d'autres développeur b4x puissent suivre la discussion voici le lien :> recevoir des données en arriere plan
Actuellement 19 paquets de un octet sont envoyés, donc 19 octets. Le dernier octet est de 252 et ne change pas.
J'arrive a décoder + afficher les données convenablement si elles sont envoyées toutes les 10 ms
Mais dès qu'elles sont envoyées toutes les 0,5 ms le smartphone freeze.

Alors je vais essayer de stocker les données venant de Aynctream NewData dans un buffer de 1024 octets (par exemple) et puis les décoder et les afficher dans un autre thread.

On dirait qu' il faut utiliser la sub Activity_Resume pour réaliser un autre thread

Merci
 
Last edited:

emexes

Expert
Licensed User
Le dernier octet est de 252 et ne change pas.

Je suis confus à ce sujet, lorsque les événements série entrants enregistrés ci-dessus indiquent :

1/ les paquets font 19 octets (content de ça)
2/ les paquets se terminent par hexadecimal F9 = decimal 249
3/ aucun hexadecimal FC = decimal 252
4/ les paquets semblent avoir des octets de départ fixes (85 7F...) cf vous extrayiez des données de ces emplacements

Si vous pouviez répéter l'enregistrement des événements en série entrants, pour vérifier ce que votre appareil d'acquisition de données envoie à l'appareil Android, ce serait génial.
 

OliverA

Expert
Licensed User
Longtime User
Version traduite par Google :

"Je peux décoder + afficher correctement les données si elles sont envoyées toutes les 10 ms"
"Mais dès qu'il est envoyé toutes les 0,5 ms, le smartphone se bloque."

Devez-vous afficher de nouvelles données toutes les 0,5 ms ? Avez-vous besoin de le capturer pour des raisons informatiques/historiques pendant 0,5 ms ? Quelle est la durée maximale pendant laquelle vous pouvez empêcher l’affichage de nouvelles données sans compromettre la sortie d’affichage ? Vous devez vous rappeler que ce n'est pas nécessairement la capture de données qui gèle votre téléphone, mais que vous créez également un événement de mise à jour pour les données d'affichage toutes les 0,5 ms. C'est peut-être la raison pour laquelle le téléphone se bloque, puisque la file d'attente des événements est bombardée d'événements de mise à jour d'affichage. Donc, même si vous devez capturer (pour stocker, traiter, faire quoi que ce soit) les données toutes les 0,5 ms, je doute vraiment que les informations doivent être affichées aussi rapidement. À un taux de rafraîchissement de 60 Hz, vous envisagez environ 16 ms par rafraîchissement, à 120 Hz, c'est environ 8 ms. Capturez donc vos données à 0,5 ms, mais affichez uniquement les données les plus récentes (ou l'algorithme que vous souhaitez utiliser : valeur la plus basse, valeur la plus élevée, valeur moyenne, dernière valeur, etc.) toutes les 8 à 16 ms.

"puis décodez-le et affichez-le dans un autre fil de discussion."

C’est là que vous pourriez avoir des ennuis. Essayer d'accéder à l'interface utilisateur à partir d'un autre thread entraînera le blocage de votre application (très probablement). En fin de compte, je ne pense vraiment pas que vous ayez besoin de threading, il vous suffit de repenser la façon dont vous capturez les données et quand les afficher. Comme mentionné précédemment, si vous utilisez un événement Timer, vous pourrez peut-être réussir sans thread (définissez la valeur de la minuterie sur la fréquence de rafraîchissement minimale requise des données à afficher).

"I can decode + display the data properly if it is sent every 10 ms"
"But as soon as it is sent every 0.5 ms the smartphone freezes."

Do you need to display new data every 0.5 ms? Do you need to capture it for computational/historical reason for 0.5ms? What is the longest time that you can keep new data from displaying without compromising the display output? You have to remember, that it may not necessarily the data capturing that is freezing you phone, but you are also creating an update event for the display data every .5ms. That may be the reason the phone freezes, since the event queue is bombarded with display update events. So even if you need to capture (to store, to process, to do whatever) the data every .5 ms, I really doubt that the information needs to be displayed that quickly. At a refresh rate of 60Hz, you are looking at roughly 16ms per refresh, at 120Hz it's about 8ms. So capture your data at .5ms, but only display the most current data (or whatever algorithm you want to go by - lowest value, highest value, average value, last value, etc) every 8 - 16ms.

"and then decode it and display it in another thread."

This is where you may get yourself in trouble. Trying to access the UI from another thread will cause you're app to crash (most likely). In the end, I really don't think you need threading, you just need to rethink how you capture data and when to display that data. As previously mentioned, if you use a Timer event, you may be able to achieve success without threading (set the timer value to the minimum required refresh rate of the data to be displayed).
 

emexes

Expert
Licensed User
afficher les données convenablement si elles sont envoyées toutes les 10 ms

Je suis toujours confus.

Est-il nécessaire de traiter chaque échantillon de données, sans en omettre aucun ?

Pourquoi 100 mises à jour par seconde ne suffisent-elles pas ?

L'écran Android se rafraîchit probablement à une fréquence de 30 à 60 images par seconde = tout ce qui est plus rapide est un effort inutile.

Si l’affichage des données est numérique : qui peut les lire rapidement ?
 

fgh3966

Active Member
Licensed User
252 ou 249 sont une balise qui ne sera jamais envoyée dans les 18 autres octets
Ensuite le programme filtre et effectue des calculs entre les autres octets pour obtenir et afficher les valeurs désirées. Tout ceci fonctionne bien.
Par contre dès que j'envoie les 19 octets très rapidement (ce qui est prévu dans le protocole rs232) le smartphone freeze et pas l'ordinateur.
Je pense qu'un smartphone récent de 2020 ou supérieur fonctionnerait bien.
 

OliverA

Expert
Licensed User
Longtime User
Je pense qu'un smartphone récent de 2020 ou supérieur fonctionnerait bien.
Google Traduction:

"Je pense qu'un smartphone récent de 2020 ou supérieur fonctionnerait bien."

Si vous effectuez une mise à jour de l'affichage toutes les 0,5 ms d'un ou plusieurs champs de texte, alors je pense que même un smartphone de 2020 ou supérieur aura des problèmes pour traiter 2 000 événements de mise à jour d'écran chaque seconde.

"I think a recent smartphone from 2020 or higher would work fine."

If you are doing display updated every 0.5 ms of one or more text fields, then I think even a smarthone from 2020 or higher will have issues with processing 2000 screen update events every second.
 

fgh3966

Active Member
Licensed User
Merci OliverA
Jje voudrais garder les informations sur des périodes de quelques minutes, je ne connais pas le nombre exact d'informations devant être retenues, aussi c'est pas gênant.
je voudrais effectuer une mise à jour de l'affichage toutes les 20 ms, ça serait très bien.
 

fgh3966

Active Member
Licensed User
Qu'en pensez vous ?
1 premier thread rapide qui stocke les données en provenances des 19octets (usb-rs232) dans un ou plusieurs buffers de ram faisant moins de 10 kbyte ou ko
2ième thread qui rapidement décode les données en ram et les affiche "doucement" toutes les 20ms
 

OliverA

Expert
Licensed User
Longtime User
je voudrais effectuer une mise à jour de l'affichage toutes les 20 ms, ça serait très bien.
Qu'en pensez vous ?
Google Traduction:

"J'aimerais mettre à jour l'affichage toutes les 20 ms, ce serait bien."

Utilisez ensuite _NewData pour mettre en mémoire tampon les données entrantes. Ensuite, à l'aide d'un Timer, à un intervalle de 20 ms, lisez les tampons du dernier paquet de 19 octets reçu et affichez les informations. Effacez le tampon (ou enregistrez-le), puis quittez l'événement timer. Voyez ce qui se passe.

"Qu'en penses-tu?"

Je ferais d’abord ce qui précède avant de me lancer dans le threading. B4A peut gérer l'encodage/décodage G.729 annexe B en langage B4A sans problème sur certains matériels Android 6 sans thread. Je voudrais donc d'abord essayer d'implémenter tout cela sans ajouter de thread supplémentaire à ce que B4A fait déjà pour vous.

"I'd like to update the display every 20ms, that would be fine."

Then use _NewData to buffer the incoming data. Then, using a Timer, with an internval of 20ms, read the buffers last 19 byte packet received and display the information. Clear the buffer (or save it) and then exit the timer event. See what happens.

"What do you think?"

I would do the above first before diving into threading. B4A can handle G.729 annex B encoding / decoding in B4A language without issues on some Android 6 hardware without threading. So I would first try to implement all of this without adding extra threading onto what B4A already does for you
 

fgh3966

Active Member
Licensed User
Je ne sais pas si j'ai totalement trouvé mais en regardant la doc du fournisseur du composant j'ai lu que le buffer en entrée est de 256 octets et le buffer en sortie est de 128 octets.
J'ai appliqué ces paramêtres au hazard avec la bibliothèque felusbserial.
Maintenant quand je reçois des informations toute les 0,5 µs ça fonctione, le smartphone ne freeze plus
Pensez vous que usbserial est mieux ?

Merci


usbserial.BUFFER_READ_SIZE = 256 usbserial.BUFFER_WRITE_SIZE = 128:
#Region  Project Attributes
    #ApplicationLabel: Counter-Data's
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
#End Region

'Activity module
Sub Process_Globals
    Private usbserial As felUsbSerial
    Private manager As UsbManager
End Sub

Sub Globals
    Dim kilobuf(512) As Byte
    Dim tst0, index As Int
    Dim lbl0, lblunit, lbldiz, lblcent As Int = 0
    Private btnConnect, Button1 As Button
    Private Label1, Label2, Label3, label4, Label5, label6, label7, label8 As Label
    Private EditText1 As EditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        manager.Initialize
        End If      
    Activity.LoadLayout("main")        ' load the layout
End Sub

Sub btnConnect_Click
    If manager.GetDevices.Length = 0 Then
        Label1.Text = "No USB devices."
    Else
        Dim device As UsbDevice = manager.GetDevices(0) 'the device
        If manager.HasPermission(device) = False Then
            manager.RequestPermission(device)
        Else
            usbserial.BUFFER_READ_SIZE = 256
            usbserial.BUFFER_WRITE_SIZE = 128
            usbserial.Initialize("serial", device, -1)
            usbserial.BaudRate = 460800
            usbserial.DataBits = usbserial.DATA_BITS_8
            usbserial.Parity = usbserial.PARITY_NONE
            usbserial.FlowControl = usbserial.FLOW_CONTROL_OFF
            usbserial.StartReading
            Label1.Text = "Connected"
        End If
    End If
End Sub

Private Sub serial_DataAvailable (Buffer() As Byte)

'    Dim incr As Byte = 0
    If Buffer.Length > 16 Then

        If 252 = Bit.And(0xFF,Buffer(16)) Then
'            incr = 0
            index = index + 1
           
'            For incr = 0 To 16 Step 1              
'                kilobuf(index+incr)  = Buffer(incr)          
'            Next
    label6.text = (index) 'tst0
        If index > 170 Then
        index = 0
        End If
           
            End If
                End If
End Sub

Sub Activity_Resume
       
'    For tst = 1 To 522222 Step 1
'        tst0 = tst0 + 1
'        Sleep (50)
'        label6.text = (index) 'tst0      
'    Next
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub
 
Last edited:

OliverA

Expert
Licensed User
Longtime User
Pensez vous que usbserial est mieux ?
Si ça marche, ça marche
Maintenant quand je reçois des informations toute les 0,5 µs ça fonctione, le smartphone ne freeze plus
Dans ce cas, même si cela fonctionne, je serais toujours réticent à mettre à jour l'interface utilisateur 2 000 fois par seconde.
 

fgh3966

Active Member
Licensed User
🥴 vous chipotez (terme Français), bon je me suis trompé de valeur : 0,5ms
Sinon le 50hz >> f=1/t = 20ms chez les frenchiies et aux US 1/60 = 16.66ms. Rafraichir l'interface plus vite que ça ne sert pas à grand chose. C'est la persistance rétiniene.
 

emexes

Expert
Licensed User
Sinon le 50hz >> f=1/t = 20ms chez les frenchiies et aux US 1/60 = 16.66ms.

Est-ce un indice que la mesure est liée à la fréquence d'alimentation électrique ?

La fréquence de rafraîchissement du cadre d’affichage de l’appareil n’est pas nécessairement la même que la fréquence d’alimentation électrique. Et le taux de mise à jour de l’affichage peut encore être différent.

Rafraichir l'interface plus vite que ça ne sert pas à grand chose.

Je suis heureux que nous soyons tous d’accord sur le fait qu’il n’est pas nécessaire de mettre à jour l’affichage plus rapidement que les mises à jour ne peuvent s’afficher.

Cela rendra votre projet beaucoup plus facile.

La question suivante est la suivante : pouvons-nous ignorer complètement l'analyse et le calcul des paquets situés entre, mais non compris, les paquets affichés ?

Par exemple, si vous recevez un événement _NewData qui vous donne 15 nouveaux paquets de 19 octets, est-il utile de traiter les 14 anciens paquets périmés, étant donné que le 15ème paquet est l'information la plus récente ?

Chaque paquet de 19 octets est-il indépendant ? Ou sont-ils liés d’une manière ou d’une autre ? Les nouvelles mesures dépendent-elles des anciennes mesures ? Ou les paquets sont-ils entrelacés, par exemple un cycle répétitif de trois paquets, le premier mesure la tension, le deuxième le courant, le troisième la température, puis le cycle se répète.

Il serait utile que vous puissiez décrire votre projet plus en détail. Mais je comprends qu'il peut exister des politiques de confidentialité de l'entreprise qui limitent les informations que vous pouvez nous fournir. Lol... nous, votre équipe internationale, opérant à moitié les yeux bandés et combinée à des accidents de traduction automatique anglais-français, devrait être divertissante. 🍻
 
Last edited:
Top