Need IR data for generic IR remote

Hi All,

Using a IR receive sketch I have retrieved the following responce for a remote to do a remote shutter relase on my Nikon D3500;

Protocol=UNKNOWN Hash=0x0 1 bits (incl. gap and start) received
Send with: 
  uint16_t rawIRTimings[1] = {2080};  // Protocol=UNKNOWN Hash=0x0 1 bits (incl. gap and start) received
  IrSender.sendRaw(rawIRTimings, sizeof(rawIRTimings) / sizeof(rawIRTimings[0]), 38, <RepeatPeriodMillis>, <numberOfRepeats>);

I have put this in a basic IR-Send sketch and have verified the IR LED I am using is working but even with an oscilloscope, I am seeing no pulse otuput on pin 3.

From reading, I am wondering if I am missing a matirx of values that the IrSender needs. So what can I do next? Any other sketches to bring back other data?

The project is for a intervalometer for astrophotgraphy. Thanks
Jeff

Welvome to the forum.

Please post that sketch.

a7

what host microcontroller are you using?
what IR interface?

I can't find anything that says the D3500 even has an IR sensor. It also doesn't seem to have a remote trigger jack for a wired connection. I would guess it's bluetooth or something similar.

There may be a smartphone app.

What are you using as the remote control for this camera? Does it work?

Please post that - entire - sketch not a snippet.

Are you attempting to create the IR receiving unit that will then use BlueTooth to fire the shutter?

Because… it does not.

I too found nothing, asked AI and it said it does, and whike googling for more info another AI said nope.

Confronted (!) the first AI and it changed its mind.

Mostly on the basis of full coverage of that capability in the D3400 manual which does not appear D3500 manual.

So @Paul_KD7HB has prolly caught on to what the OP is going for.

a7

Well, what I'm wondering is what remote he's trying to use now with the IR Receive sketch. If he has a remote (IR or not) that actually works with the D3500, I'd like to know which remote that is, because I haven't found Nikon to be offering such a remote.

Or maybe he actually has a D5300.

Thanks for the replies. I have some corrections. First off I fat fingered the camera, it is a Nikon D3400. It does have a IR sensor. I got a no name remote off Amazon.

I used the following sketch to pull the data I have now from the remote;

#include <IRremote.hpp>
#define IR_RECEIVE_PIN 2

void setup()
{

  Serial.begin(115200); // // Establish serial communication
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the receiver
}

void loop() {
  if (IrReceiver.decode()) {
      Serial.println(IrReceiver.decodedIRData.decodedRawData, HEX); // Print "old" raw data
      IrReceiver.printIRResultShort(&Serial); // Print complete received data in one line
      IrReceiver.printIRSendUsage(&Serial);   // Print the statement required to send this data
      
      IrReceiver.resume(); // Enable receiving of the next value
  }
  
}

The controller is a Arduino Nano and the IR sensor I used is the TSOP38238. The sketch brings back correct info from my TV remote as far as howing the protocol and other speicfic data.

Sorry I didn't give a complete picture. I will use an IR LE driven by a transistor to output the code to trigger the camera. Will 3d print an enclosire once I get to that point.

Jeff

I found this information on the Nikon protocol, which may or may not be accurate for the D3400:

But it doesn't show what the code actually is for the shutter release. I'm not sure IRRemote.hpp can deal with that protocol since it's a far cry from NEC. But it should be possible to do this without the library if needed because it has to be really simple.

Anyway, if the remote you have actually triggers the shutter release, and since you have a scope, you could set up your IR receiver with just power, and see what you get on the scope when you press the remote shutter button. Set the scope for single shot, and I believe falling edge for the TSOP38238. Then post a picture here of what you get.

Edit: I found a video of someone who's gone down this road before you. I'm not sure which Nikon he has, but the timing seems to match the table above.

https://www.youtube.com/watch?v=198oRcCQdP8

Thanks so much. I'll watch the video and see what I find if I trigger my scope on the incoming pulse.

Jeff

Well the sketch that FurTrader put in his Reddit post works!! The video is great as far as showing the timing and what he did but this will work for me. Just verified on my D3400.

Thanks for your help and additional research.

I'll post the finished intervalometer sketch when I got it done!!

Jeff

For the benefit of future readers, it might be useful to look at the incoming signal on your scope to see if the timing is the same as Fur Trader says. He has the On pulses as 200us, but the table says they are 500us. Of course the table could be wrong. But your scope cursors should tell you what all the timing values actually are.

Anyway, congrats on getting it working.

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);
}

![breadboarded|685x500](upload://58pPUDec1lU3WZk0EPOfOiRCOhB.jpeg)
![INT-on-CAM|646x500](upload://493vBExRpdBivHHAw2nebso5buc.jpeg)

Forget those last 2 lines in the code, I was trying to attach a couple of pictures.....

Jeff