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);
}
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?
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.
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);
}