Go Down

Topic: Light Sensor Response Time and Choosing a Light Sensor (Read 4094 times) previous topic - next topic

dts182

I am working on a project that involves communicating with LEDs. I need to be able to detect the state of a light source that is flashing at about 100 Hz. I am using the phototransistor that comes with the Arduino Starter Kit, but I am noticing that, while the phototransistor detects a difference between the high state and low state, this is very minimal (and about 200 values higher than the phototransistor's value when the LED is completely off). I find this very confusing because the datasheet for the phototransistor claims that the reaction time is 2 microseconds, while my project is working on the scale of milliseconds.

What could be causing this? Are there any other components (preferably inexpensive) that I can use to detect light from a source that is flashing at this frequency? It would be amazing if the light sensor could yield a value when the LED is low that is the same as if the LED was never on. Any help would be very much appreciated. Thank you!

The datasheet for the photoresistor can be found here:

Delta_G

In order to get it to 0 and 1023 you would need complete and total absolute darkness in the whole room and the brightest light that the sensor can handle.  In the real world you'll get two values that differ by some amount like you did.  That's just how things work in the real world.  You aren't saturating the sensor and you don't have absolute darkness so  you don't see 0 or 1023 and you aren't going to.  If you want to have more room between the two readings then you should make the darkness darker or the light brighter. 

It has nothing to do with the response time. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

dts182

Thank you for the response! I understand what you mean. However, I have tested the phototransistor in the same environment without the LED and the value is around, 50. If I have the LED on, it is around 500. However, when flickering, the value will fluctuate from 350-500. I was wondering if there was anyway to achieve a fluctuation of 50-500. I have noticed that decreasing the frequency helps, but it is necessary that I maintain a frequency of at least 100 Hz. Are there any other forms of light detection that would help with this?

Delta_G

OK.  That was a much better description of the problem.  Now I understand.  I don't know the answer, but at least we got the problem straight now. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

dts182

Sorry about that! I am new to the forums, and I will try to be more descriptive in the future. But, if anyone could answer this question, I would be very grateful!

jremington

#5
Feb 01, 2017, 06:11 am Last Edit: Feb 01, 2017, 06:13 am by jremington
Phototransistors are MUCH faster than the Arduino, especially if you print each sample, which is a very slow operation.

Post your code, using code tags ("</>" button).

dts182

Code: [Select]
#include <SPI.h>
#include <TimerOne.h>

const int CHIP_SELECT = 12;
const int LED_PIN = 3;
const int PHOTO_PIN = 0;

const int RESISTOR_VALUE = 255;

boolean triggered = false;
boolean data = false;

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(PHOTO_PIN, INPUT);
 
  setupPot();
 
  Timer1.initialize(3000);
  Timer1.attachInterrupt(trigger);
 
  Serial.begin(115200);
}

void setupPot()
{
  pinMode(CHIP_SELECT, OUTPUT);
 
  SPI.begin();
 
  digitalWrite(CHIP_SELECT, LOW);
  SPI.transfer(B00010001);
  SPI.transfer(RESISTOR_VALUE);
  digitalWrite(CHIP_SELECT, HIGH);
}

void loop()
{
  if(triggered)
  {
    digitalWrite(LED_PIN, data);
    delayMicroseconds(1500);
    Serial.println(analogRead(PHOTO_PIN));
   
    data = !data;
   
    triggered = false;
  }
}

void trigger()
{
  triggered = true;
}


Thank you for the response! Above is the code that I was running when I ran into the aforementioned problems (the frequency I was using was a little more than 100 Hz). For testing purposes, I had the transmitter and receiver running on the same Arduino. The SPI code should not be relevant to the problem (SPI was used to control a digital potentiometer). If the phototransistor is much faster than the Arduino, shouldn't it be able to detect the darkness fully?

jremington

#7
Feb 01, 2017, 05:27 pm Last Edit: Feb 01, 2017, 05:27 pm by jremington
Post a circuit diagram (hand drawn, not Fritzing).

Eliminate stray light by enclosing the photodiode and LED in a black tube (making sure that they are pointed directly at each other), with the ends taped shut with black tape.

For testing, get rid of ALL extraneous code.

dts182

I have attached a picture of the circuit, and I have included new, simplified code (it does not appear as if simplifying the code had an effect).

Code: [Select]
#include <SPI.h>
#include <TimerOne.h>

const int CHIP_SELECT = 12;
const int LED_PIN = 3;
const int PHOTO_PIN = 0;

const int RESISTOR_VALUE = 255;

boolean triggered = false;
boolean data = false;

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(PHOTO_PIN, INPUT);
 
  setupPot();
 
  Timer1.initialize(3000);
  Timer1.attachInterrupt(trigger);
 
  Serial.begin(115200);
}

void setupPot()
{
  pinMode(CHIP_SELECT, OUTPUT);
 
  SPI.begin();
 
  digitalWrite(CHIP_SELECT, LOW);
  SPI.transfer(B00010001);
  SPI.transfer(RESISTOR_VALUE);
  digitalWrite(CHIP_SELECT, HIGH);
}

void loop()
{
  if(triggered)
  {
    digitalWrite(LED_PIN, data);
   
    delayMicroseconds(1500);
    Serial.println(analogRead(PHOTO_PIN));
   
    data = !data;
   
    triggered = false;
  }
}

void trigger()
{
  triggered = true;
}

dts182

Sorry, I uploaded the wrong code. The simplified code is shown below. I've done more testing and it seems to work at 10 Hz, but not at 20 Hz.

Code: [Select]
const int LED_PIN = 3;
const int PHOTO_PIN = 0;
boolean data = false;

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(PHOTO_PIN, INPUT);
 
  Serial.begin(115200);
}

void loop()
{
    digitalWrite(LED_PIN, data);
   
    delay(25);
    Serial.println(analogRead(PHOTO_PIN));
    data = !data;
    delay(25);
}

GoForSmoke

#10
Feb 02, 2017, 12:19 am Last Edit: Feb 02, 2017, 12:19 am by GoForSmoke
Code: [Select]
void loop()
{
    digitalWrite(LED_PIN, data);
   
    delay(25);
    Serial.println(analogRead(PHOTO_PIN));
    data = !data;
    delay(25);
}


You read the detector only so often while varying the led level every how often?

The phototransistor may read in 2 usecs but analog read takes 105 usecs.

See about reading in every loop() without the delays. Save the highest and lowest and print those every 250 msecs.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

dts182

Thank you for the response! Unfortunately, even with the maximum and minimum, the problem persists.

MorganS

Quote
Code: [Select]
void loop()
{
    digitalWrite(LED_PIN, data);
    
    delay(25);
    Serial.println(analogRead(PHOTO_PIN));
    data = !data;
    delay(25);
}

Have you heard of the Nyquist criterion? To sample a specific frequency and resolve that frequency unambiguously (so it doesn't look like any other frequency) you must sample at at least twice the frequency.

You are sampling at less than 20Hz with that code. So of course it works at 10Hz and not at 20Hz.

Now, if you can synchronise to the input, then you can choose to sample 20Hz at 20Hz but then you're not actually resolving a frequency but getting digital bits at defined points in time. That's why SPI works so much faster than I2C. SPI has a separate 'clock' wire which tells the receiver exactly when it should look at the data wire to observe a high or low bit.
"The problem is in the code you didn't post."

dts182

Thank you for the response! I am just a little confused. In the code that I provided, why is it not sampling at 20 Hz (isn't the period of the sampling 50 ms)? Additionally, when I said that it worked when sampling at 10 Hz, I meant that if I changed the delay(25)s to delay(50)s, then I was able to achieve the desired result (sorry if that was ambiguous). If the problem is with regards to the Nyquist criterion, would that cause the undesired results consistently?

jremington

Try this experiment: in setup() turn the LED on, and in loop() record a bunch of samples from the phototransistor as fast as you can.  Examine the results for increase/decrease in the ADC values.

Repeat, leaving the LED off. Post a synopsis of the results.

Go Up