I wanted to give a final, (pretty much), post to this little project. Thanks so much for those who helped me alot with finding things I didn't. Once I got the code working and verifying it triggers my D3400, I put it on a breadboard (PCB), soldered it all up and then designed an enclosure for it and 3d printed it.
Here is the code. I might pretty it up some later but since this is only for me, it works.
#define CLK_PIN 2
#define DT_PIN 3
#define SW_PIN 4
#include <LiquidCrystal_I2C.h>
#include <avr/wdt.h>
#include <Encoder.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
Encoder myEnc(3, 2);
int counter = 0;
int btnPressedCount = 0;
int shutterDuration = 0;
int shutterDelay = 0;
int shotCount = 0;
int btnState = 1;
int ledPin = 13;
bool confirmFlag = false;
bool shotsTakenFlag = false;
bool transmitIR = false;
bool liveShotsTakenFlag = false;
void setup() {
// Start serial communication
Serial.begin(9600);
lcd.init(); //inits the display
lcd.backlight(); //turns on the backlight
pinMode(SW_PIN, INPUT_PULLUP);
//display instructions for use
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Rotate to set ");
lcd.setCursor(0,1);
lcd.print("Shutter time ");
delay(3000);
lcd.setCursor(0,0);
lcd.print("Then press in ");
lcd.setCursor(0,1);
lcd.print("to accept ");
delay(3000);
lcd.setCursor(0,0);
lcd.print("Rotate to set ");
lcd.setCursor(0,1);
lcd.print("Shutter delay ");
delay(3000);
lcd.setCursor(0,0);
lcd.print("Then press in ");
lcd.setCursor(0,1);
lcd.print("to accept ");
delay(3000);
lcd.setCursor(0,0);
lcd.print("Rotate to set ");
lcd.setCursor(0,1);
lcd.print("Shot count ");
delay(3000);
lcd.setCursor(0,0);
lcd.print("Then press in ");
lcd.setCursor(0,1);
lcd.print("to accept ");
delay(3000);
lcd.setCursor(0,0);
lcd.print("Press in then to ");
lcd.setCursor(0,1);
lcd.print("confirm ");
delay(3000);
lcd.clear();
}
long oldPosition = -999;
void loop() {
// Read the encoder, assign to newPoistion variable
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition/4);
lcd.setCursor(0,0);
lcd.print(newPosition/4);
}
if (!digitalRead(SW_PIN)) { // Down Button
while (!digitalRead(SW_PIN)); // De-bounce
btnPressedCount = btnPressedCount + 1;
switch (btnPressedCount){
case 1:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Shutter duration");
lcd.setCursor(0,1);
lcd.print(newPosition/4);
lcd.setCursor(3,1);
lcd.print(" - delay next ");
shutterDuration = (newPosition/4);
Serial.println("duration set");
Serial.println(shutterDuration);
Serial.println("");
delay(3000);
lcd.clear();
break;
case 2:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Shutter delay ");
lcd.setCursor(0,1);
lcd.print(newPosition/4);
lcd.setCursor(3,1);
lcd.print(" - shots next ");
shutterDelay = (newPosition/4);
Serial.println("delay set");
Serial.println(shutterDelay);
Serial.println("");
delay(3000);
lcd.clear();
break;
case 3:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Shots count ");
lcd.setCursor(0,1);
lcd.print(newPosition/4);
lcd.setCursor(3,1);
lcd.print(" - confirm nxt ");
shotCount = (newPosition/4);
Serial.println("# shots set");
Serial.println(shotCount);
Serial.println("");
delay(3000);
lcd.clear();
break;
case 4:
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Confirming..");
lcd.setCursor(0,1);
lcd.print(shutterDuration);
lcd.setCursor(3,1);
lcd.print("DR ");
lcd.setCursor(6,1);
lcd.print(shutterDelay);
lcd.setCursor(8,1);
lcd.print("DL");
lcd.setCursor(11,1);
lcd.print(shotCount);
lcd.setCursor(15,1);
lcd.print("S");
confirmFlag = true;
Serial.println("confirmation set");
delay(5000);
break;
case 5:
if (shotsTakenFlag == true){
lcd.setCursor(0,0);
lcd.print("Series completed");
lcd.setCursor(0,1);
lcd.print("Rebooting ");
delay(5000);
Serial.println("Shots series done");
initiateHardwareReset();
}
break;
}
//if confirm flag set then start the count down timer
if (confirmFlag == true){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Ready to start");
lcd.setCursor(0,1);
lcd.print("in 10 seconds");
Serial.println("Starting shots");
for (int i = 10; i > 0; i--){
lcd.setCursor(0,1);
lcd.print("in seconds");
lcd.setCursor(3,1);
if (i < 10){
lcd.setCursor(3,1);
lcd.print(" ");
}
lcd.print(i);
delay(1000);
}
transmitIR = true;
}
//if transmitIR flag set then start IR transmission by shout count
if (transmitIR == true){
lcd.setCursor(0,0);
lcd.print(" Live Shots ");
lcd.setCursor(0,1);
lcd.print(" ");
Serial.println("taking live shots");
delay(2000);
lcd.setCursor(0,1);
lcd.print("shots left ");
for (int i = -1; i < shotCount; i++){
lcd.setCursor(11,1);
if ((shotCount - i) < 10){
lcd.setCursor(11,1);
lcd.print(" ");
}
lcd.print(shotCount - (i + 1));
ML3();
delay((shutterDuration * 1000) + (shutterDelay * 1000));
}
liveShotsTakenFlag = true;
}
//if liveShotTaken flag set then start Dark shots
if (liveShotsTakenFlag == true){
lcd.setCursor(0,0);
lcd.print("Place lens cap ");
lcd.setCursor(0,1);
lcd.print("on camera. ");
delay (10000);
lcd.setCursor(0,0);
lcd.print(" Dark Shots ");
lcd.setCursor(0,1);
lcd.print(" ");
Serial.println("taking dark shots");
delay(2000);
lcd.setCursor(0,1);
lcd.print("shots left ");
for (int i = -1; i < shotCount; i++){
lcd.setCursor(11,1);
if ((shotCount - i) < 10){
lcd.setCursor(11,1);
lcd.print(" ");
}
lcd.print(shotCount - (i + 1));
ML3();
delay((shutterDuration * 1000) + (shutterDelay * 1000));
}
shotsTakenFlag = true;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Click to start ");
lcd.setCursor(0,1);
lcd.print("again ");
}
}
//restart function
void initiateHardwareReset() {
//Serial.println("Restarting system now...");
delay(100); // Give serial data time to print
wdt_enable(WDTO_15MS); // Enable WDT with a 15ms timeout
while (true) {
// Force an infinite loop so the watchdog times out and triggers a reset
}
}
// IR timings for Nikon D3400 shutter operation **Thanks furtrader
void ML3(){
// Delays are tuned to account for overhead of library code.
tone(13,38000);
delay(2);
noTone(13);
delay(28);//original delay 28ms
tone(13,38000);
delayMicroseconds(200);
noTone(13);
delayMicroseconds(1500);
tone(13,38000);
delayMicroseconds(200);
noTone(13);
delayMicroseconds(3300);
tone(13,38000);
delayMicroseconds(200);
noTone(13);
}

