Android Question [SOLVED] Byte sending USB error

saunwin

Active Member
Licensed User
Longtime User
Evening guys,
The code below throws up an error when trying to send a byte via usb
I know somethings wrong - what have i done or not done here.
Thanks in advance
Steve


B4X:
Private Sub Timer2_Tick        'used to send data to controller in 2 seconds
    
    Timer2.Enabled=False                    'switch timer off
    tx = Bit.ShiftLeft(tx,1)                'tx is a string
    Log(tx)                                    'prints the correct #
    tx=Bit.Or(tx,0x80)                        'is correct 02 becomes 130 (0x82)
    Log(tx)
        
    Dim t() As Byte = bc.HexToBytes(tx)        't becomes a byte to send - CRASH
    
        If usbserial.IsInitialized Then
            usbserial.Write(t)
        End If
    
End Sub

Logger connected to: Fusion5 Fusion5_F104Bv2
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **

2
130
Error occurred on line: 331 (Main)
java.lang.Exception: hex string has odd number of characters
at anywheresoftware.b4a.agraham.byteconverter.ByteConverter.HexToBytes(ByteConverter.java:254)
at Target.Game.main._timer2_tick(main.java:1178)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:105)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6548)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)
 

OliverA

Expert
Licensed User
Longtime User
HexToBytes converts a String of Hex characters. A string of "130" is not a Hex string. "82" would be a hex string.
One of the big problems here is conflating String with Int with Byte.

tx = Bit.ShiftLeft(tx,1)

In the code above, the String tx is converted to an Int, then shifted left, and converted back to a string.

From your example, it looks like the original string value was "1" and the resulting a "2"

tx=Bit.Or(tx,0x80)

In this code, the string "2" is converted to an Int with value of 2, Or'd with 0x80, producing an Int of value 130. This Int is converted back to the string tx, which now contains "130", not "82", which is why Log(tx) produces "130", not 82.

This "130" then cannot be converted via HexToBytes.

If tx contains a Hex string value ("00" through "FF"), then what you may be trying to do is the following

B4X:
Dim t() As Byte = bc.HexToBytes(tx)
Log($"Original value: ${t(0)}"$)
Dim myByte As Byte = Bit.ShiftLeft(t(0),1)
Log($"Shifted value: ${myByte}"$)
myByte = Bit.Or(myByte, 0x80)
Log($"Or'd value: ${bc.HexFromBytes(Array As Byte (myByte))}"$)
If usbserial.IsInitialized Then
    usbserial.Write(myByte)
End If

If tx contains a Byte value ("0" through "255"), then what you may be trying to do is the following
B4X:
Dim tempInt As Int = tx ' may blow if tx does not contain a valid integer value
Log($"Original value: ${tempInt}", in hex: ${bc.HexFromBytes(bc.IntsToBytes(Array As Int(tempInt)))}"$)
tempInt = Bit.ShiftLeft(tempInt,1)
Log($"Shifted value: ${tempInt}, in hex: ${bc.HexFromBytes(bc.IntsToBytes(Array As Int(tempInt)))}"$)
Dim myByte As Byte = Bit.And(tempInt, 0xFF)
Log($"Byte value of shifted value: ${myByte}, in hex: ${bc.HexFromBytes(Array As Byte (myByte))}"$)
myByte = Bit.Or(myByte, 0x80)
Log($"Or'd value: ${myByte}, in hex: ${bc.HexFromBytes(Array As Byte (myByte))}"$)

If usbserial.IsInitialized Then
    usbserial.Write(myByte)
End If
 
Upvote 0

teddybear

Well-Known Member
Licensed User
B4X:
Private Sub Timer2_Tick        'used to send data to controller in 2 seconds
 
    Timer2.Enabled=False                    'switch timer off
    tx = Bit.ShiftLeft(tx,1)                'tx is a string
    Log(tx)                                    'prints the correct #
    tx=Bit.Or(tx,0x80)                        'is correct 02 becomes 130 (0x82)
    Log(tx)
   
    Dim t() As Byte = bc.HexToBytes(tx)        't becomes a byte to send - CRASH
 
        If usbserial.IsInitialized Then
            usbserial.Write(t)
        End If
 
End Sub
1. Bit.ShiftLeft(N as int, Shift as int)
The1st parameter should be int not String
2. bc.HexToBytes(hex)
The hex is HexString

if tx is a char, you should use asc function to get its int value
the code is like following

B4X:
Private Sub Timer2_Tick        'used to send data to controller in 2 seconds
    Timer2.Enabled=False 
    dim tx1 as byte = asc(tx)
    tx1 = Bit.ShiftLeft(tx1,1)                                   
    tx1=Bit.Or(tx1,0x80)      
  'tx1 is just byte you won't have to do anything for it           
    If usbserial.IsInitialized Then
         usbserial.Write(tx1)
     End If
End Sub
 
Last edited:
Upvote 0

saunwin

Active Member
Licensed User
Longtime User
OliverA and Teddybear. Excellent concise explainations. Thank you.
As a (very old) bits and bytes 8051 assembly programmer all these types and castings gets my OAP brain confused LOL.
Appreciate your replies - many thanks. Steve
 
Upvote 0

saunwin

Active Member
Licensed User
Longtime User
Just to add.
I want to send the hex byte to my microcontroller out of the USB port. I used a CP2102 to plug into the usb port and the felusbserial library.
The code from OliverA above worked but the write line must change to :-

usbserial.Write(Array As Byte (myByte))
 
Upvote 0
Top