Wrong IR values received

Hi all!

I am making a LaserX Nerf gun, and I am having problems receiving correct IR codes. I finally got the transmitting and everything else working. I have been working on the receiver for 5 hours now :exploding_head: and have tried 100 different things, all to no avail!

Basically, I need to receive and decode a hash to a 32 bit code. I don't need any extra info like coding type (NEC, SONY, ETC.) or anything, I just need to distinguish between different team shots.

What I'm using is:

  • A DFRobot Fire-Beetle with its shield(I got it working with a Arduino Nano and the IRlib library, but need it working on this board)
  • A 940nm 1.5V 100mA IR LED
  • A VS1838B 3.3V / 5V 38KHz IR receiver
  • Some LED indicators
  • A on/off switch
  • A tactile button for a trigger
  • A 3.7V Li-ion battery

IR LED and receiver link

Schematic:

I finally got some code partially working. It reads the right code, but only once every 20 times. Here is the serial monitor output:

Code:

#include <Adafruit_NeoPixel.h>

#include <Arduino.h>
#include <IRsend.h>
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>


const uint16_t RECV_PIN = 14;  //D10:17, D12:4, D6:14
#define LED_PIN    D9
#define LED_COUNT 9
#define Trigger D2
const uint16_t kIrLed = 16;//D11

IRrecv myReceiver(RECV_PIN);
IRsend irsend(kIrLed);

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

decode_results results;

static const long PURPLEir = 0x67228B44;
static const long REDir    = 0xC6D404B6; //0x78653B0E;
static const long BLUEir   = 0x2FFEA610;

// PURPLE
uint16_t rawDataPurple[] = {
  2888, 5987, 2893,
  2058, 848, 2052, 843, 2069, 795, 2104, 791,  // 0, 0, 0, 0
  2109, 1816, 2109, 837, 2063, 842, 2057, 848, // 1, 0, 0, 0
  2052, 1873, 2055, 840, 2059, 846, 2054, 841, // 1, 0, 0, 0
  2071, 794, 2106, 789, 2111, 795, 2105, 841,  // 0, 0, 0, 0
  1000
};

// RED
uint16_t rawDataRed[] = {
  2899, 5977, 2897,
  2065, 842, 2058, 849, 2051, 845, 2055, 842,  // 0, 0, 0, 0
  2058, 1869, 2056, 851, 2061, 826, 2074, 792, // 1, 0, 0, 0
  2108, 789, 2111, 836, 2064, 843, 2057, 840,  // 0, 0, 0, 0
  2060, 846, 2054, 843, 2057, 850, 2050, 847,  // 0, 0, 0, 0
  1000
};

// BLUE
uint16_t rawDataBlue[] = {
  2896, 5979, 2902,
  2060, 836, 2064, 843, 2057, 848, 2052, 844,  // 0, 0, 0, 0
  2055, 1870, 2055, 851, 2052, 844, 2065, 820, // 1, 0, 0, 0
  2080, 795, 2105, 1821, 2104, 792, 2111, 836, // 0, 1, 0, 0
  2063, 843, 2057, 838, 2062, 845, 2055, 840,  // 0, 0, 0, 0
  1000
};

int life = 2;

int myColor;

int timer1;
int timer2;
int timer3;

int trig;

int teamScan = 1;

void setup()
{
  Serial.begin(115200);
  Serial.println("Setting up IR...");
  myReceiver.enableIRIn(); // Start the receiver
  irsend.begin();
  
  delay(1000);

  
  Serial.println("Setting up trigger and LEDs...");
  pinMode(Trigger, INPUT);
  
  strip.begin();
  strip.show();
  strip.setBrightness(255);
  
  trig = digitalRead(Trigger);
  
  Serial.println("Waiting for team...");
  retry:
  while (digitalRead(Trigger) == LOW);
  Serial.println("Trigger pressed...");
  if (digitalRead(Trigger) == HIGH){
    Serial.println("Trigger high...");
    while (digitalRead(Trigger) == HIGH){
      Serial.println(timer1);
      timer1++;
      delay(1);
      digitalRead(Trigger);
      if (timer1 == 2000){
        timer1 = 0;
        goto complete;
      }
    }
    teamscan:
    Serial.println("teamScan...");
    if (teamScan == 4){teamScan=1;}
    if (teamScan == 1){
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(255,0,255)); 
        strip.show();
        delay(20);
      }
      myColor = 1;
    }
    else if (teamScan == 2){
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(255,0,0)); 
        strip.show();
        delay(20);
      }
      myColor = 3;
    }
    else if (teamScan == 3){
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(0,0,255)); 
        strip.show();
        delay(20);
      }
      myColor = 2;
    }
    teamScan++;
    goto retry;
  }
  complete:
  if (myColor == 1){
    for (int k=0;k<5;k++){
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(255,0,255)); 
        strip.show();
        delay(20);
      }
      delay(600);
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(0,0,0)); 
        strip.show();
        delay(20);
      }
      delay(600);
    }
    for (int f=0;f<LED_COUNT;f++){
      strip.setPixelColor(f, strip.Color(255,0,255)); 
      strip.show();
      delay(20);
    }
    delay(3000);
    for (int f=LED_COUNT;f>1;f--){
      strip.setPixelColor(f, strip.Color(0,0,0)); 
      strip.show();
      delay(40);
    }
  }
  else if (myColor == 3){
    for (int k=0;k<5;k++){
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(255,0,0)); 
        strip.show();
        delay(20);
      }
      delay(600);
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(0,0,0)); 
        strip.show();
        delay(20);
      }
      delay(600);
    }
    for (int f=0;f<LED_COUNT;f++){
      strip.setPixelColor(f, strip.Color(255,0,0)); 
      strip.show();
      delay(20);
    }
    delay(3000);
    for (int f=LED_COUNT;f>1;f--){
      strip.setPixelColor(f, strip.Color(0,0,0)); 
      strip.show();
      delay(40);
    }
  }
  else if (myColor == 2){
    for (int k=0;k<5;k++){
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(0,0,255)); 
        strip.show();
        delay(20);
      }
      delay(600);
      for (int f=0;f<LED_COUNT;f++){
        strip.setPixelColor(f, strip.Color(0,0,0)); 
        strip.show();
        delay(20);
      }
      delay(600);
    }
    for (int f=0;f<LED_COUNT;f++){
      strip.setPixelColor(f, strip.Color(0,0,255)); 
      strip.show();
      delay(20);
    }
    delay(3000);
    for (int f=LED_COUNT;f>1;f--){
      strip.setPixelColor(f, strip.Color(0,0,0)); 
      strip.show();
      delay(40);
    }
  }
  for (int f=2;f<LED_COUNT;f++){
    strip.setPixelColor(f, strip.Color(0,255,0)); 
    strip.show();
    delay(20);
  }
  delay(1000);
  myReceiver.resume();
}

void loop() {
  if (digitalRead(Trigger) == HIGH){
    Serial.println("Trigger pulled! Shooting...");
    for (int f=2;f<LED_COUNT;f++){
      strip.setPixelColor(f, strip.Color(0,0,0)); 
      strip.show();
    }
    shoot();
    for (int f=2;f<LED_COUNT;f++){
      strip.setPixelColor(f, strip.Color(0,255,0)); 
      strip.show();
      delay(90);
    }
  }

  /*if (myReceiver.decode(&results)) {
    //Serial.print("'real' decode: ");
    Serial.println(results.value, HEX);
    Serial.println("");
    Serial.println(resultToTimingInfo(&results));
    Serial.println("");
    Serial.println("");

    //Serial.print(", hash decode: ");
    //Serial.println(decodeHash(&results), HEX);
    code(&results);
    myReceiver.resume(); // Resume decoding (necessary!)
  }*/

  if (myReceiver.decode(&results)){
    dump(&results);
    myReceiver.resume();
  }
  
  //delay(1);
}

void dump(decode_results *results) {
  serialPrintUint64(results->value, 16);
  Serial.println("");
  //normal mode
  if (results->value == PURPLEir && myColor == 1) {//PURPLEir
    Serial.println("Purple hit!!!!");
    life--;
    if (life == 0){
      die();
      life = 2;
    }
    delay(100);
  }
  else if (results->value == BLUEir && myColor == 3) {
    Serial.println("BLUE hit!!!!");
    life--;
    if (life == 0){
      die();
      life = 2;
    }
    delay(100);
  }
  else if (results->value == REDir && myColor == 2) {
    Serial.println("RED hit!!!!");
    life--;
    if (life == 0){
      die();
      life = 2;
    }
    delay(100);
  }
}

void die() {
  rainbow(9);
}

void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this outer loop:
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

  
void shoot() {
  //irsend.sendRaw(rawDataBlue, 36, 38);//data, 67, 38

  if (myColor == 1){
    irsend.sendRaw(rawDataPurple, 36, 38);//data, 67, 38
  }
  else if (myColor == 3){
    irsend.sendRaw(rawDataRed, 36, 38);//data, 67, 38
  }
  else if (myColor == 2){
    irsend.sendRaw(rawDataBlue, 36, 38);//data, 67, 38
  }
}

C6D404B6 is the correct code.

I really could use some help.
Thanks in advance!

Actually, it almost never reads the correct code (C6D404B6):

Is the IR sender's modulation frequency 38KHz?

I’m not sure. It is a LaserX Nerf gun. I did get a setup to work with an Arduino Nano. I used the same circuit, except that everything was 5v instead of 3.3V. I used the IRlib2 library. That library and my other code doesn’t work though with the ESP32.
I did use the same receiver for both.

Maybe this is the reason:

And your protocol has no real (long) start bit, so it is almost impossible for the receiver (and the receiver circuit) to detect the start of a new data packet.

Thanks @ArminJo

" IR does not work right when I use Neopixels (aka WS2811/WS2812/WS2812B) or other libraries blocking interrupts for a longer time (> 50 µs)."

Wow. I didn't use WS2812 LEDs on my previous setup. Ill try without them and see if I get better results.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.