Go Down

Topic: Nerf Laser Ops - simulate the signal (Read 375 times) previous topic - next topic

braunbaer2003

Hi!

I've got these fantastic Nerf Laser Ops. But my kids are too fast, I always loose.

I'm trying to simulate the signal. I suspect the signal is being transmitted with IR light. That's why I wrote this program and I also receive a signal.

Code: [Select]
#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>

/*
 * IRremote: IRrecvDump - dump details of IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */
 
#include <IRremote.h>
 
int RECV_PIN = 11; // Signaleingang ist PIN 11
 
IRrecv irrecv(RECV_PIN);
 
decode_results results;
 
void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}
 
// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
//  decode_results *results = (decode_results *)v
void dump(decode_results *results) {
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.print("Unknown encoding: ");
  }
  else if (results->decode_type == NEC) {
    Serial.print("Decoded NEC: ");
  }
  else if (results->decode_type == SONY) {
    Serial.print("Decoded SONY: ");
  }
  else if (results->decode_type == RC5) {
    Serial.print("Decoded RC5: ");
  }
  else if (results->decode_type == RC6) {
    Serial.print("Decoded RC6: ");
  }
  else if (results->decode_type == PANASONIC) {
    Serial.print("Decoded PANASONIC: ");
  }
  else if (results->decode_type == JVC) {
    Serial.print("Decoded JVC: ");
  }
  else if (results->decode_type == SAMSUNG) {
    Serial.print("Decoded SAMSUNG: ");
  }
  int val1 = results->value;
  Serial.print(val1, HEX);
  Serial.print(" (");
  int valbits = results->bits;
  Serial.print(valbits, DEC);
  Serial.println(" bits)");
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");
 
  for (int i = 0; i < count; i++) {
    if ((i % 2) == 1) {
      int valen = results->rawbuf[i]*USECPERTICK;
      Serial.print(valen, DEC);
 
    }
    else {
      int negvalen =-(int)results->rawbuf[i]*USECPERTICK;
      Serial.print(negvalen, DEC);
    }
    Serial.print(", ");
  }
  Serial.println("");
}
 
void loop() {
  if (irrecv.decode(&results)) {
    int hexen = results.value;
    Serial.println(hexen, HEX);
    dump(&results);
    irrecv.resume(); // Receive the next value
  }
}



I have fired the same signal over 100 times. It's fluctuating, but I think I'm quite good statistically. Now I have written another program, which sends the signal.


Code: [Select]
#include <IRremote.h> // IRremote Bibliothek nachladen
 
IRsend irsend;
 
// RAW Signal zum an/ausschalten des Fernsehers
//unsigned int powerOn[68] = {4500, 4450, 600, 1600, 600, 1650, 550, 1650, 600, 500, 600, 550, 550, 550, 600, 500, 600, 500, 600, 1650, 550, 1650, 600, 1650, 550, 550, 550, 550, 600, 500, 600, 500, 600, 550, 550, 550, 550, 1650, 600, 500, 600, 550, 550, 550, 550, 550, 600, 500, 600, 500, 600, 1600, 600, 550, 600, 1600, 600, 1650, 550, 1650, 600, 1650, 550, 1650, 600, 1650, 550};

// rot
//unsigned int powerOn[68] = {3000,1900,950,1900,950,1900,950,1900,950,1950,1950,1950,900,1950,950,1900,950,1950,900,2000,850,2000,950,1950,900,2000,900,1950,900,2000,950,1950,900};

// blau
unsigned int powerOn[68] = {2950,1950,850,2000,850,2000,850,2000,850,2000,1850,2050,850,2000,850,2000,850,2000,900,2000,1850,2000,850,2000,850,2000,850,2000,850,2000,850,2000,850};

//test
// unsigned int powerOn[68] = {700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100};
 
void setup()
{
  Serial.begin(9600);
}
 
void loop() {

  irsend.sendRaw(powerOn,68,38);  //RAW Signal, laenge, frequenz meistens 38kHz
  delay(1000);

}



The receiver program shows that the signal from the NERF is identical to the one I sent. But if I send the simulated signal to the NERF, then the NERF does not react. Nothing happens. I tried several IR-LED: 850nm, 880nm, 940nm, 950nm. The ARDUINO-receiver is the TSOP4838. But I don't know, which receiver is in the NERF. I've got a picture:



Here are two pictures of the transmitter and the receiver.



I'm not an ARDUINO-expert. Does anyone have an idea why the NERF does not receive or react to the signal?

braunbaer2003

Hi guys - I've lost again. Does somebody has any idea?

pbochu

Hi,
I have been playing with those Nerf things as well and I went a little farther. Lots of guess work, but it seems I can decode shoots from any color and shoot back. I still lack power, so I can't shoot a Nerf placed more than 50 cm from my emitter, but I'm working on it.

I haven't tested your code, but I think you missed one (maybe important) point:
the signal sent by the blasters begin with a 3 stepped header and not a unique pulse. Also, you can safely round the values in your array to multiples of 1000 microseconds. This will not enhance the signal, just improve readability. As you may already have guessed, the signal is composed of a header followed by 16 bits, depending on the shooter's color.
- The header is a 3ms pulse followed by a 6ms pause and a 3ms pulse again.
- A bit is composed of a 2ms pause followed by a 1ms pulse if the value is 0 or a 2ms pulse if the value is 1.

And finally, when the blasters are not connected to the app, the signals are:
RED: <header>, 0,0,0,0, 1,0,0,0, 0,0,0,0, 0,0,0,0
BLUE: <header>0,0,0,0, 1,0,0,0, 0,1,0,0, 0,0,0,0
PURPLE: <header>0,0,0,0, 1,0,0,0, 1,0,0,0, 0,0,0,0

So maybe you should have a try with:
unsigned int RED[35] = {3000, 6000, 3000,
                                2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000,
                                2000, 2000, 2000, 1000, 2000, 1000, 2000, 1000,
                                2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000,
                                2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000};

unsigned int BLUE[35] = {3000, 6000, 3000,
                                2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000,
                                2000, 2000, 2000, 1000, 2000, 1000, 2000, 1000,
                                2000, 1000, 2000, 2000, 2000, 1000, 2000, 1000,
                                2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000};

unsigned int PURPLE[35] = {3000, 6000, 3000,
                                2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000,
                                2000, 2000, 2000, 1000, 2000, 1000, 2000, 1000,
                                2000, 2000, 2000, 1000, 2000, 1000, 2000, 1000,
                                2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000};

irsend.sendRaw(powerOn, 35, 38); // don't forget to correct the array length!


Please let us know if it helped you and what wavelength gives the best results, I suspect my own problems come from an unadapted IR LED, so I have to buy some.
I will try your code soon and post an update if I have any idea.

You can read my work-in-progress on my github account, BTW

pbochu

Quick update: the following code worked for me (IR LED connected on pin 3, timings of previous post):
Code: [Select]

#include <IRremote.h>

IRsend irsend; // LED emitter on pin 3
unsigned int PURPLE[35] = {3000, 6000, 3000,
                           2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000,
                           2000, 2000, 2000, 1000, 2000, 1000, 2000, 1000,
                           2000, 2000, 2000, 1000, 2000, 1000, 2000, 1000,
                           2000, 1000, 2000, 1000, 2000, 1000, 2000, 1000}; 

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  irsend.sendRaw(PURPLE, 35, 38); // don't forget to correct the array length!
  delay(2000);
}

Like I said, I still can't shoot at a distance higher than 50cm or so, I still have to find a way to improve that, so any help on the IR LED used will be appreciated

skywatch

The reason the range is so short is that you are not able to give enough current to the IR led from the arduino pin.

You need a transistor and resistor. The resistor will limit base current to a safe level (to be determined by you depending on the IR led you use) and the transistor will take current directly from the power rails.

There are many posts here and on the net about IR led blasters etc, these should help you out!

braunbaer2003

Hi,

thank you for your answers. I'll try it!
I have to set up the equipment first..... Meanwhile, I did some other things with the breadboards.

I would be glad if I could at least manage the 50 cm. Which IR LED did you use?  What frequency does it have?

pbochu

@skywatch
You're right of course, I forgot to add I'm using a transistor as a power driver. With a low-but-safe resistor I merely reach 80cm, that's why I jumped to the conclusion that the LED I use (unsoldered years ago, I don't even know what the wavelength is) may not be adapted. I don't know if any wavelength in the range 850-950 nm works the same for Nerf blasters, or if the sensibility of the receiver they use is highly wavelength-dependent.

braunbaer2003

Maybe your LED has got a whide spread? There are LEDs with an opening angle of 10 degrees. A lens could also help.

But I am nowhere near that.

braunbaer2003

Oh YES!

I tried your code from posting #3 - it worked!

THANK YOU VERY VERY MUCH, GREAT!


I can shoot at a distance of about 3 meters without any transistor. Now I'm going to test several IR-LEDs. I'll beback.

braunbaer2003

Hi!

I have tested several IR-LED from 850nm to 950nm. I achieved the best result with this LED:
IR-Emitter 850 nm 20 ° 5 mm radial: 5 Meters.

The worst result I've had at 925nm: 1 Meter. This presumably means that both the frequency and the scattering angle of the LED are important. I would have guessed so, too.

Next step: More reach. Does anyone know an IR LED with 850nm that can tolerate a lot of power?

pbochu

Hi,
glad I could help, and thanks a lot for the survey, I am going to purchase another LED (or a couple of them) with the characteristics you indicated. Good luck for you project!

Go Up