Android Question Serial communication with timer

Cenny

Active Member
Licensed User
Longtime User
I have an app that is receiving data from an altimeter.
The altimeter is sending packages of 404 bytes.
The first 4 bytes contain information about the total number of packages to expect and the actual package number.
The rest is alti data.
On connection, the altimeter sends 14 bytes containing info about ID, battery voltage, etc, immediately followed by the first package of 404.
Reception of this package is confirmed by sending a code back to the altimeter, which in return sends the following package.
A timer is set at 1000ms. If the next package is not received, the tick event sends a message, asking to repeat the transmission.
This request is repeated max three times. When still unsuccessful, the connection is cut.
Sometimes this works and I do receive up to 100 packages and more, sometimes it dies in the timer_tick event.
Any Ideas?

B4X:
Sub Process_Globals
    Dim timer1 As Timer
    Dim AStream As AsyncStreams
    ...
End Sub

B4X:
Sub Bluetooth_serial_Connected (Success As Boolean)
   If Success then
        AStream.InitializePrefix(bluetooth_serial.InputStream, False, bluetooth_serial.OutputStream, "AStream") 
        Module1.SendBTConnectionEstablishedCode

End Sub

B4X:
Sub AStream_NewData (Buffer() As Byte)
    If Buffer.Length=14 Then
            'initialize an empty list to store the package data
            lst.Initialize
            'Reset the counters
            NrOfPackages=0
            PackageNumber=0
            LastPackageNumber=0
            Module1.RequestDataCommand
            timer1.Enabled=True
    else If Buffer.length= 404 Then
        Dim Shorts() As Short
        timer1.Enabled=False
        Shorts= bc.ShortsFromBytes(Buffer)

        NrOfPackages = Shorts(0)
        PackageNumber = Shorts(1)

     
       If PackageNumber > LastPackageNumber Then
          For i = 2 To Shorts.length-1 
             lst.Add(Shorts(i))
          Next
      End if

      Module1.SendPackageReceivedCommand
      'reset here the packageRepeatRequestCounter
       packageRepeatRequestCounter=0

        If PackageNumber < NrOfPackages Then
            timer1.Enabled=True
            LastPackageNumber=PackageNumber
        Else
            timer1.Enabled=False
            Log("Alles binnen " & lst.Size)
            PackageRequested=False

        End If
    End If
  

  
End Sub
B4X:
Sub timer1_Tick
    If ConnectionState=True Then   
        ' First action turn timer off
        timer1.Enabled=False
        'Increase packageRepeatRequestCounter
        packageRepeatRequestCounter=packageRepeatRequestCounter+1
                  
        If packageRepeatRequestCounter>3 Then
            packageRepeatRequestCounter=0
            timer1.Enabled=False
            btnONOff_Click
        Else
                  
            Module1.SendRepeatPackageCommand
            timer1.Enabled=True
            Log("repeat " & packageRepeatRequestCounter)
              
        End If
    End If
End Sub
 
Last edited:

agraham

Expert
Licensed User
Longtime User
Serial comms is trickier than most people think :eek:

I think that you are making the common mistake of assuming that all your data will arrive in one 'lump' in the NewData event. This is not so (unless you are using AsyncStreams in prefix mode which I suspect that you can't here). Your data can arrive split into several portions over multiple events so you should buffer successive receipts of data concatenating them into a buffer and examine that buffer in each event to see if your packet is complete.

When you add in the possibility of corrupted characters due to noise on the line, timeouts for missing characters that never arrive to complete a packet and the need to re-synchronize transmission when that happens a robust serial comms package can get quite complicated - see the TCP/IP protocols for examples of that!
 
Upvote 0

Cenny

Active Member
Licensed User
Longtime User
Serial comms is trickier than most people think :eek:

I think that you are making the common mistake of assuming that all your data will arrive in one 'lump' in the NewData event. This is not so (unless you are using AsyncStreams in prefix mode which I suspect that you can't here). Your data can arrive split into several portions over multiple events so you should buffer successive receipts of data concatenating them into a buffer and examine that buffer in each event to see if your packet is complete.

When you add in the possibility of corrupted characters due to noise on the line, timeouts for missing characters that never arrive to complete a packet and the need to re-synchronize transmission when that happens a robust serial comms package can get quite complicated - see the TCP/IP protocols for examples of that!
I am using asyncStreams in prefix mode. Sorry that I did not mention it in the declarations
 
Upvote 0
Top