Please enable JavaScript to view this site.

MaxxECU Documentation

The filter module provides 8 independent exponential moving-average (EMA) low-pass filters, intended mainly for smoothing noisy inputs. Each filter is advanced continuously in the background using real elapsed time, so the amount of smoothing is set by a time constant in seconds and is independent of how often your script runs.

A filter is identified by a slot number 1-8. You can drive a slot either with the one-line smooth() helper or with the explicit filter.* calls.

 

How it works

The output follows the input according to: output = output + alpha * (raw - output).

Where alpha is derived in the background from the time constant tau and the real elapsed time. A larger tau gives heavier smoothing and a slower response; tau <= 0 disables smoothing (pass-through).

The very first sample seeds the filter directly, so there is no ramp-up from zero.

 

Note: There are 8 filter slots (1-8), each independent. Filter state persists between script loops and is updated in the background; you do not need to call the filter at a fixed rate for the smoothing to stay time-accurate.

 

 

smooth() vs filter.config()/filter.input()

Use smooth() for quick, in-line smoothing where setting the sample and time constant together is convenient.

Use filter.config() once at startup and filter.input()/filter.get() in the loop when you want to separate setup from updating, or read a value in several places without re-sampling.

 

Choosing a time constant

Small tau (e.g., 0.05-0.2 s): fast response, light smoothing.

Larger tau (e.g., 0.5-2.0 s): slow response, heavy smoothing.

 

smooth(slot,raw[,tau]) - One-line smoothing of slot 1-8; sets sample (and optional time constant) and returns the filtered value.

One-line smoothing. Feeds a new sample into the slot (optionally updating the time constant) and returns the current filtered value. This is the recommended call for most users.

Parameters:

"slot" (integer): Filter slot 1-8.

"raw" (number): The latest raw sample (e.g., an analog reading).

"tau" (number): Time constant in seconds. Larger = smoother. If omitted, the slot keeps its previously configured value.

Returns: float - the current filtered value.

 

Lua code:

-- Smooth an analog input with a 0.5 second time constant

local oil_temp = smooth(1, ecu.getf(RTDATA.USER_AIN1), 0.5)

 

 

filter.config(slot,tau) - Configures smoothing slot 1-8 with time constant tau in seconds.

Configures a filter slot's time constant without feeding a sample. Useful for setting up filters once at script start.

Parameters:

"slot" (integer): Filter slot 1-8.

"tau" (number): Time constant in seconds. Larger = heavier smoothing; <= 0 = pass-through.

Returns: Nothing.

 

Lua code:

filter.config(2, 1.0) -- slot 2, 1.0 s time constant

 

 

filter.input(slot,raw) - Feeds a new sample into slot 1-8 and returns the filtered value.

Feeds a new raw sample into a configured slot and returns the current filtered value.

Parameters:

"slot" (integer): Filter slot 1-8.

"raw" (number): The latest raw sample.

Returns: float - the current filtered value.

 

Lua code:

local map = filter.input(2, ecu.getf(RTDATA.MAP))

 

 

filter.get(slot) - Returns current filtered value of slot 1-8.

Returns the current filtered value of a slot without feeding a new sample.

Parameter: "slot" (integer): Filter slot 1-8.

Returns: float - the last computed filtered value.

 

Lua code:

local map_now = filter.get(2)

 

 

filter.reset(slot) - Resets slot 1-8 so the next sample re-seeds the filter.

Resets a slot so that the next sample re-seeds the filter directly (no blending from the old value). Use this after a large step change or when re-using a slot.

Parameter: "slot" (integer): Filter slot 1-8.

Returns: Nothing.

 

Lua code:

filter.reset(2)

 

Example script

-- Sets Script RT-val 1 = fuel flow in CC/min, filtered

-- Sets Script RT-val 2 = fuel per engine rev CC/rev
while true do
-- Get and filter frequency (Hz = pulses per second)
-- 0.5 second filter
local filteredFrequency = smooth(1, ecu.getf(RTDATA.PWM_INPUT_1_FREQUENCY), 0.5)
   local rpm = ecu.getf(RTDATA.RPM)
-- Calculate flow (sensor gives 4000 pulses per gallon)
-- pulses/sec ÷ pulses/gallon = gallons/sec, ×60 = gallons/min
local fuelFlow = (filteredFrequency / 4000) * 60   -- gallons per minute
-- Convert to CC/min (1 US gallon = 3785.411784 cc)
fuelFlow = fuelFlow * 3785.411784                  -- cc per minute
-- Calculate fuel per engine revolution (cc/rev)
-- cc/min ÷ rev/min = cc/rev  (guard against divide-by-zero at 0 RPM)
local fuelLoad = 0
if rpm > 0 then
 fuelLoad = fuelFlow / rpm
end
-- Set Script RT-vals
ecu.set(1, fuelFlow)
ecu.set(2, fuelLoad)
yield()
end

 

 

For more information about the MaxxECU user scripts, see User Scripts (LUA), or directly reference the LUA api reference and LUA examples. For more all available LUA settings and options, see Script Code, Script Input Control, Output Functions and Script RT values.