IR Sensor problem - please help!!!!!!!!!

I have recently started to try and make an IR distance sensor using the following two items purchased from jaycar:

Ir Emitter: ZD1946
Infrared Phototransistor: ZD1950

Everything seemed to work fine, I was powering the Ir Emitters and using the analogRead function to return a value between 0-1023 from the Infrared Photo-transistor.

My issue starts when the sensor is hit with ambient light. I have encased the Infrared Photo-transistor in 5mm plastic pipe though light is still able to hit the sensor and completely change the values.

I have read about Infrared modulation which sounds like it will fix the problem, I have started by using the tone function with the IR emitters to generate a frequency of 38kHz which seems to be working fine because I still receive the same readings as I did previously.

Even with the IR emitters running at a frequency of 38kHz I am still having trouble with ambient light, which I kind of expected as no adjustments have been made to the Infrared Photo-transistor.

I am wondering if have purchased the wrong type of Infrared Photo-transistor? Maybe I need a sensor that is set to a specific frequency. Or I need to apply either a hardware or software based adjustment/addition to make the Infrared Photo-transistor work with a 38kHz frequency? Or I could be completely on the wrong track.

I have tried searching for information about setting up an ir sensor with frequency modulation for Arduino though I have not found much.

I really want to get this distance sensor working correctly, I have attached an image of the circuit and the Arduino code that I’m using.

Any help would be greatly appreciated, thank you for taking the time to read my post.

code.ino (868 Bytes)

code.txt (893 Bytes)

These are for basic send out and detect use, not distance sensing. (Unless you can pulse it and time the echo.)

The modulation is simply a "carrier" modulation.

What you need is something like


I'm with weedpharma on that: have a look at off the shelf sensors. I can't see how you would measure the time of flight seeing as light is pretty slick. But that said, you might find my write-up here of interest even if it's of no help in this case.

Vishay TSSP4P38 is a three-pin IR receiver that outputs a pulse length in proportion to the amount of light (38Khz modulated) being reflected. It’s like one-half of the Sharp sensor weedpharma linked but only $1.

With your current phototransistor setup, what you should be doing is:

void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  //Turn on ir emitters, get difference in reading from ambient
  digitalWrite(irEmitPin, HIGH);
  sensorValue = analogRead(A0) - sensorValue;
  digitalWrite(irEmitPin, LOW);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:

Basically it’s subtracting the ambient light from the reading when the IR emitter is on.

Hi Guys,

Thank you so much for the help, it has helped me a lot.

I have just one more question.

From your replies I have purchased a Infrared Receiver that is set to a frequency of 38kHz, I went to jaycar so that I could pick a component up on the day, i hope this is the right style of sensor.

I have tried hooking the output of the sensor to an analog pin on the arduino and ran the ReadAnalogVoltage function, though i only receive 1023 continually when there is nothing in front of the sensor, though when an object is about 5 centimeters away from the sensor the reading changes to 0, I can see that the reading is changing from 5v to 0v.

I’ve done a bit of research and think that the output of the sensor is in the form of a square wave? so i was thinking that i could detect when the output is high and then time the output until it changes to low to get a distance reading, i have included the code below.

int irEmitPin = 10;
int fequency =38000;
int irSensor = 9;
boolean freqState = LOW;
long freqStartTime;
long freqEndTime;
int freqTotalTime;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:

// the loop routine runs over and over again forever:
void loop(){
  tone(irEmitPin, fequency);
  long timer = micros();

   int duration = pulseIn(irSensor,HIGH);

  if(digitalRead(irSensor) == HIGH && freqState == LOW){
    freqStartTime = micros();
    freqState = HIGH;

  if(digitalRead(irSensor) == LOW && freqState == HIGH){
    freqEndTime = micros();
    freqTotalTime = freqEndTime - freqStartTime;
    freqState = LOW;

Unfortunately this is not working, I get values that seem random and not related to the distance, sometimes the values increase when an object gets close and vice versa.

Thought i should also mention that the distance does not need to be accurate to the millimeter, i just need to know when something is getting closer and further away from the sensor.

I also tried pulseIn function though it seemed slow and unreliable.

Sorry to be a pain, but again any help would be much appreciated.

Thank you.

I have a suspicion that light is too slick to be measured like that.

I stick by my suggestion that you go with an off the shelf distance measuring sensor.

JimboZA thank you for the constant help, I have been looking at the Sharp Ir sensors, though they are a bit on the pricey side (I need 20 sensors) and they don’t really fit the device i’m making (see attached image).

As a last ditch effort I was able to get the Vishay TSSP4P38 that Chargin recommend. this sensor seems perfect for the job after reading the datasheet.

The TSSP4P38 is a compact infrared detector module for
proximity sensing application. It receives 38 kHz modulated
signals and has a peak sensitivity of 940 nm.
The length of the detector’s output pulse varies in proportion
to the amount of light reflected from the object being

The only problem is that i’m still having trouble reading the output of the sensor, I feel that my code may be incorrect (the code can be seen in my previous post).
currently I am still using the tone function to set the frequency of the IR emitters.
and then timing how long the output is high for, though when I serial print the output I get random numbers that don’t correspond to the movement in front of the sensor.

I have been looking at other tutorials on reading pwm signals though they are mainly for receiving IR codes from a remote control.

Any help would be appreciated.

tssp4p38.pdf (103 KB)

Are you trying to detect the presence of an object or are you trying to measure distance? Is it an object you control or is it 'anything' which can be any colour? What distance? (Don't say zero-to-something because you can't measure zero.)

The first version works because it is measuring the brightness of the reflected light. Different colour objects will return different amounts of IR light for the same distance.

If the object is controlled (colour is known) then you can allow for different ambient light levels by measuring the analog output with the illuminator off. Then the 'distance' is the additional light received when the illuminator is on. This won't be very accurate but it's probably good enough to stop your robot from running into walls. You will have difficulty measuring distances smaller than the distance between emitter and receiver because the illuminated spot(s) won't be in the centre of the detector's view, so the distance-brightness relationship will reverse.

To measure distance to 'anything' where you don't know in advance what colour it is, then you will need a time-of-flight sensor such as the expensive examples proposed. If you are just detecting an obstruction in front of the sensor, then you may be able to set your thresholds so it works with most colours.