Flexible Logic is the fanciest-schmanciest feature of rusEfi.
Flexible Logic allows advanced users to get unprecedented level of configurability for custom outputs and engine control. rusEfi supports up to 16 flexible outputs, each of these could be either an on/off or PWM signal. In case of a PWM signal the frequency is defined in the configuration and the duty cycle is dynamically controlled by the evaluated expression.
At the moment FSIO uses Reverse Polish Notation for technical reasons, so you would need to convert human-readable popular Infix notation to RPN using relevant rusEfi console features.
Fuel pump is already using this mechanism - see https://svn.code.sf.net/p/rusefi/code/trunk/firmware/controllers/core/le_functions.h
Here are some commands to try:
eval "2 + 3"
Prints the result of "2 + 3"
eval "max (rpm, 100)"
Prints the result of "max(100, rpm)"
eval "if(1, 200, 100)"
Prints the result of "if(1, 200, 100)"
set_fsio_expression 1 "rpm > fsio_setting(4)"
Turn output #1 hi if rpm is greater than fsio setting #4
set_fsio_output_pin 1 pd11
Tells output #1 to use pin PD11
See https://svn.code.sf.net/p/rusefi/code/trunk/firmware/controllers/core/le_functions.cpp for list of available methods
set_fsio_output_frequency 1 100
Tells FSIO channel #1 to output 100Hz PWM
set_fsio_output_frequency 1 0
Now, let's assume we want duty cycle to be 10% if rpm is below 1000, 90% if rpm is above 5000, and have it grow linearly from 10% to 90% between 1000 rpm and 5000 rpm. The human-readable expression for that would be
min(0.9, max(0.1, (rpm - 1000) / 4000 * 0.8))
We can use
eval "min(0.9, max(0.1, (rpm - 1000) / 4000 * 0.8))"
to validate and then
set_fsio_expression 1 "min(0.9, max(0.1, (rpm - 1000) / 4000 * 0.8))"
Another version of the same logic would be
if (rpm < 1000, 0.1, if (rpm > 5000, 0.9, 0.1 + (rpm - 1000) / 4000 * 0.8))
FSIO expressions could be customized using 16 user-defined 'settings' which are stored within the configuration. To change a setting from dev console your command is set_fsio_setting INDEX VAlUE
To access for example setting #3 your FSIO expression is
FSIO digital inputs
These feature allows you to pull toggle switches state from your fsio expressions.
work in progress
FSIO analog inputs
As of Aug 1, 2018 only one analog input is implemented:
rpn_eval "fsio_analog_input" or set_fsio_expression 0 "((rpm > fsio_setting(4) & (fsio_analog_input < fsio_setting(5)) | rpm > fsio_setting(1) | (coolant > fsio_setting(2) > | (vbatt < fsio_setting(3)"
where input would be assigned via FSIO analog input #1
Case study #1: shift light
We want to turn on a warning light if RPM is above 4500
First we need to configure user output, let's use pin PE5 and index #3 for this example:
set_fsio_output_frequency 3 0
this would disable PWM on channel #3 and set this port to simple digital output mode
set_fsio_output_pin 3 PE5
Now we will set FSIO expression to control this output pin:
set_fsio_expression 3 "rpm > 4500"
here 3 is the index of the output pin
A configurable version of same would be
set_fsio_expression 3 "rpm > fsio_setting(3)"
set_fsio_setting 3 4500
Case study #2: A/C compressor control
Say we want to use PE0 as A/C toggle button, and we want A/C compressor logic to be 'if (rpm > 1200 AND A/C button is depressed) then output 200Hz @ 80% duty cycle on PB1 else output nothing on PB1'.
First we need to configure A/C button input pin which is currently implemented as analog input (that's a temporary hack) - see engineConfiguration->acSwitchAdc
set_fsio_output_pin 3 PB1
Configure output #3 to use pin PB1
set_fsio_output_frequency 3 200
Configure output #3 to use 200Hz PWM
And finally set the expression:
'set_fsio_expression 3 "0 80 rpm 1200 > ac_on_switch AND IF"'
Which is RPN for if(rpm > 1200 AND ac_on_switch, 80, 0)
Case study #3: digital inputs for extra devices
First we need to configure A/C digital input pin, we will use index 0:
set_fsio_input_pin 0 PE0
Case study #4: boost controller
Solenoid-controlled boost controller would need variable duty cycle.
For example, let's use fsio table #3 to define the desired duty cycle:
Let's set PE11@300Hz as FSIO output #4
And now the tricky part, let's set FSIO expression on that output using the following command
set_fsio_expression 4 "rpm map 3 fsio_table 100 /"
Do not forget writeconfig
fsioinfo could be used to monitor output value
As for the magic expression, that's RPN for "fsio_table (3, rpm, map) / 100".
Case study #5: solenoid exhaust cam actuator
Let's assume we want to turn on 200Hz solenoid at 80% duty cycle if RPM is above 6000.
Here is how this would look in Tuner Studio:
That's RPN notation for "(rpm > 6000) * 0.8"
set debug_mode 23 https://rusefi.com//wiki/index.php?title=Manual:Debug_fields