Processing multiple digital inputs

If the fuel flow can change quickly over short periods of time then you may need to count these pulses using interrupts instead of using pulse width. You have two interrupts free so go ahead and try using attach interrupt to do the count. I suggest that you start off with a test sketch that just displays the fuel count and calculated fuel consumption. When you have that working you can add in the other measurements and the performance calculations.

I think that is the case: flows will change quickly over time. What you suggest makes sense to me. I will do just that.

Last night I was reading some Arduino learning material that I downloaded. Very extense and very good. A lot more complete than the manual I got. This should help too.

Thank you very much for the suggestions. I hope I can make the sketch for the two interrupts myself. Will try to work more systematically.

Best,

OldBeaver :)

Why not post a link, others reading this thread may find that information useful also.

Ok. What thread name would you use and in what forum? This project embraces several aspects of Arduino application.

By the way, in the interrupt routine there is the following statement I do not see mentioned but once at the beginning:

long intTachoInHz_Millis = 0;

What is this for?

Sorry, you mean a link. A link to where?

OldBeaver

A link to this place: "Last night I was reading some Arduino learning material that I downloaded..."

The Arduino documents I downloaded can be find in this link:

I downloaded the version 012. Now I see there are newer versions.
I have Arduino Diecimila and probably that was the appropriate version in that moment (November 2008).

Dear Mem and all,

Follows my pulsecount sketch for two variables.

It compiles well, however, result is always zero for both counters.

Please take a look at it:

// ===================== Cuenta Pulsos New ===================
#include <DateTime.h>
#include <LiquidCrystal.h>

/* -------- reset pins, define pins, variables ------------ */

volatile byte InCount1 = 0; // declare this as a byte if the count is always less than 255
volatile byte InCount2 = 0; // declare this as a byte if the count is always less than 255
// so you don’t have to disable interrupts when using in loop

/* ------- create object to control an LCD GMD1602K -------*/
LiquidCrystal lcd(12, 11, 6, 7, 8, 9, 10);

void setup(){

DateTime.sync( 0 ); // set time to zero
lcd.clear(); // clear screen

/* ------------------ Configure pin modes -------------------*/
pinMode(2, INPUT);
digitalWrite(2, HIGH); // Turn on pullup resistor
attachInterrupt(0, count1, FALLING); // call count1 when pin falls

pinMode(3, INPUT);
digitalWrite(3, HIGH); // Turn on pullup resistor
attachInterrupt(1, count2, FALLING); // call count2 when pin falls
}

void loop(){
// ============= Execute program over and over ===============
/* ------------- declares and reset input count variables ------*/
int InCount1;
int InCount2;
float x;

if(digitalRead(2) == LOW)
{DateTime.sync( 0 ); // reset time to zero if button pressed
InCount1= 0; // reset count1 to zero
}
if(digitalRead(3) == LOW)
{DateTime.sync( 0 ); // reset time to zero if button pressed
InCount2= 0; // reset count2 to zero
}
/* --------------- print pulses count1 on LCD ---------------*/
lcd.setCursor(0,0);
lcd.print(“CountHz1”);
lcd.print(" ");
x = InCount1;
lcd.print(int(x));

/* --------------- print pulses count1 on LCD ---------------*/
lcd.setCursor(0,1);
lcd.print(“CountHz2”);
lcd.print(" ");
x = InCount2;
lcd.print(int(x));

}

In both interrupts I used HIGH, RISING and FALLING, with no results.

Looking forward to your comments,

OldBeaver

/* --------------- Function count1 ----------------------- /
void count1(){
InCount1++;
}
/
--------------- Function count2 ----------------------- */
void count2(){
InCount2++;
}

You have adeclared local version of the variables, remove these from loop: int InCount1; int InCount2;

you are also reseting the variables back to 0 in loop when the pin is low

Ok, thank you. Worked immediately. ;D

I added a delay of 500 miliseconds at the end of loop, cause counters displayed too fast to see them.

Now I will test a little in the car so to adjust scales, volts, and so on. 8-)

After that, I will test the pulseIn input lines of the other sketch with the car. Once both are ok, will work with them all together. In this routine I have the problem that have to button reset it to make it work. It runs for a while and stops. Maybe for the lack of inputs?

Thank you once more for your kind help.

OldBeaver

Will keep the Forum updated.

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.setCursor(0,0);
lcd.print(“Rpm”);
lcd.print(" “);
y=60000/pulseIn(4,LOW);
lcdPrintFloat(y,1);
lcd.print(” ");
delay(100);
/
-------- Process of Vel sensor ----------------*/
lcd.setCursor(0,1);
lcd.print(“Vel”);
lcd.print(" “);
y=1800/pulseIn(5,LOW);
lcdPrintFloat(y,1);
lcd.print(” ");
delay(100);

}

/* -------------- 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){
lcd.print(’-’);
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;
while(precision–)
mult *=10; //“amplifies” decimal values

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

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

OldBeaver

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.

Mem,

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.

OldBeaver

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?

Tks.

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:

[u]FIRST REPORT.[/u]

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.

[u]SECOND REPORT.[/u]

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

[u]THIRD REPORT.[/u]

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

[u]FOURTH REPORT.[/u]

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.

OldBeaver