I am trying to write a sketch for a “one-shot” (bistable multi-vibrator) to avoid an external device like a 555, but having difficulty with programming.
(I have tried much on both Arduino and the Net, without success. Hence my asking for help.)
The criteria for this “one-shot” is :
When INPUT goes from LOW to HIGH, OUTPUT goes HIGH immediately and remains HIGH until PERIOD (time) has expired, after which OUTPUT goes LOW.
During this PERIOD the OUTPUT remains HIGH, despite noise or other HIGH’s at INPUT during the PERIOD (time).
If no HIGH’s after PERIOD time, the OUTPUT remains LOW.
If a single HIGH pulse occurs immedately after PERIOD (time) has expired, OUTPUT switches back to HIGH again until another PERIOD has expired.
I have tried a lot of options from both Arduino and Google, without success.
The best I have tried is this sketch which doesn’t work.
I would appreciate help to correct this sketch or offer an alternative that works.
I see several problems. You’re missing some braces, you’ve used a reserved word for a variable (interval, that’s why it’s red in the IDE), you’ve mixed up some variable types (probably not an issue) and you haven’t implemented the no re-trigger logic. Try this and see if it makes sense.
const int ledPin = 12;
const int buttonPin = 2;
const unsigned long Period = 2000; //length of timer period in msecs
boolean ledState = 0;
boolean buttonState = 0;
unsigned long timerMillis = 0;
void setup() {
pinMode (ledPin, OUTPUT);
pinMode (buttonPin, INPUT); //assumes a momentary SW to Vcc and a pull-down resistor ?
}
void loop() {
if ((buttonPin == HIGH) && (ledState == 0)) { //ignore input while timer is running
ledState = 1 ; //set LED on, also used to know if timer is running
timerMillis = millis(); //remember time when input when high
}
if (millis() - timerMillis > Period) { //test if period msecs elapsed since input went high
ledState = 0; //if yes, all done timing, shut off LED
}
digitalWrite(ledPin, ledState); //output LED state, whatever it might be
}
Newbie10:
(Is that because you wrote boolean buttonState = 0 and followed that with buttonPin?)
It occurs because I didn't give it much thought and didn't test the code. You need to read a pin to know the input state. Neither your 1'st program nor mine did that. Doh ! You could eliminate the variable ButtonState and do this change instead.
```
if ((digitalRead(buttonPin) == HIGH) && (ledState == 0)) {
```
Of course! (You learn something new every minute…)
And by removing the " && (ledState == 0)" bit the sketch becomes a “signal/s stretcher” by adding the Period after the last INPUT high. Very useful when you need it, as I do.
Yes, I have an idea. You have all the learning material right there in front of you. Give it some thought. Experiment a bit. It's only software, it won't bite you.
No need for apology : I like so many of us, goof! It’s natural in the scientific environment. (But then some get a bit bitter about errors as I have found out…)
I have found the // very useful to temporarily erase something to test how it compiles or works in hardware. That way one can also SEE what you did last time; e.g. often I will copy/paste a line and place // at the start of the upper line while I wiggle/twiggle the 2nd line so I always know what came first.
As a matter of interest, I see very litte / no interest in “one-shot”/multivibrator variations. Seems that either all on the forum know how to write sketches like that, OR I am the only dummy OR nobody sees the need for them…
I have found the // very useful to temporarily erase something to test how it compiles or works in hardware. That way one can also SEE what you did last time; e.g. often I will copy/paste a line and place // at the start of the upper line while I wiggle/twiggle the 2nd line so I always know what came first.
…
I agree, but the // stays valid until the end of the line. /* */ is used to comment/disable a specific section of the line, or across multiple lines.
My mind is not working very wel to analyse code. So I will need some time to respond on the one-shot idea.
Yes, and OK with the /…/ thing : I use that too! Very useful when experimenting.
The “one-shot” is little more than an extension of the classic “debounce” (with variations in Arduino-language), except that implementation sometimes gets tricky, i.e. making it do what YOU (or I) want it to. In my case I wanted to delay the alarm relay by 4 seconds to avoid high current during a motor’s start-up.
I have some experience in making harware one-shots using NAND-gates with hysteresis, for example, using caps, resistors and diodes to achieve almsot any variation, e.g. rising/falling edge detect, delay-on/off, delay-off/on, pulse extender…
But translating them into software is a horse with a different colour.