Lua script for downshift indication

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

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Lua script for downshift indication

Post by ProtoTim35 »

Just wondering if this is possible through lua scripting, and if so, can someone write a script that will work for me?

I have a MK3, and I have a shift light that seems to work great (at least in testing so far) (it's the $20 RaceCapture shift light), using Lua scripting that I downloaded. I'm very new to lua scripting, but used to work with HTML a fair bit, so I understand some of the basics of Lua.

what I would like to do is insert a script that would change the display of the Tachometer in Dash mode. I would like to do several things, that may or may not be able to be done simultaneously in one script.

First, I would like to have a white (or any other color that will stand out, but not red) bold and slightly longer radial line at 8500 RPM. This would be my downshift RPM target normally.

Then, have a similar line except red at 11,000 RPM for upshift target.

Then, when Throttle Position is less than some value (say 15%) and between 7500 and 8500 RPM, the tachometer background (black) turns white, and the display (normally white) turns black - inverting the colors, thus signaling time to downshift to the next gear in a way that it would be likely to catch my eye without my having to be watching it, and help me be consistent in downshift points.

Any help on this would be nice.

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

Post by MikeD »

AFAIK there is no way to change the behaviour of the display with LUA, so you can not invert the colors or set markers/radial lines on your own... this would need adaption of the App by Brent.

You can change the color of the scales depending on the value and with a soon to come app version you can assign different colors, not just yellow and red as it is up to now.
There are popup messages available also in the near future, but I'm not sure how quick they come and go on the display and how user configurable they are in the end... Of course you would need a popup for your logic condition of RPM and TPS matching something and I don't know what the user interface will let you do and how it behaves in the end.
I would probably do the downshift indication also with the shiftlight to notify the driver, and not rely on the phone app at all.

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Post by ProtoTim35 »

Hi Mike. Thanks again for getting back to me. How big of a deal would it be to do that with the shift light via Lua -so that the shift light would come on for both up-shift and downshift?

One other question on Lua scripting. Do all of the scripts stay displayed in the "script" window, or only when you are working on one? I'm guessing they are all displayed. If not, how do you pull them up to edit them? I'm sorry, but I've never worked with Lua before, and am a bit lost. I know the instructions on the Autosport Labs site say Lua is easy to learn, but when I followed the links, the info at the links seemed to recommend buying a specific book to learn. I don't have time to be concentrating on learning something like that right now, so I appreciate any help I can get.

I'll be happy to forward the scripting I currently have on my MK3 later today. I'll be working on it soon. I made a few changes to the example. I wired two of the light segments together, so I'm only using two channels. I initially set it at 2K RPM and 3K RPM, to test it out without having to go to the rev limiter. After testing, I then set it at actual numbers I want - I think 10.5K and 11K RPM if I remember right.

I also installed Lua for one other thing from the example, which I'll have to look again to see what it was. I installed them in series. I hope that is the correct way. I couldn't find anything that said one way or the other.

Thanks again,

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Post by ProtoTim35 »

Hi Mike,

Below is all of the scripting I show on my MK3. I don't know if there is any way of pulling any further scripting up if it exists or not (I'm wanting one for turning the camera on too, but haven't gotten that far yet - (I figure the camera function doesn't matter until I can get the WiFi running):

setTickRate(15) --15Hz


--Shift Now!!1!

function onTick()

rpm=getTimerRpm(0) --read RPM

--activate LEDs

if rpm > 10500 then setGpio(1,1) else setGpio(1,0) end

if rpm > 11000 then setGpio(0,1) else setGpio(0,0) end

end

function onTick() if getGpsSpeed() > 20 then startLogging() else
stopLogging() end end

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

Post by MikeD »

Hey, you cannot use more than one onTick() function. The single OnTick function runs over and over again (at the tickrate frquency) and you can either input every part of your code into this function, or you write separate functions which you then start from within the onTick function everytime when the onTick function is being worked through once again. (That is a very crude description but I don't have that much time to explain anymore).

Everything that you see within your scripting window is used and is at best the ONLY text that is used. However Brent mentioned the possible use of a hardcoded function named collectgarbage() which might clean up some of the memory in the background, but I'm really not sure.
In addition with my laptop sometimes I type a line and it disappears from one moment to the other, however it is still there in the background, and as soon as I do another input like space or enter then it reappears once again. So in case you are not sure you can at least hit Ctrl-A to mark everything and then hit DEL to clear the window. Then paste the text into the scripting window that you wanna have in there. This however isn't necessary at all as long as everything is ok.
Here is a script where I added the gear calculation (values from your other post) and the shiftlight including downshift.
I also added some code to have a blinking function which might be helpfull with the shiftlights: The blinking frequency can be entered right at the top for convenience, however when you add lot's lua code in the future to what you have now you may delete some of these so called global variables and enter the value directly right where it is needed in plain numbers.

Be aware that you probably have to change the channel number of the getAnalog(0) to whatever analog channel the TPS is wired into (I really don't know and you didn't mention it).
In addition the number 15 (which would mean 15%) will only work when you have the scaling for the TPS entered within the analog section, otherwise you might get different numbers from this channel and have to take care to correct it in whatever way you have your scaling.

Gear will show -1 when you are lower than 1.61 Volts as I thought that might be a kind of indicator that something isn't ok with the signal. In case you don't do anything with the gear value other than displaying/logging then everything is fine, but in case you want to use the gear to calculate something within the lua section the -1 value might mess up your "whatever" calculation. Then you can easily replace the -1 with 0 (zero) in case that is prefered.

blinkRate = 10 --blinkfrequency in Hz

setTickRate(25)
gearId = addChannel("Gear", 10, 0, 0, 6)
LastUpT=getUptime()
blinkTime=0

function onTick()
looptime=getUptime()-LastUpT
LastUpT=getUptime()
local speed=getGpsSpeed()
if speed > 20 then
startLogging()
elseif speed < 15 then
stopLogging()
end
shiftlight()
gearcalc()
end

function shiftlight()
local rpm=getTimerRpm(0) --read RPM
local blink=1
if blinkTime > (1000/blinkRate) then blinkTime=0 end
if blinkTime > (350/blinkRate) then blink=0 end
blinkTime = blinkTime+looptime
local led1=0
local led2=0
if rpm > 7500 and rpm < 8500 and getAnalog(0) < 15 then --assign TPS input
led1=1
end
if rpm > 10500 then led1=1 end
if rpm > 11000 then led2=1 end
if rpm > 11400 then
led1=blink --start blinking
led2=blink
end
setGpio(1,led1)
setGpio(0,led2)
end

function gearcalc()
local gearvolt = getAnalog(3)
local gear = -1
if gearvolt > 1.61 then gear = 1 end
if gearvolt > 2.15 then gear = 2 end
if gearvolt > 2.75 then gear = 3 end
if gearvolt > 3.50 then gear = 4 end
if gearvolt > 4.19 then gear = 5 end
if gearvolt > 4.70 then gear = 6 end
if gearvolt > 5.00 then gear = 0 end
setChannel(gearId, gear)
end

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Post by ProtoTim35 »

Thanks Mike. I understand most of that. A few more related questions.

I have the "sample" for adding a code for turning on the camera for GPSspeed. Would I simply add that to the end, or do I have to do something else? From you notes, I suspect I would need to do something else, but not sure what that would be.

In the second line of code, I see something I don't understand, which is probably pretty simple, and I see in other scripts: gearId = addChannel("Gear", 10, 0, 0, 6) What is the "10, 0, 0, 6"?

I've noticed on some scripts (I think most) the script is ended with "end end". I'm assuming this is to end the final segment of the script and to also end the entire script. Am I at least close? I noticed that the script that you sent doesn't have the double "end". Or is it that it does, it just has the two lines of Gpio in between?

which leads me to the next question, similar to the first. What does the setGpio(1, led1) and (0, led2) tell me of the 1 and 0? I'm thinking it says the first number is the Gpio channel and the second number is the light segment lit. If that's the case though what is the significance of the led1 or 2, since they are all that is on the particular channel?

I'm guessing you have been talking with Brent, and know that the logger was defective after all. Consequently, it's on its way back to Washington. I really hope he doesn't wait to get this one to send me another one or to repair that one - that will cost me a lot of downtime. As soon as i have one, I will plug in the code that you gave me. In the mean time, I'll go into my latest file and modify it and save it, so the new file should be ready to upload as soon as I have the unit. I thought it was defective, but wasn't sure until I saw the poll log on it, which I didn't know how to obtain. Although I wasn't sure the poll log was conclusive of a defective unit, I felt it added a big red flag that aimed that direction a bit more. There were just too many things that weren't making sense on it - inconsistencies from the expected. I wish I had known how to obtain the poll log early on. It would have saved everybody a lot of time. At least we know now what it is, and we can move forward with it, and if I have problems with it in the future, I'll know how to obtain the poll log.

Thanks for your help.

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Post by ProtoTim35 »

one more quick question - sorry: what does the 25 signify in setTickRate(25) ? I'm just trying to understand as much as possible about the coding, so I might not need to bother anyone about it later. I started watching several video tutorials, but they all seem to be geared toward gaming, and I don't need to know all of that stuff.

Any recommendations where I can learn what I need for programming the MK3 without spending hours of learning tons of stuff I'm not likely to ever use would be very helpful.

I did go through the Autosport Labs Lua tips page pretty thoroughly, and was able to get a bit of information, but I know there is a lot more to know.

Thanks again

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

Post by MikeD »

For the GoPro camera script you would need to paste all the code into the scripting window (not within any other function but for example at the very end of the existing script, but don't paste the last four lines of the sample code from the wiki as they are already within the existing script I sent you. However you would still need to place this one line of text checkGoPro() within your already existing onTick function. (This command checkGoPro() is visible as the third line from the bottom of the sample code and because you already have the onTick function you place it in there, either at the beginning or at the end, but not somewhere within an IF statement that is only accessed depending on whatever conditions.)
Anyway all of this isn't needed anymore with your MK3 unit because it supports native triggering the GoPro right from the automatic control menu, as listed in the wiki: https://wiki.autosportlabs.com/Automati ... Applies_to

The number within setTickrate(25) means that the onTick() function will be called that many times per second (so in fact it is the value in Hz how often everything from the onTick function is repeatedly calculated). Everything that you have written starting from your onTick() function til the related end command is done so many times per second. https://wiki.autosportlabs.com/RaceCapt ... 28.29_rate

The addChannel() function is one of those that are predefined within the firmware, as are many others, and it generates a new channel (aka a new parameter name) to the user interface that you see when looking at the dashboard view. Also when you write the settings to the unit and then go into any of the menus where you can assign parameter names from the dropdown menus (in the Analog Sensors or Digital in/out sections for example) and you would have choosen something like addChannel("FluxComp", 1,2,3,4) then it adds a channel to the dropdown menu named FluxComp that you could choose from there, as any of the predefined channel names that you have choosen when you set up TPS, IAT, Coolant temp and so on. And similar to when you set up some things like TPS where you choose the sample rate, precision, min, max, and maybe the units within the Analog Sensors section these numbers 1,2,3,4 (or 10,0,0,6 in your script) define exactly the same. https://wiki.autosportlabs.com/RaceCapt ... its.5D_.29

I think you have to read some more within the wiki pages, as it would answer your next question similar to the ones from before:
https://wiki.autosportlabs.com/RaceCapt ... _state_.29

The led1 and led2 are simply generic variable names that I had choosen on my own and assigned as temporary variables within the onTick function so that I can have one variable for each led. This variable (led1 or led2) carries the information to switch on or off the later set GPIO. It will run through various if stages where I would check if I want to activate or deactivate with whatever conditions and then at the end the latest value of led1 for example is used to switch the GPIO of interest that I want to use. You could rename led1 to shiftlightGreen and led2 to shiftlightRed in every instance and it would work exactly the same.
meaning of setGpio(1,led1):
1 - for the second GPIO, numbering starts with zero for the first GPIO
led1 - the value of led1 is used to swith the channel off or on (when the value is exactly 0 (zero) then the GPIO is OFF, otherwise if the value of led1 is anything other than 0 then the GPIO will be ON)
Functions and various statements have to be closed with an end command.
So you could have the onTick() function and just a few lines in there like:
onTick()
variableabc = variablexyz - 10 --variableabc will be zero when variablexyz = 10 (because 10-10 = 0)
setGpio(0,variableabc) --therefore the first GPIO will be switched on when variablexyz = anything other than 10
end
When you use something like an if statement then it will need another end statement.
onTick()
variableabc = variablexyz +1
if variableabc > 5 then --variablexyz has to be at least greater than 4
setGpio(0,1) --this obviously sets the first GPIO to ON (because the seconde value is non-zero)
else
setGpio(0,0) --this obviously sets the first GPIO to OFF (because the seconde value is zero)
end --this end finishes the if statement from before
--now there could be some more lines of code which are not related to the IF statement from before
end --this end finishes the onTick() function
no, I didn't talk to Brent about your unit, I'm just an ASL dealer from outside the US.
I've no special recommendations where you could learn without spending hours for something that you need just once... moreover I think if you want to learn what you will need for coding (and with respect to what you seem to know up to now) I think you'll be better calculating in days or even weeks instead of hours ;-).
Debugging a single error in the script sometimes can take hours, not talking about complex functions that should run errorfree all day long... but that's part of the game...
If you are short on time you might consider paying someone to help you develop a script for your needs and help you get it running... my customers for example receive such service most always for free, sadly during purchase phase not that much people nowadays care about aftersales support and even buy from the other side of the world just to theoretically save a few bucks.

Hope you can get your project up and running soon!
Kind regards,
Mike

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Post by ProtoTim35 »

Mike. Thank you so much. I understand a fair bit of what you sent. I'll have to look it over a couple more times to get a better handle on some of it. All of that info definitely helps. Too bad there isn't a program to sort of translate the code from normal text. I used to do a bit of HTML work. when I started using FrontPage, WOW was I relieved. What once took me days to create, I could create in just an hour or so. I haven't done much with HTML though in years now.

Thanks again for your time and your help.

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

Post by MikeD »

ProtoTim35,
... to follow up as you mentioned in another thread that you could not make the system to run at all, feel free to give some insight where you struggled and maybe upload the configs that you used, not just the scripts (both the one that worked for you in the end and the one where you used my script, the one that you could NOT get to run) so that I may have a look at what is wrong on your side.

You may need to upload the config files to any cloud storage and point to the location of the files as I think adding config files isn't possible within the forum (at least it wasn't possible in the past).

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Post by ProtoTim35 »

Hi Mike. When you say the config files, is that the entire file that is created each time i save the setup to a file on my laptop?

Unfortunately, I have changed several things since then, and not sure what the config was at the time. It'll probably be at least a week before I get a chance to do anything else with the unit at this time. It could be a couple weeks or more now. I have a lot going on for a while.

When I get a chance, I'll see what I can do with it. I'm learning more about the unit as i go, and I might be able to figure out enough to be able to get it running without further assistance on that. If I need further assistance, I'll get back with you on it.

I'll also start over from scratch and see if I can figure out why I can't read my data file from the one race was recorded. If you can give me any advice on how to get the data file to display the data for me, I would appreciate it. All I've been able to do so far is get it to show that I have a file loaded, and show a very basic track map. I've tried loading it so many different ways, and tried every setting I could find to get it to display.

If I remember right, I tried it via plugging the memory card into my laptop, and reading the saved data through the MK3 USB from my laptop. I'll try some more when I get a chance, but at this point, I'm not sure what else i can do to get the data displayed.

The only previous experience I have with a data logger is a RacePak G2X black box. I had no problems getting it to load the data right off the start. It took a little playing around to figure out the best way to use the data, but it was there immediately. That's probably a 10 year old unit. Why is this one so much more difficult to get what I need out of it?

i would think that with today's technology capabilities, I could simply load the file and it would have a listing of the various parameters saved for me to choose from and time/distance graphs, and the rest would be pretty much automatic - including the track segments. But, I can't get it to show me any data in any format - only a basic track map in the corner. Maybe something somehow got corrupted or something. I don't know. All I know is I've got nothing useful at this point. I'll try some more as soon as I get a chance - again a week or two down the road most likely at this point.

Thanks for getting back to me.

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Post by ProtoTim35 »

I'm back to trying something on my sequential shift light that should be simple, but I ran into a kink. I have led 0 and led 2 tied together and hooked up on gpio (0) terminal, and led 1 separately to Gpio (1) terminal. There is nothing hooked up to the gpio 2 terminal. I took the script for the $19.95 shift light and edited it. I can get what I want if I don't try to get all of what I want at the same time. In other words, if I try to get either of two commands individually for gpio (0), it works. If I try to list them at the same time i appear to be getting a conflict, which I'm not surprised. I figure there has to be a simple way of writing an if -xx then the lights would be powered, or if yy then the same resulting condition.

Here is the original script, which works fine as it is, but doesn't give me all of what I'm looking for:

setTickRate(15) --15Hz

--Shift Now!!1!
function onTick()
rpm=getTimerRpm(0) --read RPM

--activate LEDs
if rpm > 5000 then setGpio(2,1) else setGpio(2,0) end
if rpm > 6000 then setGpio(1,1) else setGpio(1,0) end
if rpm > 7000 then setGpio(0,1) else setGpio(0,0) end
end

=========================================================

what I'm trying to do is have gpio(0) come on in either of two conditions - either
if rpm > 10000 then setGpio(0,1) else setGpio(0,0) end
if rpm > 6000 and if rpm < 8200 then setGpio(0,1) else setGpio(0,0) end

If I use only one of the above commands, it works fine, but if i use both commands, I wind up getting a very fast (very dim) flashing light when inside the command conditions. here is the script I tried:

=================================================

setTickRate(15) --15Hz

--Shift Now!!1!
function onTick()
rpm=getTimerRpm(0) --read RPM

--activate LEDs
if rpm > 5000 then setGpio(2,1) else setGpio(2,0) end (this one doesn't matter because it's not hooked up anyway, so I can delete it)
if rpm > 10500 then setGpio(1,1) else setGpio(1,0) end
if rpm > 10000 then setGpio(0,1) else setGpio(0,0) end
if rpm > 6000 and if rpm < 8200 then setGpio(0,1) else setGpio(0,0) end
end

==================================================

This is apparently giving me a conflict between the two commands for gpio (0).

I know Mike sent me some script (above) for several things at once, but the script never worked for me, and it's complex enough that I didn't want to try to pick it apart and make part of it work. I decided to try to just make it simple and do away with some of the stuff in that script, and this is what I decided to try to have work for me.

Any advice would be appreciated.

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

Post by brentp »

What you can do to help debug your script is to sprinkle println() messages in your logic so you can understand how it works.

You can monitor the output using the Poll logging feature - and also drop the tickRate to 1Hz to slow things down so you can understand it.

We have a comprehensive troubleshooting guide here:
https://wiki.autosportlabs.com/RaceCapt ... our_script

Hope this helps, let us know how it goes.
Brent Picasso
CEO and Founder, Autosport Labs
Facebook | Twitter

ProtoTim35
Posts: 84
Joined: Fri Jun 22, 2018 2:14 am

Post by ProtoTim35 »

is there a way to do "either" "or" in a string. Like:
if either rpm > 10000 or rpm > 6000 and rpm < 8200 then setGpio(0,1) else setGpio(0,0) end

I tried that string, and it didn't seem to work. I figure there has to be something of that nature that will do the trick for what I'm trying to accomplish.

Not sure what you mean by "script is to sprinkle println() messages in your logic "

If I can use an either-or logic, I will probably have everything working good enough for what I'm wanting for now.

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

Post by brentp »

Hi,

In Lua there's no keyword called "either". As with most programming languages, you can group logic together with parenthesis, just like you would do with equations where you say "evaluate this first within the parenthesis".

If I understand what you want to do, you would want the GPIO to activate if RPM is greater than 10000, or if RPM is between 6000 and 8200.

In this case you would write it like this:

if rpm > 10000 or (rpm > 6000 and rpm < 8200) then setGpio(0,1) else setGpio(0,0) end

More information here:
http://www.troubleshooters.com/codecorn/lua/luaif.htm

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

Post Reply