gdusan
Published © GPL3+

Speedlight trigger - NEW

Device is a photo flash trigger that responds to sound, beam interruption, it works as a timer and controller for (drop) valves control.

IntermediateFull instructions provided422
Speedlight trigger - NEW

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
2.8 INCH TOUCH SCREEN FOR UNO/MEGA DEVELOPMENT BOARD WPSH412
×1

Software apps and online services

Arduino IDE
Arduino IDE
EasyEDA designer
Tinkercad
Autodesk Tinkercad

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Lower part of the box (with connections)

Lid with screen opening

Schematics

Schema

Preampifier

Preamplifier are made around OPA LM358 that operate as inverting operational amplifier.
The gain of the preamplifier is given by resistor R28, and the best value is from 1M to 1.2 Mohm

Positive amplitude amplifier

The output voltage from the preamp varies from 1.5 to 3.5 V approx., and the positive amplitude only from 2.5 to 3.5 V.
The Arduino analog input accepts a positive voltage of 0 to 5 V at a resolution of 10 bits (1024 levels), so a resolution of positive amplitude (2.5 to 3.5 V) would be only a fifth of the total resolution (205 levels).
The circuit with the PNP transistor (in the real circuit I used BC108b with 240 hfE) amplifies only the negative amplitude and "lowers" inverted amplitude towards zero.
In this way, the useful voltage range expands from 0.4 V to 4.6 V (we have 4.2V differences and a resolution of 860-880 levels).
The gain and distortion of the output is achieved by changing the resistance R22 (in my case 22K) and selecting a transistor with higher or lower gain (in my case 240 hfE).

Port 4 DSLR activation and Arduino port D13 delay

Since I was left with very few free ports due to the touch screen, I had to use port D13 to activate output 4 (DSLR camera activation).
The problem with the D13 port is that when we turn on the Arduino, it sends three pulses that trigger the output 4 port (DSLR).
I tried to solve it with software but I didn't succeed.
Since the IC LM384 is a dual OPA, I used the second OPA as a timer to delay the excitation response from port D13 to output 4.
Capacitor C4 and divider R10-R11 determine the inactivity time of the circuit.

Part list

Code

Main menu code

Arduino
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#include <TouchScreen.h>

#define MINPRESSURE  20
#define MAXPRESSURE  900
#define BLACK       0x0000      /*   0,   0,   0 */
#define NAVY        0x000F      /*   0,   0, 128 */
#define DARKGREEN   0x03E0      /*   0, 128,   0 */
#define DARKCYAN    0x03EF      /*   0, 128, 128 */
#define MAROON      0x7800      /* 128,   0,   0 */
#define PURPLE      0x780F      /* 128,   0, 128 */
#define OLIVE       0x7BE0      /* 128, 128,   0 */
#define LIGHTGREY   0xC618      /* 192, 192, 192 */
#define DARKGREY    0x7BEF      /* 128, 128, 128 */
#define BLUE        0x001F      /*   0,   0, 255 */
#define GREEN       0x07E0      /*   0, 255,   0 */
#define CYAN        0x07FF      /*   0, 255, 255 */
#define RED         0xF800      /* 255,   0,   0 */
#define MAGENTA     0xF81F      /* 255,   0, 255 */
#define YELLOW      0xFFE0      /* 255, 255,   0 */
#define WHITE       0xFFFF      /* 255, 255, 255 */
#define ORANGE      0xFD20      /* 255, 165,   0 */
#define GREENYELLOW 0xAFE5      /* 173, 255,  47 */
#define PINK        0xF81F

// ALL Touch panels and wiring is DIFFERENT
// copy-paste results from TouchScreen_Calibr_native.ino
// PORTRAIT  CALIBRATION     240 x 320
//x = map(p.x, LEFT=916, RT=134, 0, 240)
//y = map(p.y, TOP=90, BOT=912, 0, 320)
//LANDSCAPE CALIBRATION     320 x 240
//x = map(p.y, LEFT=90, RT=912, 0, 320)
//y = map(p.x, TOP=134, BOT=916, 0, 240)

const int XP = 8, XM = A2, YP = A3, YM = 9; //240x320 ID=0x9341
const int TS_LEFT = 916, TS_RT = 134, TS_TOP = 90, TS_BOT = 912;

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_GFX_Button ok, nok , cancel, btn1, btn2, btn3,
                    n1, n2, n3, n4, n5, n6, n7, n8, n9, n0, nclear , nback ;


// **************************************************************************
// global varijables for trigger
// **************************************************************************
int  pixel_x, pixel_y;     //Touch_getXY()updates global vars
int  tmrSelect = 0 , input_a = 0 ,
     pot_h = 300 ,  slider_y = 200 , main_color = CYAN ;
long delay_ms , add_ms  , no_of_shots  , unarm_after ,
     valve1 , valve2, numfield = 0;
bool updatefield = false , trigger_armed = false , trig_d1 , trig_d2, trig_d3 ;
char* unit = "ms" ;
//uint16_t main_color = CYAN ;

#define pot_k  3.27 // 980 (cca 4.8V) analog steps / 300 slider height
#define out_trig_imp  1200 // vidth of exit pulse in microsecond
void setup()
{
  //  Serial.begin(9600);
  pinMode(1, OUTPUT)     ;
  pinMode(10, OUTPUT) ;
  pinMode(11, OUTPUT) ;
  pinMode(12, OUTPUT) ;
  pinMode(13, OUTPUT) ;
  uint16_t ID = tft.readID();
  tft.begin(ID);
  tft.setRotation(0); //PORTRAIT
  redrav_main();
}

//  ***************************************************************************************
void loop()
{
  bool down = Touch_getXY();
  btn1.press(down && btn1.contains(pixel_x, pixel_y));
  btn2.press(down && btn2.contains(pixel_x, pixel_y));
  btn3.press(down && btn3.contains(pixel_x, pixel_y));
  if (btn1.justPressed()) {
    btn1.drawButton(true);
    tmrSelect = 1;
    main_color = CYAN ;
    delay_ms = 220 , add_ms = 0 , no_of_shots = 1, unarm_after = 1 ;
    trig_d1 = true , trig_d2 = false , trig_d3 = false ;
    setup_trigger();
    loop_trigger();
    redrav_main();
  }
  if (btn2.justPressed()) {
    btn2.drawButton(true);
    tmrSelect = 2;
    main_color = ORANGE ;
    delay_ms = 2000 , add_ms = 1000 , no_of_shots = 5 , unarm_after = 1 ;
    trig_d1 = true , trig_d2 = false , trig_d3 = false ;
    setup_trigger();
    loop_trigger();
    redrav_main();
  }
  if (btn3.justPressed()) {
    btn3.drawButton(true);
    tmrSelect = 3 ;
    main_color = GREEN ;
    delay_ms = 2000 , add_ms = 100 , no_of_shots = 100,  unarm_after = 1 ,
    valve1 = 25 , valve2 = 25 ;
    trig_d1 = true , trig_d2 = true , trig_d3 = false ;
    setup_trigger();
    loop_trigger();
    redrav_main();
  }
}

//  ***************************************************************************************
//  subrutine - function

void redrav_main()
{
  tft.fillScreen(BLACK);
  btn1.initButton(&tft,  120, 170, 140, 40, CYAN, CYAN, BLACK, "TRIGGER", 2);
  btn2.initButton(&tft, 120, 230, 140, 40, ORANGE, ORANGE, BLACK, "TIMER", 2);
  btn3.initButton(&tft, 120, 290, 140, 40, GREEN, GREEN, BLACK, "DROP", 2);
  btn1.drawButton(false);
  btn2.drawButton(false);
  btn3.drawButton(false);
  showText(77, 10, 3, WHITE, BLACK, "Photo") ;
  showText(62, 40, 3, WHITE, BLACK, "trigger") ;
  showText(32, 80, 2, DARKCYAN, BLACK, "v:2.0  2010-21.") ;
  showText(52, 105, 2, DARKCYAN, BLACK, "Dusan Grbac") ;
}

bool Touch_getXY()
{
  TSPoint p = ts.getPoint();
  pinMode(YP, OUTPUT);      //restore shared pins
  pinMode(XM, OUTPUT);
  digitalWrite(YP, HIGH);   //because TFT control pins
  digitalWrite(XM, HIGH);
  bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
  if (pressed) {
    pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
    pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
  }
  return pressed;
}


void showText(int x, int y, int sz , uint16_t color, uint16_t colorb , String msg)
{
  tft.setCursor(x, y);
  tft.setTextColor(color, colorb);
  tft.setTextSize(sz);
  tft.print(msg);
}

Trigger.ino

Arduino
// Main screen for time setting, number of shots and output selection

void setup_trigger()
{
  tft.fillScreen(BLACK);
  char* title = "" ;
  int hline = 52 , yline = 10 ;
  switch (tmrSelect) {
    case 1 :
      title = "Trigger" ;
      showText(5, yline , 1, DARKGREY, BLACK,             "delay after TRIGGER (ms)") ;
      showText(5, yline + hline , 1, DARKGREY, BLACK,     "number of shots in one cycle (no)") ;
      showText(5, yline + hline * 2 , 1, DARKGREY, BLACK, "add after each cycle or shot (ms)") ;
      showText(5, yline + hline * 3 , 1, DARKGREY, BLACK, "unarm after X cycles - camera off (no)") ;
      break;
    case 2 :
      title = " Timer" ;
      showText(5, yline , 1, DARKGREY, BLACK,             "delay after ACTIVATE cycle (ms)") ;
      showText(5, yline + hline , 1, DARKGREY, BLACK,     "number of shots in one cycle (no)") ;
      showText(5, yline + hline * 2 , 1, DARKGREY, BLACK, "delay between shots (ms)") ;
      showText(5, yline + hline * 3 , 1, DARKGREY, BLACK, "repeat timer cycle (no)") ;
      break;
    case 3 :
      title = " Drop" ;
      showText(5, yline , 1, DARKGREY, BLACK,             "delay to activate Out1(ms) - valve 1") ;
      showText(5, yline + hline , 1, DARKGREY, BLACK,     "delay to activate Out2(ms) - valve 2") ;
      showText(5, yline + hline * 2 , 1, DARKGREY, BLACK, "delay to activate Out3(ms) - flash") ;
      showText(5, yline + hline * 3 , 1, DARKGREY, BLACK, "puls(ms)    valve 1   -    valve 2") ;
      break;
  }
  // ---- buttons
  tft.drawRect(15, 228, 55, 36,  DARKGREY); // output button 1
  tft.drawRect(95, 228, 55, 36,  DARKGREY); // output button 2
  tft.drawRect(175, 228, 55, 36,  DARKGREY); // output button 3

  tft.drawRect(15, 280, 60, 36,  DARKGREY); // cancel button
  showText(30, 290 , 2, WHITE, BLACK, "<-") ;
  tft.fillRect(100, 280, 130, 36,  main_color); // trigger button
  showText(125, 290 , 2, BLACK , main_color, String(title)) ;
  output_button() ;
  pixel_x = 1, pixel_y = 1 ;
}

//  ***************************************************************************************
// main loop for number enter and activate sound,light triger, timer and drop timer
//  ***************************************************************************************
void loop_trigger()
{
  while (true)
  {
    // ----- variables
    int hline = 52 , yline = 30;
    showText(30, yline , 3 , main_color, BLACK , String(delay_ms)) ;
    showText(30, yline + hline , 3 , main_color, BLACK, String(no_of_shots)) ;
    showText(30, yline + hline * 2 , 3 , main_color, BLACK, String(add_ms)) ;
    if (tmrSelect == 3) {
      showText(80, yline + hline * 3 , 3 , main_color, BLACK, String(valve1)) ;
      showText(170, yline + hline * 3 , 3 , main_color, BLACK, String(valve2)) ;
    } else {
      showText(30, yline + hline * 3 , 3 , main_color, BLACK, String(unarm_after)) ;
    }
    if (Touch_getXY()) {
      // triger button detection
      if (pixel_x > 100 && pixel_x < 230 && pixel_y > 280 && pixel_y < 320) {
        switch (tmrSelect) {
          case 1 :
            setup_trigger_active();
            loop_triger_active();
            break;
          case 2 :
            setup_timer_active();
            loop_timer_active();
            break;
          case 3 :
            setup_drop_timer_active();
            loop_drop_timer_active();
            break;
        }
        setup_trigger();
      }
      if (pixel_x > 15 && pixel_x < 75 && pixel_y > 280 && pixel_y < 315) break ;
      touch_detect() ;
      delay(20);
    }
  }
  pixel_x = 1, pixel_y = 1 ;
}


//  ***************************************************************************************
//  function for screen touch detection
//  ***************************************************************************************
void touch_detect() {
  int hline = 52 , yline = 30;
  // 1. line detection
  if (pixel_x > 30 && pixel_x < 200 && pixel_y > yline - 20 && pixel_y < yline + 20) {
    unit = "ms";
    numfield = delay_ms;
    setup_num();
    loop_num();
    if (updatefield) delay_ms = numfield ;
    setup_trigger();
  }
  // 2. line detection
  if (pixel_x > 30 && pixel_x < 200 && pixel_y > yline + hline - 20 && pixel_y < yline + hline + 20) {
    unit = "no";
    numfield = no_of_shots;
    setup_num();
    loop_num();
    if (updatefield) no_of_shots = numfield ;
    setup_trigger();
  }
  // 3. line detection
  if (pixel_x > 30 && pixel_x < 200 && pixel_y > yline + (hline * 2) - 20 && pixel_y < yline + (hline * 2) + 20) {
    unit = "ms";
    numfield = add_ms;
    setup_num();
    loop_num();
    if (updatefield) add_ms = numfield ;
    setup_trigger();
  }
  // 4. line detection
  if (tmrSelect == 3) {
    if (pixel_x > 30 && pixel_x < 120 && pixel_y > yline + (hline * 3) - 20 && pixel_y < yline + (hline * 3) + 20) {
      unit = "ms";
      numfield = valve1;
      setup_num();
      loop_num();
      if (updatefield) valve1 = numfield ;
      setup_trigger();
    }
    if (pixel_x > 150 && pixel_x < 210 && pixel_y > yline + (hline * 3) - 20 && pixel_y < yline + (hline * 3) + 20) {
      unit = "ms";
      numfield = valve2;
      setup_num();
      loop_num();
      if (updatefield) valve2 = numfield ;
      setup_trigger();
    }
  } else {
    if (pixel_x > 30 && pixel_x < 200 && pixel_y > yline + (hline * 3) - 20 && pixel_y < yline + (hline * 3) + 20) {
      unit = "no";
      numfield = unarm_after;
      setup_num();
      loop_num();
      if (updatefield) unarm_after = numfield ;
      setup_trigger();
    }
  }
  if (pixel_x > 15 && pixel_x < 70 && pixel_y > 228 && pixel_y < 266) {
    trig_d1 = !trig_d1 ;
    if (tmrSelect == 3 && trig_d1 ) trig_d3 = false ;
    output_button() ;
  }
  if (pixel_x > 95 && pixel_x < 150 && pixel_y > 228 && pixel_y < 266) {
    trig_d2 = !trig_d2 ;
    if (tmrSelect == 3 && trig_d2 ) trig_d3 = false ;
    output_button() ;
  }
  if (pixel_x > 175 && pixel_x < 230 && pixel_y > 228 && pixel_y < 266) {
    trig_d3 = !trig_d3 ;
    if (tmrSelect == 3 && trig_d3 ) trig_d1 = false, trig_d2 = false ;
    output_button() ;
  }
}
//  ***************************************************************************************
//  function for output button driving
//  ***************************************************************************************
void output_button() {
  if (!trig_d1) {
    tft.fillRect(16, 229 , 53, 34, BLACK);
    showText(39, 240 , 2, DARKGREY, BLACK, "1") ;
  } else {
    tft.fillRect(16, 229 , 53, 34, main_color);
    showText(39, 240 , 2, BLACK, BLACK, "1") ;
  }
  if (!trig_d2) {
    tft.fillRect(96, 229, 53, 34,  BLACK);
    showText(118, 240 , 2, DARKGREY, BLACK, "2") ;
  } else {
    tft.fillRect(96, 229, 53, 34,  main_color);
    showText(118, 240 , 2, BLACK, BLACK, "2") ;
  }
  if (!trig_d3) {
    tft.fillRect(176, 229, 53, 34,  BLACK);
    if (tmrSelect == 3) {
      showText(185, 240 , 2, DARKGREY, BLACK, "1+2") ;
    } else {
      showText(198, 240 , 2, DARKGREY, BLACK, "3") ;
    }
  } else {
    tft.fillRect(176, 229, 53, 34,  main_color);
    if (tmrSelect == 3) {
      showText(185, 240 , 2, BLACK, BLACK, "1+2") ;
    } else {
      showText(198, 240 , 2, BLACK, BLACK, "3") ;
    }
  }
  delay(200);
}


//  ***************************************************************************************
//  function for port driving
//  ***************************************************************************************
void trigger_portdrive() {
  if (trig_d1 ) digitalWrite(10, HIGH);
  if (trig_d2 ) digitalWrite(11, HIGH);
  if (trig_d3 ) digitalWrite(12, HIGH);
  delayMicroseconds(out_trig_imp);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
}

//  ***************************************************************************************
//  function for button redrive (button test and arm)
//  ***************************************************************************************
void trigger_apparence(int xplus , int  wplus)
{
  if (trigger_armed) {
    tft.fillRect(11 + xplus, 21, 148 + wplus, 88,  RED);
    showText(52 + wplus, 60 , 2, BLACK, BLACK,  "ACTIVE") ;
    tft.fillRect(11 + xplus, 141, 148 + wplus, 88,  BLACK);
    if (tmrSelect != 3) {
      showText(20 + wplus, 155 , 1, GREEN, BLACK, "cycle :") ;
      showText(20 + wplus, 180 , 1, GREEN, BLACK, "shot  :") ;
      showText(20 + wplus, 207 , 1, GREEN, BLACK, "delay :") ;
    }
  } else {
    tft.fillRect(11 + xplus, 21, 148 + wplus, 88,  BLACK);
    showText(41 + wplus, 60 , 2, WHITE, BLACK, "ACTIVATE") ;
    tft.fillRect(11 + xplus, 141, 148 + wplus, 88,  BLACK);
    showText(66 + wplus, 180 , 2, WHITE, BLACK, "TEST") ;
  }
}

Trigger_active.ino

Arduino
//  ***************************************************************************************
// sound and light trigger
//  ***************************************************************************************
void setup_trigger_active()
{
  tft.fillScreen(BLACK);
  trigger_armed = false ;
  tft.drawRect(10, 20, 150, 90,  RED); // activate button
  tft.drawRect(10, 140, 150, 90,  GREEN); // test button
  tft.drawRect(10, 255, 50, 50,  DARKGREY); // cancel button
  tft.drawRect(210, 10, 20, pot_h ,  DARKGREY); // sound-light meter bar
  tft.fillRect(177, pot_h - slider_y + 5, 30, 20, GREEN);
  showText(23, 273 , 2, WHITE, BLACK, "<-") ;
  showText(70, 261 , 1, GREEN, BLACK,  "max <=300");
  showText(70, 288 , 1, GREEN, BLACK,  "threshold")  ;
  trigger_apparence(0, 0);
  pixel_x = 1, pixel_y = 1 ;
}

//  ***************************************************************************************
void loop_triger_active()
{
  int input_lt = 0 ; // input latency
  int input_max = 0 ; // remeber max imput in one ciklus
  while (true)
  {
    if (Touch_getXY()) {
      // ARM area detection
      if (pixel_x > 10 && pixel_x < 150 && pixel_y > 20 && pixel_y < 110 ) {
        trigger_armed = true ;
        trigger_apparence(0, 0) ;
      }
      // TEST output area detection (only if not armed)
      if (pixel_x > 10 && pixel_x < 150 && pixel_y > 140 && pixel_y < 230 ) {
        tft.fillRect(11, 141, 148, 88,  GREEN);
        digitalWrite(1, HIGH);
        trigger_portdrive() ;
        delay(100) ;
        digitalWrite(1, LOW);
        trigger_apparence(0, 0) ;
      }
      // SLIDER MOVE area detection (only if not armed)
      if (pixel_x > 170 && pixel_x < 240 && pixel_y > 10 && pixel_y < pot_h) {
        tft.fillRect(177, pot_h - slider_y + 5, 30, 20, BLACK);
        slider_y = pot_h - (pixel_y - 10) ;
        tft.fillRect(177, pot_h - slider_y + 5, 30, 20, GREEN);
      }
      // cancel area detection
      if (pixel_x > 10 && pixel_x < 110 && pixel_y > 255 && pixel_y < 305 ) break ;
    } else {
      if (trigger_armed ) {
        trigger_apparence(0, 0) ;
        //***************************************************
        trigger_active_run(); // activate triger wait
        //***************************************************
        trigger_armed = false ;
        trigger_apparence(0, 0) ;
        delay(300) ;
      }
      input_a = analogRead(A5) ;
      input_a = min(input_a / pot_k, 300) ;
      input_max = max(input_max, input_a) ;
      input_lt = input_lt + 1 ;
      if  (input_lt > 130) {
        int border = 11 + min(pot_h - input_max , 298);
        tft.fillRect(211, border , 18, pot_h - border + 11, GREEN);
        tft.fillRect(211, 11 , 18, border - 10 , BLACK);
        tft.fillRect(137, 255, 36, 50,  BLACK);
        showText(137, 258 , 2, WHITE, BLACK,  String(input_max)) ;
        showText(137, 285 , 2, WHITE, BLACK,  String(slider_y)) ;
        if (input_max >= slider_y ) {
          tft.fillRect(177, pot_h - slider_y + 5, 30, 20, RED);
          digitalWrite(1, HIGH) ;
          input_lt = input_lt * -1.5;
        } else {
          tft.fillRect(177, pot_h - slider_y + 5, 30, 20, GREEN);
          digitalWrite(1, LOW) ;
          input_lt = 0 ;
        }
         delay(10);
        input_max = 0 ;
      }
    }
  }
  pixel_x = 1, pixel_y = 1 ;
}


//  ***************************************************************************************
void trigger_active_run()
{
  long sum_delay = delay_ms ;
  for (int i = 1 ; i <= unarm_after; i++) { // no of ciclus
    showText(70 , 150 , 2, WHITE, BLACK, String(i)) ;
    digitalWrite(13, HIGH) ; // DSLR ON out 4 ;
    delay(400) ; // delay for DSLR on port4 to stop vibrating
    for (int is = 1 ; is <= no_of_shots ; is++) {
      showText(70 , 177 , 2, WHITE, BLACK, String(is)) ;
      tft.fillRect(65, 202, 90, 20,  BLACK);
      showText(70 , 204 , 2, WHITE, BLACK, String(sum_delay)) ;
      // main trigger loop
      //**********************************************
      delay(10) ; // important delay for input A5 port to work !!
      do {
        input_a = analogRead(A5) ;
        input_a = input_a / pot_k ;
      } while (input_a < slider_y ) ;
      //**********************************************
      digitalWrite(1, HIGH) ;
      delay(sum_delay) ;
      trigger_portdrive() ;
      sum_delay = sum_delay + add_ms ;
    }
 // delay(10) ; // delay from shot to shot
    digitalWrite(1, LOW) ;
    digitalWrite(13, LOW) ; // OFF DSLR on out 4 ;
    if (unarm_after > 1) delay(800) ; // general delay from shot to shot for DSLR por4 for multiple cycles
  }
}

Timer_active.ino

Arduino
void setup_timer_active()
{
  tft.fillScreen(BLACK);
  trigger_armed = false ;
  tft.drawRect(30, 20, 180, 90,  RED);
  tft.drawRect(30, 140, 180, 90,  GREEN);
  tft.drawRect(80, 255, 80, 50,  DARKGREY);
  showText(107, 273 , 2, WHITE, BLACK, "<-") ;
  trigger_apparence(20, 30);
  pixel_x = 1, pixel_y = 1 ;
}

//  ***************************************************************************************
void loop_timer_active()
{
  while (true)
  {
    if (Touch_getXY()) {
      // arm area detection
      if (pixel_x > 30 && pixel_x < 210 && pixel_y > 20 && pixel_y < 110 && !trigger_armed) {
        trigger_armed = true ;
      }
      // delayed and test area detection (only if not armed)
      if (pixel_x > 30 && pixel_x < 210 && pixel_y > 140 && pixel_y < 230 && !trigger_armed ) {
        tft.fillRect(31, 141, 178, 88,  GREEN);
        digitalWrite(1, HIGH);
        trigger_portdrive() ;
        delay(100) ;
        digitalWrite(1, LOW);
        trigger_apparence(20, 30);
      }
      // cancel area detection
      if (pixel_x > 70 && pixel_x < 170 && pixel_y > 255 && pixel_y < 305 ) break;
    }
    if (trigger_armed) {
      trigger_apparence(20, 30);
      timer_run();
      trigger_armed = false ;
      trigger_apparence(20, 30);
      delay(300) ;
    }
  }
  pixel_x = 1, pixel_y = 1 ;
}


//  ***************************************************************************************
void timer_run()
{
  for (int i = 1 ; i <= unarm_after; i++) {
    showText(100 , 150 , 2, WHITE, BLACK, String(i)) ;
    showText(100 , 204 , 2, WHITE, BLACK, String(delay_ms)) ;
    delay(delay_ms);
    digitalWrite(13, HIGH) ; // triger DSLR on out 4 ;
    tft.fillRect(100, 202, 100, 20,  BLACK);
    showText(98 , 204 , 2, WHITE, BLACK, String(add_ms)) ;
    for (int is = 1 ; is <= no_of_shots; is++) {
      digitalWrite(1, HIGH) ;
      trigger_portdrive() ;
      showText(98 , 177 , 2, WHITE, BLACK, String(is)) ;
      digitalWrite(1, LOW) ;
      delay(add_ms);
      // cancel detection
      if (Touch_getXY()) {
        is = no_of_shots;
        i  = unarm_after;
      }
    }
    //    digitalWrite(1, LOW) ;
    digitalWrite(13, LOW) ; // OFF DSLR on out 4 ;
  }
}

Drop_timer.ino

Arduino
void setup_drop_timer_active()
{
  tft.fillScreen(BLACK);
  trigger_armed = false ;
  tft.drawRect(30, 20, 180, 90,  RED);
  tft.drawRect(30, 140, 180, 90,  GREEN);
  tft.drawRect(80, 255, 80, 50,  DARKGREY);
  showText(107, 273 , 2, WHITE, BLACK, "<-") ;
  trigger_apparence(20, 30);
  pixel_x = 1, pixel_y = 1 ;
}

//  ***************************************************************************************
void loop_drop_timer_active()
{
  while (true)
  {
    if (Touch_getXY()) {
      // arm area detection
      if (pixel_x > 30 && pixel_x < 210 && pixel_y > 20 && pixel_y < 110 && !trigger_armed) {
        trigger_armed = true ;
      }
      // delayed and test area detection (only if not armed)
      if (pixel_x > 30 && pixel_x < 210 && pixel_y > 140 && pixel_y < 230 && !trigger_armed ) {
        tft.fillRect(31, 141, 178, 88,  GREEN);
        digitalWrite(1, HIGH);
        trigger_portdrive() ;
        delay(100) ;
        digitalWrite(1, LOW);
        trigger_apparence(20, 30);
      }
      // cancel area detection
      if (pixel_x > 70 && pixel_x < 170 && pixel_y > 255 && pixel_y < 305 ) break;
    }
    if (trigger_armed) {
      trigger_apparence(20, 30);
      drop_timer_run();
      trigger_armed = false ;
      trigger_apparence(20, 30);
      delay(300) ;
    }
  }
  pixel_x = 1, pixel_y = 1 ;
}

//  ***************************************************************************************
void drop_timer_run()
{
  digitalWrite(13, HIGH) ; // triger DSLR on out 4 ;
  delay(delay_ms);
  digitalWrite(1, HIGH) ;
  if (trig_d3) { // valve 1 and valve 2 (out1 and out2) fire simultaneous
    digitalWrite(10, HIGH) ;
    digitalWrite(11, HIGH);
    delay(valve1) ;
    digitalWrite(10, LOW) ;
    digitalWrite(11, LOW);
    delay(no_of_shots);
    digitalWrite(10, HIGH) ;
    digitalWrite(11, HIGH);
    delay(valve2) ;
    digitalWrite(10, LOW) ;
    digitalWrite(11, LOW) ;
  } else {
    if (trig_d1) {
      digitalWrite(10, HIGH) ;
      delay(valve1) ;
      digitalWrite(10, LOW) ;
    }
    delay(no_of_shots);
    if (trig_d2) {
      digitalWrite(11, HIGH);
      delay(valve2) ;
      digitalWrite(11, LOW);
    }
  }
  delay(add_ms);
  digitalWrite(12, HIGH);
  delayMicroseconds(out_trig_imp) ;
  digitalWrite(12, LOW);
  digitalWrite(1, LOW) ;
  digitalWrite(13, LOW) ; // OFF DSLR on out 4
}

Num_enter.ino

Arduino
void setup_num()
{
  updatefield = false;
  tft.fillScreen(BLACK);
  int xb = 42, yb = 110, hbspa = 78, vbspa = 47, wb = 60, hb = 36 ;
  nclear.initButton(&tft, xb , yb, wb, hb, DARKGREY, BLACK, RED, "C", 2);
  nback.initButton(&tft, xb + hbspa * 2, yb, wb, hb, DARKGREY, BLACK, ORANGE, "<", 2);
  n1.initButton(&tft, xb, yb + vbspa, wb, hb, CYAN, CYAN, BLACK, "1", 3);
  n2.initButton(&tft, xb + hbspa, yb + vbspa, wb, hb, CYAN, CYAN, BLACK, "2", 3);
  n3.initButton(&tft, xb + hbspa * 2, yb + vbspa, wb, hb, CYAN, CYAN, BLACK, "3", 3);
  n4.initButton(&tft, xb, yb + vbspa * 2, wb, hb, CYAN, CYAN, BLACK, "4", 3);
  n5.initButton(&tft, xb + hbspa, yb + vbspa * 2, wb, hb, CYAN, CYAN, BLACK, "5", 3);
  n6.initButton(&tft, xb + hbspa * 2, yb + vbspa * 2, wb, hb, CYAN, CYAN, BLACK, "6", 3);
  n7.initButton(&tft, xb, yb + vbspa * 3, wb, hb, CYAN, CYAN, BLACK, "7", 3);
  n8.initButton(&tft, xb + hbspa, yb + vbspa * 3, wb, hb, CYAN, CYAN, BLACK, "8", 3);
  n9.initButton(&tft, xb + hbspa * 2, yb + vbspa * 3, wb, hb, CYAN, CYAN, BLACK, "9", 3);
  n0.initButton(&tft, xb + hbspa, yb + vbspa * 4, wb, hb, CYAN, CYAN, BLACK, "0", 3);
  nok.initButton(&tft, xb  , yb + vbspa * 4, wb, hb, DARKGREY, BLACK, WHITE, "<-", 2);
  ok.initButton(&tft, xb + hbspa * 2, yb + vbspa * 4, wb, hb, DARKGREY, BLACK, GREEN, "ok", 2);
  n1.drawButton(false);
  n2.drawButton(false);
  n3.drawButton(false);
  n4.drawButton(false);
  n5.drawButton(false);
  n6.drawButton(false);
  n7.drawButton(false);
  n8.drawButton(false);
  n9.drawButton(false);
  n0.drawButton(false);
  nclear.drawButton(false);
  nback.drawButton(false);
  nok.drawButton(false);
  ok.drawButton(false);
  tft.drawRect(10, 10, 220, 70, DARKGREY);
  pixel_x = 1, pixel_y = 1 ;
}

//  ***************************************************************************************

void loop_num()
{
  while (true)
  {
    bool down = Touch_getXY();
    nback.press(down && nback.contains(pixel_x, pixel_y));
    nclear.press(down && nclear.contains(pixel_x, pixel_y));
    n1.press(down && n1.contains(pixel_x, pixel_y));
    n2.press(down && n2.contains(pixel_x, pixel_y));
    n3.press(down && n3.contains(pixel_x, pixel_y));
    n4.press(down && n4.contains(pixel_x, pixel_y));
    n5.press(down && n5.contains(pixel_x, pixel_y));
    n6.press(down && n6.contains(pixel_x, pixel_y));
    n7.press(down && n7.contains(pixel_x, pixel_y));
    n8.press(down && n8.contains(pixel_x, pixel_y));
    n9.press(down && n9.contains(pixel_x, pixel_y));
    n0.press(down && n0.contains(pixel_x, pixel_y));
    ok.press(down && ok.contains(pixel_x, pixel_y));
    nok.press(down && nok.contains(pixel_x, pixel_y));
    if (n1.justPressed()) {
      numfield = (numfield * 10) + 1; //Pressed again
      delay(150);
    }
    if (n2.justPressed()) {
      numfield = (numfield * 10) + 2; //Pressed again
      delay(150);
    }
    if (n3.justPressed()) {
      numfield = (numfield * 10) + 3; //Pressed again
      delay(150);
    }
    if (n4.justPressed()) {
      numfield = (numfield * 10) + 4; //Pressed again
      delay(150);
    }
    if (n5.justPressed()) {
      numfield = (numfield * 10) + 5; //Pressed again
      delay(150);
    }
    if (n6.justPressed()) {
      numfield = (numfield * 10) + 6; //Pressed again
      delay(150);
    }
    if (n7.justPressed()) {
      numfield = (numfield * 10) + 7; //Pressed again
      delay(150);
    }
    if (n8.justPressed()) {
      numfield = (numfield * 10) + 8; //Pressed again
      delay(150);
    }
    if (n9.justPressed()) {
      numfield = (numfield * 10) + 9; //Pressed again
      delay(150);
    }
    if (n0.justPressed()) {
      if (numfield > 0) {
        numfield = (numfield * 10); //Pressed again
      }
      delay(150);
    }
    if (nback.justPressed()) {
      tft.fillRect(12, 12, 216, 66,  BLACK);
      unsigned lastd = numfield % 10;
      numfield = (numfield - lastd) / 10;
      delay(150);
    }
    if (nclear.justPressed()) {
      tft.fillRect(12, 12, 216, 66,  BLACK);
      numfield = 0 ;
      delay(150);
    }
    if (nok.justPressed()) {
      updatefield = false;
      break ;
    }
    if (ok.justPressed()) {
      updatefield = true;
      break ;
    }
    showText(190, 15, 2, DARKGREY, BLACK, unit) ;
    showText(30, 40, 4, WHITE, BLACK, String(numfield)) ;
  }
  pixel_x = 1, pixel_y = 1 ;
}

Credits

gdusan

gdusan

0 projects • 0 followers

Comments