Square pulse wave with a delay and a certain length

Hi Everyone,

I am trying to create a square wave with a delay of 16 seconds and a length of 8 seconds after the arrival of three input signals.

I created an ISR that counts the times the state of the input pin becomes HIGH. The output channel should go from LOW to HIGH after 16s, remain HIGH for 8 seconds and then remain LOW for the rest of the time. The sketch I wrote is generating the correct square wave, but i don't manage to keep the output on LOW after the first square wave. Does anyone have any advice on how to do this? (see sketch below).

I tried to use an if statement instead of the delay(), but I haven't been able to get this to work yet.

Any advice would be welcome!

Thank you in advance


#include "avr/interrupt.h"

volatile byte state = LOW;
volatile unsigned long count = 0; // +1 each time interrupt calls ISR
const byte interruptPin = 2;
int TTL4 = 8;

void isr () {
state = digitalRead(interruptPin);
if (state == HIGH)
{
count ++;
}
}

void setup() {
pinMode(interruptPin, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(TTL4, OUTPUT); //output signal to Syringe pump
digitalWrite(TTL4, state); //original state is when the syringe pump is off
attachInterrupt(state, isr, CHANGE);
}

void loop () {
if (count ==3){
delay(16000);
digitalWrite(LED_BUILTIN, state);
digitalWrite(TTL4,state);
delay(8000);
digitalWrite(TTL4,LOW);
digitalWrite(LED_BUILTIN, LOW);}
// else if (count >3){
// digitalWrite(TTL4,LOW);
// digitalWrite(LED_BUILTIN, LOW);
// }

}

Count pulses, do something then

what resets the whole thing? Do you literally only want to see the inputs and make one square wave, then do nothing for the rest of all time?

More specific description please.

a7

pin 2 can be configured for a rising edge, why then use a change interrupt and sample the interrupt pin instead? That is a convoluted way to do it.

Thank you for your reply.
Yes, I only need one square wave after the third count.
Then the signal should be low for the rest of the time.

I could (add a long delay and) set the count back to zero, so that the system is resets after the one square wave.

First I recommend that you correct your initial post and put your code between tags,

ArduinoForum
as recommended by the topic:
How to get the best out of this forum

Your code lacks an instruction that resets the counter value.

void loop () {
  if (count == 3) 
  {
    delay(16000);
    digitalWrite(LED_BUILTIN, state);
    digitalWrite(TTL4, state);
    delay(8000);
    digitalWrite(TTL4, LOW);
    digitalWrite(LED_BUILTIN, LOW);
    count = 0;
  }

RV mineirin

Yes, you could do many things. The beauty of having a programmable element in your design.

But what do you want / need to do as far as resetting and getting prepared to observe and react to three new pulses?

Also these pulses that are your input… how long are they and how much time between them? You might could probably do this without interrupts at all.

But the main thing we can’t tell you is what you need the system to do. As you say, a long delay or even an infinite loop that hangs the program up should leave the outputs where you left them for all time.

Are you saying something mysterious is setting an output back to HIGH? Your logic will continue to fire 16 second delays and 8 second pulses as long as the count remains 3.

To get around that you could just bump up the count artificially, that is to say by adding one to it, not because another pulse came in, but just to get off the mark that triggers your desired reaction.

Reset the whole thing by resetting the counter to 0, well, when?

a7

The input signal comes from an external device. I am not sure whether there will be more than 3 input pulses (I will check). This could indeed explain why I keep generating pulses.
For now I included an additional delay() equal to the maximum time interval that the external device is sending input pulses at the end of the if (count ==3) statement. Then after that delay I've set the count back to count=0;

The input pulse is a 10µs TTL pulse. the time in between them is not constant, but in the order of a couple of 100ms - seconds.

Dear RC Mineirin,

I have an additional question.
What If I want to run this program again, without having to reset or restart the arduino board? Can this be done by including an attachInterrupt in the void loop(){}?

Or can I use some sort of reset function?

Thank you in advance

volatile byte state = LOW;
volatile unsigned long  count = 0;              // +1 each time interrupt calls ISR
const byte interruptPin = 2;
int TTL4 = 8;

void isr () {
  state = digitalRead(interruptPin);
  if (state == HIGH){
  count ++;
  }
}
  
void setup() {
//count=0;
pinMode(interruptPin, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(TTL4, OUTPUT); //output signal to Syringe pump
digitalWrite(TTL4, state);  //original state is when the syringe pump is off
attachInterrupt(state, isr, CHANGE);
}
void loop () { 
  if (count ==3){
  delay(15999);
  digitalWrite(LED_BUILTIN, state);
  digitalWrite(TTL4,state);
  delay(8500);
  digitalWrite(TTL4,LOW);
  digitalWrite(LED_BUILTIN, LOW);
  //delay(10000);
  delay(100000);
  count=0;
  }

  attachInterrupt(state, isr, CHANGE);

}