Go Down

Topic: Setting a fixed on/high-time for digital output (Read 696 times) previous topic - next topic

Chris L

Hi folks,

Apologies for the probable n00bishness of this question, but is it possible to code a monostable for a digital output, i.e. output goes low after x amount of time, regardless of whether the output control's still on/high or not?

I've used a simple delay to turn a solenoid off after 10ms, after being activated by a MIDI-in key, so even if the key is held it still goes off after 10ms, but of course this also stops the program for 10ms, throwing the timing off if there are multiple key presses.

I've looked at millis() to see if I can use that to set an off time to 10s, but I haven't been able to get it to work due to a severe case of n00bism. I've based the MIDI stuff on Kuki's excellent code, btw.

If it's not possible to code something without monkeying with the timing, perhaps it's possible to read an analog input from a pot, set to control this gate time at all?

Any help would be magnificent, thanks.


I am not sure I understand the problem, but if all you want is something to trigger after 10 ms without blocking your application then millis() is the easiest approach.
When the Midi In event occurs read out the millis() value and store it in a (global) variable. Then keep doing your normal processing and every once in a while do a check to see if the current time, i.e. millis(), is larger than the saved time + 10. In pseudo code:

void loop() {
 static long timeOut;
 const unsigned int DURATION=10;
 if (midiEvent) timeOut=millis()+ DURATION;
 if (millis()>timeOut) turnItOff();
 if (millis()>timeOut) turnItOff();

Chris L

Thanks Cross -- yep, you've got it. I'll have another look, but I'm not very proficient with coding, and millis() seems a bit more complex than just using delay. It'd be nice to be able to do this in software, as otherwise I'll need a monostable for every solenoid I intend to drive (in this case a chromatic octave, 12 solenoids -- all the spare digi pins I think).


There is a lot of trickery going on with millis() behind the scenes, but from the development side of things it's really easy to use since it's just an automatically increasing 32-bit counter.

There is also the option of starting a timer on the arduino that will then call your own function once time is up, however that requires some more advanced programming.

By the way you can use the analog pins just like regular digital pins, giving you 6 (?) more outputs. Don't forget the arduino current limitations when driving multiple solenoids.

Chris L

Thanks Cross -- I shall persevere with millis() and try and get something going. As I'm using 12 solenoids, I'll have to address each solenoid's timing separately to have the correct on-time, which might bulk up the coding a bit. Yep -- currently driving the solenoids via a transistor and a 12v wall wart. Shouldn't have more than 3 or 4 solenoids running concurrently anyway. :)

Go Up