Page 1 of 1

Big endian txCAN

Posted: Sat Dec 24, 2016 4:29 pm
by fitdes
Hi all,
How do you send CAN messages that are more than 8 bit long in Big endian format?

I am trying to send can message to my AEM Infinity ECU and can send 8 bit messages but I'm struggling with 16bit. I want to do this to allow for AEM native logging which allows me to create math channels in AEM data

Also any idea of how to send signed messages?

Posted: Sat Dec 24, 2016 7:40 pm
by brentp
You can extract the high and low bytes with some bitwise operations:



Code: Select all

x = 0x0102 --(257 in decimal)

low = bit.band(x, 0xFF) -- mask out high byte
high = bit.rshift(x, 8) -- shift high byte to the right

println('x = ' ..x)
println('low = ' ..low)
println('high = ' ..high)
and the output:

Code: Select all

[lua] Gracefully stopping Lua Task
[lua] Destroying Lua State
[lua] Initializing Lua state
[lua] memory usage: 16KB
[lua] Starting Lua Task
[lua] Loading script. Length: 206
x = 258.0
low = 2.0
high = 1.0
[lua] Successfully loaded script.

Hope that helps!

Posted: Sun Dec 25, 2016 12:22 pm
by fitdes
Excellent thank you Brent,

I'm trying to emulate AEM's vehicle dynamics module using the RCP. So far my code looks like this but I'm still unsure of how I would create a 32bit message using bitwise. See attachment for description of message.

initCAN(0, 500000)
tickRate = 10

function onTick()

lat,lon = getGpsPos()
speedmph = getGpsSpeed()
--speedmph = 1.00
--altitude = getGpsAltitude()
quality = getGpsQuality()
sats = getGpsSats()
year,month,day,hour,minute,second = getDateTime()
xg = getImu(0)
yg = getImu(1)
zg = getImu(2)
xy = getImu(3) --yaw
yy = getImu(4) --pitch
zy = getImu(5) --roll

--lowlat = bit.band(lat.0xffffffff)
--midlat = bit.rshift(lat.
lowspeed = bit.band(speedmph,0xFF)
highspeed = bit.rshift(speedmph,8)
lowalt = bit.band(altitude,0xff)
highalt = bit.rshift(altitude,8)
lowxg = bit.band(xg,0xFF)
highxg = bit.rshift(xg,8)
lowyg = bit.band(yg,0xFF)
highyg = bit.rshift(yg,8)
lowzg = bit.band(zg,0xFF)
highzg = bit.rshift(zg,8)

lowxy = bit.band(xy,0xFF)
highxy = bit.rshift(xy,8)
lowyy = bit.band(yy,0xFF)
highyy = bit.rshift(yy,8)
lowzy = bit.band(zy,0xFF)
highzy = bit.rshift(zy,8)


--msg0 = {lat%256,lat/256,lon}
msg1 = {lowspeed,highspeed,lowalt,highalt}
msg2 = {sats,year-208,month,day,0,hour,minute,second}
msg3 = {lowxg,highxg,lowyg,highyg,lowzg,highzg}
msg4 = {lowxy,highxy,lowyy,highyy,lowzy,highzy}

--txCAN(0, 655360, 1, msg0)
txCAN(0, 655361, 1, msg1)
txCAN(0, 655362, 1, msg2)
txCAN(0, 655363, 1, msg3)
txCAN(0, 655364, 1, msg4)

end

Posted: Mon Dec 26, 2016 2:08 pm
by fitdes
The script below is verified to send Racecapture Pro2 Canbus data to an AEM Infinity 506 to simulate an AEM Vehicle Dynamics Module. The only channels that are not transmitted are:

latitude (unsure how to send a 32 bit message)
longitude (again unsure how to send a 32 bit message)
GPSTrueCouse (don't believe RCP has this channel to send)

With all the other data logged by the AEM Infinity I can now create Maths Channels with AEM data!!


initCAN(0, 500000)
tickRate = 100

function onTick()

lat,lon = getGpsPos()
speedmph = getGpsSpeed()/0.01
altitude = getGpsAltitude()
quality = getGpsQuality()
sats = getGpsSats()
course = 20/0.01
year,month,day,hour,minute,second = getDateTime()
xg = getImu(0)/0.000244141
yg = getImu(1)/0.000244141
zg = getImu(2)/0.000244141
yaw = getImu(3)/0.015258789 --yaw
pitch = getImu(4)/0.015258789 --pitch
roll = getImu(5)/0.015258789 --roll

lowlat = bit.band(lat,0xFFFF)
midlat = bit.rshift(lat,8)
highlat = bit.rshift(lat,16)
higherlat = bit.rshift(lat,32)
lowspeed = bit.band(speedmph, 0xFF)
highspeed = bit.rshift(speedmph,8)
lowcourse = bit.band(course, 0xFF)
highcourse = bit.rshift(course,8)
lowalt = bit.band(altitude,0xff)
highalt = bit.rshift(altitude,8)

lowxg = bit.band(xg,0xFF)
highxg = bit.rshift(xg,8)
lowyg = bit.band(yg,0xFF)
highyg = bit.rshift(yg,8)
lowzg = bit.band(zg,0xFF)
highzg = bit.rshift(zg,8)

lowyaw = bit.band(yaw,0xFF)
highyaw = bit.rshift(yaw,8)
lowpitch = bit.band(pitch,0xFF)
highpitch = bit.rshift(pitch,8)
lowroll = bit.band(roll,0xFF)
highroll = bit.rshift(roll,8)
steering = 50


msg0 = {higherlat,highlat,midlat,lowlat,lon}
msg1 = {highspeed,lowspeed,highalt,lowalt,highcourse,lowcourse,sats,quality}
msg2 = {quality,year-208,month,day,0,hour,minute,second}
msg3 = {highxg,lowxg,highyg,lowyg, highzg,lowzg}
msg4 = {highyaw,lowyaw,highpitch,lowpitch,highroll,lowroll}

txCAN(0, 655360, 1, msg0)
txCAN(0, 655361, 1, msg1)
txCAN(0, 655362, 1, msg2)
txCAN(0, 655363, 1, msg3)
txCAN(0, 655364, 1, msg4)

end

Posted: Tue Jan 10, 2017 8:58 pm
by fitdes
Hi all,

was wondering if anyone has an idea how to split a 32bit message into 8 bit sections for Can transmission.

Regards and thanks,

Des

Posted: Wed Jan 11, 2017 10:33 am
by MikeD
Didn't verify it but can you try the following:

lowlat = bit.band(lat,0xFF)
midlat = bit.band(bit.rshift(lat,8),0xFF)
highlat = bit.band(bit.rshift(lat,16),0xFF)
higherlat = bit.rshift(lat,24)

Please come back with the outcome of this!

www.facebook.com/RaceElectronic

Posted: Sun Jan 15, 2017 4:54 pm
by fitdes
Hi MikeD,

thanks for the help. I gave the code a shot but using printl within Racecapture to verify if the code was splitting Latitude into 8 bit segments but no luck. I'm not sure if Lua allows for cascaded commands

Posted: Mon Jan 16, 2017 6:01 pm
by MikeD
Hi Des,
what do you mean when you say that you tried but no luck?
Tested what I suggested with some generic numbers and it gave me correct results...so the cascaded commands as well as the bitwise operators seem to work correctly as they should and splitted a bigger number into single bytes.

Code: Select all

tickRate = 30
lat = 0xFDFCFBFA   -- (results in 2147483647 decimal)
lowlat = 0
midlat = 0
highlat = 0
higherlat = 0

function onTick()
  lowlat = bit.band(lat,0xFF) 
  midlat = bit.band(bit.rshift(lat,8),0xFF) 
  highlat = bit.band(bit.rshift(lat,16),0xFF) 
  higherlat = bit.rshift(lat,24)    

  println("lat       "..lat)
  println("lowlat    "..lowlat)
  println("midlat    "..midlat)
  println("highlat   "..highlat)
  println("higherlat "..higherlat)
end

setTickRate(tickRate)
and the results...

Code: Select all

lat       2147483647.0
lowlat    250.0
midlat    251.0
highlat   252.0
higherlat 253.0
Can you post some numbers/results/screenshots of whatever you think doesn't work on your end?

Posted: Wed Apr 26, 2017 8:21 pm
by fitdes
initCAN(0, 500000)
tickRate = 1000

function onTick()

function splitWord16(value)
return bit.band(value, 0xFF), bit.rshift(bit.band(value, 0xFF),8)
end

function splitWord32(value)
return bit.band(value, 0xFF), bit.rshift(bit.band(value, 0xFFFF),8), bit.rshift(bit.band(value, 0xFFFFFF),16), bit.rshift(bit.band(value, 0xFFFFFFFF),24)
end
--function onTick()

lat,lon = getGpsPos()
--lat,lon = 16777217,68500

speedmph = getGpsSpeed()/0.01
altitude = getGpsAltitude()
quality = getGpsQuality()
sats = getGpsSats()
year,month,day,hour,minute,second = getDateTime()
xg = getImu(0)/0.000244141
yg = getImu(1)/0.000244141
zg = getImu(2)/0.000244141
yaw = getImu(3)/0.015258789 --yaw
pitch = getImu(4)/0.015258789 --pitch
roll = getImu(5)/0.015258789 --roll

lowlat, midlat, highlat, higherlat = splitWord32(lat)
lowlon, midlon, highlon, higherlon = splitWord32(lon)
lowspeed, highspeed = splitWord16(speedmph)
lowalt, highalt = splitWord16(altitude)
lowxg, highxg = splitWord16(xg)
lowyg, highyg = splitWord16(yg)
lowzg, highzg = splitWord16(zg)
lowyaw, highyaw = splitWord16(yaw)
lowpitch, highpitch = splitWord16(pitch)
lowroll, highroll = splitWord16(roll)

msg1 = {higherlat,highlat,midlat,lowlat,higherlon,highlon,midlon,lowlon}
msg2 = {highspeed,lowspeed,highalt,lowalt,highcourse,lowcourse,sats,quality}
msg3 = {quality,year-208,month,day,0,hour,minute,second}
msg4 = {highxg,lowxg,highyg,lowyg, highzg,lowzg}
msg5 = {highyaw,lowyaw,highpitch,lowpitch,highroll,lowroll}

txCAN(0, 655360, 1, msg1)
txCAN(0, 655361, 1, msg2)
txCAN(0, 655362, 1, msg3)
txCAN(0, 655363, 1, msg4)
txCAN(0, 655364, 1, msg5)

println("lat "..lat)
println("lowlat "..lowlat)
println("midlat "..midlat)
println("highlat "..highlat)
println("higherlat "..higherlat)
println("latcalc "..(higherlat*16777216)+(highlat*65536)+(midlat*256)+lowlat)
println("xg "..xg*0.000244141)
println("lowxg "..lowxg)
println("highxg "..highxg)
println("xgcalc "..((highxg*256)+lowxg)*0.000244141)

end

Posted: Wed Apr 26, 2017 8:27 pm
by fitdes
Made some more progress on splitting Longitude into individual bytes by using code above. This data is to be transmitted to my AEM Infinity ECU. I think my issue is I don't know how to create the conversion to 32 bit float with degree referencing. Please see extract from AEMnet pdf. Anyone got any ideas?

Posted: Fri Dec 29, 2017 3:35 pm
by thoraxe
fitdes wrote:Made some more progress on splitting Longitude into individual bytes by using code above. This data is to be transmitted to my AEM Infinity ECU. I think my issue is I don't know how to create the conversion to 32 bit float with degree referencing. Please see extract from AEMnet pdf. Anyone got any ideas?
I realize this is an ancient thread -- did you ever figure this out?

I'm trying to transmit GPS data to an AEM CD7 dash, although I don't need to adhere to their (AEM) protocol.

I will need to send signed values, though.

Posted: Fri Dec 29, 2017 10:27 pm
by brentp
Hi,

It should work fine. Here's a script we have used to simulate SmartyCam data from our early testing, should get you started: https://gist.github.com/brentpicasso/0c ... e80c86694c

Posted: Tue Jan 02, 2018 5:31 pm
by thoraxe
* Are these values big or little endian?
* Are these values automatically signed?

For example, it looks like speed is split into two 8-bit words (total of 16 bits). It looks like you are sending speed1 and then speed2, which I guess is little endian?

Posted: Tue Jan 02, 2018 5:36 pm
by brentp
Hi,

It's being sent little endian, and the sign is automatically encoded. If you look at the lua script, you can see how it send the order of the bytes, illustrating how it's little endian.