Arduino : Run Function on Rising Clock Edge

Hi Everyone :slight_smile:

I’m working on this project which has that annoying Hydra of Heracles characteristic. To solve a problem I won’t bore you with I’d like to run c++ functions on the rising edge of a slow duty cycle (think 20-150 pulses per second slow).

I’m confident I could solve this in software with just a delay() at the bottom of the loop(). However as an exercise I’m going to make an external clock on with a 555 timer which I would like to pass into the Arduino.

Question

What are best practices for listening and detecting a rising edge with an Arduino?

My best guess…

const byte CLK_IN = 2;

setup() {
   pinMode(CLK_IN, INPUT);
}

loop() {
   if (digitalRead(CLK_IN) == HIGH) {
      /* Yuck! This could trigger twice.
      It might even miss a pulse on a fast enough cycle. 
      Something smarter here? */
   }
}

Further info

  • I’m using the Arduino Due
  • I’m not wanting the replace the Arduino’s internal clock. I may want to run other code between the slow external pulses.
  • I’d be perfectly happy catching the falling edge if that’s easier
  • Although totally overkill, If there is a solution that uses a hardware interrupt that would suit me nicely. This would allow my Arduino to listen to the user-interface in the main loop() ; then deal with any animations or feedback on an interrupt trigger by the slow external clock().

Thanks in advance <3

Hey @Pixmusix - the google-fu you’re after for Arduino is attachIntterupt: Arduino Reference

Attaching an interrupt that triggers on a rising edge will guarantee you only fire-off the interrupt service routine once.

I modified the example in that reference to trigger on the rising edge. (I haven’t tested it though :sweat_smile: )

const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);
}

void loop() {
  digitalWrite(ledPin, state);
}

void blink() {
  state = !state;
}

put simply, attachInterrupt attaches an “Interrupt Service Routine” (the blink function) to the digitalPinToInterrupt and defines the trigger condition as RISING edge.

note, in C/C++ the keyword volatile is for variables that can change at any time ie. variables that are modified inside an ISR.

2 Likes

@Michael we’re gonna put you on the $5 note.

Do you mind if I ask some quick clarifying questions to make sure I understand the example provided?

//Why did you make this an INPUT_PULLUP?
pinMode(interruptPin, INPUT_PULLUP);

Just to rephrase in my own words to ensure I understand : volatile is letting the compiler know that it cannot guarantee the state of a variable on the stack and has to verify it every time? Trading off safety for time and avoiding undefined behaviour?

1 Like

The reference is here:
volatile - Arduino Reference
The compiler is being told that some code not part of the current code sequence (specifically, an interrupt routine) could have changed the value of the variable, so it cannot be accessed from any temporary location (specifically, a register) but should only be accessed from the actual memory location assigned to that variable.

2 Likes

Ah gotcha! I can see how on a single threaded SBC like the arduino volatile is very intertwined with interrupts. Thanks @Jeff105671 , I appreciate you helping me understand the nitty gritty.

2 Likes

It’s just how the example was written :sweat_smile:
I left it as a pullup because it seemed reasonable to guarantee a stable state. If the interrupt pin is connected to a 555 timer that happens to have the Enable pin pulled low at any time (due to eg. a button press or otherwise) then the 555 output is not defined. The output essentially gets disconnected (if i recall correctly). Having a floating pin could cause spurious triggering.

Having a pullup enabled is probably unnecessary, but likely won’t hurt. I expect the behaviour to be identical if you just used INPUT - there are few reaons to disable the output of an astable (free-running) 555 timer.

1 Like

Good thoughts. Thanks again Michael for your expertise. :heavy_heart_exclamation:

1 Like

PWM → OneShot?

Hi everyone.
I’ve found that my 555 circuit is working as intended.
It has a stable HIGH LOW cycle.

I’ve realized what I need for parts of my circuit is a short pulse on the rising edge.

I can see that if I can phase shift a copy of my pulse by .9 I can create a oneshot by adding it to the original signal. I thank I can just use an AND gate.

How can I do this?
Is there a better way?

Hi Pixmusix
There are several ways to do this. I don’t know how you phase change it easily but yes you could AND the 2 to get a shorter pulse.

How is the 555 actually configured, one shot, monostable or astable.

You could modify the timing components to give you a pulse of defined width

You could modify that pulse by applying to a network comprising a capacitor to a resistor which is connected to ground and take the output from across the resistor. The cap is small in value and will not be a square pulse but a spike. You will get a positive going spike in the rising edge and a negative one on the falling edge. Place a diode 1N4148 across the resistor anode to ground to get rid of the negative going spike and you will be left with a positive spike at every rising edge. This is called a differentiator circuit and a Google “differentiator circuit” will yield lots of info. The Wikipedia entry is here
Differentiator - Wikipedia. But this will not result in a square wave but a spike.
Cheers Bob

1 Like

Hi Robert.

My 555 timer is in astable mode. :slight_smile:
At the bottom of this post I’ve put my complete circuit diagram for clarity.

I’m wanting a nice even square wave out of my 555 so I can visualize the timing easily.

I’m only wanting to shorten the HIGH pulse later on in the circuit.
More specifically, I think I want to shorted to a quick blip just before the SR latch.

Is it possible to add another 555 timer circuit just before the SET pin of my SR Latch that reduces my clock to a blip?

Hi Pixmusix
I will have to sketch this up to see what is happening here. You have 2 outputs of the 74LS08 joined and connected to an input of the 74LS02.
What is the object here. If you make that switch everything will be OFF ie; a LOW on 1B of the first AND gate so no output from 1Y. You should have some pull down resistors on pins 11 & 12 of 74LS02 as you should not allow inputs to float.
What does that strange square with the green centre on the top right do. The one on the left is meant to represent a potentiometer I think. Not too sure but it is labelled 1MΩ.
What is the timing of the 555 pulses. Your diagram does not indicate this. Just shows numbers 1 to 5 without saying what they represent. That pot (if that is what it is) on top left would alter this quite radically.
Marking the cap values would help.
Cheers Bob

1 Like

Hi Bob.

Looks like I’m going to need to research how to draw a proper circuit diagram.
I’m sure google can help with this.

I’m also really interested in this differentiator that you’ve introduced me too. ]
I think there might be something there.
I’ll do some more research with that google search term.

I’ll also see if I can redraw my circuit with more clarity so I answer your question about how my 555 timer is wired up.

Lots of work to do.
Thanks for giving my the right search terms. Hopefully I’ll return with some more well defined questions.

I found this!
image

It looks like exactly what I need.
I will try building it :slight_smile:

Hi Pixmusix

Yes.
But it can be deciphered. Still does not tell me what that square with the green centre is on top right of your diagram. At a guess it might be a picture of a push button switch.

It might but if you look at some examples you will get some clues.

If this is your first introduction to this circuit you might need to brush up on some more basics. The companion to this is the integrator where the cap and resistor swap places. Basically a differentiator is a high pass filter and an integrator is a low pass filter.
If you are playing around with 555s you will often find a differentiator circuit as a conditioner for an external trigger applied to pin 2 (trigger input). This is requires a negative pulse so the diode is reversed to what I described to get rid of the positive pulse.

The 555 is a very useful beast and you would do well to read up on it a bit. I have a very good but somewhat old publication "IC Timer Cookbook) by Walter G Jung. My copy is 4th printing 1981 and is nearly falling apart but I still use it and worth the investment if it can still be purchased

Don’t even think about Fritzing. That is just drawing a picture similar to what you have done.

Give me a day or so and I will see what I can do. Still do some research yourself though.
Cheers Bob

.

Hi
Just saw your post with that circuit. Yes that is one way BUT that OP amp is inverting. If you look closely you will see that the positive spike occurs on the FALLING edge and the RISING edge produces a negative pulse.
If you look up that Wikipedia link or any Google result you should find passive examples without the OP amp which would suit better.
Cheers Bob

EDIT Very important.
DO NOT connect the 1Y and 2Y outputs of the 74LS08 together. I just had a look at the Data sheet and the outputs are driven HIGH and LOW so if one is LOW it will effectively short the other to ground with possible damage if this one is driven HIGH.
It would appear you are trying to “OR” these 2 outputs. If so you will need to fit isolating diodes in series with each output and create what used to be known as a “Diode OR” connection. I will reflect this when I draw you a circuit. You will need signal diodes, the 1N4148 would be OK

1 Like

I found this tutorial on the 555, might be useful. https://www.electronics-tutorials.ws/waveforms/555_timer.html

The next tutorial is about 555 oscillators.

So yes, two 555 should do what you want. The first as an oscillator, the second configured as a monostable, triggered by the first.

Regarding the pull up situation, my understanding is a standard 555 output is either active high (sources current) or active low (sinks current). It does not have a high impedance state so pull up not required. But it’s a while since I used one so I may be wrong.

1 Like

Thanks for all your help @Robert93820. Wow, lot’s of great information to unpack and reply to …

I’ve never regretted anything that has the word cookbook in the name. I’ll go buy myself a copy :slight_smile:

Oh OK that’s a good idea.

It is a push button switch.
However, since drawing that diagram I’ve learned a lot. One of those things is the value of resistors and putting resistors to ground on the output of buttons so that they… work.

I actually got this little breadboard nearly functioning. However the SRLatch Set and Reset pins get stuck in a loop when the 555 timer is HIGH. Hence needing to bring it to a pulse somewhere in the chain.

Totally. I realized This isn’t exactly what I need on further inspection. I was going to persist anyway since I figured I’m going to need to start somewhere. However I can see that a passive solution may be easier as a starting point.

I found this article. Is this an example of a passive differentiator circuit?
https://www.electronics-tutorials.ws/rc/rc-differentiator.html

Hi Pixmusix

Yes, exactly that. I will lash it up later this morning and come up with some values.

I assumed that box was a push button and think I figured out what you are doing.
Closing the switch will isolate the 555 oscillator and enable the push button to operate the latch manually (Gate 1 & 2 of 74LS02). Arduino is instructed to do something then puts a HIGH reset signal on pins 3&4 of the 74LS02 to reset the latch. Opening the switch re-establishes 555 control and the latch is set and Arduino does its thing in a repetitive cycle controlled by the 555. At this stage you are relying on Arduino to reset the latch with no provision to override Arduino and reset manually. That means if Arduino has a problem the 74LS02 will remain latched until power is removed. Keep that in mind when testing and de bugging.

IMPORTANT: ALL UNUSED INPUT PINS MUST BE GROUNDED.
DO NOT use until you have fitted diodes to “OR” the 74LS08 outputs or you could damage the IC. Modified circuit will explain later.

I have not had time to produce a “proper” circuit yet but have printed yours and added some necessary components. Will scan this and post later today. It involves a couple of diodes and a couple of pull down resistors.

Alans statement

is correct. The output on pin 3 does not require pull ups. However the output on pin 7 (if used as an output) is open collector and does require pull up or load of some sort. You are not using this as an output so ignore.
Cheers Bob

2 Likes

I’ll be honest I have had made a few iterations of this circuit which has showcased some lovely burning smells. :stuck_out_tongue:. I’ll take your advice and pause use of this circuit now until my theory has improved.

Does that include outputs? Like for example y4 of my AND gate?

Sorry I think I’ve been so busy trying to understand this particular idea of a oneshot pulse I haven’t taken the time to give you enough context. I think you got all the strokes in your description.

What am I doing?

I have a situation where I want to run animations on a clock pulse. However, the number of animations the Arduino has to handle will be undefined and I can’t be sure how long it will take to complete.

What I tried

I tried a simple 555 circuit that cycled HIGH LOW with a pot to change the speed.

  • The 555 will SET a latch, which triggers an interrupt.
  • When the Arduino has finished it will RESET the latch and wait for the next clock pulse.

For debugging purposes, I wanted a way to step the clock with a simple push button. To swap between the 555 and the button I came up with a switch feeding into an AND gate.

The problem?

I had this “working” but then realized that If the animation completes before the 555 timer goes LOW then the SET pin will re-trigger and the Arduino will be interrupted twice on the same clock pulse. Same goes for the button if it is not released quickly enough.

The solution.

My solution was the create a one shot pulse into the SR latch so it would only trigger once.

Long term design.

The final design will not require the button or switch. Eventually I’ll also decide on a speed, so I wont need the variable resistor. This is where the SR latch will be much more important since I won’t necessarily be going slow enough.

This is SO generous I had no idea you were intending to provide an example. <3 Thankyou @Robert93820

Just had a closer look at your pix.
Along the bottom you seem to have one 220Ω resistor from a LED to ground, the other led resistor seems to be 22Ω (black band instead of brown). In between there is an 82Ω resistor to ground and I can’t make out where that goes but there is no mention of 82Ω on the circuit anywhere. Should this be 1kΩ (Brow, black, red). There is another 82Ω resistor in the top from somewhere to ground, is this in the same category? There are also a couple of resistors hidden by the switch to check. If the 100Ω resistor bottom right is a LED current limiting resistor it is too low.

Wiring errors…On Pix, yellow wire from '02 pin 13 goes to '08 pin 5. Should go to pin 2. Yellow wire from switch (???) to '08 pin 2 should go to '08 pin 5. Blue wire from '02 pin 1 to '02 pin 5 should go to '02 pin 6. '02 pin 5 goes to Arduino although these don’t matter as it is only swapping inputs but it is a discrepancy between drawn circuit and actual which should not happen. It does mean however that your latch “reset” is floating which could account for your reset cycling. Put a temporary 10kΩ resistor to ground while Arduino is not connected might fix that problem. Would not hurt to leave it there anyway.

Suggest you study up the resistor colour code as 22Ω is far to low for the IC to drive I think. Even 220Ω could be increased to 330Ω as you only want to light the LED not read a book.
Also double check your wiring. Mistakes can be a disaster sometimes especially if you don’t have spare ICs on hand.
Cheers Bob