Android Question Bluetooth Connection - Strange Stuff

Discussion in 'Android Questions' started by rodmcm, Jul 12, 2019.

  1. rodmcm

    rodmcm Active Member Licensed User

    Hi
    I am transmitting integers from ESp32 to B4A ( only 6 at a time in an array). Having all sorts of problems with errors including B4r Serialization. This experiment went back to basics to try and sort the problem by developing bytes from Ints ( been through the byte converter route as well)

    The attached is a summary of the reception at the B4A on a Levono Tablet. Some of the data is fine, then it all turns to custard.

    Has anyone any idea why this should be? I have tried different ESP's but unfortunately only one tablet.

    Code sending from B4R

    Code:
    Sub SendBT
        
    If btConnected Then
        
    '    bt_astream.Write(ser.ConvertArrayToBytes(Array(SendArray(0),SendArray(1),SendArray(2),SendArray(3),SendArray(4),SendArray(5),SendArray(6))))
            Log(SendArray(0)," ",SendArray(1)," ",SendArray(2)," ",SendArray(3)," ",SendArray(4)," ",SendArray(5)," ",SendArray(6))
            
    Dim SendByteArray(20As Byte
            
    Dim j =0 As Int
            
    For i = 0 To 9
                SendByteArray(j) =
    Bit.And(SendArray(i),0xFF)
                SendByteArray(j+
    1) = Bit.And(Bit.ShiftRight(SendArray(i),8),0xff)
                j=j+
    2
            
    Next
            
            
    Log(SendByteArray(0)," ",SendByteArray(1)," ",SendByteArray(2)," ",SendByteArray(3)," ",SendByteArray(4)," ",SendByteArray(5)," ",SendByteArray(6)," ",SendByteArray(7)," ",SendByteArray(8)," ",SendByteArray(9)," ",SendByteArray(10)," ",SendByteArray(11)," ",SendByteArray(12)," ",SendByteArray(13))
            
            bt_astream.Write(SendByteArray)
            Delay(
    400)
        
    End If
    End Sub
    Code Receiving at B4A

    Code:
    AStream_NewData (Buffer() As Byte)
    'Log("Buffer Length  "& Buffer.length)
    'Log(bc.HexFromBytes(Buffer))
        If Buffer.Length Mod 2 = 0 And Buffer.Length<=20 Then
            
    Log(Buffer(0) &" "&Buffer(1) &" "&Buffer(2) &" "&Buffer(3) &" "&Buffer(4) &" "&Buffer(5) &" "&Buffer(6) &" "&Buffer(7) &" "&Buffer(8) &" "&Buffer(9) &" "&Buffer(10) &" "&Buffer(11) &" "&Buffer(12) &" "&Buffer(13) &" "&Buffer(14) &" "&Buffer(15) &" "&Buffer(16) &" "&Buffer(17) &" "&Buffer(18) &" "&Buffer(19))
            
    Dim Data(Buffer.length) As Int
            
    Dim j As Int =0
            
    For i=0 To Buffer.Length-1 Step 2
                
    Dim Byte1 As Byte =Bit.Shiftleft(Buffer(i+1),8)
                
                
    'Data(j) = Bit.Or(Buffer(i),Bit.Shiftleft(Buffer(i+1),8))    ' Adds bytes to make an integer
                Data(j) = Bit.Or(Buffer(i),Byte1)
                j=j+
    1
            
    Next
        
    If Data.Length = 0 Then Return                            'invalid message
            Log("FromESP32  "& Data(0) & "  "& Data(1) &"  " & Data(2) & "  " & Data(3)&"  "& Data(4)&"  "& Data(5)&"  "& Data(6))
     

    Attached Files:

  2. emexes

    emexes Well-Known Member Licensed User

    Do you have ByteConverter library in B4R?

    If so, could use something like:
    Code:
    Dim bc As ByteConverter

    Dim IntsToSend(6As Int = Array As Int(111222333444555666)

    Log(IntsToSend.Length)
    For I = 0 To IntsToSend.Length - 1
        
    Log("IntsToSend(" & I & ") = " & IntsToSend(I))
    Next

    Dim BytesToSend() As Byte = bc.IntsToBytes(IntsToSend)    'split 32-bit Ints to 8-bit bytes

    Log(BytesToSend.Length)
    For I = 0 To BytesToSend.Length - 1
        
    Log("BytesToSend(" & I & ") = " & BytesToSend(I))
    Next
    and then the matching reverse function bc.IntsFromBytes at the other end to unpack the bytes and convert them back to Ints
     
    Last edited: Jul 12, 2019
  3. emexes

    emexes Well-Known Member Licensed User

    ByteConverter seems to be in rRandomAccessFile library. Who'd've thunk that?

    :)
     
  4. emexes

    emexes Well-Known Member Licensed User

    In fact, all that bit twiddling and looping above can probably just be condensed down to:
    Code:
    Dim bc As ByteConverter
    bt_astream.Write(bc.IntsToBytes(SendArray))
    assuming that you want to send ALL of SendArray().
     
  5. rodmcm

    rodmcm Active Member Licensed User

    Found the problem but not the solution!!!!

    Ints in B4r are 2 bytes and ints in B4A are 4 bytes. (I used B4r to test my send and receive and of course it worked fine)

    If I use

    bt_astream.Write(bc.IntsToBytes(SendArray)) at the send end

    and

    Dim Data() As Int = bc.IntsFromBytes(Buffer) at the receive end

    does not work at the B4A end
     
  6. emexes

    emexes Well-Known Member Licensed User

    Hmm. Good thing one of us is awake. No worries, though:
    Code:
    Dim Data() As Short = bc.ShortsFromBytes(Buffer)
     
  7. emexes

    emexes Well-Known Member Licensed User

    Einstein here somehow missed this. But... I use ByteConverter all the time when reading BLE packets, all works great, so I probably would have posted something about giving it another go anyway.

    Did the B4A ShortsFromBytes correctly unpack the B4R IntsToBytes?

    If not, then the Bit operations should be able to do the job too, and I'll have a closer look at why they were not working in your case.
     
  8. rodmcm

    rodmcm Active Member Licensed User

    Solved!
    Code:
    Sub AStream_NewData (Buffer() As Byte)
        
    ' Converts buffer with 2 bytes per int from B4R to B4A Int with 4 bytes per int
        Dim Data(Buffer.length) As Int
        
    Dim j As Int =0
        
    For i=0 To Buffer.Length-1 Step 2
            bc.LittleEndian = 
    True
            Data(j) = bc.IntsFromBytes(
    Array As Byte(Buffer(i),Buffer(i+1),0,0))(0)     ' first, second, third and fourth byte
        j=j+1
        
    Next
        
    Log("FromESP32  "& Data(0) & "  "& Data(1) &"  " & Data(2) & "  " & Data(3)&"  "& Data(4)&"  "& Data(5)&"  "& Data(6))
    End Sub
     
    f0raster0 likes this.
  9. emexes

    emexes Well-Known Member Licensed User

    :)

    I still prefer bc.ShortsFromBytes, but to each their own, and presumably there is a reason for Data() to be Int.

    What about when AStream splits up the received data into variously-sized chunks? Or worse: odd-sized chunks?
     
  10. rodmcm

    rodmcm Active Member Licensed User

    Buffer.length Mod 2 takes care of the odd number of bytes.. I know that I have 10 integers coming down so Buffer.length<=20

    Like your pun!
    bc.shorts works fine... 32000 off enough for me.
    I really need to come to grips with bytes etc.. I didnt know what a short was until you pointed it out!
    astream in prefix mode
     
  11. emexes

    emexes Well-Known Member Licensed User

    When I saw "astream in prefix mode", all my but-what-about-? worries melted away.

    Well, some of them flipped.* Why not just check for Buffer.Length = 20 ? When would you receive fewer than 20 bytes? And if you did somehow receive a 2-byte packet, wouldn't the Log() throw a subscript-out-of-bounds error?

    You could probably let go of the safety net where Data() is Dimmed to twice the size it needs to be (to be sure, to be sure ?!) eg: for a 20-byte packet that has 10 numbers in it, the Dim Data(Buffer.Length) is allocating space for 20 numbers. I'm guessing this is a hangover from the dark old days of "manually" unpacking the numbers.

    Other beauties of: Dim Data() = bc.ShortsFromBytes(Buffer) are that 1/ the array is automatically allocated to the required size, and 2/ Data.Length tells you how many numbers were received, no calculation or hardcoding of data type size necessary.

    Excellent save with the bc.LittleEndian = True. (I'd forgotten that there are still smouldering pockets of BigEndian misleds about ;-)

    This communication link code of yours is going to be a Work Of Art by the time we're both happy with it!


    * you can't keep a natural pessimist down (or should that be: up?)
     
  12. emexes

    emexes Well-Known Member Licensed User

    If you're going to be doing any sort of communication packet or file record stuff, then it certainly helps to visualise data as bits and bytes. Byte arrays are good because they exactly represent the physical arrangement of the data being moved about, although I am a bit sad about the Java/B4X bias towards signed numbers, which makes some arithmetic shortcuts a bit shaky if the high bit is involved.

    And I didn't know that the B4R Int is only 16 bits, so we've both learned something new! Although your info was sadder: given that a programmer using B4R is likely to be using a B4X language at the other end of the cable also, it would have been good to minimize the amount of mental gear-changing necessary when moving back and forth between the two environments.

    Perhaps one day the gods will smile upon us and implement C99-style stdint types in B4X. Write once, run anywhere. Should probably be a capital A for Anywhere.

    :)
     
    f0raster0 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