Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
|
I have been doing photography of all kinds for many years and I like to experiment.
10 years ago I made a speedlight trigger that responded to sound (with classic parts NE556, LM741...).
This year I decided to make a more advanced variant with an Arduino UNO controller. I decided to make the program, the electronics and the box myself.
My goal was that the device does not have any mechanical control (switch, potentiometer...), that it is powered from a regular mobile phone charger or 5V powerbank and that it can work completely independently (no need for a mobile phone or external controller).
The controller has an input that can receive an electret microphone or a photoresistor (for a photo trap).
Detailed description below.
Result and test photo1, 2, 3 output for speedlight or valves in any combination (It is possible to turn them off or on as needed)
4 output for camera control
MIC input for electret mic or photoresistor (5K cca)
LED output for LED for foto trap (5V thru 270 Ohm)
Consruction photoPositive amplitude amplifier
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
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.
#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);
}
// 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") ;
}
}
// ***************************************************************************************
// 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
}
}
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 ;
}
}
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
}
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 ;
}
Comments