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?
-
@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– Chris Stratton2015年12月16日 03:15:44 +00:00Commented Dec 16, 2015 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– MalphasWats2015年12月16日 08:13:08 +00:00Commented Dec 16, 2015 at 8:13
-
What happens to these questions? Do they get migrated back to EE or just lost?Nick Gammon– Nick Gammon ♦2016年01月11日 21:10:39 +00:00Commented Jan 11, 2016 at 21:10
2 Answers 2
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! ThanksMalphasWats– MalphasWats2015年12月15日 21:24:47 +00:00Commented Dec 15, 2015 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– Chris Stratton2015年12月15日 22:24:58 +00:00Commented Dec 15, 2015 at 22:24
-
yes, perhaps you can use one of the PWM outputs on your arduino to drive the LEDJasen– Jasen2015年12月16日 03:14:15 +00:00Commented Dec 16, 2015 at 3:14
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!
-
1That's a good lesson learned then. Delay() is second in line to String in the evil stakes.Majenko– Majenko2015年12月16日 00:16:21 +00:00Commented Dec 16, 2015 at 0:16