<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.autosportlabs.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Stieg</id>
	<title>Autosport Labs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.autosportlabs.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Stieg"/>
	<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/Special:Contributions/Stieg"/>
	<updated>2026-09-21T14:05:15Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6725</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6725"/>
		<updated>2016-10-17T01:35:04Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Add in `isLogging` description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=RaceCapture/Pro Scripting Guide=&lt;br /&gt;
==Example Scripts and How-Tos==&lt;br /&gt;
A large collection of example scripts can be found in our &#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Lua Script Basics==&lt;br /&gt;
&lt;br /&gt;
===Conventions===&lt;br /&gt;
* All inputs and outputs are numbered starting at 0 (getGpio(0), setChannel(0), etc)&lt;br /&gt;
* All channel values must be numbers&lt;br /&gt;
* All virtual channel names must have no spaces (to be fixed in future revisions)&lt;br /&gt;
&lt;br /&gt;
====Writing your script====&lt;br /&gt;
&lt;br /&gt;
=====onTick() function=====&lt;br /&gt;
Your Lua script is centered around the onTick() function. RaceCapture/Pro will periodically call this function, and here you can define your custom tasks and logic. &lt;br /&gt;
&lt;br /&gt;
Example: this script will periodically write a message to the log:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  println(&amp;quot;hello from RaceCapture/Pro&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Viewing the output log=====&lt;br /&gt;
You can observe the loading of new script and monitor and debug the behavior of your script by using the print() / println() functions. In order to see the log output, enable the &amp;quot;Poll Log&amp;quot; checkbox in the scripting window:&lt;br /&gt;
&lt;br /&gt;
[[image:Hello_RaceCapturePro_script.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=====Controlling the onTick() rate====&lt;br /&gt;
You can control how fast your script is executed using the setTickRate() function.  The tick Rate is specified in Hz, and the default rate is 1Hz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
count = 0&lt;br /&gt;
setTickRate(10)&lt;br /&gt;
&lt;br /&gt;
function onTick()&lt;br /&gt;
  count = count + 1&lt;br /&gt;
  println(&amp;quot;Tick: &amp;quot; ..count)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:RaceCapture_tick_count.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=====Reading and controlling inputs and outputs=====&lt;br /&gt;
&lt;br /&gt;
The Lua scripting enables endless combinations of custom behaviors by reading sensor values, controlling output lines, broadcasting CAN messages and writing data to the Auxiliary serial port. &lt;br /&gt;
&lt;br /&gt;
Example: Reading a sensor value and activating an output based on a threshold. &lt;br /&gt;
&lt;br /&gt;
Given:&lt;br /&gt;
* A calibrated temperature sensor is connected to the first analog input (0);&lt;br /&gt;
* The first GPIO is configured for output mode&lt;br /&gt;
&lt;br /&gt;
This script will activate the output upon crossing the temperature threshold of 212. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  temperature = getAnalog(0)&lt;br /&gt;
  if temperature &amp;gt; 212 then&lt;br /&gt;
    setGpio(0, 1)&lt;br /&gt;
  else&lt;br /&gt;
    setGpio(0, 0)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====Combining multiple functions=====&lt;br /&gt;
When combining multiple functions into one script, it&#039;s recommended to break them into multiple functions and reference them from the main onTick() function.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkTemps()&lt;br /&gt;
&lt;br /&gt;
[ temperature checking logic goes here ]&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function checkAutoLogging()&lt;br /&gt;
&lt;br /&gt;
[ automatic logging logic goes here ]&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onTick()&lt;br /&gt;
  checkTemps()&lt;br /&gt;
  checkAutoLogging()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Debugging your script=====&lt;br /&gt;
If you&#039;re not sure why your script is misbehaving, you can use the println() function to output messages in the log and observe how your script is behaving.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  temperature = getAnalog(0)&lt;br /&gt;
  println(&amp;quot;current temp: &amp;quot; ..temperature)&lt;br /&gt;
  if temperature &amp;gt; 212 then&lt;br /&gt;
    println(&amp;quot;over temp!&amp;quot;)&lt;br /&gt;
    setGpio(0, 1)&lt;br /&gt;
  else&lt;br /&gt;
    println(&amp;quot;under temp&amp;quot;)&lt;br /&gt;
    setGpio(0, 0)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Lua Reference=====&lt;br /&gt;
RaceCapture/Pro uses the standard, lightweight Lua scripting language used as an extension / customization language for many software applications and especially gaming. &lt;br /&gt;
&lt;br /&gt;
* See [https://www.lua.org/ lua.org] for additional information on how to use the Lua language&lt;br /&gt;
=====More examples=====&lt;br /&gt;
You can see more examples in our [[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]] section.&lt;br /&gt;
&lt;br /&gt;
=API Reference=&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
** state: (int / &#039;&#039;(since 2.10.0)&#039;&#039; bool) 1 / true = output active; 0 / false = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getGpsAltitude()===&lt;br /&gt;
Provides the current GPS calculated altitude from sea level in feet.  The method will return 0 if there is no GPS lock.&lt;br /&gt;
* Added: v2.9.0&lt;br /&gt;
* Parameters: &#039;&#039;None&#039;&#039;&lt;br /&gt;
* Returns: &amp;lt;altitude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms.  For non-blocking functionality specify a timeout of 0.&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter  and mask ID, to ignore CAN messages that match a particular ID pattern. &lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039; - you should only define one onTick() function in your code. If multiple onTick() functions are defined, only the last defined onTick() function will be used.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===isLogging()===&lt;br /&gt;
Tells the caller if a logging session is in progress&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 0 if not logging, non zero otherwise.&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state: (int / &#039;&#039;[as of 2.10.0]&#039;&#039; bool) 1 / true = on, 0 / false = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setBgStream( on/off )===&lt;br /&gt;
Sets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** Boolean: true for on, false for off.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getBgStream()===&lt;br /&gt;
Gets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** Boolean: True for on, false for off.&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 100 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===getChannel( &amp;lt;Channel ID | Channel Name&amp;gt; )===&lt;br /&gt;
* Available: v2.9.0&lt;br /&gt;
* Parameters &lt;br /&gt;
** Channel ID (number) - The channel id value as provided by the &#039;&#039;addChannel&#039;&#039; method.&lt;br /&gt;
** Channel Name (string) - The name of the channel as provided to the &#039;&#039;addChannel&#039;&#039; method.  Using the Channel ID method is preferred and is faster.&lt;br /&gt;
* Returns&lt;br /&gt;
** (number) The value of the channel.&lt;br /&gt;
* Examples: &lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(1) &amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(&amp;quot;foo&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapture-Pro_MK2&amp;diff=6689</id>
		<title>RaceCapture-Pro MK2</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapture-Pro_MK2&amp;diff=6689"/>
		<updated>2016-07-24T21:14:44Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Remove Magnetometer availability until we actually add support for it.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=RaceCapture/Pro Quick Links=&lt;br /&gt;
* [[Image:add_to_cart.png|link=http://www.autosportlabs.com/product/racecapturepro/]]&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
*&#039;&#039;&#039;[[RaceCapturePro2_QuickStart|First time setup]]&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;[[RaceCapturePro_Downloads|Software Downloads]]&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;[[RaceCapturePro2_Hardware_Install|Hardware install]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==User Guides==&lt;br /&gt;
*[[RCP_CAN|CAN bus / ECU integration guide]]&lt;br /&gt;
*[[RaceCapturePro2_hardware_guide|Hardware installation and operation guide]]&lt;br /&gt;
*[[RaceCapturePro2_3.5G_module_upgrade|3.5G Module Upgrade guide]]&lt;br /&gt;
*[[RaceCapture_App_User%27s_Guide|RaceCapture App User&#039;s guide]]&lt;br /&gt;
*[[RaceCapturePro_Sensors|Sensor guide]]&lt;br /&gt;
*[[RaceCapturePro_Lua_Scripting|Lua scripting guide]]&lt;br /&gt;
&lt;br /&gt;
==Accessory / add-on guides ==&lt;br /&gt;
*[[SensorX|SensorX sensor breakout board assembly guide]]&lt;br /&gt;
*[[CoilX|CoilX Tach interface to ignition coils guide]]&lt;br /&gt;
*[[RaceCapturePro2_GoProWiFi|WiFi module for automatic GoPro control guide]]&lt;br /&gt;
&lt;br /&gt;
==How To==&lt;br /&gt;
*[[RaceCapturePro2_TelemetryQuickstart|How to: set up telemetry]]&lt;br /&gt;
*[[RaceCapturePro2_Enable_Predictive_Timing|How to: enable Predictive Timing]]&lt;br /&gt;
*[[RaceCapturePro2_OBD2|How to: enable OBD2 channels]]&lt;br /&gt;
*[[RaceCapturePro2_Calibrate_Sensor|How to: calibrate and configure an analog sensor]]&lt;br /&gt;
*[[RaceCapturePro2_ShiftLights|How to: sequential shift lights]]&lt;br /&gt;
*[[RaceCapturePro2_GPS|How to: get best GPS data]]&lt;br /&gt;
*[[RaceTracks|How to: Submit a new race track]]&lt;br /&gt;
*[[RaceCapturePro_Analysis|How to: analyze your data]]&lt;br /&gt;
*[[RaceCapturePro_FAQ|More FAQs and How-To&#039;s]]&lt;br /&gt;
&lt;br /&gt;
==By Car==&lt;br /&gt;
*[[RaceCapturePro2_vehicle_guide|Vehicle Guide]]&lt;br /&gt;
&lt;br /&gt;
==By Sensor Type==&lt;br /&gt;
*[[RaceCapturePro2_RPM|RPM]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Reference==&lt;br /&gt;
*[[RaceCapturePro2_logfile_reference|Log file reference]]&lt;br /&gt;
&lt;br /&gt;
==More Information==&lt;br /&gt;
*[https://github.com/autosportlabs Source code]&lt;br /&gt;
&lt;br /&gt;
===Previous Hardware Versions===&lt;br /&gt;
[[RaceCapturePro-MK1|RaceCapture/Pro MK1]]&lt;br /&gt;
&lt;br /&gt;
=Quick Reference=&lt;br /&gt;
Download a [http://www.autosportlabs.com/racecapturepro-mk2-quick-reference/racecapture-pro-mk2-quick-reference-sheet printable PDF]&lt;br /&gt;
&lt;br /&gt;
[[Image:RaceCapture-Pro MK2 quick reference sheet.jpg]]&lt;br /&gt;
&lt;br /&gt;
=RaceCapture/Pro MK2 Specifications=&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: left&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Input / Output Channels&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|&#039;&#039;&#039;Analog Inputs&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels	&lt;br /&gt;
|8 (battery voltage dedicated on channel 8)&lt;br /&gt;
|-&lt;br /&gt;
|Voltage range&lt;br /&gt;
|0-5v&lt;br /&gt;
|-&lt;br /&gt;
|Input impedance&lt;br /&gt;
|1M ohm&lt;br /&gt;
|-&lt;br /&gt;
|Voltage protection&lt;br /&gt;
|400v (intermittent)&lt;br /&gt;
|-&lt;br /&gt;
|ADC precision&lt;br /&gt;
|12 bit&lt;br /&gt;
|-&lt;br /&gt;
|Maximum sample rate&lt;br /&gt;
|1000Hz&lt;br /&gt;
|-&lt;br /&gt;
|Mapping&lt;br /&gt;
|Raw / Linear formula / Interpolated map&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|&#039;&#039;&#039;Digital I/O&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Output mode type&lt;br /&gt;
|Open drain&lt;br /&gt;
|-&lt;br /&gt;
|Output current capacity&lt;br /&gt;
|1A, inductive clamped&lt;br /&gt;
|-&lt;br /&gt;
|Input mode voltage range&lt;br /&gt;
|0-12v&lt;br /&gt;
|-&lt;br /&gt;
|Input voltage protection&lt;br /&gt;
|400v (intermittent)&lt;br /&gt;
|-&lt;br /&gt;
|Maximum sample rate&lt;br /&gt;
|1000Hz&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|&#039;&#039;&#039;Timer Inputs (RPM / Frequency)&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Input voltage protection&lt;br /&gt;
|400v (intermittent)&lt;br /&gt;
|-&lt;br /&gt;
|Maximum sample rate&lt;br /&gt;
|1000Hz&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|&#039;&#039;&#039;PWM/Analog outputs&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|PWM output type&lt;br /&gt;
|push/pull&lt;br /&gt;
|-&lt;br /&gt;
|PWM output voltage range&lt;br /&gt;
|5v&lt;br /&gt;
|-&lt;br /&gt;
|Output current capacity&lt;br /&gt;
|50mA&lt;br /&gt;
|-&lt;br /&gt;
|Analog Output&lt;br /&gt;
|0-5v&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Voltage Reference&lt;br /&gt;
|-&lt;br /&gt;
|Output Voltage/Capacity&lt;br /&gt;
|5v / 1A&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Connectivity&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|&#039;&#039;&#039;CAN Bus&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|CAN Channels&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|CAN baud rate&lt;br /&gt;
|125K, 250K, 500K, 1M baud&lt;br /&gt;
|-&lt;br /&gt;
|CAN filters&lt;br /&gt;
|14 per channel&lt;br /&gt;
|-&lt;br /&gt;
|Protocol support&lt;br /&gt;
|OBDII PID, custom CAN messaging&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|&#039;&#039;&#039;Telemetry/Wireless&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Cellular (North America)&lt;br /&gt;
|3.5G GSM 850/1900MHz (internal module, optional) &lt;br /&gt;
|-&lt;br /&gt;
|Cellular (Worldwide)&lt;br /&gt;
|2.5G Quad-band GSM (internal module, optional)&lt;br /&gt;
|-&lt;br /&gt;
|Bluetooth&lt;br /&gt;
|Bluetooth 2.0 (external module, optional)&lt;br /&gt;
|-&lt;br /&gt;
|Aux Serial&lt;br /&gt;
|Type	External RJ11 / RS232 signaling &lt;br /&gt;
|-&lt;br /&gt;
|Max Baud Rate&lt;br /&gt;
|230400&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Inertial Motion Unit&lt;br /&gt;
|-&lt;br /&gt;
|Accelerometer Channels&lt;br /&gt;
|3 (X/Y/Z) (2G, 4G capable)&lt;br /&gt;
|-&lt;br /&gt;
|Gyro&lt;br /&gt;
|3 (Yaw/Pitch/Roll) (1000 degrees/sec)&lt;br /&gt;
|-&lt;br /&gt;
|GPS Type&lt;br /&gt;
|External active antenna&lt;br /&gt;
|-&lt;br /&gt;
|GPS Maximum sample rate&lt;br /&gt;
|50Hz&lt;br /&gt;
|-&lt;br /&gt;
|GPS accuracy&lt;br /&gt;
|2.5M CEP&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Storage&lt;br /&gt;
|-&lt;br /&gt;
|Micro SD&lt;br /&gt;
|Up to 32GB (SDHC) FAT32&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Configuration Capacity&lt;br /&gt;
|-&lt;br /&gt;
|Auto-detect track database&lt;br /&gt;
|240&lt;br /&gt;
|-&lt;br /&gt;
|Sectors per track&lt;br /&gt;
|20&lt;br /&gt;
|-&lt;br /&gt;
|Channel support&lt;br /&gt;
|200&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;2&amp;quot;|Physical&lt;br /&gt;
|-&lt;br /&gt;
|Dimensions&lt;br /&gt;
|5.3&amp;quot; (width) x 4.2&amp;quot; (height) x 1.2&amp;quot; (tall) / 135x110x31 mm(est)&lt;br /&gt;
|-&lt;br /&gt;
|Mounting area&lt;br /&gt;
|5.5&amp;quot;(140mm) x 4&amp;quot;(102mm)&lt;br /&gt;
|-&lt;br /&gt;
|Mounting holes&lt;br /&gt;
|Dual mounting points on 5&amp;quot; (127mm) centers - 0.125&amp;quot;-0.25&amp;quot; (3-6mm) fastener&lt;br /&gt;
|-&lt;br /&gt;
|Weight&lt;br /&gt;
|9oz / 255gm (est)&lt;br /&gt;
|-&lt;br /&gt;
|Power connection&lt;br /&gt;
|Terminal block: 1A max&amp;lt;br/&amp;gt;RJ45: 1A max&lt;br /&gt;
|-&lt;br /&gt;
|Power Consumption (max)&lt;br /&gt;
|Main System: 0.6W&amp;lt;br/&amp;gt;With Bluetooth: 1.6W&amp;lt;br/&amp;gt;With Cellular Telemetry: 8.6W&amp;lt;br/&amp;gt;With Cellular Telemetry and Bluetooth: 9.6W&lt;br /&gt;
|-&lt;br /&gt;
|Temperature&lt;br /&gt;
| Max Internal Temperature while operating: -40°C ~ 85°C / -40°C ~ 80°C (Telemetry module)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Image:add_to_cart.png|link=http://www.autosportlabs.com/product/racecapturepro/]]&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6672</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6672"/>
		<updated>2016-07-10T04:24:36Z</updated>

		<summary type="html">&lt;p&gt;Stieg: /* setLed( led, state ) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=RaceCapture/Pro Scripting Guide=&lt;br /&gt;
==Example Scripts and How-Tos==&lt;br /&gt;
A large collection of example scripts can be found in our &#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Lua Script Basics==&lt;br /&gt;
&lt;br /&gt;
===Conventions===&lt;br /&gt;
* All inputs and outputs are numbered starting at 0 (getGpio(0), setChannel(0), etc)&lt;br /&gt;
* All channel values must be numbers&lt;br /&gt;
* All virtual channel names must have no spaces (to be fixed in future revisions)&lt;br /&gt;
&lt;br /&gt;
====Writing your script====&lt;br /&gt;
&lt;br /&gt;
=====onTick() function=====&lt;br /&gt;
Your Lua script is centered around the onTick() function. RaceCapture/Pro will periodically call this function, and here you can define your custom tasks and logic. &lt;br /&gt;
&lt;br /&gt;
Example: this script will periodically write a message to the log:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  println(&amp;quot;hello from RaceCapture/Pro&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Viewing the output log=====&lt;br /&gt;
You can observe the loading of new script and monitor and debug the behavior of your script by using the print() / println() functions. In order to see the log output, enable the &amp;quot;Poll Log&amp;quot; checkbox in the scripting window:&lt;br /&gt;
&lt;br /&gt;
[[image:Hello_RaceCapturePro_script.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=====Controlling the onTick() rate====&lt;br /&gt;
You can control how fast your script is executed using the setTickRate() function.  The tick Rate is specified in Hz, and the default rate is 1Hz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
count = 0&lt;br /&gt;
setTickRate(10)&lt;br /&gt;
&lt;br /&gt;
function onTick()&lt;br /&gt;
  count = count + 1&lt;br /&gt;
  println(&amp;quot;Tick: &amp;quot; ..count)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:RaceCapture_tick_count.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=====Reading and controlling inputs and outputs=====&lt;br /&gt;
&lt;br /&gt;
The Lua scripting enables endless combinations of custom behaviors by reading sensor values, controlling output lines, broadcasting CAN messages and writing data to the Auxiliary serial port. &lt;br /&gt;
&lt;br /&gt;
Example: Reading a sensor value and activating an output based on a threshold. &lt;br /&gt;
&lt;br /&gt;
Given:&lt;br /&gt;
* A calibrated temperature sensor is connected to the first analog input (0);&lt;br /&gt;
* The first GPIO is configured for output mode&lt;br /&gt;
&lt;br /&gt;
This script will activate the output upon crossing the temperature threshold of 212. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  temperature = getAnalog(0)&lt;br /&gt;
  if temperature &amp;gt; 212 then&lt;br /&gt;
    setGpio(0, 1)&lt;br /&gt;
  else&lt;br /&gt;
    setGpio(0, 0)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====Combining multiple functions=====&lt;br /&gt;
When combining multiple functions into one script, it&#039;s recommended to break them into multiple functions and reference them from the main onTick() function.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkTemps()&lt;br /&gt;
&lt;br /&gt;
[ temperature checking logic goes here ]&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function checkAutoLogging()&lt;br /&gt;
&lt;br /&gt;
[ automatic logging logic goes here ]&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onTick()&lt;br /&gt;
  checkTemps()&lt;br /&gt;
  checkAutoLogging()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Debugging your script=====&lt;br /&gt;
If you&#039;re not sure why your script is misbehaving, you can use the println() function to output messages in the log and observe how your script is behaving.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  temperature = getAnalog(0)&lt;br /&gt;
  println(&amp;quot;current temp: &amp;quot; ..temperature)&lt;br /&gt;
  if temperature &amp;gt; 212 then&lt;br /&gt;
    println(&amp;quot;over temp!&amp;quot;)&lt;br /&gt;
    setGpio(0, 1)&lt;br /&gt;
  else&lt;br /&gt;
    println(&amp;quot;under temp&amp;quot;)&lt;br /&gt;
    setGpio(0, 0)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Lua Reference=====&lt;br /&gt;
RaceCapture/Pro uses the standard, lightweight Lua scripting language used as an extension / customization language for many software applications and especially gaming. &lt;br /&gt;
&lt;br /&gt;
* See [https://www.lua.org/ lua.org] for additional information on how to use the Lua language&lt;br /&gt;
=====More examples=====&lt;br /&gt;
You can see more examples in our [[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]] section.&lt;br /&gt;
&lt;br /&gt;
=API Reference=&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
** state: (int / &#039;&#039;(since 2.10.0)&#039;&#039; bool) 1 / true = output active; 0 / false = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getGpsAltitude()===&lt;br /&gt;
Provides the current GPS calculated altitude from sea level in feet.  The method will return 0 if there is no GPS lock.&lt;br /&gt;
* Added: v2.9.0&lt;br /&gt;
* Parameters: &#039;&#039;None&#039;&#039;&lt;br /&gt;
* Returns: &amp;lt;altitude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms.  For non-blocking functionality specify a timeout of 0.&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039; - you should only define one onTick() function in your code. If multiple onTick() functions are defined, only the last defined onTick() function will be used.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state: (int / &#039;&#039;[as of 2.10.0]&#039;&#039; bool) 1 / true = on, 0 / false = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setBgStream( on/off )===&lt;br /&gt;
Sets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** Boolean: true for on, false for off.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getBgStream()===&lt;br /&gt;
Gets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** Boolean: True for on, false for off.&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===getChannel( &amp;lt;Channel ID | Channel Name&amp;gt; )===&lt;br /&gt;
* Available: v2.9.0&lt;br /&gt;
* Parameters &lt;br /&gt;
** Channel ID (number) - The channel id value as provided by the &#039;&#039;addChannel&#039;&#039; method.&lt;br /&gt;
** Channel Name (string) - The name of the channel as provided to the &#039;&#039;addChannel&#039;&#039; method.  Using the Channel ID method is preferred and is faster.&lt;br /&gt;
* Returns&lt;br /&gt;
** (number) The value of the channel.&lt;br /&gt;
* Examples: &lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(1) &amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(&amp;quot;foo&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6671</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6671"/>
		<updated>2016-07-10T02:37:48Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Add note about bool and cleanup a bit.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=RaceCapture/Pro Scripting Guide=&lt;br /&gt;
==Example Scripts and How-Tos==&lt;br /&gt;
A large collection of example scripts can be found in our &#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Lua Script Basics==&lt;br /&gt;
&lt;br /&gt;
===Conventions===&lt;br /&gt;
* All inputs and outputs are numbered starting at 0 (getGpio(0), setChannel(0), etc)&lt;br /&gt;
* All channel values must be numbers&lt;br /&gt;
* All virtual channel names must have no spaces (to be fixed in future revisions)&lt;br /&gt;
&lt;br /&gt;
====Writing your script====&lt;br /&gt;
&lt;br /&gt;
=====onTick() function=====&lt;br /&gt;
Your Lua script is centered around the onTick() function. RaceCapture/Pro will periodically call this function, and here you can define your custom tasks and logic. &lt;br /&gt;
&lt;br /&gt;
Example: this script will periodically write a message to the log:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  println(&amp;quot;hello from RaceCapture/Pro&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Viewing the output log=====&lt;br /&gt;
You can observe the loading of new script and monitor and debug the behavior of your script by using the print() / println() functions. In order to see the log output, enable the &amp;quot;Poll Log&amp;quot; checkbox in the scripting window:&lt;br /&gt;
&lt;br /&gt;
[[image:Hello_RaceCapturePro_script.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=====Controlling the onTick() rate====&lt;br /&gt;
You can control how fast your script is executed using the setTickRate() function.  The tick Rate is specified in Hz, and the default rate is 1Hz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
count = 0&lt;br /&gt;
setTickRate(10)&lt;br /&gt;
&lt;br /&gt;
function onTick()&lt;br /&gt;
  count = count + 1&lt;br /&gt;
  println(&amp;quot;Tick: &amp;quot; ..count)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[image:RaceCapture_tick_count.png|800px]]&lt;br /&gt;
&lt;br /&gt;
=====Reading and controlling inputs and outputs=====&lt;br /&gt;
&lt;br /&gt;
The Lua scripting enables endless combinations of custom behaviors by reading sensor values, controlling output lines, broadcasting CAN messages and writing data to the Auxiliary serial port. &lt;br /&gt;
&lt;br /&gt;
Example: Reading a sensor value and activating an output based on a threshold. &lt;br /&gt;
&lt;br /&gt;
Given:&lt;br /&gt;
* A calibrated temperature sensor is connected to the first analog input (0);&lt;br /&gt;
* The first GPIO is configured for output mode&lt;br /&gt;
&lt;br /&gt;
This script will activate the output upon crossing the temperature threshold of 212. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  temperature = getAnalog(0)&lt;br /&gt;
  if temperature &amp;gt; 212 then&lt;br /&gt;
    setGpio(0, 1)&lt;br /&gt;
  else&lt;br /&gt;
    setGpio(0, 0)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=====Combining multiple functions=====&lt;br /&gt;
When combining multiple functions into one script, it&#039;s recommended to break them into multiple functions and reference them from the main onTick() function.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function checkTemps()&lt;br /&gt;
&lt;br /&gt;
[ temperature checking logic goes here ]&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function checkAutoLogging()&lt;br /&gt;
&lt;br /&gt;
[ automatic logging logic goes here ]&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onTick()&lt;br /&gt;
  checkTemps()&lt;br /&gt;
  checkAutoLogging()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Debugging your script=====&lt;br /&gt;
If you&#039;re not sure why your script is misbehaving, you can use the println() function to output messages in the log and observe how your script is behaving.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function onTick()&lt;br /&gt;
  temperature = getAnalog(0)&lt;br /&gt;
  println(&amp;quot;current temp: &amp;quot; ..temperature)&lt;br /&gt;
  if temperature &amp;gt; 212 then&lt;br /&gt;
    println(&amp;quot;over temp!&amp;quot;)&lt;br /&gt;
    setGpio(0, 1)&lt;br /&gt;
  else&lt;br /&gt;
    println(&amp;quot;under temp&amp;quot;)&lt;br /&gt;
    setGpio(0, 0)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Lua Reference=====&lt;br /&gt;
RaceCapture/Pro uses the standard, lightweight Lua scripting language used as an extension / customization language for many software applications and especially gaming. &lt;br /&gt;
&lt;br /&gt;
* See [https://www.lua.org/ lua.org] for additional information on how to use the Lua language&lt;br /&gt;
=====More examples=====&lt;br /&gt;
You can see more examples in our [[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]] section.&lt;br /&gt;
&lt;br /&gt;
=API Reference=&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
** state: (int / &#039;&#039;(since 2.10.0)&#039;&#039; bool) 1 / true = output active; 0 / false = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getGpsAltitude()===&lt;br /&gt;
Provides the current GPS calculated altitude from sea level in feet.  The method will return 0 if there is no GPS lock.&lt;br /&gt;
* Added: v2.9.0&lt;br /&gt;
* Parameters: &#039;&#039;None&#039;&#039;&lt;br /&gt;
* Returns: &amp;lt;altitude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms.  For non-blocking functionality specify a timeout of 0.&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039; - you should only define one onTick() function in your code. If multiple onTick() functions are defined, only the last defined onTick() function will be used.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state : 1 = on, 0 = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setBgStream( on/off )===&lt;br /&gt;
Sets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** Boolean: true for on, false for off.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getBgStream()===&lt;br /&gt;
Gets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** Boolean: True for on, false for off.&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===getChannel( &amp;lt;Channel ID | Channel Name&amp;gt; )===&lt;br /&gt;
* Available: v2.9.0&lt;br /&gt;
* Parameters &lt;br /&gt;
** Channel ID (number) - The channel id value as provided by the &#039;&#039;addChannel&#039;&#039; method.&lt;br /&gt;
** Channel Name (string) - The name of the channel as provided to the &#039;&#039;addChannel&#039;&#039; method.  Using the Channel ID method is preferred and is faster.&lt;br /&gt;
* Returns&lt;br /&gt;
** (number) The value of the channel.&lt;br /&gt;
* Examples: &lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(1) &amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(&amp;quot;foo&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceTracks&amp;diff=6669</id>
		<title>RaceTracks</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceTracks&amp;diff=6669"/>
		<updated>2016-06-16T16:49:21Z</updated>

		<summary type="html">&lt;p&gt;Stieg: /* Record Basic Track Info */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
=How to create / submit a track map=&lt;br /&gt;
&lt;br /&gt;
==Pick a Track==&lt;br /&gt;
Pick a track map below that isn&#039;t completed.&lt;br /&gt;
&lt;br /&gt;
==Open Up a Basic Text Editor==&lt;br /&gt;
You will need a basic text editor to copy and past information into.  Applications like Notepad, Textedit, Gedit all work very well.&lt;br /&gt;
&lt;br /&gt;
== Open Up The Drawing Tool ==&lt;br /&gt;
Use this handy [http://www.birdtheme.org/useful/v3tool.html Map Drawing tool] to create an outline of the race track as well as find GeoPoints.  I will assume you are using it throughout the rest of this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Record Basic Track Info==&lt;br /&gt;
We need a few basic things to get going.  They are as follows:&lt;br /&gt;
*Track Name&lt;br /&gt;
*Track Configuration&lt;br /&gt;
*Country Track is Located In&lt;br /&gt;
*Center area of track (We use this for zooming and display purposes).&lt;br /&gt;
*Start/Finish GeoPoint on track.&lt;br /&gt;
&lt;br /&gt;
Add all that information into your text editor.&lt;br /&gt;
&lt;br /&gt;
==Draw the Track==&lt;br /&gt;
Now its time to draw the outline of the track.  Clear the tool above using the &amp;quot;Clear Map&amp;quot; button and do the following:&lt;br /&gt;
&lt;br /&gt;
# Find the race track track using the search bar and zoom in on the track.&lt;br /&gt;
# Locate the start / finish line and make that your first point by clicking it.&lt;br /&gt;
# Follow the contour of the track by clicking around the track, making sure your lines are &#039;&#039;&#039;in the centerline of the track&#039;&#039;&#039; (This is really important).&lt;br /&gt;
# If you make a mistake, you can undo points by clicking the &amp;quot;Delete Last Point&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
When you are finished, copy the text blob from the tool into the text editor.  Label the blob as &amp;quot;Outline&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tips:&#039;&#039;&lt;br /&gt;
* Zoom all the way in on the map to get the best placement accuracy&lt;br /&gt;
* Make more points in curves so it looks smooth.&lt;br /&gt;
* Draw the lines using the centerline of the track. &lt;br /&gt;
&lt;br /&gt;
==Record Sector Points &#039;&#039;(Optional)&#039;&#039;==&lt;br /&gt;
If you want to go the extra mile and be extra awesome, you can include sector points.  These are points that allow us to partition&lt;br /&gt;
the track into sections so we can get timing info for individual sections of the track.  However there is a catch, we can only support up to 20 sector points per track (not including start/finish).  To add sector data, do the following:&lt;br /&gt;
&lt;br /&gt;
#Use the same tool.  Before you start, clear out any data by selecting the &amp;quot;Clear Map&amp;quot; button.&lt;br /&gt;
#Think about how you would logically divide the track in your mind.  What corners or sections are most important to you?&lt;br /&gt;
#With that in mind, select these points.  Don&#039;t worry about the shape you draw, we are interested in the points.&lt;br /&gt;
#* REMEMBER: You can only have up to 20 points.  DO NOT include start finish as one of these points.&lt;br /&gt;
&lt;br /&gt;
When you are finished, copy the text blob from the tool into the text editor.  Label the blob as &amp;quot;Sectors&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Submit It!==&lt;br /&gt;
When you&#039;ve gotten all the data described above, copy and paste all of the text from your text editor into an email and [mailto:racecapture@autosportlabs.com submit it to us].  Be sure you included the basic track data! We will review the track data and if sufficient, incorporate it into our Mobile app and online!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Thank you from the Autosport Labs team!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=Tracks=&lt;br /&gt;
To see a list of track maps we have in our database, visit this page: http://race-capture.com/venues&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=Cellular&amp;diff=6664</id>
		<title>Cellular</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=Cellular&amp;diff=6664"/>
		<updated>2016-06-08T18:56:07Z</updated>

		<summary type="html">&lt;p&gt;Stieg: /* SARA-U280 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Cellular Technoligies and RaceCapture/Pro =&lt;br /&gt;
&lt;br /&gt;
This page covers the equipment and technoligies used in RaceCapture/Pro telemetry implementations.  It discusses the supported bands &amp;amp; frequencies and lists the technologies used.  It also covers cellular providers in priority order based on country.  This is still a work in progress... we would love to hear from users about providers in their local country.&lt;br /&gt;
&lt;br /&gt;
= 2.5G =&lt;br /&gt;
== SIM900 ==&lt;br /&gt;
The original telemetry on MK1 and MK2 is a 2G module made by SIMCOM.  This is a GPRS device with a good range but limited bandwidth and near universal worldwide coverage. Specs are as follows:&lt;br /&gt;
&lt;br /&gt;
* Frequencies (Bands) : 850 (5) / 900 (8) / 1800 (3) / 1900 (2) MHz &lt;br /&gt;
* Protocols: GPRS multi-slot class 10/8&lt;br /&gt;
** Class 4 (2 W @850/ 900 MHz)&lt;br /&gt;
** Class 1 (1 W @ 1800/1900MHz)&lt;br /&gt;
* Max Upload Speed: 21.4 kb/s&lt;br /&gt;
&lt;br /&gt;
==== Links ==== &lt;br /&gt;
* http://www.propox.com/download/docs/SIM900.pdf&lt;br /&gt;
* https://en.wikipedia.org/wiki/General_Packet_Radio_Service&lt;br /&gt;
&lt;br /&gt;
= 3.5G =&lt;br /&gt;
This is the latest in supported telemetry chips for RaceCapture/Pro.  This unit is vastly improved compared to its predecessor, but some models can be limited by only supporting a smaller number of frequencies compared to the SIM900.  Initially RaceCapture/Pro will support the SARA-U280.  We intend to introduce other models in the future.&lt;br /&gt;
&lt;br /&gt;
== SARA-U280 ==&lt;br /&gt;
This is the initial 3G chip available for RaceCapture/Pro units in North America (USA, Canada and Mexico).  Its specs are as follows:&lt;br /&gt;
&lt;br /&gt;
* Frequencies: 850 MHz / 1900 MHz &lt;br /&gt;
* Protocols: UMTS/HSPA (HSDPA/HSUPA)&lt;br /&gt;
* Max Upload Speed: 5.76 Mb/s&lt;br /&gt;
&lt;br /&gt;
==== Links ==== &lt;br /&gt;
* https://www.u-blox.com/en/product/sara-u2-series&lt;br /&gt;
&lt;br /&gt;
== SARA-U270 ==&lt;br /&gt;
This is a 3G chip we are testing for enabling 3G support worldwide.  Its specs are as follows:&lt;br /&gt;
&lt;br /&gt;
* Frequencies: 900 MHz / 2100 MHz &lt;br /&gt;
* Protocols: UMTS/HSPA (HSDPA/HSUPA)&lt;br /&gt;
* Max Upload Speed: 5.76 Mb/s&lt;br /&gt;
&lt;br /&gt;
==== Links ==== &lt;br /&gt;
* https://www.u-blox.com/en/product/sara-u2-series&lt;br /&gt;
&lt;br /&gt;
= Cellular Providers =&lt;br /&gt;
This section convers the basics about cellular providers in various countries.  Specifically it lists what bands they are known to support.  This is so you can best match up your device with a cellular provider.  Providers are listed in descending order, with the ones at the top being prefered.&lt;br /&gt;
&lt;br /&gt;
== USA ==&lt;br /&gt;
=== AT&amp;amp;T ===&lt;br /&gt;
AT&amp;amp;T is the group we have had the best experience with in the states.  Primarily its because they support all the bands that both our 2G and 3G devices support and they tend to have the best coverage.  However, working with them directly can be a pain.  We often suggest using an Mobile Virtual Network Operator (MVNO) that makes use of the AT&amp;amp;T infrastructure.  That way you can avoid the hassle of AT&amp;amp;T and still get the same great coverage.  One common MVNO we recommend is Straight Talk.&lt;br /&gt;
&lt;br /&gt;
==== Frequencies (Bands) and Protocols ====&lt;br /&gt;
* 850 MHz (5)&lt;br /&gt;
** GPRS (This will be discontinued in 2017)&lt;br /&gt;
** UMTS&lt;br /&gt;
** HSPA&lt;br /&gt;
** HSPA+&lt;br /&gt;
* 1900 MHz (2)&lt;br /&gt;
** GPRS (This will be discontinued in 2017)&lt;br /&gt;
** UMTS&lt;br /&gt;
** HSPA&lt;br /&gt;
** HSPA+&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
* https://en.wikipedia.org/wiki/AT%26T_Mobility&lt;br /&gt;
&lt;br /&gt;
=== T-Mobile ===&lt;br /&gt;
T-Mobile is the other mobile data provider in the states that you can use with RaceCapture/Pro Telemetry.  While T-Mobile is often cheaper than AT&amp;amp;T, their coverage tends to not always be as good in remote areas where race tracks tend to live.  They also don&#039;t support all the bands that the RaceCapture/Pro can use.  Because of this, we tend to avoid them unless they are known to be good at a particular location.&lt;br /&gt;
&lt;br /&gt;
==== Frequencies (Bands) and Protocols ====&lt;br /&gt;
* 1900 MHz (2)&lt;br /&gt;
** GPRS (This will be discontinued in 2017)&lt;br /&gt;
** UMTS&lt;br /&gt;
** HSPA&lt;br /&gt;
** HSPA+&lt;br /&gt;
* 1700/2100 MHz (4) - NOTE: This is being phased out and &amp;quot;re-farmed&amp;quot; to the 1900 MHz spectrum&lt;br /&gt;
** UMTS&lt;br /&gt;
** HSPA&lt;br /&gt;
** HSPA+&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
* https://en.wikipedia.org/wiki/T-Mobile_US&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6581</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6581"/>
		<updated>2016-05-02T04:05:50Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Add note about non-blocking functionality.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Example Scripts and How-Tos==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Lua Script Basics==&lt;br /&gt;
&lt;br /&gt;
* All inputs and outputs are numbered starting at 0 (getGpio(0), setChannel(0), etc)&lt;br /&gt;
* All channel values must be numbers&lt;br /&gt;
* All virtual channel names must have no spaces (to be fixed in future revisions)&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2, state - 1 = output active; 0 = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getGpsAltitude()===&lt;br /&gt;
Provides the current GPS calculated altitude from sea level in feet.  The method will return 0 if there is no GPS lock.&lt;br /&gt;
* Added: v2.9.0&lt;br /&gt;
* Parameters: &#039;&#039;None&#039;&#039;&lt;br /&gt;
* Returns: &amp;lt;altitude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms.  For non-blocking functionality specify a timeout of 0.&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039; - you should only define one onTick() function in your code. If multiple onTick() functions are defined, only the last defined onTick() function will be used.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state : 1 = on, 0 = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setBgStream( on/off )===&lt;br /&gt;
Sets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** Boolean: true for on, false for off.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getBgStream()===&lt;br /&gt;
Gets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** Boolean: True for on, false for off.&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===getChannel( &amp;lt;Channel ID | Channel Name&amp;gt; )===&lt;br /&gt;
* Available: v2.9.0&lt;br /&gt;
* Parameters &lt;br /&gt;
** Channel ID (number) - The channel id value as provided by the &#039;&#039;addChannel&#039;&#039; method.&lt;br /&gt;
** Channel Name (string) - The name of the channel as provided to the &#039;&#039;addChannel&#039;&#039; method.  Using the Channel ID method is preferred and is faster.&lt;br /&gt;
* Returns&lt;br /&gt;
** (number) The value of the channel.&lt;br /&gt;
* Examples: &lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(1) &amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(&amp;quot;foo&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=Tablets/Android/Samsung-SM-T320&amp;diff=6575</id>
		<title>Tablets/Android/Samsung-SM-T320</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=Tablets/Android/Samsung-SM-T320&amp;diff=6575"/>
		<updated>2016-04-28T02:34:38Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Created page with &amp;quot;Known otherwise as the Samsung Galaxy Tab Pro 8.4,  == Overivew == * Status: Verified by ASL * Last Tested: 2016-04-27 ** Tested by: Stieg ** App Version: 1.5.2 ** Firmware Ve...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Known otherwise as the Samsung Galaxy Tab Pro 8.4,&lt;br /&gt;
&lt;br /&gt;
== Overivew ==&lt;br /&gt;
* Status: Verified by ASL&lt;br /&gt;
* Last Tested: 2016-04-27&lt;br /&gt;
** Tested by: Stieg&lt;br /&gt;
** App Version: 1.5.2&lt;br /&gt;
** Firmware Version: 1.9.0&lt;br /&gt;
&lt;br /&gt;
== Screen ==&lt;br /&gt;
Reasonably bright screen.  Does well during the daylight.  Not super good in direct sunlight.&lt;br /&gt;
&lt;br /&gt;
== Bluetooth ==&lt;br /&gt;
Works reasonably well.  No major hiccups.  Sometimes need to restart the Bluetooth stack to get it to recognize RaceCapture.&lt;br /&gt;
&lt;br /&gt;
== Cellular Support ==&lt;br /&gt;
None.&lt;br /&gt;
&lt;br /&gt;
== Holders &amp;amp; Charger ==&lt;br /&gt;
I use a RAM mount to hold this tablet in Lemons.  Use the 2A charger sold in the ASL store.  Works very well.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=Tablets/FireOS&amp;diff=6574</id>
		<title>Tablets/FireOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=Tablets/FireOS&amp;diff=6574"/>
		<updated>2016-04-28T02:11:01Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Created page with &amp;quot;FireOS is Amazon&amp;#039;s Android-based mobile operating system.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;FireOS is Amazon&#039;s Android-based mobile operating system.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=Tablets/iOS&amp;diff=6573</id>
		<title>Tablets/iOS</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=Tablets/iOS&amp;diff=6573"/>
		<updated>2016-04-28T02:05:46Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Created page with &amp;quot;iOS support for the RaceCapture App is still a work in progress.  When its officially released we will begin adding tablet information here.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;iOS support for the RaceCapture App is still a work in progress.  When its officially released we will begin adding tablet information here.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=Tablets/Android&amp;diff=6572</id>
		<title>Tablets/Android</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=Tablets/Android&amp;diff=6572"/>
		<updated>2016-04-28T02:03:54Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Created page with &amp;quot;This page and its sub pages contain all information about Android tablets that we support.  &amp;#039;&amp;#039;NOTE: Fire tablets are in their own section as they are not quite in the same eco...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page and its sub pages contain all information about Android tablets that we support.  &#039;&#039;NOTE: Fire tablets are in their own section as they are not quite in the same ecosystem as Android&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Minimum Requirements ==&lt;br /&gt;
* Android 4.4 (KitKat) and higher&lt;br /&gt;
* Quad core 1.6 GHz processor&lt;br /&gt;
* 2 GB RAM&lt;br /&gt;
* 8 GB Storage&lt;br /&gt;
* 1024x600 or greater resolution&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6563</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6563"/>
		<updated>2016-04-16T17:09:56Z</updated>

		<summary type="html">&lt;p&gt;Stieg: /* Logger Control Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Example Scripts and How-Tos==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Lua Script Basics==&lt;br /&gt;
&lt;br /&gt;
* All inputs and outputs are numbered starting at 0 (getGpio(0), setChannel(0), etc)&lt;br /&gt;
* All channel values must be numbers&lt;br /&gt;
* All virtual channel names must have no spaces (to be fixed in future revisions)&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2, state - 1 = output active; 0 = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getGpsAltitude()===&lt;br /&gt;
Provides the current GPS calculated altitude from sea level in feet.  The method will return 0 if there is no GPS lock.&lt;br /&gt;
* Added: v2.9.0&lt;br /&gt;
* Parameters: &#039;&#039;None&#039;&#039;&lt;br /&gt;
* Returns: &amp;lt;altitude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039; - you should only define one onTick() function in your code. If multiple onTick() functions are defined, only the last defined onTick() function will be used.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state : 1 = on, 0 = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setBgStream( on/off )===&lt;br /&gt;
Sets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** Boolean: true for on, false for off.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getBgStream()===&lt;br /&gt;
Gets the state of background streaming&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** Boolean: True for on, false for off.&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===getChannel( &amp;lt;Channel ID | Channel Name&amp;gt; )===&lt;br /&gt;
* Available: v2.9.0&lt;br /&gt;
* Parameters &lt;br /&gt;
** Channel ID (number) - The channel id value as provided by the &#039;&#039;addChannel&#039;&#039; method.&lt;br /&gt;
** Channel Name (string) - The name of the channel as provided to the &#039;&#039;addChannel&#039;&#039; method.  Using the Channel ID method is preferred and is faster.&lt;br /&gt;
* Returns&lt;br /&gt;
** (number) The value of the channel.&lt;br /&gt;
* Examples: &lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(1) &amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(&amp;quot;foo&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=Cellular&amp;diff=6535</id>
		<title>Cellular</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=Cellular&amp;diff=6535"/>
		<updated>2016-04-07T03:41:22Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Created page with &amp;quot; = Cellular Technoligies and RaceCapture/Pro =  This page covers the equipment and technoligies used in RaceCapture/Pro telemetry implementations.  It discusses the supported...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Cellular Technoligies and RaceCapture/Pro =&lt;br /&gt;
&lt;br /&gt;
This page covers the equipment and technoligies used in RaceCapture/Pro telemetry implementations.  It discusses the supported bands &amp;amp; frequencies and lists the technologies used.  It also covers cellular providers in priority order based on country.  This is still a work in progress... we would love to hear from users about providers in their local country.&lt;br /&gt;
&lt;br /&gt;
= 2G =&lt;br /&gt;
== SIM900 ==&lt;br /&gt;
The original telemetry on MK1 and MK2 is a 2G module made by SIMCOM.  This is a GPRS device with a good range but limited bandwidth.  Specs are as follows:&lt;br /&gt;
&lt;br /&gt;
* Frequencies (Bands) : 850 (5) / 900 (8) / 1800 (3) / 1900 (2) MHz &lt;br /&gt;
* Protocols: GPRS multi-slot class 10/8&lt;br /&gt;
** Class 4 (2 W @850/ 900 MHz)&lt;br /&gt;
** Class 1 (1 W @ 1800/1900MHz)&lt;br /&gt;
* Max Upload Speed: 21.4 kb/s&lt;br /&gt;
&lt;br /&gt;
==== Links ==== &lt;br /&gt;
* http://www.propox.com/download/docs/SIM900.pdf&lt;br /&gt;
* https://en.wikipedia.org/wiki/General_Packet_Radio_Service&lt;br /&gt;
&lt;br /&gt;
= 3G =&lt;br /&gt;
This is the latest in supported telemetry chips for RaceCapture/Pro.  This unit is vastly improved compared to its predecessor, but some models can be limited by only supporting a smaller number of frequencies compared to the SIM900.  Initially RaceCapture/Pro will support the SARA-U280.  We intend to introduce other models in the future.&lt;br /&gt;
&lt;br /&gt;
== SARA-U280 ==&lt;br /&gt;
This is the initial 3G chip available for RaceCapture/Pro units in the USA.  Its specs are as follows:&lt;br /&gt;
&lt;br /&gt;
* Frequencies (Band): 850 (5) / 1900 (2) MHz &lt;br /&gt;
* Protocols: UMTS/HSPA&lt;br /&gt;
* Max Upload Speed: 5.76 Mb/s&lt;br /&gt;
&lt;br /&gt;
==== Links ==== &lt;br /&gt;
* https://www.u-blox.com/en/product/sara-u2-series&lt;br /&gt;
= Cellular Providers =&lt;br /&gt;
This section convers the basics about cellular providers in various countries.  Specifically it lists what bands they are known to support.  This is so you can best match up your device with a cellular provider.  Providers are listed in descending order, with the ones at the top being prefered.&lt;br /&gt;
&lt;br /&gt;
== USA ==&lt;br /&gt;
=== AT&amp;amp;T ===&lt;br /&gt;
AT&amp;amp;T is the group we have had the best experience with in the states.  Primarily its because they support all the bands that both our 2G and 3G devices support and they tend to have the best coverage.  However, working with them directly can be a pain.  We often suggest using an Mobile Virtual Network Operator (MVNO) that makes use of the AT&amp;amp;T infrastructure.  That way you can avoid the hassle of AT&amp;amp;T and still get the same great coverage.  One common MVNO we recommend is Straight Talk.&lt;br /&gt;
&lt;br /&gt;
==== Frequencies (Bands) and Protocols ====&lt;br /&gt;
* 850 MHz (5)&lt;br /&gt;
** GPRS (This will be discontinued in 2017)&lt;br /&gt;
** UMTS&lt;br /&gt;
** HSPA&lt;br /&gt;
** HSPA+&lt;br /&gt;
* 1900 MHz (2)&lt;br /&gt;
** GPRS (This will be discontinued in 2017)&lt;br /&gt;
** UMTS&lt;br /&gt;
** HSPA&lt;br /&gt;
** HSPA+&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
* https://en.wikipedia.org/wiki/AT%26T_Mobility&lt;br /&gt;
&lt;br /&gt;
=== T-Mobile ===&lt;br /&gt;
T-Mobile is the other mobile data provider in the states that you can use with RaceCapture/Pro Telemetry.  While T-Mobile is often cheaper than AT&amp;amp;T, their coverage tends to not always be as good in remote areas where race tracks tend to live.  They also don&#039;t support all the bands that the RaceCapture/Pro can use.  Because of this, we tend to avoid them unless they are known to be good at a particular location.&lt;br /&gt;
&lt;br /&gt;
==== Frequencies (Bands) and Protocols ====&lt;br /&gt;
* 1900 MHz (2)&lt;br /&gt;
** GPRS (This will be discontinued in 2017)&lt;br /&gt;
** UMTS&lt;br /&gt;
** HSPA&lt;br /&gt;
** HSPA+&lt;br /&gt;
* 1700/2100 MHz (4) - NOTE: This is being phased out and &amp;quot;re-farmed&amp;quot; to the 1900 MHz spectrum&lt;br /&gt;
** UMTS&lt;br /&gt;
** HSPA&lt;br /&gt;
** HSPA+&lt;br /&gt;
&lt;br /&gt;
==== Links ====&lt;br /&gt;
* https://en.wikipedia.org/wiki/T-Mobile_US&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6446</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6446"/>
		<updated>2016-03-07T02:36:00Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Add the getChannel method&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Example Scripts and How-Tos==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2, state - 1 = output active; 0 = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getGpsAltitude()===&lt;br /&gt;
Provides the current GPS calculated altitude from sea level in feet.  The method will return 0 if there is no GPS lock.&lt;br /&gt;
* Added: v2.9.0&lt;br /&gt;
* Parameters: &#039;&#039;None&#039;&#039;&lt;br /&gt;
* Returns: &amp;lt;altitude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039; - you should only define one onTick() function in your code. If multiple onTick() functions are defined, only the last defined onTick() function will be used.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state : 1 = on, 0 = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===getChannel( &amp;lt;Channel ID | Channel Name&amp;gt; )===&lt;br /&gt;
* Available: v2.9.0&lt;br /&gt;
* Parameters &lt;br /&gt;
** Channel ID (number) - The channel id value as provided by the &#039;&#039;addChannel&#039;&#039; method.&lt;br /&gt;
** Channel Name (string) - The name of the channel as provided to the &#039;&#039;addChannel&#039;&#039; method.  Using the Channel ID method is preferred and is faster.&lt;br /&gt;
* Returns&lt;br /&gt;
** (number) The value of the channel.&lt;br /&gt;
* Examples: &lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(1) &amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt; val = getChannel(&amp;quot;foo&amp;quot;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6445</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6445"/>
		<updated>2016-03-07T02:20:03Z</updated>

		<summary type="html">&lt;p&gt;Stieg: /* GPS Sensor Functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Example Scripts and How-Tos==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2, state - 1 = output active; 0 = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getGpsAltitude()===&lt;br /&gt;
Provides the current GPS calculated altitude from sea level in feet.  The method will return 0 if there is no GPS lock.&lt;br /&gt;
* Added: v2.9.0&lt;br /&gt;
* Parameters: &#039;&#039;None&#039;&#039;&lt;br /&gt;
* Returns: &amp;lt;altitude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039; - you should only define one onTick() function in your code. If multiple onTick() functions are defined, only the last defined onTick() function will be used.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state : 1 = on, 0 = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6444</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6444"/>
		<updated>2016-03-07T02:16:55Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Add getGpsAltitude&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Example Scripts and How-Tos==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2, state - 1 = output active; 0 = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getGpsAltitude()===&lt;br /&gt;
Provides the current GPS calculated altitude from sea level in feet.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** Feet above sea level.&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039; - you should only define one onTick() function in your code. If multiple onTick() functions are defined, only the last defined onTick() function will be used.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state : 1 = on, 0 = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6429</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6429"/>
		<updated>2016-02-15T21:02:31Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Add dutyCyclePct param description.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Example Scripts and How-Tos==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2, state - 1 = output active; 0 = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** dutyCyclePct: Percentage value of the duty cycle as a counting number 0 - 100&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state : 1 = on, 0 = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port, [timeout])===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port, [timeout])===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available since firmware 2.8.4&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro2_Hardware_Install&amp;diff=6412</id>
		<title>RaceCapturePro2 Hardware Install</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro2_Hardware_Install&amp;diff=6412"/>
		<updated>2016-01-21T05:11:30Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Improved the installation section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Connections==&lt;br /&gt;
&lt;br /&gt;
[[Image:RaceCapture-Pro MK2 quick reference sheet.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Power Connection===&lt;br /&gt;
Connect RaceCapture/Pro to a power source between 9 and 24V. To fully support all devices and outputs, provide at least a 5A fused connection.&lt;br /&gt;
&lt;br /&gt;
==Sensors==&lt;br /&gt;
&#039;&#039;&#039;Also see the [[RaceCapturePro_Sensors|Comprehensive Sensor installation guide]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===Analog Inputs 1-7===&lt;br /&gt;
&lt;br /&gt;
====Specifications====&lt;br /&gt;
* RaceCapture/Pro has 8 analog inputs; the 8th input is wired internally to measuring battery voltage.&lt;br /&gt;
* Analog input range is 0 - 5v&lt;br /&gt;
* Input Impedance: 15K ohm&lt;br /&gt;
&lt;br /&gt;
====Active Sensors/Signals====&lt;br /&gt;
The Analog Input Channels accept a 0-5v input signal (protected up to 40V). Connect the input from a sensor to the appropriate connection of the terminal block.  &lt;br /&gt;
&amp;lt;center&amp;gt;[[Image:active_sensor_connection.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Resistive sensor====&lt;br /&gt;
When connecting resistive style sensors, like many temperature and pressure sensors, one terminal of the sensor is connected to ground, and the other is connected to the Analog input, with a pullup resistor connected to the +5V Voltage Reference on the terminal block. A 2.2K resistor is recommended for most applications.&lt;br /&gt;
&amp;lt;center&amp;gt;[[Image:temp_sensor_connection.png]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===5V Voltage Reference===&lt;br /&gt;
This output provides a 5V reference to be used with the Analog Inputs. Up to 50mA is provided to supply power to active sensors, pull-up resistors and other purposes. This reference output is protected against short-circuits with an auto-resetting fuse. If the fuse is active, a low or zero voltage reading may be observed on this port. To verify an over-current situation, test the voltage on the port without any load connected.&lt;br /&gt;
&lt;br /&gt;
===Analog/Frequency Outputs 1 - 4===&lt;br /&gt;
Depending on configuration, these outputs provide a settable 0-5v analog output voltage, or frequency output where the pulse-width and frequency can be set. These outputs can supply 50mA each.&lt;br /&gt;
&lt;br /&gt;
===General Input/Output Channels 1 - 3===&lt;br /&gt;
Depending on configuration, these channels can accept either a digital input, or provide an output to control external devices.&lt;br /&gt;
* When configured for &#039;&#039;&#039;input&#039;&#039;&#039;, the channel accepts a 0-5v input (protected up to 45V). Each input channel has a built-in 10K pullup resistor connected to 5V.&lt;br /&gt;
* When configured for &#039;&#039;&#039;output&#039;&#039;&#039;, the channel provides an open-drain output that can drive 1A and is thermal / over-current protected with inductive load clamping. When the output is deactivated, a 1K ohm pull-up to +5v is present.&lt;br /&gt;
&lt;br /&gt;
===Frequency/Pulse Input 1 - 3===&lt;br /&gt;
These input channels can be used to time the duration between digital pulses for purposes of measuring RPM, shaft speed, and so on. The input accepts 0-5V (protected up to 40V). Each input has a built-in 10K pullup resistor connected to 5V.&lt;br /&gt;
&lt;br /&gt;
====TACH SIGNAL NOTES====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not connect the old-style tachometer signal directly to RaceCapture/Pro.&#039;&#039;&#039; This signal is typically sourced from a wire that connects directly to the (-) post of the ignition coil. These signals are 400-500v peak and can damage your RaceCapture/Pro hardware.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[CoilX CoilX Sensor Module]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:coilx_wiring_sm.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
You can use the CoilX sensor module to safely interface this high voltage RPM signal. See the [[CoilX|CoilX page]] for more information.&lt;br /&gt;
&lt;br /&gt;
Newer style tach signals sourced from the ECU will likely provide a clean square wave signal and can be connected directly to this input.&lt;br /&gt;
&lt;br /&gt;
If unsure, observe the signal with an oscilloscope and/or consult technical documentation of your vehicle.&lt;br /&gt;
&lt;br /&gt;
===LED Indicators===&lt;br /&gt;
&lt;br /&gt;
[[File:Leds.jpg]]&lt;br /&gt;
&lt;br /&gt;
* Power LED&lt;br /&gt;
Indicates the unit is powered up (via 12v supply or USB)&lt;br /&gt;
* LED1&lt;br /&gt;
Indicates GPS Activity. Slow flash (1Hz) indicates GPS is actively acquiring. Fast flash (10 times per second) indicates GPS is locked on to satellites.&lt;br /&gt;
* LED2&lt;br /&gt;
Indicates SD card Logging Activity. The flash rate matches the channel with the highest configured logging rate.&lt;br /&gt;
* LED3&lt;br /&gt;
Indicates error status when writing to SD Card (future error conditions will be indicated by this LED)&lt;br /&gt;
&lt;br /&gt;
===Pushbutton===&lt;br /&gt;
&lt;br /&gt;
[[File:Pushbutton.jpg]]&lt;br /&gt;
&lt;br /&gt;
Press to manually start / stop a logging session. Note this may be overridden by any on-board scripts that may automatically start or stop logging.&lt;br /&gt;
&lt;br /&gt;
===Communication Ports===&lt;br /&gt;
&lt;br /&gt;
[[File:Expansionports.jpg]]&lt;br /&gt;
&lt;br /&gt;
The communication ports a standard RS232 serial connection with power (up to 5v at 1.5A)&lt;br /&gt;
* Port 1&lt;br /&gt;
Used for BT module&lt;br /&gt;
* Port 2&lt;br /&gt;
Serial I/O&lt;br /&gt;
&lt;br /&gt;
=Installation=&lt;br /&gt;
This section will give you the basic overview of installation best practices.&lt;br /&gt;
&lt;br /&gt;
==Location==&lt;br /&gt;
Picking a location that is easily accessible is key.  You will want to mount your RaceCapture so that access to the front of the unit (the side with the lights) is easy.  Remember that in a driver&#039;s suit your vision and range of motion can be limited, so try to place the unit where the front is visible.  For optimal perfomance of your RaceCapture unit, you should place the unit as close to the center of the vehicle&#039;s axis&#039;s as is possible.  This ensures that the lateral accelerations will be minimal in the event of body roll, pitch and rotation.&lt;br /&gt;
&lt;br /&gt;
==Orientation==&lt;br /&gt;
The unit must be mounted squarely with the vehcile.  You may rotate it in 90 degree increments in along any of the three axis as you see fit, but the final result must be square against the sides, front and bottom of the vehicle.  Rotating anything less than 90 degress along any one axis will lead to inaccurate G-force mesaurements.  If you rotate the unit away from its default orientation (described below), you will need to remap the accelerometer when you configure the unit.&lt;br /&gt;
&lt;br /&gt;
===Default Orientation===&lt;br /&gt;
The default configuration is setup so that the front of the unit (the side with the LEDs) is facing towards the rear of the vehicle and the side with the green connector is facing towards the front of the vehicle.  The side of the unit with the RaceCapture/Pro sticker is facing up.  Below is an image of the default orientation cofiguration:&lt;br /&gt;
[[File:RCP_MK2_3quarter_LED_Axis.png|none|200px]]&lt;br /&gt;
If your unit installation does not align with this orientation, you will need to re-map the channels in the firmware.&lt;br /&gt;
&lt;br /&gt;
==Isolation==&lt;br /&gt;
Vibration from the vehicle can cause noise in the accelerometers, which can lead to dirty data.  Ideally it is best to have some form of isolation between the frame of the vehicle and the RaceCapture unit.  Rubber spacers work well as do adhesive strips like the 3M DualLock adhesive strips.  These also allow for easy removal of the unit.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6410</id>
		<title>RaceCapture CustomTrackBestPractices</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6410"/>
		<updated>2016-01-13T00:36:48Z</updated>

		<summary type="html">&lt;p&gt;Stieg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Walking/Building a Course - Best Practices=&lt;br /&gt;
Whether you are doing an autocross, rally, karting or whatever else you may race, sometimes you need to create your own course.  Fortunately Autosport Labs has you covered for this very scenario with our custom course design tool.  Using a GPS enabled tablet or phone with the RaceCapture App, you can define start &amp;amp; finish points as well as sector points along your track.&lt;br /&gt;
&lt;br /&gt;
This page goes over the best practices in creating a course as well as in covers course setup to ensure that you get the best performance from your RaceCapture device.&lt;br /&gt;
&lt;br /&gt;
==Basic System Overview==&lt;br /&gt;
In order to understand these recommendations, its best to first understand how RaceCapture works internally.  Below is a brief definition of concepts used internally.&lt;br /&gt;
&lt;br /&gt;
===Geo-Circles===&lt;br /&gt;
A Geo-Circle is simply a gps point and a distance.  We use this information to draw a circle on the map.  This is how we implement start, finish and sector points in RaceCapture firmware.  When you enter the circle, you have reached that particular point.  By default, the radius of a Geo-Circle is 11 meters (~36 ft).  Here is what it looks like conceptually:&lt;br /&gt;
&lt;br /&gt;
[[File:Race_Track_StartFinish_GeoPoint.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
===Geo-Triggers===&lt;br /&gt;
Geo-Triggers are like Geo-Circles in that they have a gps point and a distance, but they also have one more element: a boolean indicating when the object has been triggered.  We use Geo-Triggers on top of Geo-Circles in RaceCapture to prevent false positives results.  Here is what it looks like conceptually:&lt;br /&gt;
&lt;br /&gt;
[[File:Race_Track_StartFinish_GeoPoint_with_GeoTrigger.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
===Sector Counting===&lt;br /&gt;
Sectors work like sequential counters.  So when you start a lap with sectors on the track, RaceCapture will look for the first sector.  When you reach it, it will search for the next.  This process repeats until there are no more sectors, at which point it uses the finish point as the last sector point.&lt;br /&gt;
&lt;br /&gt;
==Best Practices==&lt;br /&gt;
Now that you are armed with a basic understanding of how the internals work, these best practices are hopefully very reasonable.&lt;br /&gt;
&lt;br /&gt;
===Avoid Overlapping Geo Circles With Other Parts of the Track===&lt;br /&gt;
Because Geo-Circles are triggered when a vehicle enters them, we must be careful in where we place them.  Overlapping Geo-Circles can cause unpredictable results such as early finishes, early sector time values.  This often occurs because drivers can take different drive lines.  Some lines may trigger the event while others miss the Geo-Circle, and thus don&#039;t trigger the event.  If there is a chance that a Geo circle overlaps an earlier part of the track, adjust its position away from the overlapping portion to prevent a false trigger.  Here is what an overlapping Geo-Circle might look like:&lt;br /&gt;
&lt;br /&gt;
[[File:Geo_Circle_Overlapping.png|200px|center]]&lt;br /&gt;
&lt;br /&gt;
===In Stage Mode, Drive 25 M From Start Before Next Run===&lt;br /&gt;
Start/Finish points in RaceCapture are protected by a Geo-Trigger.  Geo-Triggers are present to prevent false triggering of Geo-Circles when start and finish locations are close together.  The Geo-Trigger radius is configured to be 2x the Geo-Circle radius.  This means the default trigger radius is 22 meters (~72 ft) since the default Geo-Circle radius is 11 meters.  In order to trigger a Geo-Trigger, you must leave the boundary it covers.  Thus, if you on a Stage course (like for autocross), then after you finish you must ensure you drive than 72 feet away from the start point before you make your next run.  Otherwise, RaceCapture may not trigger the start event.&lt;br /&gt;
&lt;br /&gt;
===Use RaceCapture&#039;s Launch Control Feature===&lt;br /&gt;
Since the release of 2.8.0 firmware, RaceCapture has supported Launch Control, a feature that allows you to start from a dead stop in the start Geo-Circle and have RaceCapture properly record the start timing.  This feature is available for the first lap on Circuit tracks and for every lap on Stage tracks.  On Stage tracks, see the previous note about driving 25 M from the start point before your next run after finishing your previous run.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6409</id>
		<title>RaceCapture CustomTrackBestPractices</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6409"/>
		<updated>2016-01-13T00:33:54Z</updated>

		<summary type="html">&lt;p&gt;Stieg: /* Avoid Overlapping Geo Circles With Other Parts of the Track */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Walking/Building a Course - Best Practices=&lt;br /&gt;
Whether you are doing an autocross, rally, karting or whatever else you may race, sometimes you need to create your own course.  Fortunately Autosport Labs has you covered for this very scenario with our custom course design tool.  Using a GPS enabled tablet or phone with the RaceCapture App, you can define start &amp;amp; finish points as well as sector points along your track.&lt;br /&gt;
&lt;br /&gt;
This page goes over the best practices in creating a course as well as in covers course setup to ensure that you get the best performance from your RaceCapture device.&lt;br /&gt;
&lt;br /&gt;
==Basic System Overview==&lt;br /&gt;
In order to understand these recommendations, its best to first understand how RaceCapture works internally.  Below is a brief definition of concepts used internally.&lt;br /&gt;
&lt;br /&gt;
===Geo-Circles===&lt;br /&gt;
A Geo-Circle is simply a gps point and a distance.  We use this information to draw a circle on the map.  This is how we implement start, finish and sector points in RaceCapture firmware.  When you enter the circle, you have reached that particular point.  By default, the radius of a Geo-Circle is 11 meters (~36 ft).&lt;br /&gt;
&lt;br /&gt;
===Geo-Triggers===&lt;br /&gt;
Geo-Triggers are like Geo-Circles in that they have a gps point and a distance, but they also have one more element: a boolean indicating when the object has been triggered.  We use Geo-Triggers on top of Geo-Circles in RaceCapture to prevent false positives results.&lt;br /&gt;
&lt;br /&gt;
===Sector Counting===&lt;br /&gt;
Sectors work like sequential counters.  So when you start a lap with sectors on the track, RaceCapture will look for the first sector.  When you reach it, it will search for the next.  This process repeats until there are no more sectors, at which point it uses the finish point as the last sector point.&lt;br /&gt;
&lt;br /&gt;
==Best Practices==&lt;br /&gt;
Now that you are armed with a basic understanding of how the internals work, these best practices are hopefully very reasonable.&lt;br /&gt;
&lt;br /&gt;
===Avoid Overlapping Geo Circles With Other Parts of the Track===&lt;br /&gt;
Because Geo-Circles are triggered when a vehicle enters them, we must be careful in where we place them.  Overlapping Geo-Circles can cause unpredictable results such as early finishes, early sector time values.  This often occurs because drivers can take different drive lines.  Some lines may trigger the event while others miss the Geo-Circle, and thus don&#039;t trigger the event.  If there is a chance that a Geo circle overlaps an earlier part of the track, adjust its position away from the overlapping portion to prevent a false trigger.  Here is what an overlapping Geo-Circle might look like:&lt;br /&gt;
&lt;br /&gt;
[[File:Geo_Circle_Overlapping.png|200px]]&lt;br /&gt;
&lt;br /&gt;
===In Stage Mode, Drive 25 M From Start Before Next Run===&lt;br /&gt;
Start/Finish points in RaceCapture are protected by a Geo-Trigger.  Geo-Triggers are present to prevent false triggering of Geo-Circles when start and finish locations are close together.  The Geo-Trigger radius is configured to be 2x the Geo-Circle radius.  This means the default trigger radius is 22 meters (~72 ft) since the default Geo-Circle radius is 11 meters.  In order to trigger a Geo-Trigger, you must leave the boundary it covers.  Thus, if you on a Stage course (like for autocross), then after you finish you must ensure you drive than 72 feet away from the start point before you make your next run.  Otherwise, RaceCapture may not trigger the start event.&lt;br /&gt;
&lt;br /&gt;
===Use RaceCapture&#039;s Launch Control Feature===&lt;br /&gt;
Since the release of 2.8.0 firmware, RaceCapture has supported Launch Control, a feature that allows you to start from a dead stop in the start Geo-Circle and have RaceCapture properly record the start timing.  This feature is available for the first lap on Circuit tracks and for every lap on Stage tracks.  On Stage tracks, see the previous note about driving 25 M from the start point before your next run after finishing your previous run.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=File:Race_Track_StartFinish_GeoPoint_with_GeoTrigger.png&amp;diff=6408</id>
		<title>File:Race Track StartFinish GeoPoint with GeoTrigger.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=File:Race_Track_StartFinish_GeoPoint_with_GeoTrigger.png&amp;diff=6408"/>
		<updated>2016-01-13T00:33:46Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Shows what a Geo-Point protected by a Geo-Trigger looks like.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Shows what a Geo-Point protected by a Geo-Trigger looks like.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=File:Race_Track_StartFinish_GeoPoint.png&amp;diff=6407</id>
		<title>File:Race Track StartFinish GeoPoint.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=File:Race_Track_StartFinish_GeoPoint.png&amp;diff=6407"/>
		<updated>2016-01-13T00:32:56Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Shows what a Geo-Point looks like at the start/finish line.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Shows what a Geo-Point looks like at the start/finish line.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=File:Geo_Circle_Overlapping.png&amp;diff=6406</id>
		<title>File:Geo Circle Overlapping.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=File:Geo_Circle_Overlapping.png&amp;diff=6406"/>
		<updated>2016-01-13T00:28:10Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Shows a Geo-Circle overlapping onto another part of the track&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Shows a Geo-Circle overlapping onto another part of the track&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6405</id>
		<title>RaceCapture CustomTrackBestPractices</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6405"/>
		<updated>2016-01-13T00:07:19Z</updated>

		<summary type="html">&lt;p&gt;Stieg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Walking/Building a Course - Best Practices=&lt;br /&gt;
Whether you are doing an autocross, rally, karting or whatever else you may race, sometimes you need to create your own course.  Fortunately Autosport Labs has you covered for this very scenario with our custom course design tool.  Using a GPS enabled tablet or phone with the RaceCapture App, you can define start &amp;amp; finish points as well as sector points along your track.&lt;br /&gt;
&lt;br /&gt;
This page goes over the best practices in creating a course as well as in covers course setup to ensure that you get the best performance from your RaceCapture device.&lt;br /&gt;
&lt;br /&gt;
==Basic System Overview==&lt;br /&gt;
In order to understand these recommendations, its best to first understand how RaceCapture works internally.  Below is a brief definition of concepts used internally.&lt;br /&gt;
&lt;br /&gt;
===Geo-Circles===&lt;br /&gt;
A Geo-Circle is simply a gps point and a distance.  We use this information to draw a circle on the map.  This is how we implement start, finish and sector points in RaceCapture firmware.  When you enter the circle, you have reached that particular point.  By default, the radius of a Geo-Circle is 11 meters (~36 ft).&lt;br /&gt;
&lt;br /&gt;
===Geo-Triggers===&lt;br /&gt;
Geo-Triggers are like Geo-Circles in that they have a gps point and a distance, but they also have one more element: a boolean indicating when the object has been triggered.  We use Geo-Triggers on top of Geo-Circles in RaceCapture to prevent false positives results.&lt;br /&gt;
&lt;br /&gt;
===Sector Counting===&lt;br /&gt;
Sectors work like sequential counters.  So when you start a lap with sectors on the track, RaceCapture will look for the first sector.  When you reach it, it will search for the next.  This process repeats until there are no more sectors, at which point it uses the finish point as the last sector point.&lt;br /&gt;
&lt;br /&gt;
==Best Practices==&lt;br /&gt;
Now that you are armed with a basic understanding of how the internals work, these best practices are hopefully very reasonable.&lt;br /&gt;
&lt;br /&gt;
===Avoid Overlapping Geo Circles With Other Parts of the Track===&lt;br /&gt;
Because Geo-Circles are triggered when a vehicle enters them, we must be careful in where we place them.  Overlapping Geo-Circles can cause unpredictable results such as early finishes, early sector time values.  This often occurs because drivers can take different drive lines.  Some lines may trigger the event while others miss the Geo-Circle, and thus don&#039;t trigger the event.  If there is a chance that a Geo circle overlaps an earlier part of the track, adjust its position away from the overlapping portion to prevent a false trigger.&lt;br /&gt;
&lt;br /&gt;
===In Stage Mode, Drive 25 M From Start Before Next Run===&lt;br /&gt;
Start/Finish points in RaceCapture are protected by a Geo-Trigger.  Geo-Triggers are present to prevent false triggering of Geo-Circles when start and finish locations are close together.  The Geo-Trigger radius is configured to be 2x the Geo-Circle radius.  This means the default trigger radius is 22 meters (~72 ft) since the default Geo-Circle radius is 11 meters.  In order to trigger a Geo-Trigger, you must leave the boundary it covers.  Thus, if you on a Stage course (like for autocross), then after you finish you must ensure you drive than 72 feet away from the start point before you make your next run.  Otherwise, RaceCapture may not trigger the start event.&lt;br /&gt;
&lt;br /&gt;
===Use RaceCapture&#039;s Launch Control Feature===&lt;br /&gt;
Since the release of 2.8.0 firmware, RaceCapture has supported Launch Control, a feature that allows you to start from a dead stop in the start Geo-Circle and have RaceCapture properly record the start timing.  This feature is available for the first lap on Circuit tracks and for every lap on Stage tracks.  On Stage tracks, see the previous note about driving 25 M from the start point before your next run after finishing your previous run.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6404</id>
		<title>RaceCapture CustomTrackBestPractices</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6404"/>
		<updated>2016-01-13T00:06:27Z</updated>

		<summary type="html">&lt;p&gt;Stieg: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Walking/Building a Course - Best Practices=&lt;br /&gt;
Whether you are doing an autocross, rally, karting or whatever else you may race, sometimes you need to create your own course.  Fortunately Autosport Labs has you covered for this very scenario with our custom course design tool.  Using a GPS enabled tablet or phone with the RaceCapture App, you can define start &amp;amp; finish points as well as sector points along your track.&lt;br /&gt;
&lt;br /&gt;
This page goes over the best practices in creating a course as well as in covers course setup to ensure that you get the best performance from your RaceCapture device.&lt;br /&gt;
&lt;br /&gt;
==Basic System Overview==&lt;br /&gt;
In order to understand these recommendations, its best to first understand how RaceCapture works internally.  Below is a brief definition of concepts used internally.&lt;br /&gt;
&lt;br /&gt;
===Geo-Circles===&lt;br /&gt;
A Geo-Circle is simply a gps point and a distance.  We use this information to draw a circle on the map.  This is how we implement start, finish and sector points in RaceCapture firmware.  When you enter the circle, you have reached that particular point.  By default, the radius of a Geo-Circle is 11 meters (~36 ft).&lt;br /&gt;
&lt;br /&gt;
===Geo-Triggers===&lt;br /&gt;
Geo-Triggers are like Geo-Circles in that they have a gps point and a distance, but they also have one more element: a boolean indicating when the object has been triggered.  We use Geo-Triggers on top of Geo-Circles in RaceCapture to prevent false positives results.&lt;br /&gt;
&lt;br /&gt;
===Sector Counting===&lt;br /&gt;
Sectors work like sequential counters.  So when you start a lap with sectors on the track, RaceCapture will look for the first sector.  When you reach it, it will search for the next.  This process repeats until there are no more sectors, at which point it uses the finish point as the last sector point.&lt;br /&gt;
&lt;br /&gt;
=Best Practices=&lt;br /&gt;
Now that you are armed with a basic understanding of how the internals work, these best practices are hopefully very reasonable.&lt;br /&gt;
&lt;br /&gt;
==Avoid Overlapping Geo Circles With Other Parts of the Track==&lt;br /&gt;
Because Geo-Circles are triggered when a vehicle enters them, we must be careful in where we place them.  Overlapping Geo-Circles can cause unpredictable results such as early finishes, early sector time values.  This often occurs because drivers can take different drive lines.  Some lines may trigger the event while others miss the Geo-Circle, and thus don&#039;t trigger the event.  If there is a chance that a Geo circle overlaps an earlier part of the track, adjust its position away from the overlapping portion to prevent a false trigger.&lt;br /&gt;
&lt;br /&gt;
==In Stage Mode, Drive 25 M From Start Before Next Run==&lt;br /&gt;
Start/Finish points in RaceCapture are protected by a Geo-Trigger.  Geo-Triggers are present to prevent false triggering of Geo-Circles when start and finish locations are close together.  The Geo-Trigger radius is configured to be 2x the Geo-Circle radius.  This means the default trigger radius is 22 meters (~72 ft) since the default Geo-Circle radius is 11 meters.  In order to trigger a Geo-Trigger, you must leave the boundary it covers.  Thus, if you on a Stage course (like for autocross), then after you finish you must ensure you drive than 72 feet away from the start point before you make your next run.  Otherwise, RaceCapture may not trigger the start event.&lt;br /&gt;
&lt;br /&gt;
==Use RaceCapture&#039;s Launch Control Feature==&lt;br /&gt;
Since the release of 2.8.0 firmware, RaceCapture has supported Launch Control, a feature that allows you to start from a dead stop in the start Geo-Circle and have RaceCapture properly record the start timing.  This feature is available for the first lap on Circuit tracks and for every lap on Stage tracks.  On Stage tracks, see the previous note about driving 25 M from the start point before your next run after finishing your previous run.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6403</id>
		<title>RaceCapture CustomTrackBestPractices</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6403"/>
		<updated>2016-01-13T00:02:13Z</updated>

		<summary type="html">&lt;p&gt;Stieg: /* In Stage Mode, Drive 25 M from Start Before Next Run */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Walking/Building a Course - Best Practices=&lt;br /&gt;
Whether you are doing an autocross, rally, karting or whatever else you may race, sometimes you need to create your own course.  Fortunately Autosportlabs has you covered for this very scenario with our custom course design tool.  Using a GPS enabled tablet or phone with the RaceCapture App, you can define start &amp;amp; finish points as well as sector points along your track.&lt;br /&gt;
&lt;br /&gt;
This page goes over the best practices in creating a course as well as in covers course setup to ensure that you get the best performance from your RaceCapture device.&lt;br /&gt;
&lt;br /&gt;
==Basic System Overview==&lt;br /&gt;
In order to understand these recommendations, its best to first understand how RaceCapture works internally.  Below is a brief definition of concepts used internally.&lt;br /&gt;
&lt;br /&gt;
===Geo Circles===&lt;br /&gt;
A geo circle is simply a gps point and a distance.  We use this information to draw a circle on the map.  This is how we implement start, finish and sector points in RaceCapture firmware.  When you enter the circle, you have reached that particular point.  By default, the radius of a geo circle is 11 meters (~36 ft).&lt;br /&gt;
&lt;br /&gt;
===Geo Triggers===&lt;br /&gt;
Geo triggers are like geo circles in that they have a gps point and a distance, but they also have one more element: a triggered boolean.  We use geo triggers on top of geo circles in RaceCapture to prevent false positives results.&lt;br /&gt;
&lt;br /&gt;
===Sector Counting===&lt;br /&gt;
Sectors work like sequential counters.  So when you start a lap with sectors on the track, RaceCapture will look for the first sector.  When you reach it, it will search for the next.  This process repeats until there are no more sectors, at which point it uses the finish point as the last sector point.&lt;br /&gt;
&lt;br /&gt;
=Best Practices=&lt;br /&gt;
Now that you are armed with a basic understanding of how the internals work, these best practices are hopefully very reasonable.&lt;br /&gt;
&lt;br /&gt;
==Avoid Overlapping Geo Circles With Other Parts of the Track==&lt;br /&gt;
Because geo circles are triggered when a vehicle enters them, we must be careful in where we place them.  Overlapping GeoCircles can cause unpredictable results such as early finishes, early sector time values.  This often occurs because drivers can take different drive lines.  Some lines may trigger the event while others miss the geo circle, and thus don&#039;t trigger the event.  If there is a chance that a Geo circle overlaps an earlier part of the track, adjust its position away from the overlapping portion to prevent a false trigger.&lt;br /&gt;
&lt;br /&gt;
==In Stage Mode, Drive 25 M From Start Before Next Run==&lt;br /&gt;
Start/Finish points in RaceCapture are protected by a GeoTrigger.  Geo triggers are present to prevent false triggering of GeoCircles when start and finish locations are close together.  The GeoTrigger radius is configured to be 2x the geo circle radius.  This means the default trigger radius is 22 meters (~72 ft) since the default geo circle radius is 11 meters.  In order to trigger a GeoTrigger, you must leave the boundary it covers.  Thus, if you on a Stage course (like for autocross), then after you finish you must ensure you drive than 72 feet awar from the start point before you make your next run.  Otherwise, RaceCapture may not trigger the start event.&lt;br /&gt;
&lt;br /&gt;
==Use RaceCapture&#039;s Launch Control Feature==&lt;br /&gt;
Since the release of 2.8.0 firmware, RaceCapture has supported Launch Control, a feature that allows you to start from a dead stop in the start geo circle and have RaceCapture properly record the start timing.  This feature is available for the first lap on Circuit tracks and for every lap on Stage tracks.  On Stage tracks, see the previous note about driving 25 M from the start point before your next run after finishing your previous run.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6402</id>
		<title>RaceCapture CustomTrackBestPractices</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapture_CustomTrackBestPractices&amp;diff=6402"/>
		<updated>2016-01-13T00:01:54Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Created page with &amp;quot;=Walking/Building a Course - Best Practices= Whether you are doing an autocross, rally, karting or whatever else you may race, sometimes you need to create your own course.  F...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Walking/Building a Course - Best Practices=&lt;br /&gt;
Whether you are doing an autocross, rally, karting or whatever else you may race, sometimes you need to create your own course.  Fortunately Autosportlabs has you covered for this very scenario with our custom course design tool.  Using a GPS enabled tablet or phone with the RaceCapture App, you can define start &amp;amp; finish points as well as sector points along your track.&lt;br /&gt;
&lt;br /&gt;
This page goes over the best practices in creating a course as well as in covers course setup to ensure that you get the best performance from your RaceCapture device.&lt;br /&gt;
&lt;br /&gt;
==Basic System Overview==&lt;br /&gt;
In order to understand these recommendations, its best to first understand how RaceCapture works internally.  Below is a brief definition of concepts used internally.&lt;br /&gt;
&lt;br /&gt;
===Geo Circles===&lt;br /&gt;
A geo circle is simply a gps point and a distance.  We use this information to draw a circle on the map.  This is how we implement start, finish and sector points in RaceCapture firmware.  When you enter the circle, you have reached that particular point.  By default, the radius of a geo circle is 11 meters (~36 ft).&lt;br /&gt;
&lt;br /&gt;
===Geo Triggers===&lt;br /&gt;
Geo triggers are like geo circles in that they have a gps point and a distance, but they also have one more element: a triggered boolean.  We use geo triggers on top of geo circles in RaceCapture to prevent false positives results.&lt;br /&gt;
&lt;br /&gt;
===Sector Counting===&lt;br /&gt;
Sectors work like sequential counters.  So when you start a lap with sectors on the track, RaceCapture will look for the first sector.  When you reach it, it will search for the next.  This process repeats until there are no more sectors, at which point it uses the finish point as the last sector point.&lt;br /&gt;
&lt;br /&gt;
=Best Practices=&lt;br /&gt;
Now that you are armed with a basic understanding of how the internals work, these best practices are hopefully very reasonable.&lt;br /&gt;
&lt;br /&gt;
==Avoid Overlapping Geo Circles With Other Parts of the Track==&lt;br /&gt;
Because geo circles are triggered when a vehicle enters them, we must be careful in where we place them.  Overlapping GeoCircles can cause unpredictable results such as early finishes, early sector time values.  This often occurs because drivers can take different drive lines.  Some lines may trigger the event while others miss the geo circle, and thus don&#039;t trigger the event.  If there is a chance that a Geo circle overlaps an earlier part of the track, adjust its position away from the overlapping portion to prevent a false trigger.&lt;br /&gt;
&lt;br /&gt;
==In Stage Mode, Drive 25 M from Start Before Next Run==&lt;br /&gt;
Start/Finish points in RaceCapture are protected by a GeoTrigger.  Geo triggers are present to prevent false triggering of GeoCircles when start and finish locations are close together.  The GeoTrigger radius is configured to be 2x the geo circle radius.  This means the default trigger radius is 22 meters (~72 ft) since the default geo circle radius is 11 meters.  In order to trigger a GeoTrigger, you must leave the boundary it covers.  Thus, if you on a Stage course (like for autocross), then after you finish you must ensure you drive than 72 feet awar from the start point before you make your next run.  Otherwise, RaceCapture may not trigger the start event.&lt;br /&gt;
&lt;br /&gt;
==Use RaceCapture&#039;s Launch Control Feature==&lt;br /&gt;
Since the release of 2.8.0 firmware, RaceCapture has supported Launch Control, a feature that allows you to start from a dead stop in the start geo circle and have RaceCapture properly record the start timing.  This feature is available for the first lap on Circuit tracks and for every lap on Stage tracks.  On Stage tracks, see the previous note about driving 25 M from the start point before your next run after finishing your previous run.&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceTracks&amp;diff=6328</id>
		<title>RaceTracks</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceTracks&amp;diff=6328"/>
		<updated>2015-08-17T17:47:43Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Clean up this page, add info on how to do sector selection&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&lt;br /&gt;
=How to create / submit a track map=&lt;br /&gt;
&lt;br /&gt;
==Pick a Track==&lt;br /&gt;
Pick a track map below that isn&#039;t completed.&lt;br /&gt;
&lt;br /&gt;
==Open Up a Basic Text Editor==&lt;br /&gt;
You will need a basic text editor to copy and past information into.  Applications like Notepad, Textedit, Gedit all work very well.&lt;br /&gt;
&lt;br /&gt;
== Open Up The Drawing Tool ==&lt;br /&gt;
Use this handy [http://www.birdtheme.org/useful/v3tool.html Map Drawing tool] to create an outline of the race track as well as find GeoPoints.  I will assume you are using it throughout the rest of this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Record Basic Track Info==&lt;br /&gt;
We need a few basic things to get going.  They are as follows:&lt;br /&gt;
*Track Name&lt;br /&gt;
*Track Configuration (if known)&lt;br /&gt;
*Country Track is Located In&lt;br /&gt;
*Start/Finish GeoPoint on track.&lt;br /&gt;
*Center area of track (We use this for zooming and display purposes).&lt;br /&gt;
&lt;br /&gt;
Add all that information into your text editor.&lt;br /&gt;
&lt;br /&gt;
==Draw the Track==&lt;br /&gt;
Now its time to draw the outline of the track.  Clear the tool above using the &amp;quot;Clear Map&amp;quot; button and do the following:&lt;br /&gt;
&lt;br /&gt;
# Find the race track track using the search bar and zoom in on the track.&lt;br /&gt;
# Locate the start / finish line and make that your first point by clicking it.&lt;br /&gt;
# Follow the contour of the track by clicking around the track, making sure your lines are &#039;&#039;&#039;in the centerline of the track&#039;&#039;&#039; (This is really important).&lt;br /&gt;
# If you make a mistake, you can undo points by clicking the &amp;quot;Delete Last Point&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
When you are finished, copy the text blob from the tool into the text editor.  Label the blob as &amp;quot;Outline&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Tips:&#039;&#039;&lt;br /&gt;
* Zoom all the way in on the map to get the best placement accuracy&lt;br /&gt;
* Make more points in curves so it looks smooth.&lt;br /&gt;
* Draw the lines using the centerline of the track. &lt;br /&gt;
&lt;br /&gt;
==Record Sector Points &#039;&#039;(Optional)&#039;&#039;==&lt;br /&gt;
If you want to go the extra mile and be extra awesome, you can include sector points.  These are points that allow us to partition&lt;br /&gt;
the track into sections so we can get timing info for individual sections of the track.  However there is a catch, we can only support up to 20 sector points per track (not including start/finish).  To add sector data, do the following:&lt;br /&gt;
&lt;br /&gt;
#Use the same tool.  Before you start, clear out any data by selecting the &amp;quot;Clear Map&amp;quot; button.&lt;br /&gt;
#Think about how you would logically divide the track in your mind.  What corners or sections are most important to you?&lt;br /&gt;
#With that in mind, select these points.  Don&#039;t worry about the shape you draw, we are interested in the points.&lt;br /&gt;
#* REMEMBER: You can only have up to 20 points.  DO NOT include start finish as one of these points.&lt;br /&gt;
&lt;br /&gt;
When you are finished, copy the text blob from the tool into the text editor.  Label the blob as &amp;quot;Sectors&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Submit It!==&lt;br /&gt;
When you&#039;ve gotten all the data described above, copy and paste all of the text from your text editor into an email and [mailto:racecapture@autosportlabs.com submit it to us].  Be sure you included the basic track data! We will review the track data and if sufficient, incorporate it into our Mobile app and online!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Thank you from the Autosport Labs team!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=Tracks=&lt;br /&gt;
To see a list of track maps we have in our database, visit this page: http://race-capture.com/venues&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
	<entry>
		<id>https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6318</id>
		<title>RaceCapturePro Lua Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.autosportlabs.com/index.php?title=RaceCapturePro_Lua_Scripting&amp;diff=6318"/>
		<updated>2015-08-02T19:38:28Z</updated>

		<summary type="html">&lt;p&gt;Stieg: Add the Time Info section at the bottom for the new LUA methods&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Example Scripts and How-Tos==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RaceCapturePro Lua Scripting Examples|Lua Scripting Examples]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==General Input / Output (GPIO) Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpio( channel )===&lt;br /&gt;
Retrieves the state of the specified GPIO channel&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2&lt;br /&gt;
*returns:&lt;br /&gt;
** state: 1 = channel is high, 0 = channel is low&lt;br /&gt;
&lt;br /&gt;
When the channel is configured for input mode, a voltage high input (&amp;gt; 2 volts) will read as 1; a voltage low will read as 0. A disconnected channel will read as high due to the internal pullup resistor.&lt;br /&gt;
&lt;br /&gt;
When the channel is configured as output, the channel reads 1 when the channel is activated (output transistor is connected to ground) and 0 when the channel is deactivated (pullup resistor is active)&lt;br /&gt;
&lt;br /&gt;
===setGpio ( channel, state )===&lt;br /&gt;
Sets the state of the GPIO channel when the channel is configured for output mode. &lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: integer 0 - 2, state - 1 = output active; 0 = output inactive&lt;br /&gt;
*returns:&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
When the state specified is 1, the output is active (transistor is connected to ground). When state is 0, transistor is disconnected, and pullup resistor is active.&lt;br /&gt;
&lt;br /&gt;
When configured for input mode this function has no effect.&lt;br /&gt;
&lt;br /&gt;
===getButton()===&lt;br /&gt;
Gets the state of the front panel pushbutton.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** none&lt;br /&gt;
*returns&lt;br /&gt;
** state: 1 = pushbutton is depressed; 0 = pushbutton is not depressed&lt;br /&gt;
&lt;br /&gt;
==PWM / Analog Output functions==&lt;br /&gt;
&lt;br /&gt;
===setPwmDutyCycle( channel, dutyCyclePct )===&lt;br /&gt;
Sets the duty cycle of the specified PWM / Analog output channel to the specified duty cycle percentage&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
*returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setPwmClockFreq( frequency )===&lt;br /&gt;
Sets the clock frequency of the PWM outputs&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** frequency: the frequency of the PWM clock, in Hz. Supported range is 320-40000 Hz&lt;br /&gt;
* returns&lt;br /&gt;
** none&lt;br /&gt;
&lt;br /&gt;
===setAnalogOut( channel, voltage )===&lt;br /&gt;
Sets the output voltage of the specified PWM / Analog output channel to the specified period. A convenience function equivalent to setPwmDutyCycle that translates voltage to PWM percentage.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: PWM / Analog output channel 0 - 3&lt;br /&gt;
** voltage: the specified output voltage ( 0 - 5v)&lt;br /&gt;
** returns&lt;br /&gt;
* none&lt;br /&gt;
&lt;br /&gt;
==Timer / RPM Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getTimerRpm(channel)===&lt;br /&gt;
Returns the current RPM of the specified timer input channel. Note, the timer channel configuration must be set to RPM mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 2&lt;br /&gt;
** returns: RPM value&lt;br /&gt;
&lt;br /&gt;
===getTimerPeriodMs(channel)===&lt;br /&gt;
Returns the current duration of the full cycle pulse of the specified timer input channel, in milliseconds. Note the timer channel configuration must be set to Duration mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  millisecond value&lt;br /&gt;
&lt;br /&gt;
===getTimerFreq(channel)===&lt;br /&gt;
Returns the current frequency present on the specified timer input channel, in Hz. Note the timer channel configuration must be set to Frequency Mode.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns:  Frequency in Hz&lt;br /&gt;
&lt;br /&gt;
===getTimerRaw(channel)===&lt;br /&gt;
Returns the current raw timer value as measured on the specified timer input channel.&lt;br /&gt;
&lt;br /&gt;
*params&lt;br /&gt;
** channel: Timer channel 0 - 3&lt;br /&gt;
** returns: Raw timer value between 0 - 65535&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===resetTimerCount===&lt;br /&gt;
===getTimerCount===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Analog Sensor Functions==&lt;br /&gt;
    &lt;br /&gt;
===getAnalog(channel)===&lt;br /&gt;
Reads the scaled analog value for the specified analog input channel.&lt;br /&gt;
*params&lt;br /&gt;
** channel: Analog input channel 0 - 7&lt;br /&gt;
*** Note: channel 7 is internally dedicated to battery voltage.&lt;br /&gt;
** returns: Scaled / calculated value for the specified analog channel as defined in the channel scaling configuration&lt;br /&gt;
&lt;br /&gt;
==Accelerometer / Yaw Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getImu(channel)===&lt;br /&gt;
Reads the specified IMU channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The value scaled to G force, or degrees/sec depending on the channel selected&lt;br /&gt;
&lt;br /&gt;
===getImuRaw(channel)===&lt;br /&gt;
Reads the raw value of the specified accelerometer or yaw channel&lt;br /&gt;
* params&lt;br /&gt;
** channel (0 - 2 for accelerometer, 3 for yaw gyro sensor)&lt;br /&gt;
* returns&lt;br /&gt;
** The raw accelerometer value&lt;br /&gt;
&lt;br /&gt;
==GPS Sensor Functions==&lt;br /&gt;
&lt;br /&gt;
===getGpsPos()===&lt;br /&gt;
Reads the current position as measured by the attached GPS module &#039;&#039;coming in firmware 2.0&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** none&lt;br /&gt;
* returns&lt;br /&gt;
** Latitude: latitude in decimal degrees&lt;br /&gt;
** Longitude: longitude in decimal degress&lt;br /&gt;
&lt;br /&gt;
===getGpsSpeed()===&lt;br /&gt;
Provides the current speed as measured by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current speed in MPH&lt;br /&gt;
&lt;br /&gt;
===getGpsQuality()===&lt;br /&gt;
Provides the current GPS quality indicator as indicated by the attached GPS module&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS quality indicator&lt;br /&gt;
** 0: No fix; 1: Fixed; 2: SPS Fix; 3: Differential Fix&lt;br /&gt;
&lt;br /&gt;
===getGpsTime()===&lt;br /&gt;
Provides the current GPS time as indicated by the attached GPS module (in NMEA format) &#039;&#039;todo: document this&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The current GPS time value&lt;br /&gt;
&lt;br /&gt;
===getGpsDist()===&lt;br /&gt;
Provides the current GPS calculated distance from the beginning of the logging session, or from the start finish line, if configured.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The distance, in Miles&lt;br /&gt;
&lt;br /&gt;
===getLapCount()===&lt;br /&gt;
Provides the current Lap Count as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The number of laps detected since the logging session started&lt;br /&gt;
&lt;br /&gt;
===getLapTime()===&lt;br /&gt;
Provides the last lap time as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** The last measured lap time in decimal minutes / seconds&lt;br /&gt;
&lt;br /&gt;
===getGpsSec()===&lt;br /&gt;
Provides the number of seconds since midnight, as measured by the GPS module. &#039;&#039;todo: how does this relate to timezone? GMT or local?&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** number of seconds since midnight, as measured by the attached GPS module&lt;br /&gt;
&lt;br /&gt;
===getAtStartFinish()===&lt;br /&gt;
Indicates if within the start finish line target as determined by the start/finish line configuration and measured by the attached GPS module.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if currently within the start/finish line target, 0 if outside&lt;br /&gt;
&lt;br /&gt;
===getTimeDiff(time1, time2)===&lt;br /&gt;
Utility function to calculate the absolute difference between two time values, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time1&lt;br /&gt;
** time2&lt;br /&gt;
* returns&lt;br /&gt;
** The absolute difference between the specified values&lt;br /&gt;
&lt;br /&gt;
===getTimeSince(time)===&lt;br /&gt;
Utility function to calculate the time since midnight, in seconds. &#039;&#039;todo: investigate the need for this function. may be eliminated in 1.2 firmware&#039;&#039;&lt;br /&gt;
* params&lt;br /&gt;
** time&lt;br /&gt;
* returns&lt;br /&gt;
** The number of seconds since midnight&lt;br /&gt;
&lt;br /&gt;
==CAN Bus functions==  &lt;br /&gt;
&lt;br /&gt;
===initCAN(channel, baud )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Initializes the CAN bus module. Normally this is done when RaceCapture/Pro powers on; use this function if you need to change the CAN baud rate on the fly.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** baud rate: Supported baud rates: 100000, 125000, 250000, 500000, 1000000&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if initialization fails, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===txCAN(channel, id, isExtended, data, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Transmit a CAN message.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
** timeout: (optional) specify a timeout for sending this message. if the transmit queue is full, will block for the specified milliseconds. Defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if successful, 0 if failed, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 channel = 0&lt;br /&gt;
 id = 1234&lt;br /&gt;
 ext = 0&lt;br /&gt;
 data = {11,22,33}&lt;br /&gt;
 res = txCAN(channel, id, ext, data)&lt;br /&gt;
&lt;br /&gt;
===rxCAN(channel, [timeout] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Receive a CAN message, if available.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** timeout (optional). read timeout in milliseconds. defaults to 100ms&lt;br /&gt;
* returns&lt;br /&gt;
** identifier: The Identifier value of the message, either in standard (11 bit) or extended (29 bit) format.&lt;br /&gt;
** isExtended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** Data: CAN message payload; array up to 8 elements long.&lt;br /&gt;
&lt;br /&gt;
If no CAN message was received, the function returns nil&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 id, ext, data = rxCAN(0, 100) --100ms timeout&lt;br /&gt;
 if id ~= nil then&lt;br /&gt;
   println(&amp;quot;CAN rx: &amp;quot; ..id ..&amp;quot; &amp;quot; ..data[1]) --print ID and first element of received message&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setCANfilter(channel, filterId, extended, filter, mask )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Sets the specified CAN filter ID, to ignore messages with a particular address. Must use in combination with setCANMask() to set a complete filter and mask.&lt;br /&gt;
* params&lt;br /&gt;
** channel: The CAN channel. 0 for the first channel, 1 for the 2nd, if supported on the hardware&lt;br /&gt;
** filterId: The id of the filter. Up to 6 filters are supported on MK1, 15 per channel on MK2. Filter ids start at 0.&lt;br /&gt;
** extended: 0 for Standard (11 bit) Identifier or 1 for Extended (29 bit) Identifier.&lt;br /&gt;
** filter: Pattern value for CAN filter&lt;br /&gt;
** mask: the mask for the CAN filter&lt;br /&gt;
* returns&lt;br /&gt;
** 1 for success, 0 for fail, nil if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readOBD2( PID )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Reads an OBD2 PID and returns the calculated value. This is a convenience method wrapped around the built-in CAN functions.&lt;br /&gt;
* params&lt;br /&gt;
** The OBD2 PID to read. Supported PIDs (TBD documented)&lt;br /&gt;
* returns&lt;br /&gt;
** The calculated PID value, or nil if the OBD2 PID was invalid or could not be read (e.g. CAN receive message timeout)&lt;br /&gt;
&lt;br /&gt;
==Logger Control Functions==&lt;br /&gt;
&lt;br /&gt;
===onTick()===&lt;br /&gt;
* params:&lt;br /&gt;
** (none)&lt;br /&gt;
* returns:&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
The onTick() function is the main loop where scripting activity takes place. By default it is called by RaceCapture/Pro every 1 second (1Hz). The rate can be adjusted using the setTickRate() function. &lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 function onTick()&lt;br /&gt;
   println(&amp;quot;Hello&amp;quot;) --write something to the log&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
===setTickRate(rate)===&lt;br /&gt;
Sets the rate at which the onTick() function is called&lt;br /&gt;
* params&lt;br /&gt;
** rate: The rate the onTick() function is called, in Hz. Max tick rate is 30Hz.&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===startLogging()===&lt;br /&gt;
Begins a logging session&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===stopLogging()===&lt;br /&gt;
Stops the current logging session. If not logging, this function has no effect.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===setLed( led, state )===&lt;br /&gt;
Sets the state of a front panel LED&lt;br /&gt;
* params&lt;br /&gt;
** led (1-3)&lt;br /&gt;
** state : 1 = on, 0 = off&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Serial Port Communications==&lt;br /&gt;
&lt;br /&gt;
These function calls allow reading / writing line oriented data from the built in serial ports. &lt;br /&gt;
&lt;br /&gt;
===Port mappings===&lt;br /&gt;
0 = USB port&amp;lt;br/&amp;gt;&lt;br /&gt;
1 = GPS port&amp;lt;br/&amp;gt;&lt;br /&gt;
2 = Internal telemetry port (MK2 only)&amp;lt;br/&amp;gt;&lt;br /&gt;
3 = Wireless / Bluetooth port&amp;lt;br/&amp;gt;&lt;br /&gt;
4 = Auxiliary port&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Note&#039;&#039;&#039;: We only recommend using ports 3 and 4 for connecting script to external devices. Ports 0 - 2 have been included for reference; using them may interfere with normal operations of the unit.&lt;br /&gt;
&lt;br /&gt;
===initSer( port, baud, bits, parity, stopBits)===&lt;br /&gt;
Initializes the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to initialize. (defaults to Auxiliary port)&lt;br /&gt;
** baud: The baud rate to set (defaults to 115200)&lt;br /&gt;
** bits: Number of bit in the message (8 or 7) (defaults to 8)&lt;br /&gt;
** parity: (1 = Even Parity, 2 = Odd Parity, 0 = No Parity) (defaults to No Parity)&lt;br /&gt;
** stopBits: number of stop bits (1 or 2) (defaults to 1)&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** 1 if initialization succeeds, -1 if parameters are incorrect&lt;br /&gt;
&lt;br /&gt;
===readCSer( port )===&lt;br /&gt;
Read a character from the specified serial port&lt;br /&gt;
&lt;br /&gt;
* params&lt;br /&gt;
** port: The port to read. (required)&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the character read, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===readSer( port )===&lt;br /&gt;
Read a line of data from the specified serial port. This command blocks until a newline (&#039;\n&#039;) character is received on the port, or a timeout occurs.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** timeout - the read timeout, in ms.&lt;br /&gt;
** returns: a line of serial data, or nil if the timeout was reached&lt;br /&gt;
&lt;br /&gt;
===writeCSer( port, data )===&lt;br /&gt;
Writes the specified character to the serial port. The call will block until the character is written.&lt;br /&gt;
* params:&lt;br /&gt;
** port - the serial port to write&lt;br /&gt;
** char - the character to write.&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
===writeSer( port, data )===&lt;br /&gt;
Writes a line of data to the specified serial port, appending a newline at the end. The call will block until all characters are written.&lt;br /&gt;
* params&lt;br /&gt;
** port: Serial port 0 - 4&lt;br /&gt;
** data: the data in string format&lt;br /&gt;
&lt;br /&gt;
* returns:&lt;br /&gt;
(no return values)&lt;br /&gt;
&lt;br /&gt;
==Logger Configuration Functions==&lt;br /&gt;
&lt;br /&gt;
===flashLoggerCfg()===&lt;br /&gt;
Writes the current configuration in RAM to flash memory.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
    &lt;br /&gt;
===setPwmClockFreq( freq )===&lt;br /&gt;
Sets the clock frequency for all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** freq: The clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
===getPwmClockFreq()=== &lt;br /&gt;
Gets the PWM clock frequency controlling all PWM channels&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** the PWM clock frequency &#039;&#039;todo: what units?&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===calibrateImuZero()===&lt;br /&gt;
Automatically Calibrates the accelerometer zero position.&lt;br /&gt;
* params&lt;br /&gt;
** (none)&lt;br /&gt;
* returns&lt;br /&gt;
** (none)&lt;br /&gt;
&lt;br /&gt;
==Virtual Channels==&lt;br /&gt;
&lt;br /&gt;
===addChannel( name, sampleRate, [precision], [min], [max], [units] )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Adds a virtual channel. This virtual channel remains in memory during runtime; it is not persisted in the configuration. Up to 30 virtual channels can be created.&lt;br /&gt;
* params&lt;br /&gt;
** name: The name of the channel, up to 10 characters long. We recommend using an existing System channel name as defined by the app when possible.&lt;br /&gt;
** sampleRate: A supported sample rate (1,10,25,50,100,200Hz)&lt;br /&gt;
** precision: (optional) the numerical precision (number of decimal places) used when logging to SD and telemetry. Defaults to 2&lt;br /&gt;
** min: (optional) The min expected value for this channel. Defaults to 0&lt;br /&gt;
** max: (optional) The max expected value for this channel. Defaults to 1000&lt;br /&gt;
** units: (optional) The units label for this channel. Defaults to empty string / none&lt;br /&gt;
&lt;br /&gt;
* returns&lt;br /&gt;
** the id of the new virtual channel, or NIL if the virtual channel could not be created. Use this id for setting the channel value (see setChannel() )&lt;br /&gt;
&lt;br /&gt;
===setChannel( channelId, value )===&lt;br /&gt;
&#039;&#039;available in firmware 2.0&#039;&#039;&lt;br /&gt;
Updates the value of a previously created virtual channel.&lt;br /&gt;
* params&lt;br /&gt;
** channelId: the ID of the channel provided by addChannel()&lt;br /&gt;
** value: the new value to set for the virtual channel&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 id = addChannel(&amp;quot;EGT&amp;quot;, 1)&lt;br /&gt;
 &lt;br /&gt;
 function onTick()&lt;br /&gt;
    temp = getAnalog(0) --read analog channel 0&lt;br /&gt;
    temp = temp * 1000&lt;br /&gt;
    setChannel(id, temp) --sets the virtual channel value&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==Time Info==&lt;br /&gt;
These methods get you information about dates and time.  This is useful in controlling script behavior or just knowing what time it is.&lt;br /&gt;
&lt;br /&gt;
===getUptime()===&lt;br /&gt;
&#039;&#039;Available in Firmware 2.8.4 and Newer&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns the number of miliseconds since the device last started.  This is always available and is the most consistent way to time things in LUA script on RaceCapture.&lt;br /&gt;
&lt;br /&gt;
* Returns&lt;br /&gt;
** Number of milliseconds since CPU boot.&lt;br /&gt;
&lt;br /&gt;
===getDateTime()===&lt;br /&gt;
&#039;&#039;Available in Firmware 2.8.4 and Newer&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Returns date and time info to the best of the systems ability.  Only available after GPS lock has been established.  Will return epoch time (Jan 1, 1970 00:00:000) if time is not available.&lt;br /&gt;
&lt;br /&gt;
* Returns: A list of date and time information in the following order:&lt;br /&gt;
** Year&lt;br /&gt;
** Month&lt;br /&gt;
** Day&lt;br /&gt;
** Hour&lt;br /&gt;
** Second&lt;br /&gt;
** Millisecond&lt;/div&gt;</summary>
		<author><name>Stieg</name></author>
	</entry>
</feed>