ShiftX3: Difference between revisions

(Created page with "=Introduction= ==Parts in the Kit== In the kit you will receive: * ShiftX2 module * 2 M2x5mm screws for enclosure assembly * 2 #6 screws for surface mounting Image:ShiftX3...")
 
No edit summary
 
(121 intermediate revisions by 2 users not shown)
Line 2: Line 2:


==Parts in the Kit==
==Parts in the Kit==
In the kit you will receive:
* ShiftX3
* ShiftX2 module
* 2 M2x5mm screws for enclosure assembly
* 2 #6 screws for surface mounting


[[Image:ShiftX3_board]]
[[image:shiftx3_3quarter.jpg|1024px]]


==Dimensions==
==Compatibility==
* ShiftX3 bare board: 114 x 27mm (4.48 x 1.06 inches)
ShiftX3 is compatible with:
* ShiftX3 with enclosure 136 x 32 x 9.46 mm (5.35 x 1.26 x .37 inches)
* RaceCapture/Track MK2,MK3
* RaceCapture/Pro MK2,MK3,MK4
* RaceCapture/Apex
* PodiumConnect MK1,MK2


=Installation=
'''Note:''' Not compatible with RaceCapture/Track MK1.
ShiftX3 is designed to be surface mounted with the companion enclosure, or it can be embedded into your dashboard in a custom installation.  


==Printing the enclosure==
==Firmware Requirements==
The enclosure can be 3D printed by downloading the printer files.
ShiftX3 requires RaceCapture/PodiumConnect firmware 2.15.0 or higher. [http://podium.live/software Download the latest firmware]


[[file:shiftx3_enclosure_rev_A.zip|Download ShiftX3 enclosure Revision A]]
=Connection and Installation=


The enclosure consists of the following parts:
==Mounting ShiftX3==


* shiftx3.stl : Main housing for ShiftX3 - Qty 1 needed
Attach ShiftX3 with #6 mounting screws and tighten until snug.
* shiftx3_back_3dprint: Back cover for housing - Qty 1 needed
* shiftx3_light_pipe.stl: Light pipe for LEDs - Qty 9 needed
* shiftx3_light_pipe_photosensor.stl: Light pipe for photosensor - Qty 1 needed


===Printing the enclosure===
* '''Note''': You can install with the 7 segment display above or below the LED strip; see the setup instructions for selecting the orientation.
Color and material are not critical for the enclosure; however we recommend PETG.  


===Printing light pipes===
==Dimensions==
Print the 9 LED light pipes and 1 photosensor light pipe in clear filament. PETG is recommended for optical clarity.  
* ShiftX3 with enclosure 136 x 32 x 9.46 mm (5.35 x 1.26 x .37 inches)
* Enclosure DXF and PDF drawing [[file:ShiftX3_enclosure.zip]]


===Enclosure clean up===
[[image:ShiftX3_enclosure_dimensions.jpg|800px]]
Ensure extra filament is completely removed from the inside of the enclosure and is completely clean, so ShiftX3 board can fit flush and level inside the enclosure.  


====3D printing notes====
===Plug and Play connection===
* Print extra light pipes and print with a brim to purge heat-scorched / darkened filament from the extruder.
* '''Note:''' ShiftX3 requires 12v power, via RaceCapture's own power connection.
* Avoid printing just one light pipe at a time - printing just one will cause the part to sag and deform due to concentrated heat in the small part. We recommend you print at least 4 at a time to ensure heat is distributed across the parts and retain dimensional accuracy.


==Assembling the enclosure==
ShiftX3 connects effortlessly into our plug and play connector system, using the  recommended cabling accessories:
===Install light pipes===
Press the LED light pipes into the enclosure from the back side, ensuring they are flush with the front.  
* '''Note''' -The LED light pipes have a small lip that locks into the back surface.


Press the photo sensor light pipe into the front of the enclosure. There should be a tight interference fit; if there is not, use a tiny drop of super glue from the back side of the enclosure to secure it.  
* [https://www.autosportlabs.com/product/can1-can2-dual-can-splitter/ Dual CAN splitter]
* [https://www.autosportlabs.com/product/can-bus-extension-cable/ CAN extension] (choose your desired length)
* [https://www.autosportlabs.com/product/inline-can-terminator/ Inline CAN terminator]


===Install ShiftX3===
Connect the Dual CAN splitter into the CAN1/CAN2 port of your main system:
Install ShiftX3 into the back of the enclosure, guiding the switches into their respective hole.
* '''Note''' - Take care to not torque the switch handles sideways to prevent damage.


Gently press the back of ShiftX3 board so that it is fully seated into the enclosure. There should be a 0.5mm lip around the back of the enclosure where the back plate will lock into place.  
[[file:dual_can_splitter_plugged_in.jpg|600px]]


Install the back panel of ShiftX3 so the shallow lip of the back panel sits within the recess of the ShiftX3 enclosure.
Then connect your CAN extension cable to the "B" port of the Dual CAN splitter:


When pressed together, there should be no gap between the enclosure and the back plate.  If there is, check the inside of the enclosure to clean up any additional 3D printed filament.  
[[file:dual_CAN_splitter_closeup.jpg|600px]]


Secure the back plate using the two M2x5mm screws. Do not over-torque.
At the opposite end of the CAN extension, attach the inline CAN terminator:


==Connection and Installation==
[[file:inline_terminator_plugged_in.jpg|600px]]


==Mounting ShiftX3==
Finally, attach ShiftX3 to the other end of the Terminator to complete the installation.


Attach ShiftX2 with the mounting screws and tighten until snug.  
[[file:ShiftX3_with_terminator.jpg|600px]]


===Integration with RaceCapture / PodiumConnect===
===Direct wire connection===
You can connect ShiftX3 into a non plug and play system by using the following cabling accessories:


Suggested parts:
* [https://www.autosportlabs.com/product/can-power-pigtail-for-device/ Device Power+CAN Pigtail]
* [https://www.autosportlabs.com/product/inline-can-terminator/ Inline CAN terminator]


* RJ45 Splitter [https://www.amazon.com/gp/product/B078TGG5YC "Hub" shaped]
Connect the pigtail wires to your system:
* RJ45 network cable [https://www.amazon.com/s/?ref=nb_sb_noss?url=search-alias%3Delectronics&field-keywords=rj45+flat+6+foot+cable+black&rh=n%3A172282%2Ck%3Arj45+flat+6+foot+cable+black Flat style] [https://www.amazon.com/s/?ref=nb_sb_noss_2?url=search-alias%3Delectronics&field-keywords=rj45+6+foot+cable+black+round&rh=n%3A172282%2Ck%3Arj45+6+foot+cable+black+round round style]
* Green to CAN2 High
** '''Note''' Any standard CAT5 or CAT6 patch cable should work, so long as it is not a cross-over cable.
* White to CAN2 Low
* Red to +12v (same power connection for your system)
* Black to Ground (same ground connection for your system)


=====Patching the RJ45 cable to ShiftX2=====
Then connect the pigtail to the inline CAN terminator.


You will need to splice ShiftX2 to the conductors of the patch cable.  Start by snipping the RJ45 connector off the end of a patch cable, and then expose the individual wires.  
Finally, attach ShiftX3 to the other end of the Terminator to complete the installation.


[[file:Rj45labeled.jpg|500px]]
=Using ShiftX3=
The LEDs and display on ShiftX3 are controlled by RaceCapture's Lua scripting capabilities. Built-in functions provide access to ShiftX3's capabilities.  See the [[RaceCapturePro_Lua_Scripting#ShiftX2.2F3_control|ShiftX3 Lua scripting reference]] for additional details.


{| class="wikitable" style="text-align:center; width:700px; height:200px;"
'''Note:''' Ready to go scripts may be available as a preset. When in the Scripting view, press the Presets button to access a list of pre-configured scriptsBe sure to press the cloud update button to get the latest set of presets.  
|+ RJ45 power and CAN connection pinout
|-
! ShiftX2 connection
! RaceCapture Connection
! CAT5 EIA-T568B RJ45 cable
|-
| Red
| +12v
| Brown
|-
| White
| Ground
| Orange/White
|-
| No Connection
| CAN 1 High
| Orange
|-
| No Connection
| CAN 1 Low
| Green/White
|-
| Black
| CAN 2 High
| Blue
|-
| Yellow
| CAN 2 Low
| Blue/White
|}
'''Note:''' These color codes assume EIA-T568B RJ45 cable (check printing on the cable to confirm)
 
===CAN Termination===
CAN termination is enabled by defaultTo disable termination, cut the '''CAN Term''' jumper on the bottom of ShiftX3.


==Powering and Connecting to RaceCapture==
[[image:Lua_scripting_presets.png]]


=Scripts=
==Navigation Buttons==
Once ShiftX3 is powered and connected via CAN bus, the left and right ShiftX3 buttons will automatically trigger corresponding left and right navigation actions on the RaceCapture dashboard.


The following scripts assume ShiftX2 is connected to the 2nd CAN bus, and is the first ShiftX2 on the bus (ADR1 jumper default setting)
[file:https://i.imgur.com/CSQfW4s.gif]


==Disco Lights Demo==
==Disco Lights Demo==
This is a test script that exercises all of the LEDs on ShiftX2. You can use this as a first time test, as it does not rely on any sensors.  
This is a test script that exercises all of the LEDs and the 7 segment display on ShiftX3. You can use this as a first time test, as it does not rely on any sensors.  


===Script===
===Script===
Copy and paste this entire script into the scripting window, replacing any existing script.  
Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.  
 
This script will randomly set LEDs with different colors and the display will update with random numbers.
 
<pre>
<pre>
sxCan = 1
setTickRate(10)
sxId=0
tickRate=30
sxBright=0


function rndc()
function rndc()
Line 137: Line 100:
end
end


function sxOnUpdate()
function onTick()
   for i=0,9,1 do
   for i=0,9,1 do
     r = rndc()
     sxSetLed(i,1,rndc(),rndc(),rndc(),0)
    g = rndc()
    b = rndc()
sxSetLed(i,1,r,g,b,0)
   end
   end
  -- ascii characters between 0 and 9
  sxSetDisplay(0, math.random(0,9))
end
end
</pre>


function sxOnBut(b)
==Sequential shift light + Gear indicator==
  println('button: ' ..b)
This script configures just a sequential shift light, and update gear display.
end


function sxOnInit()
===Script (Gear is calculated from RPM and Speed)===
  print('sx onInit')
Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.
end


--ShiftX2 library functions--
* Default is reading RPM from the channel named "RPM"
* Default is creating the Gear channel with the channel name "Gear"


function sxSetLed(i,l,r,g,b,f)
<pre>
  sxTx(10,{i,l,r,g,b,f})
setTickRate(30)
end


function sxSetLinearThresh(id,s,th,r,g,b,f)
-- Set ShiftX3 configuration parameters with default parameters
  sxTx(41,{id,s,spl(th),sph(th),r,g,b,f})
-- orientation: 0=normal, 1=inverted (display above LED bar)
end
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)


function sxSetAlertThresh(id,tid,th,r,g,b,f)
--create gear channel
  sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
gearId = addChannel("Gear", 10, 0, 0, 6)
end


function sxSetBaseConfig(bright)
--config shift light
  sxTx(3,{bright})
sxCfgLinearGraph(0,0,0,7000) --left to right graph, smooth style, 0 - 7000 RPM range
end


function sxSetAlert(id,r,g,b,f)
sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
  sxTx(20,{id,r,g,b,f})
sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
end
sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6000 RPM


function sxUpdateAlert(id,v)
function onTick()
   if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
   sxUpdateLinearGraph(getChannel("RPM"))
end


function sxCfgLinearGraph(rs,ls,lr,hr)
  -- calculate gear: tire diameter(cm), final gear ratio, individual gear ratios 1-6
   sxTx(40,{rs,ls,spl(lr),sph(lr),spl(hr),sph(hr)})
   local gear = calcGear(62.7, 3.45, 4.23, 2.52, 1.66, 1.22, 1.0, 0.8)
  setChannel(gearId, gear)
  sxSetDisplay(0, gear)
end
end
</pre>


function sxUpdateLinearGraph(v)
===Script (Gear is provided by an existing channel)===
  sxTx(42,{spl(v),sph(v)})
Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.
end


function sxInit()
* Default is reading RPM from the channel named "RPM"
  println('config shiftX2')
* Default is reading the Gear channel with the channel name "Gear"
  sxSetBaseConfig(sxBright)
  if sxOnInit~=nil then sxOnInit() end
end


function sxChkCan()
<pre>
  id,ext,data=rxCAN(sxCan,0)
setTickRate(30)
  if id==sxCanId then sxInit() end
  if id==sxCanId+60 and sxOnBut~=nil then sxOnBut(data[1]) end
end


function sxProcess()
-- Set ShiftX3 configuration parameters with default parameters
  sxChkCan()
-- orientation: 0=normal, 1=inverted (display above LED bar)
  if sxOnUpdate~=nil then sxOnUpdate() end
-- brightness: 0-100%, 0 = auto brightness
end
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)


function sxTx(offset, data)
--config shift light
  txCAN(sxCan, sxCanId + offset, 1, data)
sxCfgLinearGraph(0,0,0,7000) --left to right graph, smooth style, 0 - 7000 RPM range
  sleep(10)
end


function spl(v) return bit.band(v,0xFF) end
sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
function sph(v) return bit.rshift(bit.band(v,0xFF00),8) end
sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6000 RPM


function onTick()
function onTick()
   sxProcess()
   sxUpdateLinearGraph(getChannel("RPM"))
  sxSetDisplay(0, getChannel("Gear"))
end
end
</pre>


sxCanId = 0xE3600 + (256 * sxId)
==Shift Light + Twin Alert + Gear Example (Gear calculated by RPM and Speed)==
println('shiftx2 base id ' ..sxCanId)
This script shows a more complete example that demos a sequential shift light + two alerts + Gear indicator.


setTickRate(tickRate)
Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.
sxInit()


</pre>
Assumptions:
* Engine Temperature on the 1st alert LED, connected to first analog channel - channel name "EngineTemp"
* Oil Pressure on the 2nd alert LED, connected to second analog channel - channel name "OilPress"
* Gear channel already exists, named "Gear"


==Sequential shift light==
Edit the script to change the analog channels you want to monitor.
This script configures just a sequential shift light.  


===Script===
===Script===
Copy and paste this entire script, replacing any existing script:
Copy and paste this entire script into the scripting window, replacing any existing script.  
 
* Default is reading RPM via OBDII. You can change to direct RPM input in the script.
 
<pre>
<pre>
-- What CAN bus ShiftX2 is connected to. 0=CAN1, 1=CAN2
setTickRate(30)
sxCan = 1
 
-- 0=first ShiftX2 on bus, 1=second ShiftX2 (if ADR1 jumper is cut)
sxId=0


--how often ShiftX2 is updated
-- Set ShiftX3 configuration parameters with default parameters
tickRate=30
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)


--Brightness, 0-100. 0=automatic brightness
--config shift light
sxBright=0
sxCfgLinearGraph(0,0,0,7000) --left to right graph, smooth style, 0 - 7000 RPM range


function sxOnUpdate()
sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
  --add your code to update ShiftX2 alerts or linear graph during run time.
sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
  --Runs continuously based on tickRate.
sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6000 RPM
 
  --uncomment the below for OBDII RPM PID
  sxUpdateLinearGraph(readOBD2(12))


  --uncomment the below for Direct RPM on input 0
--configure first alert (right LED) as engine temperature (F)
  --sxUpdateLinearGraph(getTimerRpm(0))
sxSetAlertThresh(0,0,205,255,255,0,0) --yellow warning at 205F
end
sxSetAlertThresh(0,1,225,255,0,0,10) -- red flash at 225F


function sxOnInit()
--configure second alert (left LED) as oil pressure (PSI)
  --config shift light
sxSetAlertThresh(1,0,0,0,0,255,10) --red flash below 15 psi
  sxCfgLinearGraph(0,0,0,7000) --left to right graph, linear style, 0 - 7000 RPM range
sxSetAlertThresh(1,1,15,255,255,0,5) --yellow flash 15-20 PSI
sxSetAlertThresh(1,2,20,0,0,0,0) --above 20, no alert


  sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
--create gear channel
  sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
gearId = addChannel("Gear", 10, 0, 0, 6)
  sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6500 RPM
end


function sxOnBut(b)
function onTick()
   --called if the button state changes
   --update RPM
   println('button: ' ..b)
   sxUpdateLinearGraph(getChannel("RPM"))
end


---ShiftX2 functions
  -- calculate gear: tire diameter(cm), final gear ratio, individual gear ratios 1-6
  local gear = calcGear(62.7, 3.45, 4.23, 2.52, 1.66, 1.22, 1.0, 0.8)
  setChannel(gearId, gear)
  sxSetDisplay(0, gear)


function sxSetLed(i,l,r,g,b,f)
  --update engine temp alert
   sxTx(10,{i,l,r,g,b,f})
   sxUpdateAlert(0, getChannel("EngineTemp"))
end


function sxSetLinearThresh(id,s,th,r,g,b,f)
  --update oil pressure alert
   sxTx(41,{id,s,spl(th),sph(th),r,g,b,f})
   sxUpdateAlert(1, getChannel("OilPress"))
end
end</pre>


function sxSetAlertThresh(id,tid,th,r,g,b,f)
==Shift Light + Twin Alert + Gear Example (Existing gear channel provided by ECU)==
  sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
This script shows a more complete example that demos a sequential shift light + two alerts.
end


function setBaseConfig(bright)
Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.  
  sxTx(3,{bright})
end
 
function sxSetAlert(id,r,g,b,f)
  sxTx(20,{id,r,g,b,f})
end
 
function sxUpdateAlert(id,v)
  if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
end
 
function sxCfgLinearGraph(rs,ls,lr,hr)
  sxTx(40,{rs,ls,spl(lr),sph(lr),spl(hr),sph(hr)})
end
 
function sxUpdateLinearGraph(v)
  if v ~= nil then sxTx(42,{spl(v),sph(v)}) end
end
 
function sxInit()
  println('config shiftX2')
  setBaseConfig(sxBright)
  if sxOnInit~=nil then sxOnInit() end
end
 
function sxChkCan()
  id,ext,data=rxCAN(sxCan,0)
  if id==sxCanId then sxInit() end
  if id==sxCanId+60 and sxOnBut~=nil then sxOnBut(data[1]) end
end
 
function sxProcess()
  sxChkCan()
  if sxOnUpdate~=nil then sxOnUpdate() end
end
 
function sxTx(offset, data)
  txCAN(sxCan, sxCanId + offset, 1, data)
  sleep(10)
end
 
function spl(v) return bit.band(v,0xFF) end
function sph(v) return bit.rshift(bit.band(v,0xFF00),8) end
 
function onTick()
  sxProcess()
end
 
sxCanId = 0xE3600 + (256 * sxId)
println('shiftx2 base id ' ..sxCanId)
 
setTickRate(tickRate)
sxInit()
</pre>
 
==Shift Light + Twin Alert Example==
This script shows a more complete example that demos a sequential shift light + two alerts.  


Assumptions:
Assumptions:
* Engine Temperature on the 1st alert LED, connected to first analog channel
* Engine Temperature on the 1st alert LED, connected to first analog channel - channel name "EngineTemp"
* Oil Pressure on the 2nd alert LED, connected to second analog channel
* Oil Pressure on the 2nd alert LED, connected to second analog channel - channel name "OilPress"
* Gear channel already exists (provided by ECU) and is named "Gear"


Edit the script to change the analog channels you want to monitor.
Edit the script to change the analog channels you want to monitor.
Line 353: Line 248:
Copy and paste this entire script into the scripting window, replacing any existing script.  
Copy and paste this entire script into the scripting window, replacing any existing script.  
<pre>
<pre>
-- What CAN bus ShiftX2 is connected to. 0=CAN1, 1=CAN2
setTickRate(30)
sxCan = 1
 
-- Set ShiftX3 configuration parameters with default parameters
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)


-- 0=first ShiftX2 on bus, 1=second ShiftX2 (if ADR1 jumper is cut)
--config shift light
sxId=0
sxCfgLinearGraph(0,0,0,7000) --left to right graph, smooth style, 0 - 7000 RPM range


--how often ShiftX2 is updated
sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
tickRate=30
sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6000 RPM


--Brightness, 0-100. 0=automatic brightness
--configure first alert (right LED) as engine temperature (F)
sxBright=0
sxSetAlertThresh(0,0,205,255,255,0,0) --yellow warning at 205F
sxSetAlertThresh(0,1,225,255,0,0,10) -- red flash at 225F


function sxOnUpdate()
--configure second alert (left LED) as oil pressure (PSI)
  --add your code to update ShiftX2 alerts or linear graph during run time.
sxSetAlertThresh(1,0,0,0,0,255,10) --red flash below 15 psi
  --Runs continuously based on tickRate.
sxSetAlertThresh(1,1,15,255,255,0,5) --yellow flash 15-20 PSI
 
sxSetAlertThresh(1,2,20,0,0,0,0) --above 20, no alert
  --uncomment the below for OBDII RPM PID
  sxUpdateLinearGraph(readOBD2(12))


   --uncomment the below for Direct RPM on input 0
function onTick()
   --sxUpdateLinearGraph(getTimerRpm(0))
   sxUpdateLinearGraph(getChannel("RPM"))
   sxSetDisplay(0, getChannel("Gear"))


   --update engine temp alert
   --update engine temp alert
   sxUpdateAlert(0, getAnalog(0))
   sxUpdateAlert(0, getChannel("EngineTemp"))


   --update oil pressure alert
   --update oil pressure alert
   sxUpdateAlert(1, getAnalog(1))
   sxUpdateAlert(1, getChannel("OilPress"))
end
end</pre>
 
function sxOnInit()
  --config shift light
  sxCfgLinearGraph(0,0,0,7000) --left to right graph, linear style, 0 - 7000 RPM range
 
  sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
  sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
  sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6500 RPM
 
  --configure first alert (right LED) as engine temperature (F)
  sxSetAlertThresh(0,0,205,255,255,0,0) --yellow warning at 205F
  sxSetAlertThresh(0,1,225,255,0,0,10) -- red flash at 225F
 
  --configure second alert (left LED) as oil pressure (PSI)
  sxSetAlertThresh(1,0,0,255,0,0,10) --red flash below 15 psi
  sxSetAlertThresh(1,1,15,255,255,0,5) --yellow flash 15-20 PSI
  sxSetAlertThresh(1,2,20,0,0,0,0) --above 20, no alert
end
 
function sxOnBut(b)
  --called if the button state changes
  println('button: ' ..b)
end
 
---ShiftX2 functions
 
function sxSetLed(i,l,r,g,b,f)
  sxTx(10,{i,l,r,g,b,f})
end
 
function sxSetLinearThresh(id,s,th,r,g,b,f)
  sxTx(41,{id,s,spl(th),sph(th),r,g,b,f})
end
 
function sxSetAlertThresh(id,tid,th,r,g,b,f)
  sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
end
 
function setBaseConfig(bright)
  sxTx(3,{bright})
end
 
function sxSetAlert(id,r,g,b,f)
  sxTx(20,{id,r,g,b,f})
end
 
function sxUpdateAlert(id,v)
  if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
end
 
function sxCfgLinearGraph(rs,ls,lr,hr)
  sxTx(40,{rs,ls,spl(lr),sph(lr),spl(hr),sph(hr)})
end
 
function sxUpdateLinearGraph(v)
  if v ~= nil then sxTx(42,{spl(v),sph(v)}) end
end
 
function sxInit()
  println('config shiftX2')
  setBaseConfig(sxBright)
  if sxOnInit~=nil then sxOnInit() end
end
 
function sxChkCan()
  id,ext,data=rxCAN(sxCan,0)
  if id==sxCanId then sxInit() end
  if id==sxCanId+60 and sxOnBut~=nil then sxOnBut(data[1]) end
end
 
function sxProcess()
  sxChkCan()
  if sxOnUpdate~=nil then sxOnUpdate() end
end
 
function sxTx(offset, data)
  txCAN(sxCan, sxCanId + offset, 1, data)
  sleep(10)
end
 
function spl(v) return bit.band(v,0xFF) end
function sph(v) return bit.rshift(bit.band(v,0xFF00),8) end
 
function onTick()
  sxProcess()
end
 
sxCanId = 0xE3600 + (256 * sxId)
println('shiftx2 base id ' ..sxCanId)
 
setTickRate(tickRate)
sxInit()
</pre>


==Predictive Lap Timer Indicator==
==Predictive Lap Timer Indicator==
Line 491: Line 299:
===Script===
===Script===
Copy and paste this entire script into the scripting window, replacing any existing script.  
Copy and paste this entire script into the scripting window, replacing any existing script.  


<pre>
<pre>
-- Predictive time visualizer
-- Predictive time visualizer


-- What CAN bus ShiftX2 is connected to. 0=CAN1, 1=CAN2
--save best lap time
sxCan = 1
bestTime = 0


-- 0=first ShiftX2 on bus, 1=second ShiftX2 (if ADR1 jumper is cut)
-- Set ShiftX3 configuration parameters with default parameters
sxId=1
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)


--how often ShiftX2 is updated
--config shift light
tickRate=30
sxCfgLinearGraph(1,0,0,200) --center-out graph, linear style, +/- 10.0 seconds in 0.1 sec resolution


--Brightness, 0-100. 0=automatic brightness
sxSetLinearThresh(0,0,0,255,0,0,0) --red if you're falling behind best lap
sxBright=0
sxSetLinearThresh(1,0,80,0,0,255,0) --blue if you're close to best lap
sxSetLinearThresh(2,0,110,0,255,0,0) --green if you're beating best lap
setTickRate(30)


--save best lap time
function onTick()
bestTime = 0
 
function sxOnUpdate()
   local predTime = getPredTime()
   local predTime = getPredTime()


Line 527: Line 336:
   if lastLapTime < bestTime or bestTime == 0 then bestTime = lastLapTime end
   if lastLapTime < bestTime or bestTime == 0 then bestTime = lastLapTime end
end
end
function sxOnInit()
  --config shift light
  sxCfgLinearGraph(1,0,0,200) --center-out graph, linear style, +/- 10.0 seconds in 0.1 sec resolution
  sxSetLinearThresh(0,0,0,255,0,0,0) --red if you're falling behind best lap
  sxSetLinearThresh(1,0,80,0,0,255,0) --blue if you're close to best lap
  sxSetLinearThresh(2,0,110,0,255,0,0) --green if you're beating best lap
end
function sxOnBut(b)
  --if button is pressed, reset the best lap time
  bestTime = 0
end
---ShiftX2 functions
function sxSetLed(i,l,r,g,b,f)
  sxTx(10,{i,l,r,g,b,f})
end
function sxSetLinearThresh(id,s,th,r,g,b,f)
  sxTx(41,{id,s,spl(th),sph(th),r,g,b,f})
end
function sxSetAlertThresh(id,tid,th,r,g,b,f)
  sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
end
function setBaseConfig(bright)
  sxTx(3,{bright})
end
function sxSetAlert(id,r,g,b,f)
  sxTx(20,{id,r,g,b,f})
end
function sxUpdateAlert(id,v)
  if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
end
function sxCfgLinearGraph(rs,ls,lr,hr)
  sxTx(40,{rs,ls,spl(lr),sph(lr),spl(hr),sph(hr)})
end
function sxUpdateLinearGraph(v)
  if v ~= nil then sxTx(42,{spl(v),sph(v)}) end
end
function sxInit()
  println('config shiftX2')
  setBaseConfig(sxBright)
  if sxOnInit~=nil then sxOnInit() end
end
function sxChkCan()
  id,ext,data=rxCAN(sxCan,0)
  if id==sxCanId then sxInit() end
  if id==sxCanId+60 and sxOnBut~=nil then sxOnBut(data[1]) end
end
function sxProcess()
  sxChkCan()
  if sxOnUpdate~=nil then sxOnUpdate() end
end
function sxTx(offset, data)
  txCAN(sxCan, sxCanId + offset, 1, data)
  sleep(10)
end
function spl(v) return bit.band(v,0xFF) end
function sph(v) return bit.rshift(bit.band(v,0xFF00),8) end
function onTick()
  sxProcess()
end
sxCanId = 0xE3600 + (256 * sxId)
setTickRate(tickRate)
sxInit()
</pre>
</pre>


Line 618: Line 345:


===Assumptions===
===Assumptions===
* MAP sensor channel is on the first Analog channel, and reads in KPa - typically 0-255.  You can also connect this to the MAP reading on OBDII (PID 11)
* MAP sensor is on the channel named "MAP"


===Script===
===Script===
Copy and paste this entire script into the scripting window, replacing any existing script.  
Copy and paste this entire script into the scripting window, replacing any existing script.  
<pre>
<pre>
-- What CAN bus ShiftX2 is connected to. 0=CAN1, 1=CAN2
setTickRate(30)
sxCan = 1
 
-- 0=first ShiftX2 on bus, 1=second ShiftX2 (if ADR1 jumper is cut)
sxId=1
 
--how often ShiftX2 is updated
tickRate=30
 
--Brightness, 0-100. 0=automatic brightness
sxBright=0
 
function sxOnUpdate()
  local map = getAnalog(0) --MAP sensor in KPa
  --convert to PSI boost
  local boost = math.max(map - 100, 0) * .145038
  sxUpdateLinearGraph(boost)
  println(map ..' ' ..boost)
end
 
function sxOnInit()
  --config shift light
  sxCfgLinearGraph(0,0,0, 20) --left to right graph, linear style, 0 - 20 PSI boost
 
  sxSetLinearThresh(0,0,0,0,255,0,0) --green starting at no boost
  sxSetLinearThresh(1,0,10,255,255,0,0) --yellow starting at 10 PSI boost
  sxSetLinearThresh(2,0,15,255,0,0,10) --red+flash at 15 PSI boost
end
 
function sxOnBut(b)
  --called if the button state changes
  println('button: ' ..b)
end
 
---ShiftX2 functions
 
function sxSetLed(i,l,r,g,b,f)
  sxTx(10,{i,l,r,g,b,f})
end
 
function sxSetLinearThresh(id,s,th,r,g,b,f)
  sxTx(41,{id,s,spl(th),sph(th),r,g,b,f})
end
 
function sxSetAlertThresh(id,tid,th,r,g,b,f)
  sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
end
 
function setBaseConfig(bright)
  sxTx(3,{bright})
end
 
function sxSetAlert(id,r,g,b,f)
  sxTx(20,{id,r,g,b,f})
end


function sxUpdateAlert(id,v)
-- Set ShiftX3 configuration parameters with default parameters
  if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
-- orientation: 0=normal, 1=inverted (display above LED bar)
end
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)


function sxCfgLinearGraph(rs,ls,lr,hr)  
--config shift light
  sxTx(40,{rs,ls,spl(lr),sph(lr),spl(hr),sph(hr)})
sxCfgLinearGraph(0,0,0, 20) --left to right graph, linear style, 0 - 20 PSI boost
end


function sxUpdateLinearGraph(v)
sxSetLinearThresh(0,0,0,0,255,0,0) --green starting at no boost
  if v ~= nil then sxTx(42,{spl(v),sph(v)}) end
sxSetLinearThresh(1,0,10,255,255,0,0) --yellow starting at 10 PSI boost
end
sxSetLinearThresh(2,0,15,255,0,0,10) --red+flash at 15 PSI boost
 
function sxInit()
  println('config shiftX2')
  setBaseConfig(sxBright)
  if sxOnInit~=nil then sxOnInit() end
end
 
function sxChkCan()
  id,ext,data=rxCAN(sxCan,0)
  if id==sxCanId then sxInit() end
  if id==sxCanId+60 and sxOnBut~=nil then sxOnBut(data[1]) end
end
 
function sxProcess()
  sxChkCan()
  if sxOnUpdate~=nil then sxOnUpdate() end
end
 
function sxTx(offset, data)
  txCAN(sxCan, sxCanId + offset, 1, data)
  sleep(10)
end
 
function spl(v) return bit.band(v,0xFF) end
function sph(v) return bit.rshift(bit.band(v,0xFF00),8) end


function onTick()
function onTick()
   sxProcess()
   local map = getChannel("MAP")
  if map ~= nil then
    --convert to PSI boost
    local boost = math.max(map - 100, 0) * .145038
    sxUpdateLinearGraph(boost)
  end
end
end
sxCanId = 0xE3600 + (256 * sxId)
println('shiftx2 base id ' ..sxCanId)
setTickRate(tickRate)
sxInit()
</pre>
</pre>


<!--
==Only Alerts==
==Only Alerts==
This script enables 3 alert channels:
This script enables 3 alert channels:
Line 743: Line 392:
end
end
</pre>
</pre>
-->


==ShiftX2 starter script==
=ShiftX3 CAN bus API=
Use this as a starter for your own custom script
 
<pre>
-- What CAN bus ShiftX2 is connected to. 0=CAN1, 1=CAN2
sxCan = 0
 
-- 0=first ShiftX2 on bus, 1=second ShiftX2 (if ADR1 jumper is cut)
sxId=0
 
--how often ShiftX2 is updated
tickRate=30
 
--Brightness, 0-100. 0=automatic brightness
sxBright=0
 
function sxOnUpdate()
  --add your code to update ShiftX2 alerts or linear graph during run time.
  --Runs continuously based on tickRate.
 
end
 
function sxOnInit()
  --add your code for configuring ShiftX2. Runs once during startup
 
end
 
function sxOnBut(b)
  --called if the button state changes
  println('button: ' ..b)
end
 
---ShiftX2 functions
--===============
--Reference. Delete me to save space
--===============
 
--function sxSetLed(index,length,red,green,blue,flash)
--Set an individual LED
--index: LED index, starting at 0
--length: number of LEDs to set at once
--red: Red value (0-255)
--green: Green value (0-255)
--blue: Blue value(0-255)
--flashHz: Flash rate, in Hz; 0=no flash
 
--sxSetLinearThresh(thresholdId,segmentLength,thresholdValue,red,green,blue,flashHz)
--Setup a threshold for the linear graph
--thresholdId: Threshold ID to set. from 0-4. define in ascending order.
--segmentLength: Length of the segment when in stepped graph mode. ignored for smooth mode.
--thresholdValue: Value for this threshold.
--red: Red value (0-255)
--green: Green value (0-255)
--blue: Blue value (0-255)
--flashHz: Flash rate, in Hz; 0=no flash
 
--sxSetAlertThresh(alertId,thresholdId,thresholdValue,red,green,blue,flashHz)
--Setup a threshold for an alert indicator
--alertId: Id of the alert to configure
--thresholdId: Threshold ID to set. from 0-4. define in ascending order.
--thresholdValue: Value for this threshold.
--red: Red value (0-255)
--green: Green value (0-255)
--blue: Blue value (0-255)
--flashHz: Flash rate, in Hz; 0=no flash
 
--sxSetAlert(alertId,red,green,blue,flashHz)
--Directly sets an alert indicator
--alertId: Alert Id to set
--red: Red value (0-255)
--green: Green value (0-255)
--blue: Blue value (0-255)
--flashHz: Flash rate, in Hz; 0=no flash
 
--sxUpdateAlert(alertId,currentValue)
--Updates Current alert value, using the previously configured thresholds
--alertId: Alert Id to set
--currentValue: Updated value
 
--sxCfgLinearGraph(renderStyle,linearStyle,lowRange,highRange)
--Configures the linear graph
--renderStyle: 0=left->right, 1=center,2=right->left
--linearStyle: 0=smooth/interpolated, 1=stepped
--lowRange: low range of the graph
--highRange: high range of the graph (ignored if stepped linear style)
 
--sxUpdateLinearGraph(currentValue)
--Updates the linear graph value, using the previously configured thresholds
--currentValue: Updated value
--===============
--End reference
--===============
 
function sxSetLed(i,l,r,g,b,f)
  sxTx(10,{i,l,r,g,b,f})
end
 
function sxSetLinearThresh(id,s,th,r,g,b,f)
  sxTx(41,{id,s,spl(th),sph(th),r,g,b,f})
end
 
function sxSetAlertThresh(id,tid,th,r,g,b,f)
  sxTx(21,{id,tid,spl(th),sph(th),r,g,b,f})
end
 
function setBaseConfig(bright)
  sxTx(3,{bright})
end
 
function sxSetAlert(id,r,g,b,f)
  sxTx(20,{id,r,g,b,f})
end
 
function sxUpdateAlert(id,v)
  if v~=nil then sxTx(22,{id,spl(v),sph(v)}) end
end
 
function sxCfgLinearGraph(rs,ls,lr,hr)
  sxTx(40,{rs,ls,spl(lr),sph(lr),spl(hr),sph(hr)})
end
 
function sxUpdateLinearGraph(v)
  sxTx(42,{spl(v),sph(v)})
end
 
function sxInit()
  println('config shiftX2')
  setBaseConfig(sxBright)
  if sxOnInit~=nil then sxOnInit() end
end
 
function sxChkCan()
  id,ext,data=rxCAN(sxCan,0)
  if id==sxCanId then sxInit() end
  if id==sxCanId+60 and sxOnBut~=nil then sxOnBut(data[1]) end
end
 
function sxProcess()
  sxChkCan()
  if sxOnUpdate~=nil then sxOnUpdate() end
end
 
function sxTx(offset, data)
  txCAN(sxCan, sxCanId + offset, 1, data)
  sleep(10)
end
 
function spl(v) return bit.band(v,0xFF) end
function sph(v) return bit.rshift(bit.band(v,0xFF00),8) end
 
function onTick()
  sxProcess()
end
 
sxCanId = 0xE3600 + (256 * sxId)
println('shiftx2 base id ' ..sxCanId)
 
setTickRate(tickRate)
sxInit()
</pre>
 
=ShiftX2 CAN bus API=
==Overview==
==Overview==
The CAN bus API provides the configuration and control interface for ShiftX2.  
The CAN bus API provides the configuration and control interface for ShiftX3.  


Two styles of control are available:
Two styles of control are available:
Line 913: Line 402:
* High level control - configuring alert thresholds and linear graph up front, and then providing simple value updates
* High level control - configuring alert thresholds and linear graph up front, and then providing simple value updates


==CAN Messages==
==Hardware / CAN configuration==
===CAN base ID===
===CAN Termination===
CAN termination is disabled by default.  To enable termination, bridge the  '''CAN Term''' jumper on the bottom of the ShiftX3 circuit board.


CAN base ID is 0xE3600 (931328)
===CAN Base Address===
   
The default CAN base address is 931328 (0xE3600). You can change it by breaking the trace bridging the ADR1 jumper on the bottom of the ShiftX3 circuit board.
Cutting the jumper ADR1 will add 256 to the base ID, allowing up to two ShiftX2 displays on the same CAN bus.


===CAN Baud rate===
{| class="wikitable" style="text-align:center; width:700px; height:200px;"
 
|+ ShiftX3 CAN bus base address setting
500K and 1MB rates are supported.
 
500K is enabled by default; cut the jumper ADR2 on the bottom of ShiftX2 to enable 1MB.
 
===Configuration / Runtime Options===
 
====Announcement====
 
Broadcast by the device upon power up
 
'''CAN ID:''' Base + 0
{| class="wikitable" | width="600px"
|-
|-
! Offset
! ADR1 jumper setting
! What
! Base address
! Value
|-
|-
| 0
| Closed (Default setting)
| Total LEDs
| 931328 (0xE3600)
| Total number of LEDs on the device
|-
|-
| 1
| Open
| Alert Indicators
| 931584 (0xE3700)
| Number of logical alert indicators
|}
|-
 
| 2
===CAN Baud Rate===
| Linear Bar Graph Length
The default CAN baud rate is 1MB. You can switch to 500K by breaking the ADR2 Jumper on the bottom of the ShiftX3 board.
| Number of LEDs in linear graph
 
{| class="wikitable" style="text-align:center; width:700px; height:200px;"
|+ ShiftX3 CAN baud rate setting
|-
|-
| 3
! ADR2 jumper setting
| Major Version
! Baud Rate
| Firmware major version number
|-
|-
| 4
| Closed (Default setting)
| Minor Version
| 1MB
| Firmware minor version number
|-
|-
| 5
| Open
| Patch Version
| 500K
| Firmware patch version number
|}
|}


====Statistics====
[[Image:ShiftXCanBaudRateJumper.jpg|700px]]
Statistics information, broadcast periodically by device
 
==ShiftX3 CAN Protocol==
 
===Configuration / Runtime Options===


'''CAN ID:''' Base + 2
====Set Configuration Parameters Group 1====
Sets various configuration options.


'''CAN ID:''' Base + 3
{| class="wikitable" | width="600px"
{| class="wikitable" | width="600px"
|-
|-
Line 976: Line 455:
|-
|-
| 0
| 0
| Major Version
| Brightness
| Firmware major version number
| 0 - 100; 1 = dimmest; 100 = brightest; 0 = automatic brightness control using built-in light sensor.
|-
|-
| 1
| 1
| Minor Version
| Automatic brightness scaling (Optional)
| Firmware minor version number
| 0-255; default=61. adjust this value to adjust the relative gain of the built-in light sensor when in automatic brightness mode.
|-
|-
| 2
| 2
| Patch Version
| Display orientation
| Firmware patch version number
| 0: 7-segment display is below shift light; 1: 7-segment display is above shift light
 
|}
|}


====Set Configuration Parameters Group 1====
====Set Display====
Sets various configuration options.  
Directly sets the value of the 7 segment display.


'''CAN ID:''' Base + 3
'''CAN ID:''' Base + 50
{| class="wikitable" | width="600px"
{| class="wikitable" | width="600px"
|-
|-
Line 999: Line 479:
|-
|-
| 0
| 0
| Brightness
| Digit index
|  0 - 100; 1 = dimmest; 100 = brightest; 0 = automatic brightness control using built-in light sensor.
|  0 (must be 0)
|-
|-
| 1
| 1
| Automatic brightness scaling (Optional)
| Character
0-255; default=51. adjust this value to adjust the relative gain of the built-in light sensor when in automatic brightness mode.
ASCII value of character to display
|}
|}
The value of the display is set by the ASCII coded value. To set a numeric value, offset the value by 48: e.g. 48 = 0, 49 = 1, etc.
Most alphanumeric characters are supported as well, also via ASCII representation.


====Set Discrete LED====
====Set Discrete LED====
Line 1,277: Line 761:


===Notifications===
===Notifications===
Notifications related to events broadcasted from ShiftX2
Notifications related to events broadcasted from ShiftX3
 
====Announcement====
 
Broadcast by the device upon power up
 
'''CAN ID:''' Base + 0
{| class="wikitable" | width="600px"
|-
! Offset
! What
! Value
|-
| 0
| Total LEDs
| Total number of LEDs on the device
|-
| 1
| Alert Indicators
| Number of logical alert indicators
|-
| 2
| Linear Bar Graph Length
| Number of LEDs in linear graph
|-
| 3
| Major Version
| Firmware major version number
|-
| 4
| Minor Version
| Firmware minor version number
|-
| 5
| Patch Version
| Firmware patch version number
|}
 
====Statistics====
Statistics information, broadcast periodically by device
 
'''CAN ID:''' Base + 2
 
{| class="wikitable" | width="600px"
|-
! Offset
! What
! Value
|-
| 0
| Major Version
| Firmware major version number
|-
| 1
| Minor Version
| Firmware minor version number
|-
| 2
| Patch Version
| Firmware patch version number
|}


====Button State====
====Button State====
Line 1,291: Line 835:
| 0
| 0
| Button state
| Button state
|  1 = button is pressed; 0 = button  
|  1 = button is pressed; 0 = button
|-
| 1
| Button ID
|  ID of button
 
|}
|}

Latest revision as of 04:56, 5 September 2023

Introduction

Parts in the Kit

  • ShiftX3

Shiftx3 3quarter.jpg

Compatibility

ShiftX3 is compatible with:

  • RaceCapture/Track MK2,MK3
  • RaceCapture/Pro MK2,MK3,MK4
  • RaceCapture/Apex
  • PodiumConnect MK1,MK2

Note: Not compatible with RaceCapture/Track MK1.

Firmware Requirements

ShiftX3 requires RaceCapture/PodiumConnect firmware 2.15.0 or higher. Download the latest firmware

Connection and Installation

Mounting ShiftX3

Attach ShiftX3 with #6 mounting screws and tighten until snug.

  • Note: You can install with the 7 segment display above or below the LED strip; see the setup instructions for selecting the orientation.

Dimensions

ShiftX3 enclosure dimensions.jpg

Plug and Play connection

  • Note: ShiftX3 requires 12v power, via RaceCapture's own power connection.

ShiftX3 connects effortlessly into our plug and play connector system, using the recommended cabling accessories:

Connect the Dual CAN splitter into the CAN1/CAN2 port of your main system:

Dual can splitter plugged in.jpg

Then connect your CAN extension cable to the "B" port of the Dual CAN splitter:

Dual CAN splitter closeup.jpg

At the opposite end of the CAN extension, attach the inline CAN terminator:

Inline terminator plugged in.jpg

Finally, attach ShiftX3 to the other end of the Terminator to complete the installation.

ShiftX3 with terminator.jpg

Direct wire connection

You can connect ShiftX3 into a non plug and play system by using the following cabling accessories:

Connect the pigtail wires to your system:

  • Green to CAN2 High
  • White to CAN2 Low
  • Red to +12v (same power connection for your system)
  • Black to Ground (same ground connection for your system)

Then connect the pigtail to the inline CAN terminator.

Finally, attach ShiftX3 to the other end of the Terminator to complete the installation.

Using ShiftX3

The LEDs and display on ShiftX3 are controlled by RaceCapture's Lua scripting capabilities. Built-in functions provide access to ShiftX3's capabilities. See the ShiftX3 Lua scripting reference for additional details.

Note: Ready to go scripts may be available as a preset. When in the Scripting view, press the Presets button to access a list of pre-configured scripts. Be sure to press the cloud update button to get the latest set of presets.

Lua scripting presets.png

Navigation Buttons

Once ShiftX3 is powered and connected via CAN bus, the left and right ShiftX3 buttons will automatically trigger corresponding left and right navigation actions on the RaceCapture dashboard.

[file:CSQfW4s.gif]

Disco Lights Demo

This is a test script that exercises all of the LEDs and the 7 segment display on ShiftX3. You can use this as a first time test, as it does not rely on any sensors.

Script

Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.

This script will randomly set LEDs with different colors and the display will update with random numbers.

setTickRate(10)

function rndc()
  return math.random(0,255)
end

function onTick()
  for i=0,9,1 do
    sxSetLed(i,1,rndc(),rndc(),rndc(),0)
  end
  -- ascii characters between 0 and 9
  sxSetDisplay(0, math.random(0,9)) 
end

Sequential shift light + Gear indicator

This script configures just a sequential shift light, and update gear display.

Script (Gear is calculated from RPM and Speed)

Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.

  • Default is reading RPM from the channel named "RPM"
  • Default is creating the Gear channel with the channel name "Gear"
setTickRate(30)

-- Set ShiftX3 configuration parameters with default parameters
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)

--create gear channel
gearId = addChannel("Gear", 10, 0, 0, 6)

--config shift light
sxCfgLinearGraph(0,0,0,7000) --left to right graph, smooth style, 0 - 7000 RPM range

sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6000 RPM

function onTick()
  sxUpdateLinearGraph(getChannel("RPM"))

  -- calculate gear: tire diameter(cm), final gear ratio, individual gear ratios 1-6
  local gear = calcGear(62.7, 3.45, 4.23, 2.52, 1.66, 1.22, 1.0, 0.8)
  setChannel(gearId, gear)
  sxSetDisplay(0, gear)
end

Script (Gear is provided by an existing channel)

Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.

  • Default is reading RPM from the channel named "RPM"
  • Default is reading the Gear channel with the channel name "Gear"
setTickRate(30)

-- Set ShiftX3 configuration parameters with default parameters
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)

--config shift light
sxCfgLinearGraph(0,0,0,7000) --left to right graph, smooth style, 0 - 7000 RPM range

sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6000 RPM

function onTick()
  sxUpdateLinearGraph(getChannel("RPM"))
  sxSetDisplay(0, getChannel("Gear"))
end

Shift Light + Twin Alert + Gear Example (Gear calculated by RPM and Speed)

This script shows a more complete example that demos a sequential shift light + two alerts + Gear indicator.

Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.

Assumptions:

  • Engine Temperature on the 1st alert LED, connected to first analog channel - channel name "EngineTemp"
  • Oil Pressure on the 2nd alert LED, connected to second analog channel - channel name "OilPress"
  • Gear channel already exists, named "Gear"

Edit the script to change the analog channels you want to monitor.

Script

Copy and paste this entire script into the scripting window, replacing any existing script.

setTickRate(30)

-- Set ShiftX3 configuration parameters with default parameters
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)

--config shift light
sxCfgLinearGraph(0,0,0,7000) --left to right graph, smooth style, 0 - 7000 RPM range

sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6000 RPM

--configure first alert (right LED) as engine temperature (F)
sxSetAlertThresh(0,0,205,255,255,0,0) --yellow warning at 205F
sxSetAlertThresh(0,1,225,255,0,0,10) -- red flash at 225F

--configure second alert (left LED) as oil pressure (PSI)
sxSetAlertThresh(1,0,0,0,0,255,10) --red flash below 15 psi
sxSetAlertThresh(1,1,15,255,255,0,5) --yellow flash 15-20 PSI
sxSetAlertThresh(1,2,20,0,0,0,0) --above 20, no alert

--create gear channel
gearId = addChannel("Gear", 10, 0, 0, 6)

function onTick()
  --update RPM
  sxUpdateLinearGraph(getChannel("RPM"))

  -- calculate gear: tire diameter(cm), final gear ratio, individual gear ratios 1-6
  local gear = calcGear(62.7, 3.45, 4.23, 2.52, 1.66, 1.22, 1.0, 0.8)
  setChannel(gearId, gear)
  sxSetDisplay(0, gear)

  --update engine temp alert
  sxUpdateAlert(0, getChannel("EngineTemp"))

  --update oil pressure alert
  sxUpdateAlert(1, getChannel("OilPress"))
end

Shift Light + Twin Alert + Gear Example (Existing gear channel provided by ECU)

This script shows a more complete example that demos a sequential shift light + two alerts.

Available as a scripting preset - or you can copy and paste this entire script into the scripting window, replacing any existing script.

Assumptions:

  • Engine Temperature on the 1st alert LED, connected to first analog channel - channel name "EngineTemp"
  • Oil Pressure on the 2nd alert LED, connected to second analog channel - channel name "OilPress"
  • Gear channel already exists (provided by ECU) and is named "Gear"

Edit the script to change the analog channels you want to monitor.

Script

Copy and paste this entire script into the scripting window, replacing any existing script.

setTickRate(30)

-- Set ShiftX3 configuration parameters with default parameters
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)

--config shift light
sxCfgLinearGraph(0,0,0,7000) --left to right graph, smooth style, 0 - 7000 RPM range

sxSetLinearThresh(0,0,3000,0,255,0,0) --green at 3000 RPM
sxSetLinearThresh(1,0,5000,255,255,0,0) --yellow at 5000 RPM
sxSetLinearThresh(2,0,6000,255,0,0,10) --red+flash at 6000 RPM

--configure first alert (right LED) as engine temperature (F)
sxSetAlertThresh(0,0,205,255,255,0,0) --yellow warning at 205F
sxSetAlertThresh(0,1,225,255,0,0,10) -- red flash at 225F

--configure second alert (left LED) as oil pressure (PSI)
sxSetAlertThresh(1,0,0,0,0,255,10) --red flash below 15 psi
sxSetAlertThresh(1,1,15,255,255,0,5) --yellow flash 15-20 PSI
sxSetAlertThresh(1,2,20,0,0,0,0) --above 20, no alert

function onTick()
  sxUpdateLinearGraph(getChannel("RPM"))
  sxSetDisplay(0, getChannel("Gear"))

  --update engine temp alert
  sxUpdateAlert(0, getChannel("EngineTemp"))

  --update oil pressure alert
  sxUpdateAlert(1, getChannel("OilPress"))
end

Predictive Lap Timer Indicator

This script enables predictive lap time visualization.

How it works

A bar extends left or right from the center of the linear graph:

  • Green bar extending to the right indicates you're beating the best time
  • Red bar extending to the left means you're falling behind.
  • When you're close to the best time, the center blue LED illuminates.


Notes:

  • The script is designed for a +/- 10 second maximum delta - so if you're ahead or behind by 10 seconds, the linear graph will be fully illuminated center-right, or center-left.
  • You will need to complete a a full lap to train the predictive timer before the graph will update.

Script

Copy and paste this entire script into the scripting window, replacing any existing script.

-- Predictive time visualizer

--save best lap time
bestTime = 0

-- Set ShiftX3 configuration parameters with default parameters
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)

--config shift light
sxCfgLinearGraph(1,0,0,200) --center-out graph, linear style, +/- 10.0 seconds in 0.1 sec resolution

sxSetLinearThresh(0,0,0,255,0,0,0) --red if you're falling behind best lap
sxSetLinearThresh(1,0,80,0,0,255,0) --blue if you're close to best lap
sxSetLinearThresh(2,0,110,0,255,0,0) --green if you're beating best lap
setTickRate(30)

function onTick()
  local predTime = getPredTime()

  local timeDiff = (bestTime - predTime) * 60
  -- rail values 
  timeDiff = math.max(timeDiff, -10)
  timeDiff = math.min(timeDiff, 10)
  --scale values from +/- 10 sec to a 0-200 scale
  timeDiff = (timeDiff + 10) * 10

  sxUpdateLinearGraph(timeDiff)

  --update best lap time if an updated lap time is available
  local lastLapTime = getLapTime()
  if lastLapTime < bestTime or bestTime == 0 then bestTime = lastLapTime end
end

Boost Gauge

This script visualizes a single analog input channel on the linear graph.

How it works

The script configures the linear graph, then reads an analog channel and updates the graph with the current value. In this case, the value represents boost level measured from a MAP sensor.

Assumptions

  • MAP sensor is on the channel named "MAP"

Script

Copy and paste this entire script into the scripting window, replacing any existing script.

setTickRate(30)

-- Set ShiftX3 configuration parameters with default parameters
-- orientation: 0=normal, 1=inverted (display above LED bar)
-- brightness: 0-100%, 0 = auto brightness
-- can bus: 0=CAN1, 1=CAN2
sxSetConfig(0,0,1)

--config shift light
sxCfgLinearGraph(0,0,0, 20) --left to right graph, linear style, 0 - 20 PSI boost

sxSetLinearThresh(0,0,0,0,255,0,0) --green starting at no boost
sxSetLinearThresh(1,0,10,255,255,0,0) --yellow starting at 10 PSI boost
sxSetLinearThresh(2,0,15,255,0,0,10) --red+flash at 15 PSI boost

function onTick()
  local map = getChannel("MAP")
  if map ~= nil then 
    --convert to PSI boost
    local boost = math.max(map - 100, 0) * .145038
    sxUpdateLinearGraph(boost)
  end
end


ShiftX3 CAN bus API

Overview

The CAN bus API provides the configuration and control interface for ShiftX3.

Two styles of control are available:

  • Low level control of LEDs - the ability to discretely set LED color and flash behavior
  • High level control - configuring alert thresholds and linear graph up front, and then providing simple value updates

Hardware / CAN configuration

CAN Termination

CAN termination is disabled by default. To enable termination, bridge the CAN Term jumper on the bottom of the ShiftX3 circuit board.

CAN Base Address

The default CAN base address is 931328 (0xE3600). You can change it by breaking the trace bridging the ADR1 jumper on the bottom of the ShiftX3 circuit board.

ShiftX3 CAN bus base address setting
ADR1 jumper setting Base address
Closed (Default setting) 931328 (0xE3600)
Open 931584 (0xE3700)

CAN Baud Rate

The default CAN baud rate is 1MB. You can switch to 500K by breaking the ADR2 Jumper on the bottom of the ShiftX3 board.

ShiftX3 CAN baud rate setting
ADR2 jumper setting Baud Rate
Closed (Default setting) 1MB
Open 500K

ShiftXCanBaudRateJumper.jpg

ShiftX3 CAN Protocol

Configuration / Runtime Options

Set Configuration Parameters Group 1

Sets various configuration options.

CAN ID: Base + 3

Offset What Value
0 Brightness 0 - 100; 1 = dimmest; 100 = brightest; 0 = automatic brightness control using built-in light sensor.
1 Automatic brightness scaling (Optional) 0-255; default=61. adjust this value to adjust the relative gain of the built-in light sensor when in automatic brightness mode.
2 Display orientation 0: 7-segment display is below shift light; 1: 7-segment display is above shift light

Set Display

Directly sets the value of the 7 segment display.

CAN ID: Base + 50

Offset What Value
0 Digit index 0 (must be 0)
1 Character ASCII value of character to display

The value of the display is set by the ASCII coded value. To set a numeric value, offset the value by 48: e.g. 48 = 0, 49 = 1, etc.

Most alphanumeric characters are supported as well, also via ASCII representation.

Set Discrete LED

A low level function to directly set any LED on the device.

CAN ID: Base + 10

Offset What Value
0 LED index 0 -> # of LEDs on device
1 Number of LEDs to set 0 -> # of LEDs on device (0 = set all remaining)
2 Red 0 - 255
3 Green 0 - 255
4 Blue 0 - 255
5 Flash 0-10Hz (0 = full on)

Alert Indicators

Alert Indicators are typically single LEDs or a group of LEDs treated as one logical unit. This is defined by the hardware configuration of the device.

Set Alert

Directly set an alert indicator

CAN ID: Base + 20

Offset What Value
0 Alert ID 0 -> # of Alert indicators
1 Red 0 - 255
2 Green 0 - 255
3 Blue 0 - 255
4 Flash 0-10Hz (0 = full on)

Set Alert Threshold

Configures an alert threshold. Up to 5 thresholds can be configured per alert indicator.

Notes:

  • If the current value is greater than the last threshold, then the last threshold is selected.
  • The first threshold may have a threshold value >= 0; remaining thresholds must be > 0

CAN ID: Base + 21

Offset What Value
0 Alert ID 0 -> # of Alert indicators
1 Threshold ID 0 - 4
2 Threshold (low byte)
3 Threshold (high byte)
4 Red 0 - 255
5 Green 0 - 255
6 Blue 0 - 255
7 Flash Hz 0 - 10 (0 = full on)

Update Current Alert Value

Updates the current value for an alert indicator. The configured alert thresholds will be applied to the current value.

CAN ID: Base + 22

Offset What Value
0 Alert ID 0 -> # of Alert indicators
1 Value (low byte)
2 Value (high byte)

Linear Graph

The linear graph mode provides visualizations for common scenarios:

  • Sequential RPM shift light where the progression is stepped
  • Linear bar graph to linearly indicate a sensor value
  • Center left/right graph to indicate +/- performance against a reference - such as visualizing current predictive time vs best time

Power up default configuration

Upon power up the linear graph is configured:

  • Rendering style: left->right
  • Linear style: stepped
  • Low Range: 0
  • High Range: N/A
  • Threshold :
    • Threshold value: 3000 / segment length: 3 / color RGB: (0, 255, 0) / flash: 0
    • Threshold value: 5000 / segment length: 5 / color RGB: (0, 255, 255) / flash: 0
    • Threshold value: 7000 / segment length: 7 / color RGB: (255, 0, 0) / flash: 5

Configure Linear Graph

Configures the options for the linear graph portion of the device.

Rendering style:

  • If left->right, linear graph illuminates left to right
  • If centered, values below the mid-point in the range extend from the center to the left, and values above the mid-point extend from the center to the right.
  • If right->left, linear graph illuminates right to left

Linear style:

  • if smooth, graph length is updated smoothly by interpolating the current value in-between LEDs
  • If stepped, creates the visual effect of stepped progressions by setting the segment length of the threshold configuration. High Range of configuration is ignored.


CAN ID: Base + 40

Offset What Value
0 Rendering Style 0 = left->right, 1=center, 2=right->left
1 Linear Style 0 = Smooth / interpolated, 1 = stepped
2 Low Range (low byte)
3 Low Range (high byte)
4 High Range (low byte) (ignored if linear style = stepped)
5 High Range (high byte) (ignored if linear style = stepped)

Set Linear Graph Threshold

Configures a linear threshold. Up to 5 thresholds can be configured

Notes:

  • If the current value is greater than the last threshold, then the last threshold is selected.
  • The first threshold may have a threshold value >= 0; remaining thresholds must be > 0

CAN ID: Base + 41

Offset What Value
0 Threshold ID 0 - 4
1 Segment Length 0 -> # of LEDs on device (ignored if linear style is ‘smooth’)
2 Threshold (low byte)
3 Threshold (high byte)
4 Red 0 - 255
5 Green 0 - 255
6 Blue 0 - 255
7 Flash Hz 0 - 10 (0 = full on)

Update Current Linear Graph Value

Updates the current value for the linear graph

CAN ID: Base + 42

Offset What Value
0 Value (low byte)
1 Value (high byte)

Notifications

Notifications related to events broadcasted from ShiftX3

Announcement

Broadcast by the device upon power up

CAN ID: Base + 0

Offset What Value
0 Total LEDs Total number of LEDs on the device
1 Alert Indicators Number of logical alert indicators
2 Linear Bar Graph Length Number of LEDs in linear graph
3 Major Version Firmware major version number
4 Minor Version Firmware minor version number
5 Patch Version Firmware patch version number

Statistics

Statistics information, broadcast periodically by device

CAN ID: Base + 2

Offset What Value
0 Major Version Firmware major version number
1 Minor Version Firmware minor version number
2 Patch Version Firmware patch version number

Button State

Indicates a change in the button state

CAN ID: Base + 60

Offset What Value
0 Button state 1 = button is pressed; 0 = button
1 Button ID ID of button