Run an action after some time since the beginning of a method

Hi all,
I'm trying to implement a system to make high speed photography of drops. I prepared the circuit and the firmware of the arduino to control the solenoids and this is working as expected.
The thing I want to add now is the possibility to trigger the flahes and the camera automatically: in fact I calculate the time after I want the shot to be triggered. From the Arduino firmware point of view it means to put an output port to HIGH at the correct time and for a predefined time and then put them back to LOW.
This must happen regardless what the arduino is doing in parallel: there are more than one solenoid and they can be activated with particular patterns, so it might happen that while the solenoids are still activated the flahses must be triggered (also more than once).

This may be achieved using multithreading or interrupts (or ?), and here I'm coming to ask for your help and suggestion in finding the best way to achieve this. I'm using Arduino UNO

I hope that I formulated the question in a clear way. Please, feel free to ask me for other information in case!

Thank you so much!

Regards

Please post your program as it is now. You can do what you want but only if the current program is written in a suitable way and has no code in it that would block its running which would prevent timing taking place. An example of such code would be the delay() function, but there are others.

Thank you UKHeliBob,
Here is the code: as you can see, it is full of "delay", but I change it with other things to get the correct behavior.
I'm also doing some code cleanup to better use the memoy (using const, ...), but the functionality is there.

Thank you!

Mirko

simple_firmware.ino (6.91 KB)

I have not gone through your code in detail but I believe that this is what you are trying to do

flash LEDs to indicate that the run is starting (what actually starts it ?)
open the solenoid to release a drop
a short time later close the solenoid having released the drop
wait a short time
a short time later open the shutter
a further short time later fire the flash
a further short time later close the shutter

It looks like you want to do the drop release/shutter/flash sequence several times in succession on each run. Is my understanding correct ?

If so, or something like, it then a state machine using millis() for timing would seem made for the job. At any one time the system is in a known state, mostly waiting for

Thank you UKHeliBob,
Yes, you got it right; at the moment the start is triggered by an interrupt on a button.
The sequence you draw is essentially correct; the firing of the flash must happen after a time T since the first drop was released (independently from the fact that all the solenoids were fired or not, or are still releasing the drops), and the user will be able to change the timing (in the new version I'm working on, the user can change the value of the variables for the timing from serial input). Anyway, what I want to say is that in the general case, things can happen in parallel (the flash should be fired while one of the solenoids is still creating the drop).
I'll investigate the FSM solution, and hopefully I'll find a solution. Do you have any example / library for that task? I saw that there are many options... do you have any suggestion?

Thank you!

Look at post #1 to see an example of a state machine program that I wrote in response to a query. If you loop at what the OP wanted it should be easy to follow.

In that example there is only 1 state machine implemented using switch/case but you might need 2 or more because of

(independently from the fact that all the solenoids were fired or not, or are still releasing the drops),

but that is no problem as long as millis() is used for all timing and the code is not blocked at any point.

You could have one SM to control the release of the drops, a second to control the firing of the shutter and a third to control the flash. Each would be in an initial state waiting for the sequence to start (there is no need for an interrupt to simply read a button) and all the timings would be started by the button press. Save that start time from millis() and you have the basis for your timing in all of the SMs

Each SM would proceed through its states based on elapsed times since the start or the start of the previous action and all timing periods could be varied by user input.

There are libraries to implement this but I have found switch/case easy to work with and it makes what is going on very visible.

Thank you again!!

UKHeliBob:
Look at post #1 to see an example of a state machine program that I wrote in response to a query. If you loop at what the OP wanted it should be easy to follow.

Do you mean this post?
Otherwise I didn't get the one you mean...

UKHeliBob:
In that example there is only 1 state machine implemented using switch/case but you might need 2 or more because ofbut that is no problem as long as millis() is used for all timing and the code is not blocked at any point.
You could have one SM to control the release of the drops, a second to control the firing of the shutter and a third to control the flash. Each would be in an initial state waiting for the sequence to start (there is no need for an interrupt to simply read a button) and all the timings would be started by the button press. Save that start time from millis() and you have the basis for your timing in all of the SMs
Each SM would proceed through its states based on elapsed times since the start or the start of the previous action and all timing periods could be varied by user input.

I guess I'll go for a solution with 1 FSM for each solenoid + 1 for flash and 1 for camera... I'll verify.

UKHeliBob:
There are libraries to implement this but I have found switch/case easy to work with and it makes what is going on very visible.

I'll try... maybe I'll find a good one, because I may need to instanciate 3 FSM which have the same states and transitions (for the 3 solenoids).
I'll try out something!

Thank you again!

Do you mean this post?

That's the one. I could have sworn that I put it in the message but obviously not. I wonder where I did put it !

I'll try... maybe I'll find a good one, because I may need to instanciate 3 FSM which have the same states and transitions

Look at the example using arrays further down that thread.

The demo several things at a time is an extended example of using millis() for timing.

...R

UKHeliBob:
That's the one. I could have sworn that I put it in the message but obviously not. I wonder where I did put it!
Look at the example using arrays further down that thread.

Robin2:
The demo several things at a time is an extended example of using millis() for timing.

Thank you both for the examples!
I'm going to implement a solution like this!!