Go Down

Topic: Processing multiple digital inputs (Read 10139 times) previous topic - next topic


Dear Mem and all interested fellows. Here is the stage of the project so far.

I divided the Performance program into three modules:

1) Analog processing module.

2) Fuel flow meters module (that uses interrupts).

3) Speed and rpm processing module (that uses pulseIn).

This was following advice from mem and others, in order to make things work one by one, and later integrate them.

Analog Processing Module:

I got all the variables read by Arduino. Made some voltage dividers to low the voltage of these variables below 5 VDC. The variables are:
Tank level
Throttle position
Temp (of engine cooling water)

These variables are all ratiometric (a percentage of the 12V of the battery) and will be used (I don´t know how yet) to calibrate and validate digital variables.

Some further work will be necessary to scale and convert the read values to physical meaning variables, like Fuel liters remaining in tank and so on.

Fuel flow meters module.

This part of the program is working "ok", meaning that I am getting signals from both meters, which when converted to volume of fuel are reasonable figures. But very unstable, very variable, even with a stable throttle position.

As I am getting the same effect with other digital variables, even with a square pulse generator in the laboratory, I cannot blame the flow sensors for the unstable signals. I think I have to build a voltage regulator to set asside possible variation causes. First but not only.

Speed and rpm module.

This module is giving more problems than the others. In the lab it works reasonable well, however, with a great variation of the frequency read from the square signal generator.

One additional problem is it is necessary to reset Arduino to see results. Otherwise, only the "rpm" label is shown, not the "vel" label.

If only rpm signal is injected, the "vel" tittle is not shown ¿?
If both signals are injected, then both titles shows.

Results are strange: very variable as the other digital inputs, and suddendly a very large value appear and full all the space of the lcd at the right of the label of the variable.

I changed this module, and add float variables format to fix de size of the numbers, but even though, results "overflow" what is a reasonable range. It was necessary to include an auxiliary variable "y" for calling the print float routine also.

Another change made was to put a couple of delays so results remain for some moment in the display. Otherwise they change very fast.

Another general issue that is still a mistery for me is defining pins for time resetting. I have to read a good reference for this.

Here is the sketch of this last module:

/* ================== Cuenta Milliseconds Pulses Vel & Rpm ====================*/

#include <DateTime.h>
#include <LiquidCrystal.h>

/* ------------- reset pins, define pins, variables ---------------- */
int resetPin = 1;             // pin 1 resets the time
float y;
/* ------- create object to control an LCD GMD1602K -------*/
LiquidCrystal lcd(12, 11, 6, 7, 8, 9, 10);

/* ==================== SETUP ================================== */
void setup(){
pinMode(2, INPUT);                 // a button on this pin resets the time
digitalWrite(resetPin, HIGH);   // enables pull-up
DateTime.sync( 0 );               // set time to zero
lcd.clear();                            // cleans display

void loop(){
/* ============= Execute program over and over ===============*/

 /* -------- Process of RPM sensor ----------------*/  
 lcd.print(" ");
 lcd.print(" ");  
 /* -------- Process of Vel sensor ----------------*/  
 lcd.print(" ");
 lcd.print(" ");

/* -------------- Function LcdPrintFloat ---------------- */  
void lcdPrintFloat( float x, byte precision){
 // prints val on a ver 0012 text lcd with number of decimal places determine by precision
 // precision is a number from 0 to 6 indicating the desired decimal places

 if(x < 0.0){
   x = -x;

 lcd.print ((long)x);              //prints integer part
 if( precision > 0) {
   lcd.print(".");                    //prints decimal point
   unsigned long frac;
   unsigned long mult = 1;
   byte padding = precision -1;
     mult *=10;                   //"amplifies" decimal values

   if(x >= 0)
     frac = (x - int(x)) * mult;
     frac = (int(x)- x) * mult;
   unsigned long frac1 = frac;
   while( frac1 /= 10 )
   while(  padding--)
   lcd.print(frac,DEC) ;

Hope it is not boring. And look forward any comments.



Try a testing just one of the inputs and see if you can get that stable. I notice that you are not using timeouts on your pulseIn calls, any reason why not? These should prevent an overflow.

Although floating point should work, I suggest that you use long integers for your values until you get things working as expected. pulseIn returns long integers so avoiding the conversions simplifies your test code.



ok to timeouts.

Will work with long integers also.

And one variable at a time.

Ok, will follow these pieces of advice and tell you how they work out.

What do you think about delays to see results displayed?
What do you think about those reset pins? When I integrate all together I suppose should use only one of them?

Thank you much.



Dear Mem,

The Arduino reference for pulseIn timeout says you can use from 10 microseconds to ten minutes for timeout, and that the common use is one second. However, it doesn't say in what units the compiler expects timeout to be set....

I will suppose in milliseconds...
Hope I am right.

Will put 500 milliseconds as timeout.


PulseIn works in units of microseconds, but if 500 milliseconds is a reasonable timeout than perhaps you can just leave it at the default setting  and not bother passing a timeout value.


I think I need a protoshield for Arduino (didn´t know they exists until today), to put some switches, and improve input filters, connections, put some oscilloscope check port, etc. so to work more systematic and trust on results obtained.

Switches would be necessary to change display of results.

Any routine available for that purpose?



Switches would be necessary to change display of results.
Any routine available for that purpose?

can you say more about hwat you want to do


Dear mem,

Of course:

The ideal is to have several "display reports", meaning differents results shown at a time on the display. I have to discuss and think what would be the most useful contents of the displays. But as a first approach:


On the first line I would like to show performance in km/lt  (metric form of mpg) in real time or, say,  every one second. Together with that the mean performance for trip so far. Both based on fuel flow meters and speed sensed.

On the second line it would be interesting to have the mean performance based on liters remaining and consumed on the tank and kilometers of the trip. For comparing purposes and callibrating.

I will have a third way to calculate real time performance, based on consumption estimated by rpm and throttle position. This can be calculated as a mean performance too, and every one minute.


The second display may show direct sensed variables for checking purposes, such as Throttle position, speed, temperature, rpm. flow.


A third display may be to show the best performance estimator in big capital letters and big numbers, for ease of reading.


Another useful display that need a lot more on programming may be a mean of calibrate directly some variables like tank from zero to full every 3 liters or so. But this is a major tasks. Maybe only with the computer connected via the serial port.

So, to have 4 buttons to press that show me four "display reports" would easy to operate and practical. These buttons must be accessible from a case cover.

Talking about stability:

In fact, car digital signals are more stable than those of my pulse generator. So, at this stage, I think I must use more the car with the Arduino board. I have a 8 pins plug to connect it to the car and one extra pin making nine for all.

+12 VDC
- earth
-Engine coolant temp (needed to correct expansion of fuel on second flow meter), analog.
- rpm signal, digital.
- speed signal, digital.
- throttle position signal, analog.
- tank level signal, analog.
- fuel flow meter 1 signal, digital.
- fuel flow meter 2 signal, digital.

But I don't have a good physical mean to attach the board to the car so far. I think a necessary improvement would be to add a protoshield, a case, and buttons at this stage. To ease manipulation, secure connections and avoid physical damages to the board.

I am in bed now, due to some health problem, but when I get up I will take some pictures of all the staff and put them here. Including wiring signals in the car.

And, of course, will start sensing on variable at a time from the car.
Will need to disconect power of the sensors I will be not sensing.
I want to add a voltage regulator too.

All the wiring I made for digital signals was made with common copper wires. Do you think I should have made that with shielded wires?

Thank you for asking. Looking forward to yr comments.


Go Up