Page 1 of 2

FSIO: GPIO implementation

Posted: Wed Jul 09, 2014 3:13 am
by blundar
Rather than keep implementing specific functions (i.e. fan control) it seems like it would be a good idea to implement general purpose condition driven I/O.
This is done on many other systems and is a great way to implement features in a generic way so that the same code instance can be called with a different set of parameters to implement basically all digital I/O.

Examples:

1. Radiator fan control if((ECT > 180) AND (VSS < 40mph)) -> OUTPUT3
2. Shift light if (RPM>7000) ->OUTPUT5
3. Alternator control if (volts<13) -> OUTPUT6
4. Nitrous if(TPS>80 AND AFR < 0.87lambda and RPM>2000 and RPM<7500 and INPUT3) -> OUTPUT7 +add300fuelunits -6degrees timing

Here is a screenshot of a pretty versatile example implemented in the Nismotronic system:
gpio screenshot
gpio screenshot
gpio.png (15.65 KiB) Viewed 21867 times
Update: http://rusefi.com/wiki/index.php?title=Manual:Flexible_Logic

Re: GPIO implementation

Posted: Wed Jul 09, 2014 6:27 am
by rus084
just such a setting as the image?
will be easier if you tell me more specifically.
  this setting may not be necessary, it can be done in the code: p
program and all the features included as needed (conditional compilation or setting tunerstudio)
fan control is already there, there is a setting temperature.

@, right?
I can start coding, you only have the exact terms of reference

Re: GPIO implementation

Posted: Wed Jul 09, 2014 11:13 am
by AndreyB
Dave, this is a great suggestion!

5. fuel pump if(time_running<30 seconds) OR (RPM>0)

I will need to do some research how to implement this most efficiently.

Re: GPIO implementation

Posted: Wed Jul 09, 2014 5:40 pm
by Nobody
This is somewhat common in aftermarket. I’ve only seen (w>x) AND (y<z) AND …. AND… You simply create a temporary bit that each expression can set or reset, when done if true turn on output.

I’ve been doing this for some time, allows end user some flexibility.

Re: GPIO implementation

Posted: Wed Jul 09, 2014 5:47 pm
by AndreyB
Nobody wrote:This is somewhat common in aftermarket. I’ve only seen (w>x) AND (y<z) AND …. AND… You simply create a temporary bit that each expression can set or reset, when done if true turn on output.
But what about fuel pump which you want to prime on start? I guess introducing OR would add a new level of flexibility
Nobody wrote: I’ve been doing this for some time, allows end user some flexibility.
Have you even mentioned the name/url of your project? :)

Re: GPIO implementation

Posted: Wed Jul 09, 2014 5:49 pm
by Nobody
You don't use it for fuel pump, its to allow non standard options like NOS enable.

EDIT

My project is something I'm doing on my own and as I said before, is proprietary and for profit. I will set up company and URL when completed or close to completed, till then I'm keeping it off the web so people don't try to knock it off LOL.

Re: GPIO implementation

Posted: Wed Jul 09, 2014 5:51 pm
by AndreyB
Nobody wrote:You don't use it for fuel pump, its to allow non standard options like NOS enable.
Why so? I guess if you have both standard and non-standard stuff using the same logic, you have less code which is more proven to work property.

Re: GPIO implementation

Posted: Wed Jul 09, 2014 5:58 pm
by Nobody
Correct you have standard stuff and options like NOS, second fuel pump... things that would not make sense to have dedicated outputs for.

Re: GPIO implementation

Posted: Wed Jul 09, 2014 6:18 pm
by AndreyB
So my point is that it might be beneficial to make the programmable I/O logic a bit smarter - smart enough to handle more of the mandatory output channels. It looks like OR could be that step up which would allow treating fuel pump as just a programmable output. It does not mean that users would have to program it - this would be part of the default configuration, but the benefit is that users would be able to set more advanced logic.

Open question is what kind of customization would be allowed using Tuner Studio. Does TS support String fields?

I know that TS has conditional field enable/disabling. I guess one of the implementations would be to offer a number of pre-defined skeletons so that users can choose if he wants to use either
(A & B) | C
or
(A & B) | ( C & D)
or
A | B & C & D

I guess I should find some wire frames application and make some sketches.

Re: GPIO implementation

Posted: Wed Jul 09, 2014 11:31 pm
by kb1gtt
I think fuel is also commonly cut via accelerator for collision detection, and via remote control for monster trucks in an arena. So additional smarts would probably be a handy feature. Oh and of course, don't forget to cut fuel after X hours of operation just to make people climb under the hood :)

Re: GPIO implementation

Posted: Thu Jul 10, 2014 1:21 am
by UnaClocker
Don't forget to include a hysteresis in the settings, otherwise things like toggling between 119.9 and 120.0 will turn the radiator fan on and off rapidly. Bad for the relays, and kind of annoying. Just about any output needs a hysteresis.

Re: GPIO implementation

Posted: Thu Jul 10, 2014 1:30 am
by AndreyB
UnaClocker wrote:toggling between 119.9 and 120.0 will turn the radiator fan on and off rapidly
Actually I already have two ideas how to handle this, tell me what do you think about both?
Approach#1:
Just split fan control into two expression - ON control and OFF control
Radiator_fan_ON_EVENT = temp > 90
Radiator_fan_OFF_EVENT = temp < 85

Approach#2:
Enable full-scale scripting with user variables
# this would keep ran on if it's already on or turn it all at above 90
RAD_FAN = RAD_FAN OR temp > 90
// this would turn rad off if temp below 85
RAD_FAN = temp > 85 AND RAD_FAN

The first approach is simpler. The second approach might be more confusing, but it is potentially more powerful. Maybe even too powerful :)

Re: GPIO implementation

Posted: Thu Jul 10, 2014 3:49 am
by blundar
remember in our discussion the suggestion of "dma" inputs and "dma" outputs?

-Hardware inputs moved into variables
-Hardware outputs set from state of variables
-Control logic in middle simply manipulates variables

How does this work on a practical level?

unsigned char ECT_ADC; //8bit ADC value for coolant temp
unsigned long VSS_pulses; //32 bit unsigned int for number of VSS pulses this period
float EngineTemp, VehicleSpeed;
unsigned char fan1_state, fan2_state;

//do conversion from raw ADCs to real world units for ease of thought and display
EngineTemp = ((float)ECT_ADC / 256 * 546) -273; //some imaginary formula to convert between raw units and real numbers
VehicleSpeed = ((float)VSS_pulses / 5.1214; //some imaginary formula to convert between raw measurements and real numbers

//Criteria for GPIO
if(fan1_state ==0) { /* check to turn on here */
if((EngineTemp > 87) & (VehicleSpeed < 40) { fan1_state =1 ; }
}

if(fan1_state >0) { /* check to turn off here ... */
if(EngineTemp <85) | (VehicleSpeed >40) { fan1_state=0;}
}

Re: GPIO implementation

Posted: Fri Jul 11, 2014 4:46 pm
by AndreyB
In ARM the way you toggle a physical pin is by writing a pretty weird value into a specific address in memory - along the lines of "((~(bits) & (mask)) << (16 + (offset))) | (((bits) & (mask)) << (offset)))", so since if not just writing a 0 or 1 byte or even bit there would have to be a function making the masking / offsetting. Not really a big deal - nothing seems broken so looks like nothing to fix.

If we are looking in the direction of user-defined scripting, the branching IF - conditional statement - would be a pretty challenging thing to implement. It would be REALLY easier to only support pure functional expressions - without branching or GOTO.

So, more like
FUEL_PUMP_STATE = IF( RPM > 0, ON, OFF);

here we have an explicit if function - which is much easier then if statement. An important difference is that bot branches are calculated.. blah blah blah we are getting deeper.

So, probably no user-defined branching for us. And even with functional approach open question is how to input this into the ECU in a user-friendly manner. If we are staying with Tuner Studio there is only that much we can do.

Oh, I know. We can get really crazy and support PS/2 keyboard (where do you buy a PS/2 keyboard these days?) or go mad and support USB keyboards.

Re: GPIO implementation

Posted: Fri Jul 11, 2014 5:48 pm
by rus084
i have ps/2 keyboard , it was buyed in 2009y in nearest computer shop for 300rub (10$) .
now i cant see this keyboards is this shop , but inexpensive monobloc computers are bundled with ps\2 keyboards ( i can see this computers in different organizations )

i think about rusefi terminal with lcd and keyboard connected to the ecu :)

Re: GPIO implementation

Posted: Fri Oct 03, 2014 3:29 pm
by AndreyB
I think I've decided on how this would be implemented, see https://sourceforge.net/p/rusefi/tickets/102/ for details

Re: GPIO implementation

Posted: Sat Oct 04, 2014 2:11 am
by abecedarian
So, basically... and yeah, I'm making it more complicated.... How much GPIO and memory do you have? ;)

Code: Select all

// Turn fuel pump on when the ECU has been powered on, and it has been less
// than 4 seconds since power was applied, or if RPMs are greater than 1
// or if the ECU detects the ignition key is in the "START" or "CRANK" position:
// "ENGINE_IS_CRANKING" is redundant, sort of, since if that is true, RPM should be > 1,
// but better safe than sorry, no? However, if the engine is cranking and we don't have sync,
// the fuel pump will not turn on until RPM can be determined, and it's possible fuel pressure
// could bleed off before sync. Additionally, this could be refactored to work in conjunction
// with a safety system, such that when triggered will ignore RPM and only restart the pump if
// the key is turned to crank position. Note: ON_TIME is in milliseconds
FUEL_PUMP_STATE = ((RPM > 1) || (ON_TIME < 4000) || ENGINE_IS_CRANKING || (MAP < BARO));
// maybe make the "on time" a user-defined variable for vehicles with low pump volume or similar requirements
// that could require more than a few seconds priming?
// MAP < BARO indicates the engine is cranking to start as well.
// could probably simplify to the below, and be fine.
// FUEL_PUMP_STATE = ((ON_TIME < 4000) || (MAP < BARO));


// Coolant fan control:
// On start / warm up, FAN=0, note: there may be two fans, or the fan may be dual-speed
// capable, so having something in the code to support this may be helpful. Suggest using
// qualifiers for that situation, to differentiate between one single speed fan and one dual-speed
// or two independent fans.
// FAN1 will only turn on once ENG_TEMP exceeds 95 degrees (Centigrade / Celsius I presume).
// Once on, it will remain on, due to the logical "OR" that the second condition presents until
// ENG_TEMP falls below 85 degrees.
// FAN2 will only turn on once ENG_TEMP exceeds 105 degrees (Centigrade / Celsius I presume).
// Once on, it will remain on, due to the logical "OR" that the second condition presents until
// ENG_TEMP falls below 95 degrees.
// Value "FAN2_PRESENT" is user-defined, indicating either a two-speed or second cooling fan
// is installed. If A/C is on the vehicle, FAN1 should run whenever the A/C is on if FAN2 is not 
// declared separately.
FAN1_STATE = ((AC_ON && !FAN2_PRESENT) || ((ENG_TEMP > 95) || (FAN1 * (ENG_TEMP > 85)))); 
FAN2_STATE = ((AC_ON && FAN2_PRESENT) || ((ENG_TEMP > 105) || (FAN2 * (ENG_TEMP > 95))));
// proper cooling system bypass and thermostat should negate any issues with 
// temperatures being below 'optimal'.

// Use of bit banding would allow mapping the above 'variables': FUEL_PUMP_STATE,
// FAN1_STATE and FAN2_STATE, to individual bits within GPIO ports so that those could be
// individually addressed and have actions affecting them applied as soon as
// 'assignments' such as above occur within the code.
Actualizing the fuel pump and fan states will have to occur elsewhere unless bit banding has been implemented, where individual bits in a port / register can be addressed directly.

Otherwise, FUEL_PUMP_STATE, FAN1_STATE and FAN2_STATE would be pointing at bits within the GPIO PORT(s), and simply redirect the logic above and flip the bits within the GPIO port(s) as needed.


See? Aren't you glad I'm not contributing to the code? :D

Re: GPIO implementation

Posted: Sat Oct 04, 2014 1:22 pm
by AndreyB
FAN and COOLANT tokens would be higher-level functions, not really related to actual hardware registers.

Re: GPIO implementation

Posted: Sat Oct 04, 2014 6:11 pm
by abecedarian
russian wrote:FAN and COOLANT tokens would be higher-level functions, not really related to actual hardware registers.
High-level functions that determine low-level GPIO states, and thus affect hardware registers, no?

Re: GPIO implementation

Posted: Sat Oct 04, 2014 6:13 pm
by AndreyB
abecedarian wrote:High-level functions that influence low-level GPIO, and thus hardware registers, no?
Sure, at the end of the day the outputs are toggled thus the registers are involved somehow :)

Re: GPIO implementation

Posted: Sat Oct 04, 2014 6:47 pm
by abecedarian
russian wrote:
abecedarian wrote:High-level functions that influence low-level GPIO, and thus hardware registers, no?
Sure, at the end of the day the outputs are toggled thus the registers are involved somehow :)
My point was that spending the time to do the calcs and then later changing the GPIO status to match is a waste of time- set the GPIO/registers when you do the calcs, and use bit banding if it makes sense. Defining "FAN_STATE" to point to some bit in GPIO, it can be both written to and read from and may save some MCU cycles in the process.

Re: GPIO implementation

Posted: Sat Oct 04, 2014 6:56 pm
by AndreyB
abecedarian wrote:My point was that spending the time to do the calcs and then later changing the GPIO status to match is a waste of time
I cannot agree with this point.

Premature optimization is evil, at this point I'd rather focus on usability and flexibility, we should only talk performance when and if it would be an issue. I am a strong believe of the opposite pattern, http://c2.com/cgi/wiki?OptimizeLater

Re: GPIO implementation

Posted: Sat Oct 04, 2014 7:30 pm
by abecedarian
Suppose we'll have to agree to disagree.

The concept mentioned, though specifically addressing radiator fans and fuel pumps, is just as valid toggling GPIO for fuel injectors and ignition.

It may mean a total rethink / refactor of the extant code, to accommodate real time events in real time, though.

Re: GPIO implementation

Posted: Tue Nov 18, 2014 11:51 pm
by AndreyB
abecedarian wrote:The concept mentioned, though specifically addressing radiator fans and fuel pumps, is just as valid toggling GPIO for fuel injectors and ignition.

It may mean a total rethink / refactor of the extant code, to accommodate real time events in real time, though.
You are absolutely right here, the fan or the pump are just the slower use-cases, and injectors and ignitions are the faster use-cases of more or less the same nature. However one step at a time.

What I actually plan as an intermediate solution is programmable fuel or ignition correction: so while all this is probably not fast enough to control actual individual event scheduling, this slower GPIO can already be used to adjust the values as in "add 3ms fuel in case of so and so"

Re: GPIO implementation

Posted: Tue Nov 18, 2014 11:55 pm
by AndreyB
What would be the fancy-schmancy marketable name for this? "GPIO" does not sound sexy enough.

"Programmable outputs"? But it's going to be more then outputs. "Flexible logic"? "fullControl"?

Re: GPIO implementation

Posted: Wed Nov 19, 2014 12:17 am
by puff
something about flexible pin configuration?

Re: GPIO implementation

Posted: Wed Nov 19, 2014 12:59 am
by kb1gtt
How about FSIO for Flexible Sexy Input Output.

Re: GPIO implementation

Posted: Wed Nov 19, 2014 1:24 am
by AndreyB
kb1gtt wrote:How about FSIO for Flexible Sexy Input Output.
FSIOIO for
Flexible Sexy Input Output Input Output
?

Re: GPIO implementation

Posted: Wed Nov 19, 2014 2:02 am
by AndreyB
With current version one can already try this magic:
eval "2 3 +"

See also http://rusefi.com/wiki/index.php?title=Manual:Flexible_Logic

Re: FSIO: GPIO implementation

Posted: Fri Dec 05, 2014 2:11 am
by AndreyB
It's ready - you can control sixteen on/off or variable duty cycle PWM pins.

See http://rusefi.com/wiki/index.php?title=Manual:Flexible_Logic for more details