Unreliable interrupt with 555 osc.

Hi All.

Recently i thought how to measure capacitance. So i prepared a 555 oscillator circuit, tested it with a led, working.
Then i decided to count the off->on's in a given time, so i coded it in my Arduino Uno.
In a jiffy i found out that the out-pulse from 555 can not be coded time driven, it must be coded event driven. So i coded this:

const byte ledPin = 13;
const byte interruptPin = 2; //Buraya 555 çıkışını bağladım. GG.
volatile byte state = LOW;
volatile int i=0;
unsigned long vbasla;
unsigned long vbit;

void setup() {
  Serial.begin(57600);
  interrupts();
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, LOW);
  vbasla = micros();
}

void loop() {
  digitalWrite(ledPin, state); 
  if (i>=10) {
    vbit = micros();
    Serial.print(" . S:");
    Serial.print(vbit-vbasla);
    Serial.print(" . I:");
    Serial.println(i);
    i=0;
    vbasla = micros();
 }
}

void blink() {
  state = !state;
  i++;
//  Serial.print(" i:");
//  Serial.print(i);
}

But even though i see the 555 side led working okay, the arduino side led misses about 20-30% of the incoming signal, making the measurement irreliable. (Put a led between D13 and ground to watch)

555 is using a power source and arduino is connected to the usb of the laptop.
The frequency is between 1-100Hz. Not fast.

What i tried:

  • attachInterrupt(..., RISING, FALLING ) made it worse.
  • Not connecting the 555 out pin directly, using a pullup resistance.
  • Putting various capacitors everywhere on the breadboard between 5V and ground.
  • I had an enlightement that 555 side and arduino side are NOT using the same ground. Connected, not gone better.
  • The 555 side used 80mA max current, so i used arduino as the 555's power source. Nope.

Any help would be very nice.

Thank you All.

i found out that the out-pulse from 555 can not be coded time driven, it must be coded event driven.

What does that mean, please?

You almost never want to use HIGH or LOW as an interrupt condition.

One simple way of testing your code without external hardware is to do a non-zero analogWrite on one of the PWM pins, and use that as your input.

looks like you expect to process each interrupt event with code in loop ... you expect to see the led toggle and a corresponding print for each event.

but you won't see each event of that processing takes longer than the period between events.

i believe it would be better to capture the time between interrupt events and process that time in loop()

and look for FALLING

Recently i thought how to measure capacitance. So i prepared a 555 oscillator circuit, tested it with a led, working.

But isn't that taking the long way home ? If you connect a resistor to an OUTPUT (pin) , connect the Capacitor to that, and measure the time it takes for the Capacitor to go logic HIGH on an interrupt pin after you switch the OUTPUT pin HIGH. You can use a smaller resistor to 'drain' or 'fill' the capacitor and verify it is full drained or filled using an analog INPUT.

Deva_Rishi:
But isn't that taking the long way home ? If you connect a resistor to an OUTPUT (pin) , connect the Capacitor to that, and measure the time it takes for the Capacitor to go logic HIGH on an interrupt pin after you switch the OUTPUT pin HIGH. You can use a smaller resistor to 'drain' or 'fill' the capacitor and verify it is full drained or filled using an analog INPUT.

wouldn't an accurate measure of the capacitance require accurately knowing the charge current and the voltage on the capacitor, not just when the input becomes HIGH?

the 555 has two fairly accurate comparators and the 555 freq equation is relative, so measuring the freq can more reliably determine the capacitance in the 555 circuit (presumably with an accurate measure of the resistor

accurately knowing the charge current

Going from the point of view that you've assured
yourself of the capacitor being empty (using an analog pin) Then all you need is the resistance and the time it takes when you apply 5v (using the output pin) to reach the 3.0v logic 'HIGH' as is stated in the
Reference You can modify the scale by using different resistors. (which you turn on 1 at a time) If you google 'Arduino multimeter' you will find some example projects.
To be honest you won't even need interrupts, since you can poll just a single charge.
You could even go the opposite way, and measure the voltage over a fixed period of time. The rest is anyway just mathematics.

Deva_Rishi:
3.0v logic 'HIGH' as is stated in the Reference

the switching thresholds on digital pins aren't that precise nor need to be. the output voltage isn't guaranteed to be 5V.

take a look at pg 355 of this ATmega datasheet

i believe a calibrated circuit that results in an oscillation that is measured is a more conventional way for measuring a capacitance (or inductance). (i've been told of military applications that do something like you suggest to adjust for component aging. they use precise voltage measures)

Quote

i found out that the out-pulse from 555 can not be coded time driven, it must be coded event driven.

What does that mean, please?

There are 2 types of "happenings". Time triggered and event triggered.
For my case, counting the time is no good because, the response would be erratic. Say, 11000011 one time, 00000011 other time.
So i decided to use the event trigger, which is waiting for the D2 pin to become LOW.

You almost never want to use HIGH or LOW as an interrupt condition.

Why?

Thank you All again.

looks like you expect to process each interrupt event with code in loop ... you expect to see the led toggle and a corresponding print for each event.

but you won't see each event of that processing takes longer than the period between events.

i believe it would be better to capture the time between interrupt events and process that time in loop()

I mostly tested the project at 5 Hz. I think arduino is way faster than that.

and look for FALLING

Why?

Thank you All one more time.

You generally don't use HIGH and LOW because those conditions persist; as soon as the processor returns from the ISR, if the line is still in the same condition, you'll trigger another interrupt.
Using edges is much more common.

The frequency is between 1-100Hz. Not fast.

Using an analog input, you could see what the signal looks like using the Serial Plotter.

void setup() {
  Serial.begin(57600);
}

void loop() {
  Serial.println(analogRead(A0));
  delay(2);
}

Quote

Recently i thought how to measure capacitance. So i prepared a 555 oscillator circuit, tested it with a led, working.

But isn't that taking the long way home ? If you connect a resistor to an OUTPUT (pin) , connect the Capacitor to that, and measure the time it takes for the Capacitor to go logic HIGH on an interrupt pin after you switch the OUTPUT pin HIGH. You can use a smaller resistor to 'drain' or 'fill' the capacitor and verify it is full drained or filled using an analog INPUT.

Think this as a project that you must use the arduino, the 555; and using the interrupt will get you more points.

Thanks.

Now I'm thinking of this as an assignment, where we can give you pointers and you can earn the points ... win-win.

guentherbentherr:
I mostly tested the project at 5 Hz. I think arduino is way faster than that.

i just tried an experiment with an ISR that simply increments a counter and displays the count every sec with the ISR triggered LOW and FALLING. i see no output while i pull the input low

with the ISR triggered LOW, the ISR is repeatedly invoked so that loop() doesn't run.

the output voltage isn't guaranteed to be 5V.

Nor is the clock frequency guaranteed.
I doubt that the accuracy of the resistors (or the tools you may use to measure them) is any greater than what the atmega provides.

TheMemberFormerlyKnownAsAWOL:
You generally don't use HIGH and LOW because those conditions persist; as soon as the processor returns from the ISR, if the line is still in the same condition, you'll trigger another interrupt.
Using edges is much more common.

Thank you. That is correct. Using LOW, the interrupt triggered multiple times while pulse-OFF status.
Then i changed it to FALLING, and i got 30-40% additional pulse readings. (First thought: Can be parasitic. Will try putting a schmitt-trigger between arduino and 555.)
Then i changed it to RISING. Now i get pulse readings with 0% error.
A new question appears: **Why to choose ****RISING over **FALLING?

Good night for now.

Why to choose RISING over FALLING?

No hysteresis in your timer circuit?
Noise characteristics are different at each end of the pulse?
Seeing a trace (plot) of your signal might help.

Why to choose RISING over FALLING?

Normally speaking there shouldn't be a difference, but... a 555 doesn't alternate it's output between 5v+ and GND (at 5v supply voltage) But rather between 5v+ and 5v- !! (actually not quite 5v, but that is not so relevant) That may have something to do with it.

Show your 555 schematic.
Some 555 circuits, in this case a monostable, show pin 5 left unconnected:

You get away with the bipolar version of the 555 but not with CMOS version which must have a decoupling capacitor to prevent instability.

And that both the LEDs will light up

555-LED blinker.PNG

555-LED blinker.PNG