Hi to you all
I really didnt want to ask for help but its got to the piont that I need to,
What i am trying to do, is control 3 solenoids for high speed photography ie water splashes
The problem is using the delay function as 1 change alter all as you may well know. I can get 2 solenoids to what i want in a fashion add the 3rd and the droplet doesnt even show in the photo. Any help would be a benefit or a link. thanks
#define BUTTON_PIN 2
#define CAM_TRIGGER_PIN 10
#define FLASH_TRIGGER_PIN 9
#define LED_PIN 12
#define STANDBY 0
#define ACTIVE 1
#define WORKLIGHT_RELAY 6
#define Sol_One 5
#define Sol_Two 4
#define Sol_Three 3
#define sol_One_working 0 // change to 1 to activate solenoid ONE
#define sol_Two_working 1 // solenoid TWO
#define sol_Three_working 0 // solenoid THREE
int Sol_One_Delay = 60; // change value for DELAY solenoid ONE
int Sol_Two_Delay = 50; // solenoid TWO
int Sol_Three_Delay = 60; // solenoid THREE
long flashDelayMS = 278; // DELAY for flash
int mode = STANDBY;
void setup() {
pinMode(BUTTON_PIN, INPUT);
pinMode(CAM_TRIGGER_PIN, OUTPUT);
pinMode(FLASH_TRIGGER_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(WORKLIGHT_RELAY, OUTPUT);
digitalWrite(LED_PIN, HIGH);
digitalWrite(WORKLIGHT_RELAY, HIGH); //turn the lights on
if (sol_One_working)
pinMode(Sol_One, OUTPUT);
if (sol_Two_working)
pinMode(Sol_Two, OUTPUT);
if (sol_Three_working)
pinMode(Sol_Three, OUTPUT);
}
void loop() {
if (digitalRead(BUTTON_PIN) == LOW)
{
mode = ACTIVE;
digitalWrite(LED_PIN, LOW); // show we're ready
digitalWrite(WORKLIGHT_RELAY, LOW); // turn the lights off
delay(1500); // to give time for light to go down and settle after button push
delay(500);
digitalWrite(CAM_TRIGGER_PIN, HIGH); // open the camera shutte
digitalWrite(Sol_Two, HIGH); //
delay(Sol_Two_Delay);
digitalWrite(Sol_Two, LOW); //
delay(145);
digitalWrite(Sol_One, HIGH); //
delay(Sol_One_Delay);
digitalWrite(Sol_One, LOW); //
digitalWrite(Sol_Three, HIGH); //
delay(Sol_Three_Delay);
digitalWrite(Sol_Three, LOW); //
delay(flashDelayMS);
digitalWrite(FLASH_TRIGGER_PIN, HIGH); // fire flash
delay(70);
digitalWrite(FLASH_TRIGGER_PIN, LOW);
digitalWrite(CAM_TRIGGER_PIN, LOW); // close camera shutter
mode = STANDBY;
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(WORKLIGHT_RELAY, HIGH); // turn lights back on
}
}
This could be a hardware issue, a software issue, a communications issue, or a combination of all three.
I can't even understand what your issue is, so I have no idea how to help you. This code does something. You expect it to do something. If those two somethings were the same thing, it is unlikely that you would have posted, so I think that it is safe to assume that they are not.
How are the solenoids powered? What is connected to the Arduino? What do the solenoids actually do? How are the lights controlled? What kind of lights are they? What is actually connected to the Arduino?
Use Tools + Auto format before posting code, please. The random indents do not make for readable code. Post the code properly, too, using the # icon above.
Thank for your reply
sorry for not doing the forum correctly, first time ive used one
How are the solenoids powered? 12v power supply via transistor switch
What is connected to the Arduino? Start button (push to make), led, 12v worklight(via transistor switch) camera and flash using opto for switching
What do the solenoids actually do? Fire to release a drip of water
How are the lights controlled? 12volt transitor switch
The electonic seem to be working fine all doing what they should be, it the controlling them.
what i am trying to do, get 3 drips of water to hit each other with a few millisecond diffence, while timing the flash at a given piont
OK. So, the Arduino doesn't care about solenoids and lights. All it is doing is turning some transistors off and on at appropriate times. This should rule out a current draw issue.
The problem is using the delay function as 1 change alter all as you may well know. I can get 2 solenoids to what i want in a fashion add the 3rd and the droplet doesnt even show in the photo.
what i am trying to do, get 3 drips of water to hit each other with a few millisecond diffence, while timing the flash at a given piont
It's still not clear what the problem is. The second statement says there will be 3 drops of water that should come together. The first says that the drop doesn't appear in the photo. But there are 3 individual drops at one time, one larger blob after 1 and 2 come together and a smaller one where 3 is still separate, and a large blob where all three have come together. Which of the drops, 1, 2, 3, 1+2, or 1+2+3 is not appearing in the picture?
In the code posted, only one pin is set to an OUTPUT, and yet all three are turned on and off for various lengths of time, with various delays.
I do appreciate your help.
I will try to explain was trying to keep it short but its not working
because of the way I have programed the sketch using the delays the last(ie soleniod 3 ) release the drip to late
sorry it seemed a simple task but turning into a nightmare
how it should work
connect the aruino which switches the worklight on
press the switch
light goes off
opens camera shutter
trigger 1 soleniod ( small drip open for about 60 ms) if it can be done would like to have control so i can change the size of the drip
delay of a few millisecond soleniod 2 triggers ( small drip open for about 60 ms)
delay of a few millisecond soleniod 3 triggers ( small drip open for about 60 ms)
trigger the flash ( at a variable delay)
close camera shutter
worklight back on
Thats all, no loop just once though the sketch press the button and start again
not sure if this helps - clear from solendiod one - yellow from soleniod 2 - orange from soleniod 3
by changing the 0 to 1 will switch on the soleniod sorry was just left that way as i was try a different set
#define sol_One_working 0 // change to 1 to activate solenoid ONE
#define sol_Two_working 1 // solenoid TWO
#define sol_Three_working 0 //
First thing I'd recommend is that if you don't declare a solenoid to be OUTPUT, don't toggle the solenoid pin, and, most importantly, don't delay.
You could add a collection of potentiometers that you read to control the delay. Then, use that information to define the delay(s).
Believe me, I understand your frustration, but I can't see your setup. I can't see what is happening. I can't see that is working or what is not working.
You must pretend that we are blind. Because we are, effectively. State exactly what is happening, and what isn't.
I think the issue is that any adjustment of the solenoid delays to get a larger drip has a knock on effect through the other delays, in this case resulting in the final solenoid getting held up and is thus missing from the photograph. I assume that you could eventually fine tune this back to get it working by tweaking the delays, but then you'd have to go through that calibration process every time you wanted to change anything.
I suggest that you revisit your code and get rid of (most of) the delays. When the button is pressed, note the time using millis. Set up the time since start at which you want each event to happen. Then you can adjust the time solenoid two stays open to get a larger drip without impacting the time that solendoid three is activated. You'll need to keep some state as well to keep track of what's been done. Starting to look like a little state machine would serve your purpose well.
I might be over-thinking your problem, but I think it might be interesting to make "drip detectors" that could be positioned below each of the nozzles and used to determine the time between the 'open solenoid' signal and the time a drop fell free.
I'd guess that there is some variance in timing from one solenoid to another - perhaps even some variance from one trial to another for the same solenoid - and it might be worthwhile to get a handle on the behavior of all three nozzles...
I would like to change the delay in the loop to millis from what i have just been reading ie blink without delay, i unsure if this would work with the switch, flash etc or how the IF statement could be controlled
You could perhaps try making the whole thing data driven. You need to know four things about each action you take:
How long after the trigger is hit do I do this?
What pin do I use to do it?
Do I set the pin high or low?
Has this action been done?
You could model this as four arrays, or better an array of structs. Then, keep note of whether the trigger was pressed and the time it was. Each time round loop, just iterate over your actions with a for loop. Any that need doing, do them and mark them done.
It can be made more efficient by ordering the actions by the timeline and then you can ignore stuff that's already done. You'll need some cleanup code to reset it all for another run when you're done.
This way, the code's fairly trivial - your control is all in the data.
Thanks Wildbill
I like that idea, havnt got a clue how to do it but been having a look on different sites, it makes sence so another big learning curve.
Does anyone have or suggest a good site to learn about array?
Ive been looking at arrays but am I right in thinking they need to loop to be affective ?
My problem is in the loop ( it runs once )
Everything works fine apart from the timing of the solenoids
void loop() {
if (digitalRead(BUTTON_PIN) == LOW)
{
mode = ACTIVE;
digitalWrite(LED_PIN, LOW); // show we're ready
digitalWrite(WORKLIGHT_RELAY, LOW); // turn the lights off
delay(1500); // to give time for light to go down and settle after button push
delay(500);
digitalWrite(CAM_TRIGGER_PIN, HIGH); // open the camera shutte
// Problem is below *******************************************************[/b]
digitalWrite(Sol_Two, HIGH); //
delay(Sol_Two_Delay);
digitalWrite(Sol_Two, LOW); //
delay(145);
digitalWrite(Sol_One, HIGH); //
delay(Sol_One_Delay);
digitalWrite(Sol_One, LOW); //
digitalWrite(Sol_Three, HIGH); //
delay(Sol_Three_Delay);
digitalWrite(Sol_Three, LOW); //
// Problem above ***********************************************************[/b]
delay(flashDelayMS);
digitalWrite(FLASH_TRIGGER_PIN, HIGH); // fire flash
delay(70);
digitalWrite(FLASH_TRIGGER_PIN, LOW);
digitalWrite(CAM_TRIGGER_PIN, LOW); // close camera shutter
mode = STANDBY;
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(WORKLIGHT_RELAY, HIGH); // turn lights back on
}
}
Solenoid open for drips to be produced
int Sol_One_Delay = 60; // change value for drip size solenoid ONE
int Sol_Two_Delay = 50; // solenoid TWO
int Sol_Three_Delay = 60; // solenoid THREE
Sol_Two takes 425ms to hit the water
Sol_One and Sol_Three 350ms (difference is do to nozzle size)
The delay of 145 is because the drip hits the water and comes back up in to a spike as picture above, Sol_One then triggers and hits the top of the drips released by Sol_Two
Sol_Three then triggers with the drip 60ms later but everything in the water as finished
Is there away this can be done by using millis?
Can it be done by a loop with it running 3 times and triggering a solenoid each time ? but keeping the other bits?
You write the code so that you can set the delays independently of each other.
In the setup up you use millis() to find the current time and add to it the time you want the solenoids to turn on for and store it in a variable.
By not posting all the code I can't see if this compiles but it should give you the right idea:-
boolean allFiringNotdone;
long int timeNow, sol1delay,sol2delay,sol3delay;
long int sol1OnTime,sol2OnTime,sol3OnTime;
// put in the other stuff to define the variables or constants you use.
void setup(){
// put in the other stuff in your setup
// put some sensible figures here, time in milliseconds
sol1delay = 50; // time delay before solinoide 1 fires
sol2delay = 60; // time delay before solinoide 2 fires
sol3delay = 90; // time delay before solinoide 3 fires
sol1OnTime = 100; // the time this solinoide is on
sol2OnTime = 200; // the time this solinoide is on
sol2OnTime = 300; // the time this solinoide is on
}
void loop() {
if (digitalRead(BUTTON_PIN) == LOW)
{
mode = ACTIVE;
digitalWrite(LED_PIN, LOW); // show we're ready
digitalWrite(WORKLIGHT_RELAY, LOW); // turn the lights off
delay(1500); // to give time for light to go down and settle after button push
delay(500);
digitalWrite(CAM_TRIGGER_PIN, HIGH); // open the camera shutte
// Problem is below *******************************************************[/b]
allFiringNotdone = true;
timeNow = millis();
fire_Sol1 = timeNow + sol1delay;
fire_Sol2 = timeNow + sol2delay;
fire_Sol2 = timeNow + sol3delay;
release_Sol1 = timeNow + sol1OnTime;
release_Sol2 = timeNow + sol2OnTime;
release_Sol3 = timeNow + sol3OnTime;
while(allFiringNotdone){
timeNow = millis();
if(timeNow > fire_Sol1 && timeNow < release_Sol1) digitalWrite(Sol_One, HIGH);
if(timeNow > release_Sol1) digitalWrite(Sol_One, LOW);
if(timeNow > fire_Sol2 && timeNow < release_Sol2) digitalWrite(Sol_Two, HIGH);
if(timeNow > release_Sol2) digitalWrite(Sol_Two, LOW);
if(timeNow > fire_Sol3 && timeNow < release_Sol3) digitalWrite(Sol_Three, HIGH);
if(timeNow > release_Sol3) digitalWrite(Sol_Three, LOW);
if(timeNow > release_Sol1 && timeNow > release_Sol2 && timeNow > release_Sol3) allFiringNotdone = false;
}
}
// Problem above ***********************************************************[/b]
delay(flashDelayMS);
digitalWrite(FLASH_TRIGGER_PIN, HIGH); // fire flash
delay(70);
digitalWrite(FLASH_TRIGGER_PIN, LOW);
digitalWrite(CAM_TRIGGER_PIN, LOW); // close camera shutter
mode = STANDBY;
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(WORKLIGHT_RELAY, HIGH); // turn lights back on
}
}
Hi Mike
Thank you for your time and work, Im now going though what you have done to understand it. The full code was on the first post on this thread. Im working away next week so may not get back to you with the results until next weekend.
I have been working on this sketch since for christmas and not moving forward (with the delay) so thanks again for your input
Hi Mike
Would just like to say a BIG THANK YOU the program you posted as help more than you realise, I have changed all the delays using your formula and the control i now have is fantastic.
Still dont know how you manged to work it out in the first place, I understand how it works, just wish I could learn to think in that way. I was born to early I think.
Thanks again for you help.
Ive just looked at your profile so if im ever in Manchester will buy you a pint... The other bit which made me think, there's hope was your age thought it was only young guys who could work with arduino, well you have prove me wrong.