Big endian txCAN

Discussion on the Lua Scripting capabilities for RaceCapture/Pro. Also see the <a href="http://autosportlabs.net/RaceCapturePro_Lua_Scripting">Lua Scripting Guide</a>

Moderators: JeffC, stieg

Post Reply
fitdes
Posts: 18
Joined: Tue Sep 01, 2015 5:03 pm

Big endian txCAN

Post 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?

brentp
Site Admin
Posts: 6282
Joined: Wed Jan 24, 2007 6:36 am

Post by brentp »

You can extract the high and low bytes with some bitwise operations:



Code: Select all

x = 0x0102 --&#40;257 in decimal&#41;

low = bit.band&#40;x, 0xFF&#41; -- mask out high byte
high = bit.rshift&#40;x, 8&#41; -- shift high byte to the right

println&#40;'x = ' ..x&#41;
println&#40;'low = ' ..low&#41;
println&#40;'high = ' ..high&#41;
and the output:

Code: Select all

&#91;lua&#93; Gracefully stopping Lua Task
&#91;lua&#93; Destroying Lua State
&#91;lua&#93; Initializing Lua state
&#91;lua&#93; memory usage&#58; 16KB
&#91;lua&#93; Starting Lua Task
&#91;lua&#93; Loading script. Length&#58; 206
x = 258.0
low = 2.0
high = 1.0
&#91;lua&#93; Successfully loaded script.

Hope that helps!
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

fitdes
Posts: 18
Joined: Tue Sep 01, 2015 5:03 pm

Post 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
Attachments
Capture.JPG
Capture.JPG (52.28 KiB) Viewed 6614 times

fitdes
Posts: 18
Joined: Tue Sep 01, 2015 5:03 pm

Post 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

fitdes
Posts: 18
Joined: Tue Sep 01, 2015 5:03 pm

Post 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

MikeD
Posts: 39
Joined: Sun May 29, 2016 11:55 am
Location: Austria
Contact:

Post 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

fitdes
Posts: 18
Joined: Tue Sep 01, 2015 5:03 pm

Post 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

MikeD
Posts: 39
Joined: Sun May 29, 2016 11:55 am
Location: Austria
Contact:

Post 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   -- &#40;results in 2147483647 decimal&#41;
lowlat = 0
midlat = 0
highlat = 0
higherlat = 0

function onTick&#40;&#41;
  lowlat = bit.band&#40;lat,0xFF&#41; 
  midlat = bit.band&#40;bit.rshift&#40;lat,8&#41;,0xFF&#41; 
  highlat = bit.band&#40;bit.rshift&#40;lat,16&#41;,0xFF&#41; 
  higherlat = bit.rshift&#40;lat,24&#41;    

  println&#40;"lat       "..lat&#41;
  println&#40;"lowlat    "..lowlat&#41;
  println&#40;"midlat    "..midlat&#41;
  println&#40;"highlat   "..highlat&#41;
  println&#40;"higherlat "..higherlat&#41;
end

setTickRate&#40;tickRate&#41;
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?

fitdes
Posts: 18
Joined: Tue Sep 01, 2015 5:03 pm

Post 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

fitdes
Posts: 18
Joined: Tue Sep 01, 2015 5:03 pm

Post 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?
Attachments
Capture.JPG
Capture.JPG (42.49 KiB) Viewed 6559 times

thoraxe
Posts: 47
Joined: Wed Dec 14, 2016 2:29 am
Location: Atlanta, GA
Contact:

Post 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.

brentp
Site Admin
Posts: 6282
Joined: Wed Jan 24, 2007 6:36 am

Post 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
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

thoraxe
Posts: 47
Joined: Wed Dec 14, 2016 2:29 am
Location: Atlanta, GA
Contact:

Post 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?

brentp
Site Admin
Posts: 6282
Joined: Wed Jan 24, 2007 6:36 am

Post 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.
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

Post Reply