PCINT interrupt on level change with slow rising signal

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

Hi!
I'm using a atmega328P with a PCINT interrupt on pin PCINT21 which receives a digital signal with a "slow" rising time of 1ms.
I have PCINT2_vect ISR enabled on PCINT21 with the following code:

void Init(void)
{
    PCICR |= (1 << PCIE2);
    PCMSK2 |= (1 << PCINT21);
}

ISR(PCINT2_vect)
{
	toggle_output_pin(TEST);
	if (read_pin(SIGNAL) == 0) {
		return;
	}
	
	time = GetTime();

	//test
	toggle_output_pin(TEST);
}

It happens that in a 0 to 1 change, this ISR runs for 2 or 3 times while the signal is still rising, since the main clock source is the internal RC at 8MHz and it runs faster than the signal. Check the image in attachment.

Is this the normal operation? Should I wait some time until the signal rises completely? Shouldn't the PCINT have some kind of hysteresis?

Thanks!

Attachment(s): 

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

You are feeding an analog signal to a digital input - no surprize the result is that crappy.

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

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

Use the analog comparator or use the ADC in cintinuous mode.

A GIF is worth a thousend words   They are called Rosa, Sylvia, Tessa and Tina, You can find them https://www.linuxmint.com/

Dragon broken ? http://aplomb.nl/TechStuff/Dragon/Dragon.html for how-to-fix tips

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

Or use a software debouncing - e.g. ignore consecutive triggers if they happen faster than say once a 200 uS.

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

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

Quote:

Is this the normal operation? Should I wait some time until the signal rises completely? Shouldn't the PCINT have some kind of hysteresis?


I'd think it should work-->>if<< the signal is "clean".

Are you sure there is no noise/bouncing, especially about the logic threshold?

What does toggle_output_pin() do?

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

Guessing there's a good reason to use PCINT ( low power app?) then here is a suggestion. As soon as the ISR fires, change the PCINT to the opposite edge.Assuming you can still logically work with edge change as opposed to level change.Just a thought.
The only other 'proper' solution would be to use a comparator with hysteresis....

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

theusch wrote:
Quote:

Is this the normal operation? Should I wait some time until the signal rises completely? Shouldn't the PCINT have some kind of hysteresis?


I'd think it should work-->>if<< the signal is "clean".

Are you sure there is no noise/bouncing, especially about the logic threshold?

What does toggle_output_pin() do?


Lots of times the action taken on the interrupt turns something on or off that changes the supply voltage slightly and/or induces a bit of noise. That alone could cause another trigger. You were probably hinting at that with your question about the output function.

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

logic_bit wrote:
I'm using a atmega328P with a PCINT interrupt on pin PCINT21 which receives a digital signal with a "slow" rising time of 1ms.
Quote:
It happens that in a 0 to 1 change, this ISR runs for 2 or 3 times while the signal is still rising, since the main clock source is the internal RC at 8MHz and it runs faster than the signal. Check the image in attachment.

Is this the normal operation? Should I wait some time until the signal rises completely? Shouldn't the PCINT have some kind of hysteresis?

Little, if any, hysteresis.
When your PCINT ISR fires, mask off the pin and clear its interrupt flag.
Use a timer compare match ISR to unmask the pin 0.5 ms later.

You might also consider using only timer interrupts a la switch debouncing algorithms.

Iluvatar is the better part of Valar.

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

Quote:

That alone could cause another trigger.

Yahbut, kids, this is pin-change interrupt that works on both edges (not configurable) of the logic level on the input pin.

there is a quite extensive thread on that recently. While the PCINT mechanism may have no inherent hysteresis, there certainly is a bit on AVR input pins. Some datasheets even have a chart.

In some production apps I use PCINT for edge work such as encoders and flowmeters. while the signals are decent and the rise time is certainly less than a millisecond they aren't all that square. I haven't seen a multiple-hit problem.

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

theusch wrote:
In some production apps I use PCINT for edge work such as encoders and flowmeters. while the signals are decent and the rise time is certainly less than a millisecond they aren't all that square. I haven't seen a multiple-hit problem.
To me, a 1 ms rise time on an 8 MHz processor seems really slow.
Also, I don't know whether the image is a drawing or a capture from a scope.
The signal could be a lot less clean than indicated.

Iluvatar is the better part of Valar.

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

Quote:

The signal could be a lot less clean than indicated.

IME that would be the situation. PCINT should be pretty "clean" with a monotonic rise/fall; slow-moving signal should be all right. E.g. what if you have a PCINT to trip on "bad" power from, say, a resistor divider on the raw supply? Or a temperature sensor input? Or a light sensor?

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

AFAIK every pin of an AVR has a schmitt-trigger. I don't recall any specific maximum rise/fall times for the inputs as most digital ICs have.

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

Yes, this is a drawing, but the signal is that clean, at least from what I see from the oscilloscope.

The analog signal comes from an opamp used as an analog comparator:
-the positive input has a resistor divider to get a constant voltage reference;
-the negative input receives a messy analog signal.

I'm using PCINT because the uC would be on power-save mode. (INT0/1 won't work on level change on that mode). So, analog comparator or ADC in continuous mode is out of the question because the uC won't wake up from them in power-save mode.

"toggle_output_pin(TEST)" turns on or off a another pin in another port, to serve as output debug and is the signal "Debug Pin Output" on the drawing.

"read_pin(SIGNAL)" reads the PCINT21 (the same pin that receives the interrupt) to check whether it's a positive or negative transition (PCINT has only level changed interrupt and we can't choose which direction).

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

1mS rise time from an opamp comparator sounds very slow to me - are you sure that the analogue domain schematic/hardware implementation is correct?

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

Opamp: mcp6044
Slew rate: 3V/ms

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

Ugh. MCP6002...
Slew Rate: 0.6V/us

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

MartinM57 wrote:
Ugh. MCP6002...
Slew Rate: 0.6V/us

MCP6002: supply current: 100uA
MCP6044: supply current: 0.6uA
Since this is low power, I must use the latter...

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

How much current down your resistor divider compared with 100uA/0.6uA (with regards to a low power app)?

Anyway, if your stuck with 3V/ms then you have plenty of suggestions on what to do...good luck, I'm sure it can be sorted :)

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

MartinM57 wrote:
How much current down your resistor divider compared with 100uA/0.6uA (with regards to a low power app)?

Anyway, if your stuck with 3V/ms then you have plenty of suggestions on what to do...good luck, I'm sure it can be sorted :)


The resistor divider has ~1Mohms, so the current is less than 3uA (@3V).

Yes, I have lots of suggestions and solutions, but I'd like to know if the several detections of the PCINT level change is due to the slow rising signal or there's some trick on the uC that can be done to avoid that, such as clearing some flag for instance.

I think the best solution is the one based on knowing exactly where the problem comes from, rather than using some trick that worked well under particular conditions.

Anyway, I might clear the PCINT21 bit for 0.5ms as suggested above.

Thanks!

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

The AVR inputs are schmidt-trigger inputs, but with little hysteresis. So they can be quite noise sensitive if the signal is slow rising or falling.

An alternative for the OP-AMP would be a real comparator like MCP6542. This is similar in current consumption but has a relatively fast rise time.

It should also be possible to use some software solution to get rid of extra interrupts due to noise. A fist step would be manually clearing the interrupt flags at the end of the ISR, an maybe testing for a real change in one of the other inputs. This would remove the extra interrupts for the runtime of the ISR, e.g. some 5 µs.

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

Quote:

The AVR inputs are schmidt-trigger inputs, but with little hysteresis. So they can be quite noise sensitive if the signal is slow rising or falling.

??? The newer datasheets have a chart. 0.3V+ for input pin hysteresis. That shouldn't cause any false trips for a monotonically increasing/decreasing signal regardless of the rise/fall time.

Lee

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

Could there be major ripple from a power supply?

Iluvatar is the better part of Valar.

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

Quote:

The resistor divider has ~1Mohms, so the current is less than 3uA (@3V).

Yes, I have lots of suggestions and solutions, but I'd like to know if the several detections of the PCINT level change is due to the slow rising signal or there's some trick on the uC that can be done to avoid that, such as clearing some flag for instance.

I think the best solution is the one based on knowing exactly where the problem comes from, rather than using some trick that worked well under particular conditions.


I'd wager that if you closely examine the signal you will see some kind of noise/bounce, since you have a very high impedance signal that is susceptible to noise.

There is nothing inherent in the slow-rising signal, as long as it is monotonic, to cause any "double hits".

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

theusch wrote:
Quote:

The resistor divider has ~1Mohms, so the current is less than 3uA (@3V).

...


I'd wager that if you closely examine the signal you will see some kind of noise/bounce, since you have a very high impedance signal that is susceptible to noise.

There is nothing inherent in the slow-rising signal, as long as it is monotonic, to cause any "double hits".

Might a 100 pF capacitor be a good investment?

Iluvatar is the better part of Valar.

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

Quote:

Might a 100 pF capacitor be a good investment?

This is one of the cases where it is interesting to see if the results change when 'scoped, as the small capacitance of the probe can sometimes clean things up. But yes; add a cap. Quick and dirty--touch the pin with a finger. ;)

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.