Pulse counting problem

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have an input, give me continous pulse (1 and 0) non-stop when no object. When got object, it send high only (will remain high as long as the object is blocking the IR).

Any simple idea to detect the object is presence?

I can read the pin high and low without problem.

if (prevPin!=currentPin)
{
    count++;
}

prevPin=currentPin;

won't work coz it will continue to add to my count when no object is presence. When got object presence, the above code stop adding! I want the reverse...

I also thought about

if (prevPin==currentPin && currentPin==1)
   count++;
prevPin=currentPin;

Also not working. Then I use more variables, prevPin1, prevPin2, prevPin3, prevPin4, not working also....

cs

I'm happy ytd, today, and tmr :)

Last Edited: Mon. Nov 1, 2010 - 02:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
if (prevPin1==prevPin2 && prevPin2==prevPin3 && prevPin3==prevPin4 && prevPin1==1)
count++;

prevPin1=currentPin;
prevPin2=prevPin1;
prevPin3=prevPin2;
prevPin4=prevPin3;

Not working too :(

Running the above code the count keeps adding with or without object.

cs

I'm happy ytd, today, and tmr :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
if (prevPin!=currentPin)

Surely this depends when in the cycle you are sampling the state? How do you know if a '1' state is not simply the high pulse of an alternating 1-0-1-0-1... or as a result of a constant 1 ?

You can use external or pin change interrupts perhaps to sample only at changes of state. But when constantly high you'd still need a temporal element to recognise that the state hasn't changed within period N.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Every positive-going edge, clear and start a timer (hardware or software). Every negative-going edge, stop the timer. Set a compare match on the timer for your "missed my negative pulse, must be the signal I want" time value. When the timer reaches that value, you've detected your condition.

This is just like debouncing a switch, BTW.

Some sample pseudocode, showing a variant of the above that uses levels, not edges. There will be additional details you'll have to work out:

loop
{
  if (input_is_low)
    clear_timer;
  else
    increment_timer;
  if (timer >= MAGIC_TIMER_VALUE
    process_the_condition;
}
Last Edited: Mon. Nov 1, 2010 - 02:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I also thought abt using PCINT, but no object 1-0-1-0-1-0 will continue to send interrupt, which I dont want.

What I want is 1-1-1-1-1-1-1 to send interrupt. How to do that?

cs

I'm happy ytd, today, and tmr :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Any simple idea to detect the object is presence?

Set up a timer-as-counter using a Tn pin. Periodically, examine the count and see if it below the threshold for "continuous high".

Example: If you look at TCNTn every 10 milliseconds, and the count is 0 (or maybe 1) for that period, then it is "made". Clear TCNTn and then look again in (say) 10ms.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

What I want is 1-1-1-1-1-1-1 to send interrupt. How to do that?

As I think we've all said you need a temporal element with this - sample the signal at various points in time and only when the signal has remained high longer than the high part of the 010101010 alternation can you be sure it is truly high. There's no way (that I can see) of having this generate an interrupt except by using the "soft interrupt" technique described in AVR datasheets where you sacrifice an IO pin to be able to create a soft interrupt:
mega48/88/168 datasheet wrote:
The External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23..0 pins.
Observe that, if enabled, the interrupts will trigger even if the INT0 and INT1 or PCINT23..0 pins
are configured as outputs. This feature provides a way of generating a software interrupt.

But you might as well just call the handler from the timer interrupt where you have been sampling pin state unless you need to get out of the ISR quickly for some reason.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

Any simple idea to detect the object is presence?

Set up a timer-as-counter using a Tn pin. Periodically, examine the count and see if it below the threshold for "continuous high".

Example: If you look at TCNTn every 10 milliseconds, and the count is 0 (or maybe 1) for that period, then it is "made". Clear TCNTn and then look again in (say) 10ms.

Not really understand...For example:-

        Time (ms) 1 2 3 4 5 6 7 8 9 10
Say  the pulse is 1 0 1 0 1 0 1 0 1 0
     My sampling  ^       ^       ^

Looks like 1 but it is actually 1010101010...
Wouldnt this possibility will happen?

cs

I'm happy ytd, today, and tmr :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can I use a cap to smooth the voltage and use a op-amp as a comparator to get 1 - got object, 0 - no object.

1010101010 - 2.4V
1111111111 - 2.6V

cs

I'm happy ytd, today, and tmr :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kk6gm wrote:
Every positive-going edge, clear and start a timer (hardware or software). Every negative-going edge, stop the timer. Set a compare match on the timer for your "missed my negative pulse, must be the signal I want" time value. When the timer reaches that value, you've detected your condition.

This is just like debouncing a switch, BTW.

Some sample pseudocode, showing a variant of the above that uses levels, not edges. There will be additional details you'll have to work out:

loop
{
  if (input_is_low)
    clear_timer;
  else
    increment_timer;
  if (timer >= MAGIC_TIMER_VALUE
    process_the_condition;
}

What is a MAGIC TIMER VALUE?

cs

I'm happy ytd, today, and tmr :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Clear a timer on every 1->0 transition, and you will get a timer overflow interrupt when there are no transitions during the whole timer overflow cycle. Choose the timer overflow period according to your input pulse period (Tin) - it should be [slightly] longer than Tin.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just the raw digital signal applied to an ADC input is going to look like Vcc/2 if the 1010101 is 50:50 duty cycle and Vcc when it is 111111111

Where did you get the 2.4V/2.6V figure from? If true is suggests that the 1010101010 is more like 111110111110111110111110 - that is a much higher mark to space ratio and that both signals are around half-Vcc

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Can I use a cap to smooth the voltage and use a op-amp as a comparator to get 1 - got object, 0 - no object.

It sounds like more design (and components) than the timer-as-counter. Every real app will have a heartbeat timer anyway so you just need one timer.

And MBedder described an alternate one-timer solution using an external int.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

External hardware you might try includes an
RC filter with a diode across the resistor.
Use the analog comparator.

Absent external components to do it for you,
you will need to do something on every rising edge.
Otherwise you will have no way of knowing how long is long enough.

On each rising edge, adjust a compare match value.
It should be the old timer value plus the
number of ticks in the desired interval.
If the compare match interrupt fires next and
the pin value is still one, you have an object.

There are more precise ways of doing it,
but they are not necessary on a millisecond time scale.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Where did you get the 2.4V/2.6V figure from? If true is suggests that the 1010101010 is more like 111110111110111110111110 - that is a much higher mark to space ratio and that both signals are around half-Vcc

The Vcc of the IR receiver is 5V. My atmega running at 3V3, thus I use a Zener 3V3 and a resistor to reduce the voltage. The Zener 3V3 is only 2.6V when it is 1111111, and 2.4V when it is 10101010.

I dont have a scope, thus cant be sure it is 10101010 or 111011101110 something like tat.

cs

I'm happy ytd, today, and tmr :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After reading the post here, I understood the whole concept what to do and I implemented a software approach to solve the problem. Viola, problem solved, so happy! Reading this forum is much better than attending the so-called expert seminar/workshop/training!

BTW, what is the benefit of using
10101010 for no object, 111111 for got object? It make my life so much difficult!

Cant it make our life simpler like
1 no object
0 got object

Or
11111 no object
101 (a single pulse) got object - thus I can use a PCINT (falling edge) to count?

cs

I'm happy ytd, today, and tmr :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The IR pulse train is much better in terms of object recognition reliability. A single pulse has many chances to be just an interference of a random event (a fly :)), rapid ambient light intensity change etc.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Most IR sensor based object detection systems use an IR transmitter (LED) modulation (i.e. 1-0-1-0-1-0-1-0:D) to increase the object recognition reliability as I mentioned above.

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.