I am making a water drop system for photography. Currently i have it running with a simple delay program but it is very slow to tune. each time i change a droplet parameter a have to ajust the flash delay and it takes alot of time.
I want to make a program that allows me to adjust the flash delay independently from the droplet delays. After allot of searching i finnaly made this one. Do you think it will work for what i want?
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int valPin = 13; // the number of the Valve pin
const int vallPin = 12; // the number of the second Valve pin
const int FlashPin = 11; // the number of the flash pin
//Define Variables
int sysloop = 0; // Start Program System Loop
int buttonState = 0; // variable for reading the pushbutton status
int FlashDelay = 300; // Delay before flash is fired ----- Millisecond
int ValveDelay = 130; // Delay betwin drops ----- Microsecond
int DropSize = 20; // Droplet size ----- Microsecond
int DropSizeII = 20; // Droplet size ----- Microsecond
//difine if Buton are Input or Output
void setup() {
// initialize the Valve pin as an output:
pinMode(valPin, OUTPUT);
// initialize the second Valve pin as an output:
pinMode(vallPin, OUTPUT);
// initialize the flash pin as an output:
pinMode(FlashPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
//Loop that ocures every time you press button pin2
void loop(){
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
sysloop = 0;
} else {
dropWater();
while(sysloop != 1){
detectFlash();
}
sysloop = 0;
}
// stop the program for for xxx milliseconds:
delay(100); // wait for a 1/100 of a second;
}
// turn the VallPin on
int dropWater(){
digitalWrite(valPin, HIGH);
delay(DropSize);
digitalWrite(valPin, LOW);
// stop the program for ValveDelay milliseconds:
delay(ValveDelay);
// turn the VallPin on
digitalWrite(valPin, HIGH);
delay(DropSizeII);
digitalWrite(valPin, LOW);
}
// turn the FlashPin on
int detectFlash(){
delay(FlashDelay);
digitalWrite(FlashPin, HIGH);
delay(5);
digitalWrite(FlashPin, LOW);
}
I need to:
1º - Press button to start system
2º - Start Flash delay countdown
3º - Wile the Flash delay is counting the valves will fire and the droplets will start falling.
This will allow me to set the number and sise of drops without having to adjust the flashdelay every time.
It's been done before and I'm going to do one myself someday. In saying that, I would have an IR or laser beam break detector setup to capture a drop, then you just need to tune the delay until the flash fires. Repeatable and adjustable via an LCD would be cool.
You would need to prime the system and the single button press could trigger your shutter as well. I assume you are shooting in darkness so the exposure is flash only?
Personally I would use an LCD as it gives you the ability to very accurately adjust the delay you seek. One manual way to do it would be a potentiometer attached to an analog input which then assigns a range of delay values you can preset in the program
You think wrong.
Do you want me to merge the threads?
Yes please. If you dont mind.
negativ3:
Personally I would use an LCD as it gives you the ability to very accurately adjust the delay you seek. One manual way to do it would be a potentiometer attached to an analog input which then assigns a range of delay values you can preset in the program
For now i have the laptop connected and setup through there, but in the near future maybe i will get a lcd so i dont have to have the laptop connected.
Im back to a cleaner Delay program i made....much esear to edit.
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int valPin = 13; // the number of the Valve pin
const int vallPin = 11; // the number of the second Valve pin
const int FlashPin = 10; // the number of the flash pin
//Define Variables
int buttonState = 0; // variable for reading the pushbutton status
int DropSize = 20; // Droplet size ----- Microsecond
int DropSizeII = 20; // Droplet size ----- Microsecond
int ValveDelay = 130; // Delay betwin drops ----- Microsecond
int FlashDelay = 300; // Delay before flash is fired ----- Millisecond
// turn the VallPin on
int dropWater(){
digitalWrite(valPin, HIGH);
delay(DropSize);
digitalWrite(valPin, LOW);
// stop the program for ValveDelay milliseconds:
delay(ValveDelay);
// turn the VallPin on
digitalWrite(vallPin, HIGH);
delay(DropSizeII);
digitalWrite(vallPin, LOW);
}
// turn the FlashPin on
int detectFlash(){
delay(FlashDelay);
digitalWrite(FlashPin, HIGH);
delay(5);
digitalWrite(FlashPin, LOW);
}
//difine if Buton are Input or Output
void setup() {
// initialize the Valve pin as an output:
pinMode(valPin, OUTPUT);
// initialize the second Valve pin as an output:
pinMode(vallPin, OUTPUT);
// initialize the flash pin as an output:
pinMode(FlashPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
//Loop that ocures every time you press button pin2
void loop(){
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
dropWater();
detectFlash();
}
// stop the program for for xxx milliseconds:
else {
// turn LED off:
}
}
Anyone has any ideas on how i can make it work? without the flash having to w8 for the drops to end?
To just change flash timing, get data from a turn pot and scale it down. 300 ms is near what you want then map analog pin 0-1023 to be, say 200-400 ms.
If you put a charge on the water drops then you can detect drops and use an electromagnet to divert any you don't want to fall straight down. It would need to be a good bit of charge but not hard to do with an electrostatic generator. In fact, a Kelvin water-drop generator would work and knowing how they work tells a way to detect a charged drop falling.
If you know how far the drop falls and where you sense the drop then by gravity you should know when the drop will hit. But I see maybe you are interested in slightly after by different tiny intervals. You might even be interested in drops from different heights and streams instead of drops.
With a coil you could slow the fall of a charged drop (Milliken used oil drops) or even hold it up until you cut power.
Well. After a 16h Home work i finely got what i need. Wrote this code and simplified it so its practical.
All parameters work seperatly
//..............................................Use these Values.....................................................
int ValveDelay1 = 0;
int DropSize = 20; // Droplet size ----- Microsecond
int DropSize2 = 20; // Droplet size ----- Microsecond
int ValveDelay2 = 130; // Delay betwin drops ----- Microsecond
int FlashDelay = 400; // Delay before flash is fired ----- Millisecond
int FlashDuration = 5; // Flash Pulse ----- Millisecond
int GLOBAlReset = 500; // Global Reset ----- Millisecond
//..............................................Use these Values.....................................................
//.................................................Dont Touch........................................................
const int VAL1Pin = 13; // the number of the Valve pins
const int VAL2Pin = 11 ;
const int FLASHPin = 10 ; // opto-isolator anode connected to digital pin 10
int buttonPin = 2; // The Number of the Button Pin
int globalReset = GLOBAlReset; // time to activate button again.
int VAL1Delay = ValveDelay1 ; // time until Valve 1 fires
int VAL1Duration = DropSize ; //duration of Valve 1 fire
int VAL2Delay = ValveDelay2; // time until Valve 2 fires
int VAL2Duration = DropSize2; //duration of Valve 2 fire
int FLASHDelay = FlashDelay; // time until Flash fires
int FLASHDuration = FlashDuration; //duration of Flash fire
int VAL1Timer = VAL1Delay+VAL1Duration ; //total time of delay and duration
int VAL2Timer = VAL2Delay+VAL2Duration;
int FLASHTimer = FLASHDelay+FLASHDuration;
unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called
void setup()
{
pinMode(VAL1Pin, OUTPUT); // initialize the Valve1 pins as an output:
pinMode(VAL2Pin, OUTPUT); // initialize the Valve2 pins as an output:
pinMode(FLASHPin, OUTPUT); // declare flashPin as as OUTPUT
digitalWrite(VAL1Pin, LOW); // initialize Valves at Closed
digitalWrite(VAL2Pin, LOW); // initialize Valves at Closed
pinMode(buttonPin, INPUT); // Initialize Button as input
}
void loop()
{
if (btnMillis != 0)
{
unsigned long timePassed = millis() - btnMillis;
//Flash.............................................................................
if ((timePassed >= FLASHDelay) && (timePassed <= FLASHTimer))
{
digitalWrite(FLASHPin, HIGH); // trigger flash by bringing digital output to high
}
else {
digitalWrite(FLASHPin, LOW); // set it back to low
}
//VALVE 1............................................................................
if ((timePassed >= VAL1Delay) && (timePassed <= VAL1Timer))
{
digitalWrite(VAL1Pin, HIGH); //turn on Relay 1 pin
}
else {
digitalWrite(VAL1Pin, LOW); //turn off Relay 1 pin
}
//VALVE 2............................................................................
if (timePassed >= VAL2Delay && timePassed <= VAL2Timer)
{
digitalWrite(VAL2Pin, HIGH); //turn on Relay 2 pin
}
else {
digitalWrite(VAL2Pin, LOW); //turn off Relay 2 pin
}
//Longest off time, to re-enable the button.........................................
if (timePassed >= globalReset)
{
btnMillis = 0;
}
} else { // i.e. btnMillis==0
if (digitalRead(2) == HIGH)
btnMillis=millis();
} // end the big if
}
//.....................................................THE END..........................
Latter today ive got to test it but seems like it works perfectly.
Hi again. After getting it to work how i wanted i decided to make a LCD+button interface, but am having some trouble. I have the LCD working, Got the menus running, Buttons change parameters on LCD, But nothing happens to the actual Program timings. In the video, you can see the shield i built and the Led's corresponding to the valves Blinking. the RED Led (Valve1) when i put 250ms it should blink at the same time as the yellow (Valve2)
Here you can see my Code, And if possible give me a hand on what i am doing wrong. This is my first Arduino project so be gentle
#include <LiquidCrystal.h>
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);
//..............................................Use these Values.....................................................
int ValveDelay1 = 125; // Delay Beffor first drop
int ValveDelay2 = 250; // Delay betwin drops ----- Microsecond
int ValveDelay3 = 500; // Delay betwin drops ----- Microsecond
int DropSize = 100; // Droplet size ----- Microsecond
int DropSize2 = 102; // Droplet size ----- Microsecond
int DropSize3 = 103; // Droplet size ----- Microsecond
int FlashDelay = 500; // Delay before flash is fired ----- Millisecond
int FlashDuration = 5; // Flash Pulse ----- Millisecond
int CameraDelay = 0; // Delay before camera is fired ----- Millisecond
int CameraDuration = 5; // camera Pulse ----- Millisecond
int GLOBAlReset = 2000; // Global Reset ----- Millisecond
//..............................................Use these Values.....................................................
//.................................................Dont Touch........................................................
const int VAL1Pin = 13; // the number of the Valve pins
const int VAL2Pin = 12 ;
const int VAL3Pin = 11 ;
const int FLASHPin = 10 ; // opto-isolator anode connected to digital pin 10
const int CAMERAPin = 9 ; // opto-isolator anode connected to digital pin 10
int LastValveDelay1 = 0;
int globalReset = GLOBAlReset; // time to activate button again.
int VAL1Delay = ValveDelay1 ; // time until Valve 1 fires
int VAL1Duration = DropSize ; //duration of Valve 1 fire
int VAL2Delay = ValveDelay2; // time until Valve 2 fires
int VAL2Duration = DropSize2; //duration of Valve 2 fire
int VAL3Delay = ValveDelay3; // time until Valve 3 fires
int VAL3Duration = DropSize3; //duration of Valve 3 fire
int FLASHDelay = FlashDelay; // time until Flash fires
int FLASHDuration = FlashDuration; //duration of Flash fire
int CAMERADelay = CameraDelay; // time until camera fires
int CAMERADuration = CameraDuration; //duration of camera fire
int VAL1Timer = VAL1Delay+VAL1Duration ; //total time of delay and duration
int VAL2Timer = VAL2Delay+VAL2Duration;
int VAL3Timer = VAL3Delay+VAL3Duration;
int FLASHTimer = FLASHDelay+FLASHDuration;
int CAMERATimer = CAMERADelay+CAMERADuration;
unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called
int buttonPin = 19; // The Number of the Button Pin
int upbtn = 18; // up button
int downbtn = 17; // down button
int modebtn = 16; // mode button
int upbtnsize = 14; // up button
int downbtnsize = 15; // down button
int i;
int remain;
int run = 0;
int pageid = 0;
unsigned long currenttime;
unsigned long remaintime;
unsigned long prevtick;
#define IR_LED 13 //Pin the IR LED is on
#define DELAY 13 //Half of the clock cycle of a 38.4Khz signal
#define DELAY_OFFSET 4 //The amount of time the micros() function takes to return a value
#define SEQ_LEN 4 //The number of long's in the sequence
unsigned long seq_on[] = {
2000, 390, 410, 400}; //Period in uS the LED should oscillate
unsigned long seq_off[] = {
27830, 1580, 3580, 0}; //Period in uS that should be delayed between pulses
void setup() {
pinMode(VAL1Pin, OUTPUT); // initialize the Valve1 pins as an output:
pinMode(VAL2Pin, OUTPUT); // initialize the Valve2 pins as an output:
pinMode(VAL3Pin, OUTPUT); // initialize the Valve3 pins as an output:
pinMode(FLASHPin, OUTPUT); // declare flashPin as as OUTPUT
pinMode(CAMERAPin, OUTPUT); // declare CAMERAPin as as OUTPUT
digitalWrite(VAL1Pin, LOW); // initialize Valves at Closed
digitalWrite(VAL2Pin, LOW);
digitalWrite(VAL3Pin, LOW);
pinMode(buttonPin, INPUT); // Initialize Button as input
pinMode(modebtn, INPUT);
pinMode(downbtn, INPUT);
pinMode(upbtnsize, INPUT);
pinMode(downbtnsize, INPUT);
pinMode(upbtn, INPUT);
digitalWrite(buttonPin, HIGH);
digitalWrite(modebtn, HIGH);
digitalWrite(downbtn, HIGH);
digitalWrite(upbtn, HIGH);
pinMode(IR_LED, OUTPUT);
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("---Welcome to---");
delay(5);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("---WaterDrop----");
lcd.setCursor(2, 1);
lcd.print("Photography");
delay(5);
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("MAIN MENU");
lcd.setCursor(2, 1);
lcd.print("Cycle Menu");
delay(5);
lcd.clear();
showpage();
}
//INTRO ...
void customDelay(unsigned long time) {
unsigned long end_time = micros() + time; //Calculate when the function should return to it's caller
while(micros() < end_time); //Do nothing 'till we get to the end time
}
void oscillationWrite(int pin, int time) {
unsigned long end_time = micros() + time; //Calculate when function should return to it's caller
while(micros() < end_time) { //Until we get to the end time oscillate the LED at 38.4Khz
digitalWrite(pin, HIGH);
customDelay(DELAY);
digitalWrite(pin, LOW);
customDelay(DELAY - DELAY_OFFSET); //Assume micros() takes about 4uS to return a value
}
}
void triggerCamera() { // this triggers the camera
for(int i = 0; i < SEQ_LEN; i++) { //For each long in the sequence
oscillationWrite(IR_LED, seq_on[i]); //Oscillate for the current long's value in uS
customDelay(seq_off[i]); //Delay for the current long's value in uS
}
customDelay(63200); //Wait about 63mS before repeating the sequence
for(int i = 0; i < SEQ_LEN; i++) {
oscillationWrite(IR_LED, seq_on[i]);
customDelay(seq_off[i]);
}
}
If i was not clear on explaining something feel free to ask. I am from portugal and have a hard time trying to explain
Hope you can help me.
Here is a link to a device that does what you want. The code is available. http://www.cameraaxe.com/wiki/index.php?title=Programming. This device uses a different display module but you should be able to get info on how he did his timing. This is a versatile little box.
Here is a link to my water drop controller project. This is Uno based with a DFRobot Display shield and a protoshield that houses the solenoid driver chip. This controller does not time the flash duration. I use another device that is 555 timer based. I bought it several years ago. I lost the documentation for this box in a disk crash. The Arduino controller just controls the size of the drops, the timing between the drops, and how many drops (1-3). I built the controller because I was frustrated with the manual drop delivery of the 555 timer box. (eyedropper thru a IR interrupter.) The Arduino generates the drops and triggers the flash delay timer. Works pretty well.
I can't see quite what the problem is. It flashes three LEDs in sequence each time you push the button. Are you saying that the LED flash length is supposed to vary as you change the 'Time' parameter and it isn't varying?
thank you all for the replyes. yes that was exacly what was happening. the leds represent the valves so the delay shold varry. i have found the problem. iwas using the contant int instead of the int. now it works and i can change the valiues.the only problem now is that the delay on the buttons seems to be interfering with the valve times.
for example.ifi use 1000ms drops all with 0ms timing, they shold all turn on and off at the same time. but they dont. red turnes just a few ms beffor the yellow and the yellow a little beffor the green. must be the delay for the buttons? how cani remove them?