B4J Question Hex conversion problem [SOLVED]

Didier99

Member
Licensed User
I am trying to convert a large decimal value (the ID from a CAN DBC file) like 2566848554 into a hex string.
When I read the value into a long and use debug, B4J correctly displays the value as 0x18FF002A
but when I use byte converter as below, it returns the wrong value (0x98FF002A):

B4X:
Sub getIDinHex( in As Long ) As String
    Dim bc As ByteConverter, out As String
    Dim l(1) as Long
    l(0) = in
    Dim byteArray() As Byte = bc.LongsToBytes( l )
    ' Convert the byte array to a hexadecimal string
    out = bc.HexFromBytes( byteArray )
    out = "0x" & Regex.Replace( "^0+", out, "" )
    Return out
End Sub ' getIDinHex()

Debugging gets to be very confusing because the byte array is displayed as signed.
It may be because there is no unsigned variable of any type and I am getting very confused about the best way to deal with that...
If I replace Dim l(1) As Long with Dim l(1) As Int, and use bc.IntsToBytes(), I get the same result.

I fixed it as below, but this can't be the only way or the best way:
B4X:
If byteArray(0) < 0 Then byteArray(0) = byteArray(0) + 128

Any help appreciated
 

Swissmade

Well-Known Member
Licensed User
Longtime User
can you not use
Dim Result as long = 2566848554
log( Bit.ToHexString(Result).ToUpperCase)
 
Upvote 0

teddybear

Well-Known Member
Licensed User
I am trying to convert a large decimal value (the ID from a CAN DBC file) like 2566848554 into a hex string.
When I read the value into a long and use debug, B4J correctly displays the value as 0x18FF002A
but when I use byte converter as below, it returns the wrong value (0x98FF002A):
Why do you say the value (0x98FF002A) is wrong?
Using debug, the value also is 0x98FF002A
You can validate it here
 
Last edited:
Upvote 0

Didier99

Member
Licensed User
Why do you say the value (0x98FF002A) is wrong?
Using debug, the value also is 0x98FF002A
Interestingly, that's what my calculator also says (now that I have checked it), but that's not what my CAN tool says...
My CAN tool (SavvyCAN) is converting 0x18FF002A into 2566848554 but it is accepting 0x18FF002A as ID in the CAN message.
The difference between the two is 0x80000000.
Maybe the CAN tool is stripping the upper bit, which is what I am doing with If byteArray(0) < 0 Then byteArray(0) = byteArray(0) + 128

Looks like the problem may be with my CAN tool!
 
Upvote 0

Didier99

Member
Licensed User
I have done a bit more investigation:
SavvyCAN interprets both 2566848554 (0x98FF002A) and 419364906 (0x18FF002A) as 0x18FF002A but when asked to load then save a dbc file that has ID 419364906, it saves it as 2566848554.
That definitely looks like a bug with SavvyCAN.

Thank you for questioning my erroneous assumption!
 
Upvote 0

teddybear

Well-Known Member
Licensed User
That definitely looks like a bug with SavvyCAN.
This is not a bug.
The rule should be "add 0x80000000, 419364906 in decimal" , to the ID numbers when describing to 29 bit IDs in a DBC file.
 
Last edited:
Upvote 0

Didier99

Member
Licensed User
This is not a bug.
The rule should be "add 0x80000000, 419364906 in decimal" , to the ID numbers when describing to 29 bit IDs in a DBC file.
The rule "should be" or "is"? Do you have a link to this rule?

Interestingly, I discovered this "conversion" because I originally created a simple dbc file "by hand", where the ID was 419364906 (0x18FF002A) .
I fed this file into SavvyCAN which took it and used it as expected.
Then I exported my hand-made dbc file from SavvyCAN and that's when the ID changed from 419364906 to 2566848554
But SavvyCAN will treat both 2566848554 (0x98FF002A) and 419364906 (0x18FF002A) the same way.
I do not understand the purpose of converting from one to the other?
 
Upvote 0

teddybear

Well-Known Member
Licensed User
That one bit is there to differentiate between 29 and 11 bit IDs. it should be rule.
277375685-cd998b68-c2c9-4c15-8867-6fe7d0d76564.png
 
Upvote 0

Didier99

Member
Licensed User
That one bit is there to differentiate between 29 and 11 bit IDs. it should be rule.
View attachment 168771
Thank you, I had missed this. What document or resource did you get this from?

By the way, I am using this to debug/test an embedded device I designed that is generating the CAN messages, and the driver for the CAN controller in that device has a separate bit to indicate the 29 bit ID (not bit 31 of the 32 bit variable used to store the ID), so in my code, the ID remains a 29 bit variable (stored in a 32 bit int) as it should be and a separate bit is used to denote an extended ID.
I also use an inexpensive CAN-USB adaptor to decode the messages, and it also has a separate field to indicate extended ID, so up until now, everything was working as expected.

Edit: I found the reference in the CSS Electronics website: https://www.csselectronics.com/pages/can-dbc-file-database-intro
B4X:
29-bit CAN IDs: 29-bit IDs are stored in the DBC as 32 bit IDs, with the extra 3 bits indicating that the ID is extended. You can extract the 29-bit ID by applying a mask (0x1FFFFFFF).
 
Last edited:
Upvote 0

teddybear

Well-Known Member
Licensed User
Upvote 0

Didier99

Member
Licensed User
Thank you.
It's kinda crazy to use the 31st bit to identify extended ID when the IDE field is explicitly designated for that.
1765221535925.png

But that's not the craziest thing with CANBus, J1939 or the DBC file format :)
Thank you for the link!
 
Upvote 0
Top