Measure distances with a laser, a phototransistor and an Arduino Nano

Hi everyone!

I'm working on an optoelectronics project for a college course that is supposed to measure distance, but it's not working properly. The measured voltage value either doesn't change when I move the object, or it changes only slightly and gives results that don't make sense (for example, a higher voltage when the object reflecting the light is farther away than when it is closer).

I have a red laser diode (RYZ1230) and a phototransistor (BPY62-4) pointing in the same direction, with an Arduino Nano performing the calculations while connected to my laptop.

My measurement procedure is:

  1. Take a reading with the laser off.
  2. Take another reading with the laser (at the same known distance).
  3. Subtract the first reading from the second to estimate the laser's contribution.

My goal is to create a lookup table of known distances and their corresponding voltages, and then use linear interpolation with that data to estimate unknown distances during actual measurements.

I'm not sure how to solve this issue or how to obtain reliable calibration data for the table. If anyone has experience with this kind of setup or knows how I could make it work, I would greatly appreciate your help.

Thank you!

What is your plan for eliminating the effect of ambient illumination? I see you are measuring a background to subtract.

Please post a circuit diagram that explains what "measuring the voltage" means.

Hi. I thought that measuring while the laser was off, then when the laser was on (in the same circumstances) and subtracting the first from the second was enough. It doesn't have to be precise, it just has to show me reasonable values.
Is this enough or could it be causing problems?

Also, the table for the lineal interpolation will only have values that result from the substraction.

Tell me if you need any more info. Thanks for replying!!

Since you did not respond to post 2 I expect you have not read the pinned post re 'How to get the most from the forum'. Once you have a circuit and code the helpers can point you in the right direction.

Ah, sorry, I haven't read that post. I'm travelling right now, but as soon as I get home I will post the code I'm running and the circuit diagram.

Is this your lab partner, or a competitor?

Nah, I'm doing my project alone (although I have received some guidance from other students) and I'm not competing against anyone. Also, my project's only purpose is to measure distances, nothing else.

Just curious! We do get instances on this forum where several students working on the same project post independently.

Your method of measuring distance is valid and used by racing vehicles in the international Micromouse contest. However it does not work over long distances because light reflected from a rough surface drops off very rapidly with distance and can't compete with ambient illumination.

It helps to have a tubular collimator on the phototransistor to reduce background, and an appropriate bandpass filter in the collimator to selectively pass the laser illumination wavelengths.

Also check that the laser emission wavelength and the reception bandwidth of the phototransistor overlap (see the phototransistor data sheet).

About that, the wavelength emitted by my laser is around 650 nm and the relative spectral sensitivy of my phototransistor goes from 400nm to 1100nm, being at like 65% for 650nm.

Another thing I forgot to add is that I use analogRead() which output ranges from 0 to 1023 and right now it's reading really low values, like 70 or 80.

You need to post a schematic diagram of your setup.

Sorry for making you wait. Here is the schematic diagram I made in Kicad. If I connected everything correctly, that's how it looks in my real life circuit.

I have the phototransistor connected as common collector so that the closer the object gets, the bigger the voltage that's measured.

And here is the code I wrote:


//cambiar cuando sepa a qué pines los voy a conectar
const int pinFototransistor = A0;
const int pinLaser = 8;

float medir();
void limpiarBuffer();
void esperarAccionDeUsuario();

void setup()
{
  Serial.begin(9600);

  pinMode(pinFototransistor, INPUT);

  pinMode(pinLaser, OUTPUT);
}

void loop()
{
  float tensionParaInterpolar = medir();

  Serial.print("Tensión para interpolar: ");
  Serial.println(tensionParaInterpolar);

  limpiarBuffer();
  Serial.println("Presione una tecla para medir otra vez...");
  esperarAccionDeUsuario();
}

float medir()
{
  digitalWrite(pinLaser, LOW);

  float tensionSinLaser = analogRead(pinFototransistor);

  Serial.print("Tension sin láser: ");
  Serial.println(tensionSinLaser);

  Serial.println("Prendiendo láser");

  digitalWrite(pinLaser, HIGH);

  float tensionConLaser = analogRead(pinFototransistor);

  Serial.print("Tension con láser: ");
  Serial.println(tensionConLaser);

  Serial.println("Apagando Láser");
  digitalWrite(pinLaser, LOW);

  return (tensionConLaser - tensionSinLaser);
}

void limpiarBuffer()
{
  while(Serial.available() > 0)
  {
    Serial.read(); // consume caracter por caracter y deja el buffer sin nada al terminar
  }
}

void esperarAccionDeUsuario()
{
  while(Serial.available() == 0)
  {
    //No hace nada, solo espera a que haya algo en el buffer del serial
  }
}

You mean the brighter the illumination on the phototransistor, the larger the voltage.

For low illumination levels and low output voltages, increase the emitter resistor to increase the photocurrent to voltage conversion gain. 100K or even 1Meg are realistic values.

Yeah, you're right, that's what I meant.

Okay, I will try that. Thanks for the suggestion!

But back to my problem, I still don't know why it's showing me inconsistent values... It should show larger voltage values in the monitor the closer the object gets and lower values the farther it gets, but it's showing me the almost the same values each time I run the loop or it even does the opposite of what it should do (like, if I get it closer it shows a value that's little bigger).

Do you think that if I increase the emitter resistor to 100k/1M the problem will be solved?

Can you specify the range and precision you need/want to achieve?

Measuring the reflected power of a continuous-wave (CW) laser to calculate distance requires highly specific circumstances, as power alone only indicates distance when the absolute optical loss is known and predictable.

The commonly available laser ranging tools for short distance e.g. for home improvement are based on angular measurement. For larger distances like land surveyance pulsed lasers are used and the targets are equipped with triple prisms (corner cube reflectors) so that the requirements of eye safety can be satisfied [Edit: These devices use the time-of-flight principle. For certain applications modulated signals and phase measurement is used to increase accuracy.]

The method you apply may be useable to detect if a reflective object is within a certain range or not, but still highly depends on the environment.

You might need a higher resolution ADC e.g. ADS1115 to get a few more bits.

Have you tried it in the dark to maximize the delta V?

I want it to calculate distances from 5cm to 50cm max. Is that realistic with my setup?

I didn't think about the precision before, but I think +/- 3cm would be fine. Again, is this realistic?

I use a Leica Disto range/distance finder on a regular basis.
I don't know what it's operating principle is other than reflection, but it's accuracy is as good as if not better than a standard tape measure.

It has a range up to 50-metres or so, but a lot depends on the reflection surface.
To achieve goods results at longer distances, it needs a reflector similar to a bicycle reflector.

It uses red light, and one noticeable feature is that it has a large (15-mm diameter) lens on the receiving side to gather as much light as possible.

Look up time of flight measurement method. (ToF)

These devices are available for microcontroller use.

It has nothing to do with the different intensity of the laser over distance.

Tom.... :smiley: :+1: :coffee: :australia:

Basically because what you are trying to do is impossible with that LASER, phototransistor and a DIY mechanical setup.
First thing you would need is a good quality optical bench, are you using one?

Next you want to use a photodiode NOT a phototransistor and a LASER that has a constant power output.

I'm not so sure if this approach could work with your hardware. You could make a test setup pointing laser to white printing paper at 50cm distance in complete darkness and try to measure that.
Also, visible light phototransistor like TEPT4400 would match better your 650nm laser.

But that would be valid only for one object and angle. Another object could have different reflectance and shape... And phototransistor doesn't have linear output, so you need many calibration points.