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?

migrated from electronics.stackexchange.com Dec 15 '15 at 22:36

This question came from our site for electronics and electrical engineering professionals, students, and enthusiasts.

  • @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 3: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 8:13
  • What happens to these questions? Do they get migrated back to EE or just lost? – Nick Gammon Jan 11 '16 at 21:10
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.

  • 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 3: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!

  • 1
    That's a good lesson learned then. Delay() is second in line to String in the evil stakes. – Majenko Dec 16 '15 at 0:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.