2

I bought some 'lucky dip' IR sensors from China, no idea what they are, but they appeared to get lost in the post so instead I bought some of these from a reputable place in the UK that come with a datasheet.

The next day, both items arrived together!

I'm trying to build a very simple proximity sensor for a robot, I built the following circuit:

schematic

simulate this circuit – Schematic created using CircuitLab

and stole this code to test it out:

#define IRledPin 8
#define D13ledPin 13
#define IRsensorPin 9

void IR38Write() {
  for(int i = 0; i <= 384; i++) {
    digitalWrite(IRledPin, HIGH);
    delayMicroseconds(13);
    digitalWrite(IRledPin, LOW);
    delayMicroseconds(13);
  }
}


void setup(){
  pinMode(IRledPin, OUTPUT);
  digitalWrite(IRledPin, LOW);
  pinMode(D13ledPin, OUTPUT);
  digitalWrite(D13ledPin, LOW);
}



void loop(){
  IR38Write();
  if (digitalRead(IRsensorPin)==LOW){
    digitalWrite(D13ledPin, HIGH);
  } else {
    digitalWrite(D13ledPin, LOW);
  }
}

If I hold my hand in front of it, nothing happens (LED on-board arduino should light up), however if I point a TV remote at it and press a button, the LED lights up. I tested 2 of the 'fancy' sensors that I got and both behaved the same.

Then I tried one of the 'lucky dip' sensors, swapped it straight in and the whole thing works perfectly - point a TV remote and the LED lights, hold my hand ~10cm in front of it and the LED lights!

So, where have I gone wrong?

VE7JRO
  • 2,554
  • 18
  • 25
  • 29
MalphasWats
  • 304
  • 1
  • 10
  • @NickAlexeev - this is not actually an Arduino question, rather it revolves around the behavior of the IR receiver module. Migrating it was improper - you have to read these things, not just trigger off of keywords. – Chris Stratton Dec 16 '15 at 03:15
  • I did wonder about that - this isn't really an Arduino-specific issue, it just happens that I'm using one in this instance. – MalphasWats Dec 16 '15 at 08:13
  • What happens to these questions? Do they get migrated back to EE or just lost? – Nick Gammon Jan 11 '16 at 21:10

2 Answers2

4

See page 5 of your datasheet - that 'fancy' sensor suppresses "• Continuous signals at any frequency".

So you'll need to pulse your 38.4kHz signal for the sensor to produce an output.

brhans
  • 163
  • 5
  • Wow, thanks. Datasheets are hard! It's actually quite hard to do that all on the same board - by the time the sensor starts looking for the signal, it's pretty much stopped bouncing back. I did manage to get it to trip with my hand by making it pulse but it's really unreliable. I chose entirely the wrong sensor for what I'm trying to do, I had no idea some were that clever! Thanks – MalphasWats Dec 15 '15 at 21:24
  • You should be able to put a delay at the start of your loop, perhap 100ms, and adjust the number of cycles of output to be in range of what the detector considers a pulse. It would be better if you checked for results while transmitting, subtracting the time to do so from the delays (probably use a scope to calibrate). Or you can probably use a hardware timer to transmit. Best proximity results will be with a synchronous detector, ie, lock-in amplifier rather than a remote receiver blob. – Chris Stratton Dec 15 '15 at 22:24
  • yes, perhaps you can use one of the PWM outputs on your arduino to drive the LED – Jasen Dec 16 '15 at 03:14
3

The answer I've accepted is the correct answer, but I wanted to add this extra bit for completeness. I reworked my code to use non-blocking delays for the IR LED so the sensor actually gets a chance to see it before it stops transmitting and it works! Range is quite a bit shorter than the 'lucky dip' sensor (~ 2cm).

#define IR_LED 8
#define LED 13
#define SENSOR 9

unsigned long burst_timer;
unsigned long gap_timer;

unsigned long timestamp;

char led_state;
char burst_count;

const char BURST_MAX = 20;


void setup()
{
  pinMode(IR_LED, OUTPUT);
  led_state = LOW;
  burst_count = 0;
  digitalWrite(IR_LED, led_state);

  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);

  pinMode(SENSOR, INPUT);

  timestamp = micros();
  burst_timer = timestamp;
  gap_timer = timestamp;
}


void toggle_led()
{
  if (led_state == LOW)
  {
    led_state = HIGH;
  }
  else
  {
    led_state = LOW;
    burst_count++;
  }

  digitalWrite(IR_LED, led_state);
}

void loop()
{
  timestamp = micros();
  if (timestamp - burst_timer > 13 && burst_count < BURST_MAX)
  {
    toggle_led();
    burst_timer = timestamp;
    gap_timer = timestamp;
  }

  if (burst_count >= BURST_MAX && timestamp - gap_timer > (13*2*BURST_MAX) )
  {
    burst_count = 0;
    burst_timer = timestamp;
    gap_timer = timestamp;
  }


  if (digitalRead(SENSOR) == LOW)
  {
    digitalWrite(LED, HIGH);
  } 
  else 
  {
    digitalWrite(LED, LOW);
  }
}

Every time I use delay() (or delayMicroseconds()) I find a new reason not to!

MalphasWats
  • 304
  • 1
  • 10