// ver 1.8 24 March 2019
// Mega2560 version
//Note the word 'pause' used as 'delay' is a function & could cause confusion
//Note TriggerPin must be debounced, else it plays havoc. - look at link below...
//https://hackaday.com/2015/12/09/embed-with-elliot-debounce-your-noisy-buttons-part-i/
#define DEBUG false //set to true for debug output, false for no debug ouput
#define Serial if(DEBUG)Serial
#include <TimerOne.h> // https://github.com/PaulStoffregen/TimerOne
#include <Wire.h> // built in libray
#include <LiquidCrystal_I2C.h> // built in library
LiquidCrystal_I2C LCD(0x27, 20, 4); // set the LCD address to 0x27
// how to wre LCD https://www.youtube.com/watch?v=ZtwFpFIS1_0
// trigger timer Variables seup here.
volatile long pauseTime = 850000; // time between triggering and flash firing uS
volatile int timeoutFlag = 0; // set to 1 if trigger pushed and timeout not expired
const int led = LED_BUILTIN; // the pin with on-pcb LED Uno pin 13, Nano pin 16
const int triggerPin = 18; // user input to start pause (interrupt 5)
const int flashLed = 23; // output to flashLed, lights when flash fires
const int pauseLed = 22; // output to pauseLed, lights between triggering and firing
const int coarsePausePot = A8; // user input coarse pause pot
const int finePausePot = A9; // user input fine pause pot
const int timeoutPot = A10; // user input time between triggering and re-triggering
long int pause = 620; // user input pot to set pauseTime
long int oldPause = 620; // last reading from user input pot
long int coarsePause = 500; // var to store user input
long int finePause = 120; // var to store user input
int val; // misc variable
int ledState = LOW; // LED status (on or off)
int timeout = 100; // timeout before sytem can trigger again mS
int timeoutOld = 10;
// splash vars
const int solPin = 7; // assign pin 7 to solenoid
const int camPIN = 6; // assign pin 6 to camera
const int dropOnePot = A1; // assign pin A1 to potentiometer 1
const int dropTwoPot = A2; // assign pin A2 to potentiometer 2
const int dropThreePot = A3; // assign pin A3 to potentiometer 3
const int dropDelayOnePot = A4; // assign pin A4 to potentiometer 4
const int dropDelayTwoPot = A5; // assign pin A5 to potentiometer 5
const int startBUTTON = 11; // assign pin 11 to startBUTTON
const int intTriggerSel = 10; // assign pin 10 to trigger select
int solDelayOne; // declare solDelayOne variable
int solDelayTwo; // declare solDelayOne variable
int camDEL; // declare camDEL variable
int dropOne; // declare dropOne variable
int dropTwo; // declare dropTwo variable
int dropThree; // declare dropTwo variable
int dropOneOld; // declare dropOne variable
int dropTwoOld; // declare dropTwo variable
int dropThreeOld; // declare dropTwo variable
int solDelayOneOld; // declare solDelayOne variable
int solDelayTwoOld;
int buttonSTATE = HIGH; // set buttonSTATE variable to HIGH
boolean internalTrigger = true; // select if drop button also starts trigger timer
void setup() { // put your setup code here, to run once: *************************
//trigger timer
pinMode(led, OUTPUT); // set on-pcb LED pin as output
pinMode(triggerPin, INPUT_PULLUP); // user input pin to start pause
pinMode(coarsePausePot, INPUT); // user input pot to set coarse pauseTime
pinMode(finePausePot, INPUT); // user input pot to set fine pauseTime
pinMode(timeoutPot, INPUT); // user input pot min time before next trigger allowed
pinMode(intTriggerSel, INPUT_PULLUP); // user input select how flash is fired when using drop
pinMode(flashLed, OUTPUT); // setup flashLed - lights when flash fires
pinMode(pauseLed, OUTPUT); // setup pauseLed - lights between triggering and flash firing
Timer1.initialize(500000); // setup timer 500000uS
Timer1.stop(); // stop timer as not needed yet
Timer1.attachInterrupt(timer1Expired); // setup interrupt timer1Expired to run for pauseTime uS
attachInterrupt(digitalPinToInterrupt(triggerPin), trigger, FALLING); // setup interrupt
// splash
pinMode(solPin, OUTPUT); // set solPin to output
pinMode(camPIN, OUTPUT); // set camPIN to output
pinMode(dropOnePot, INPUT); // set potentiometer 1 as input
pinMode(dropTwoPot, INPUT); // set potentiometer 2 as input
pinMode(dropThreePot, INPUT); // set potentiometer 3 as input
pinMode(dropDelayOnePot, INPUT); // set potentiometer 4 as input
pinMode(startBUTTON, INPUT_PULLUP); // set startBUTTON as input
Serial.begin(9600); // debug setup output to screen
LCD.init();
LCD.backlight();
LCD.clear(); // clear LCD screen
LCD.setCursor(0, 0); // position cursor on LCD
LCD.print(" TriggerTimer "); // print to LCD
LCD.setCursor(0, 1); // reset the cursor position
LCD.print("FLPa"); // Flash Pause
LCD.setCursor(10, 1); // reset the cursor position
LCD.print("TO"); // TimeOut
LCD.setCursor(0, 2); // reset the cursor position
LCD.print("Drp"); // print the line "Drp" drop
LCD.setCursor(0, 3); // reset the cursor position
LCD.print("Pau"); // print the line "Pau" pause
}
// ISRs go here *************************
// ISR when triggered, sets Timer1 pauseTime
void trigger (void) {
if (timeoutFlag == 0) { // check timeout time has expired before allowing new trigger
Timer1.setPeriod(pauseTime); // activate timer pause counter
digitalWrite(pauseLed, HIGH);
timeoutFlag = 1; // set timeout flag to stop second activation
}
}
// ISR is called at end of Timer1 period.
void timer1Expired(void) {
digitalWrite(pauseLed, LOW); // update state of pasuselength LED
digitalWrite(flashLed, HIGH); // fire flashgun
Timer1.stop(); // stop timer as no longer needed
}
// end of ISRs ***************************************************
void loop() { // put your main code here, to run repeatedly:**********************
// read and format triggertimer user input
coarsePause = analogRead(coarsePausePot); // readuser input from coarse pause pot
finePause = analogRead(finePausePot); // readuser input from coarse pause pot
coarsePause = map(coarsePause, 0 , 1023, 1, 800); // map input to mS
finePause = map(finePause, 0 , 1023, 0, 50); // map input to mS
pause = (coarsePause + finePause); // add coarse & fine delays to give total pause
// triggertimer - Update Pausetime & LCD if user has changed input
if (pause != oldPause) { // if user changed pause, update
noInterrupts(); // turn off interrupts as variable is used in ISR
pauseTime = pause * 1000; // convert to uS and update var used in interrupt
interrupts(); // turn on interrupts
oldPause = pause; // update to check next time round
LCD.setCursor(5, 1); // position LCD cursor
LCD.print(" "); // blank out old reading
LCD.setCursor(5, 1); // position LCD cursor
LCD.print(pause); // print updated pauseTime to LCD
} // end if
// triggertimer - Update timeout & LCD if user has changed input
timeout = analogRead(timeoutPot); // read user input from timeOut pot
timeout = map(timeout, 0 , 1023, 0, 500); // map result
timeout = (timeout * 10); // convert to mS
if (timeout != timeoutOld) { // if user changed timeut, update
timeoutOld = timeout; // update to check next time round
LCD.setCursor(13, 1); // position LCD cursor
LCD.print(" "); // blank out old reading
LCD.setCursor(13, 1); // position LCD cursor
LCD.print(timeout); // print updated pauseTime to LCD
}
// splash Update drop & delay times & LCD if user has changed input
dropOne = analogRead(dropOnePot); // read analogue value from potentiometer 1
dropOne = map(dropOne, 0, 1023, 10, 100); // use map to increase accuracy of pot
if (dropOne != dropOneOld) { // only update LCD if value has changed
dropOneOld = dropOne; // copy var to check for change in if-loop
LCD.setCursor(5, 2); // set cursor position as bottom left
LCD.print(" "); // print 3 spaces to keep LCD clean
LCD.setCursor(5, 2); // reset cursor position
LCD.print(dropOne); // print the calculated time value dropOneval
} // end if
dropTwo = analogRead(dropTwoPot); // read analogue value from potentiometer 2
dropTwo = map(dropTwo, 0, 1023, 9, 100); // use map to increase accuracy of pot
if (dropTwo == 9) dropTwo = 0; // if below 10, set to 0, no second drop
if (dropTwo != dropTwoOld) { // only update LCD if value has changed
dropTwoOld = dropTwo; // copy var to check for change in if-loop
LCD.setCursor(9, 2); // reset cursor position
LCD.print(" "); // print 3 spaces to keep LCD clean
LCD.setCursor(9, 2); // reset cursor position
LCD.print(dropTwo); // print the calculated time value dropTwoval
} // end if
dropThree = analogRead(dropThreePot); // read analogue value from potentiometer 2
dropThree = map(dropThree, 0, 1023, 9, 100); // use map to increase accuracy of pot
if (dropThree == 9) dropThree = 0;
if (dropThree != dropThreeOld) { // only update LCD if value has changed
dropThreeOld = dropThree; // copy var to check for change in if-loop
if (dropThree == 9) dropThree = 0; // if below 10, set to 0, no second drop
LCD.setCursor(13, 2); // reset cursor position
LCD.print(" "); // print 3 spaces to keep LCD clean
LCD.setCursor(13, 2); // reset cursor position
LCD.print(dropThree); // print the calculated time value dropTwoval
} // end if
solDelayOne = analogRead(dropDelayOnePot); // read analogue value from potentiometer 3
solDelayOne = map(solDelayOne, 0, 1023, 20, 200); // use map to increase accuracy of pot
if (solDelayOne != solDelayOneOld) { // only update LCD if value has changed
solDelayOneOld = solDelayOne; // copy var to check for change in if-loop
LCD.setCursor(5, 3); // set cursor position as bottom line, 9 characters from left
LCD.print(" "); // print 3 spaces to keep LCD clean
LCD.setCursor(5, 3); // reset cursor position
LCD.print(solDelayOne); // print the calculated time value dropThreeval
} // end if
solDelayTwo = analogRead(dropDelayTwoPot); // read analogue value from potentiometer 3
solDelayTwo = map(solDelayTwo, 0, 1023, 20, 200); // use map to increase accuracy of pot
if (solDelayTwo != solDelayTwoOld) { // only update LCD if value has changed
solDelayTwoOld = solDelayTwo; // copy var to check for change in if-loop
LCD.setCursor(9, 3); // reset cursor position
LCD.print(" "); // print 3 spaces to keep LCD clean
LCD.setCursor(9, 3); // reset cursor position
LCD.print(solDelayTwo); // print the calculated time value dropThreeval
} // end if
// Test for user input. If drop button pressed, start drop sequence
buttonSTATE = digitalRead(startBUTTON); // test state of start button
if ((buttonSTATE == LOW) && timeoutFlag == 0) { // if pressed, start drop sequence
Timer1.setPeriod(pauseTime); // activate timer pause counter for flash delay
digitalWrite(pauseLed, HIGH);
LCD.setCursor(17, 1);
LCD.blink();
timeoutFlag = 1;
digitalWrite(solPin, HIGH); // set solPin to HIGH - open the solenoid for first drop
delay(dropOne); // delay for time value dropOne - first drop size
digitalWrite(solPin, LOW); // set solPin to LOW - close the solenoid
if (dropTwo != 0) { //test if second drop reqired
delay(solDelayOne); //delay for time value solDelayOneval
digitalWrite(solPin, HIGH); //set solPin to HIGH - open solenoid for second drop
delay(dropTwo); //delay for time value dropTwo - second drop size
digitalWrite(solPin, LOW); //set solPin to LOW - close the solenoid
}
if (dropThree != 0) { //test if third drop reqired
delay(solDelayTwo); //delay for time value solDelayOneval
digitalWrite(solPin, HIGH); //set solPin to HIGH - open solenoid for third drop
delay(dropThree); //delay for time value dropThree - third drop size
digitalWrite(solPin, LOW); //set solPin to LOW - close the solenoid
}
}
val = digitalRead(flashLed); // read flashpause
if (val == HIGH) { // if flash has fired...
Serial.println("Flash has Fired"); // debug
delay(100); // delay before releasing flash contacts
digitalWrite(flashLed, LOW); //.........and open contacts
delay(timeout); //.....timeout delay....
timeoutFlag = 0; //reset timeoutFlag
LCD.setCursor(17, 1);
LCD.noBlink();
}
else { // debug
Serial.println("not fired"); // debug
} // debug
// debug print out variables to screen
if (DEBUG) {
Serial.print("finePause: ");
Serial.println(finePause);
Serial.print("coarsePause: ");
Serial.println(coarsePause);
Serial.print("pause: ");
Serial.println(pause);
Serial.print("pauseTime: "); // debug output to screen
Serial.println(pauseTime); // debug output to screen
Serial.print("timeout: "); // debug output to screen
Serial.println(timeout); // debug output to screen
Serial.println(" ");
delay(500);
}
}
// end of void loop **********************