Go Down

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

#### Oldbeaver

##### Jun 01, 2009, 02:36 am
Hello there,

My present Arduino project needs to process, at least, three (3) digital (pulse) signals, hopefully four (4).

But digital inputs are another thing.

At present, tks to the help of mem, I can cope with one digital pulse input.

What about several simultaneous digital signals?

The vast majority of posts of members I have read, deal with several OUTPUT digital signals, but only a few with multiple INPUT signals.
And these are too complicated to me.

Any member of the Forum with experience with that?

Fo the help, many thanks in advance.

#### AWOL

#1
##### Jun 01, 2009, 08:27 am
Quote
needs to process, at least, three

"Process" is a pretty broad term.
Can you give some idea of what you are trying to achieve?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### mem

#2
##### Jun 01, 2009, 10:08 am
I think this is a cross post, the problem Oldbeaver wants to solve is described in his other thread: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1243816570/1

#### Oldbeaver

#3
##### Jun 01, 2009, 06:45 pm
Dear AWOL,

Thank you much for coming.

What I am trying to achieve is to "process" four pulse input signals. I explain: two of the signals come in pulses from two fuel meters. This is for a diesel engine, therefore, you need two signals. The first "process" is to count both signals (pulses). The second is to calculate the aritmetic difference between the resulting values. The third is refer that to to a period of time (minutes, hours, seconds, whatever).

Another signal I need to process is speed, which comes in pulses. This must be refer to time also. Don´t know if that last part is necessary or not.

The fourth signal is rpm, which is the only one I am able to manage so far, using the following sketch, kindly improved and corrected by Mem:

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

/* -------- reset pins, define pins, variables ------------ */
int resetPin = 3;              // pin 3 resets the time
int pinTachoInHz = 2 ;                // D2 for Tacho Input - Measuring the Hz
volatile byte TachoInCount = 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
long intTachoInHz_Millis = 0;

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

void setup(){
pinMode(13,OUTPUT);             // flash the LED each second
pinMode(resetPin, INPUT);       // a button on this pin resets the time
digitalWrite(resetPin,HIGH);    // this line enables pull-up
DateTime.sync( 0 );             // set time to zero

//Configure pin modes
pinMode(pinTachoInHz, INPUT);
digitalWrite(pinTachoInHz, HIGH);  // Turn on pullup resistor
attachInterrupt(0, count, HIGH);   // call count when pin goes high

}

void loop(){
// ============= Execute program over and over ===============
/* --------- declares and reset tacho count variables ------*/
float actualSpeed;
float x;                        // auxiliary variable
DateTime.sync( 0 );       // reset time to zero if button pressed
TachoInCount= 0;                // reset the count to zero

/* --------- lights the LED each second --------------*/
digitalWrite(13, LOW);
delay (900);
digitalWrite(13, HIGH);
delay (100);

/* --------------- print pulses count on LCD ---------------*/
actualSpeed = TachoInCount * 10;         // scales
lcd.setCursor(0,0);
lcd.print("Hz");
lcd.print(" ");
x=actualSpeed;
lcdPrintFloat(x,0);     // this prints with no decimal places
}

/* --------------- Function count ----------------------- */
void count(){
TachoInCount++;
}

/* -------------- 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 the integer part
if( precision > 0) {
lcd.print(".");                 //prints decimal point
unsigned long frac;
unsigned long mult = 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 )
lcd.print("0");
lcd.print(frac,DEC) ;
}
}

The routine is OK for "processing" one pulse signal, but I don´t know how can be generalized to three or four inputs.

OldBeaver

#### AWOL

#4
##### Jun 01, 2009, 07:45 pmLast Edit: Jun 01, 2009, 07:46 pm by AWOL Reason: 1
OK, first thing - those "delay"s in "loop" - they gotta go!

Do you have any specs on what sort of frequency of pulses to expect - this will have a big bearing on how much stuff you can do in "loop", or if you're going to need more interrupts.
Generally, I'd suggest putting the fastest stuff on interrupts, and try to keep up with the slower stuff in "loop".

Is there anything about the way the pulses are "structured" (phasing) that could be exploited, or is it all asynchronous?

If speed is critical, try to eliminate the "float"s too. Get creative with fixed-point numbers, if possible.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### Oldbeaver

#5
##### Jun 02, 2009, 01:04 am
Dear Awol,

Well, there are 4 signals:

1) Speed: this is a signal I need to examine in the Oscilloscope (I do that on a PC-Oscilloscope emulator). We may think on a pulse per turn or such, I think. As the transmission axle turns 3.5 times per wheel turn, we may think that it produces 1 pulse per transmission turn. This is about one pulse each 50 cm. At 100km/h it is about 3333 pulses/min. It should be proportional to speed, so at 50km/h the pulses should be half, about 1650 pulses/min, and so on.

2) Fuel flow sensors: these guys send 600 pulses per liter of fuel. It means from 2000 to 6000 pulses per minute, in my case.

3) Tachometer: well, this device sends about 1000 to 3000 pulses per minute. One per engine turn, or less.

Syncronism: There is a clear relation between revolutions, speed and consumption. However, the slope, the gear, the wind, the load, etc make things to vary, I think. I would not expect syncronism between signals.

Ok to delete the delays. I use that only to see that blinking led.

Well, I will use fixed point numbers wherever possible. Will check the manual.

Suppose for a minute, that speed is not a concern. That the IC is so fast that this is not a problem. Well, even then, I don´t know how to program my sketch to "process" (sorry) that pulse signals. The only way I can imagine is just write four times the functions I have for one pulse variable. This means repeating the same function four times, declare four times as much variables, and so on.

So far so good. But, Is Arduino capable of that? Somewhere I read it has only two interrupts? Do I need 4 interrupts for processing 4 variables?

Well, yes, you was answering that already: let´s try to devote interrupts for the fastests variables... I want to hear all the story.

And, once again, thank you much.

OldBeaver

#### AWOL

#6
##### Jun 02, 2009, 08:56 am
Quote
Fuel flow sensors: these guys send 600 pulses per liter of fuel. It means from 2000 to 6000 pulses per minute, in my case

You're burning three to ten litres of fuel a minute?

That's a thirsty motor!
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### mem

#7
##### Jun 02, 2009, 10:09 am
an approach you can take that does not require interrupts is to sample the period of the pulses at regular intervals. For example, if say every second you measured the period if a pulse from the tacho you can calculate the actual rotation rate. The period is the reciprocal of the frequency, so 600 rpm would have a pulse period of 100ms, 6000 rpm 10ms.   If pulses from the fuel gauge range from 33 to 100 per second then the period is 33ms down to 10ms.  If you plan to use the output for engine control then you would need to sample over shorter intervals but for display purposes once a second may be fast enough.

#### Oldbeaver

#8
##### Jun 02, 2009, 04:43 pm
AWOL,

UUUUPPPS ! Did I made a 10 times mistake?

Let see: The car at 100km/h spends 7 liters of fuel. This means 4200 pulses. yap, I made a 10 times mistake! I wrote 42000 instead of 4200 in my spreadsheet. Thank you for the correction!

Then, the fuel flow sensors will send:
600 pulses per liter of fuel. It means from 200 to 800 pulses per minute, in both sensors. Note that the real consumption is the difference between these two: between 0.12 and 0.33 lt/min.

Sorry for the mistake and thank you again for the correction.

#### AWOL

#9
##### Jun 02, 2009, 05:00 pm
No worries - the more usual mistake is to make RPM == Hz.

I wish I had a (insert a small amount of your local currency here) for every time someone's given me that one to sort out!
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### Oldbeaver

#10
##### Jun 02, 2009, 05:00 pm
Mem,

Ok, good idea. So clever of you! To sample the period every second is very good for monitoring the engine behavior and the car performance.

Now, in practical terms, measuring the period is to count the number of milliseconds between two consecutive pulses, isn´t it?
So, for 4 sensors, I need to have 4 variables to monitor every second.

This seems to be a lot simpler than using interrupts. And the simpler, the better.

Then I would need to start and stop 4 milli counters every second. Integers. Then assign this results to 4 calculation auxiliary integer variables, and make my computations, while the counters start counting again. The results of this may be in with one or two decimal place (enough I think), or fixed with one or two decimal places, as suggested by AWOL.

I will try to setup a sketch for counting milliseconds first, make some arithmetic with results, while restarting the counter and then combine that with my present sketch.

All this must be done with digitalRead inputs, am I right? Any other tricks for this to work?

Thank you very much for your new suggestion.

#### Oldbeaver

#11
##### Jun 02, 2009, 05:44 pm
AWOL,

Yes, I confuse rpm with Hz too myself!

That is why I have to convert my tacho pulses signal to rpm.

By the way, how do you convert that? I think it will depend on the Hall sensor you have. Pls correct me if I am wrong.

#### mem

#12
##### Jun 02, 2009, 06:23 pm
I think the simplest way is to use pulseIn for each of your four sensors in turn, with a timeout for the longest period expected (i.e. the slowest speed, RPM and fuel rate that you will display.

For example
Get pulseIn value for RPM
Convert pulse duration to rpm ( rpm = 60000/width in ms)
Get pulseIn value for Speed
Convert pulse duration to speed ( speed  = 1800/width in ms)

( I think your figures were that 100km/h = 333pulses per minute, so you would get one pulse for each 1.8km/h

You may need to tweak the math but I hope that gets you going in a useful direction

#### Oldbeaver

#13
##### Jun 02, 2009, 07:38 pm
Dear Mem,

I tried to make a pulse counting sketch by myself. It seamed easy to me,
but I couldn´t find my way out.

Will consider your approach, and try to convert that to useful programming lines.

How do you timeout the pulse counting?

maybe someting like:

do
{
count pulses;

}while (millis <= 1000),  // case 1000 milliseconds is a good timeframe

make calculations;
Lcd print results;
some delay here to allow results to be displayed?

(pulseIn not in my manual. Nor width). Will check playground

Thank you.

#### AWOL

#14
##### Jun 02, 2009, 07:43 pm
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

Go Up