Complete Example (Light Detector)

Modified on Wed, 4 Jan, 2023 at 10:22 PM

In this example, we put together everything we saw in the Basics examples. 


Our goal is to control the position of a servo depending on the ambient light. The principle is the following : when there is no light, the servo moves to position 1. And when light is detected, the servo moves to position 2. 



Light detector principle

The light detector must be a binary detector which detects light or dark. To build this light detector, we will use a photoresistor. As this sensor outputs analog values representing light intensity, we will need to find which value represents the amount of light delimiting light and dark. To make this detection more robust, we will filter sensor values with a hysteresis filter based on 2 thresholds: a high threshold, and a low threshold. Here is how this filter works:

  • When the sensor value is above the high threshold, light is detected
  • When the sensor value is under the low threshold, dark is detected
  • When the sensor value is between the 2 thresholds, nothing can be deduced from this state


Moreover, we will use the on-board LED to monitor detection (light detected = LED on, dark detected = LED off).



Detection adjustment

You will need to adjust the thresholds to your ambient light. How to do this?


At board startup, the low and high thresholds will be initialized at 0 and 1023, respectively. We will start by continuously plotting the sensor values in the Chart. Then we will move our hand over the sensor to simulate a change in the ambient light and we will note the min and max sensor values. Finally, we will adjust the low threshold value to be just above the min sensor value and the high threshold value to be just under the max sensor value.


 

Wiring diagram

  • Connect a servo on pin 8
  • Add an electrolyticcapacitor in parallel with the servo power supply (beware of the polarity!!!). Connect it as close as possible to the servo.
  • Connect a photoresistor on pin A2
  • Add a resistance in series with the photoresistor

 

 

 

Sketch

Upload this program : 1_Basics \ 11_LightDetector


In the setup(), we start by identifying our code with a name and a version number.


Then, we declare pin 13 as an output to control the on-board LED, and we attach a Servo variable to pin 8. We set the servo initial position to 10.0°.


Finally, we display the initial threshold values in the Command Panels of Analog Data 0 and 1.


#include <HITIComm.h>

// code ID
const char code_name[]    PROGMEM = "Light Detector";
const char code_version[] PROGMEM = "1.0.0";

// pins assignment
const int pin_servo       = 8;
const int pin_LED         = LED_BUILTIN;
const int pin_LightSensor = A2;

// Analog Data assignment:
const int ad_threshold_Low  = 0;
const int ad_threshold_High = 1;

// hysteresis filter threshold values
int threshold_Low = 0;
int threshold_High = 1023;

void setup()
{
  // initialize library
  HC_begin();

  // set code ID
  HC_codeName(code_name);
  HC_codeVersion(code_version);

  // set pins mode
  pinMode(pin_LED, OUTPUT);

  // attach Servo to the pin. Move servo to position 10°.
  HC_attachServo(pin_servo, 10000);

  // send initial threshold values to HITIPanel
  HC_analogDataWrite(ad_threshold_Low,  threshold_Low);
  HC_analogDataWrite(ad_threshold_High, threshold_High);
}


Inside the loop(), we start by reading the new threshold values entered in the Command Panels of Analog Data 0 and 1.


As the values you entered might be incorrect, a check is required on these input values: a range check (value must range between 0 and 1023), and a value check (the low threshold must be lower than the high threshold). If required, values are corrected and automatically updated in the ANALOG DATA Control Panel.


Eventually, we compare sensor and threshold values to determine whether light or dark are detected. If light is detected, the LED is switched on and the servo is moved to position 170°. If dark is detected, the LED is turned off and the servo is moved back to its initial position of 10°.


void loop()
{
  // communicate with HITIPanel
  HC_communicate();

  // read threshold values from HITIPanel
  threshold_Low  = (int) HC_analogDataRead(ad_threshold_Low);
  threshold_High = (int) HC_analogDataRead(ad_threshold_High);

  // check inputs range and values
  checkInputs();

  // if light is detected
  if (analogRead(pin_LightSensor) > threshold_High)
  {
    digitalWrite(pin_LED, HIGH);      // turn LED on
    HC_servoWrite(pin_servo, 170000); // move servo to position 170°
  }
  // if dark is detected
  else if (analogRead(pin_LightSensor) < threshold_Low)
  {
    digitalWrite(pin_LED, LOW);       // turn LED off
    HC_servoWrite(pin_servo, 10000);  // move servo back to position 10°
  }
}

void checkInputs()
{
  // check range : 0 <= Threshold <= 1023
  if (threshold_Low > 1023)
  {
    threshold_Low = 1023;

    // update value in HITIPanel
    HC_analogDataWrite(ad_threshold_Low, threshold_Low);
  }
  if (threshold_High > 1023)
  {
    threshold_High = 1023;

    // update value in HITIPanel
    HC_analogDataWrite(ad_threshold_High, threshold_High);
  }

  // check values : Low threshold <= High threshold
  if (threshold_Low > threshold_High)
  {
    threshold_Low = threshold_High;

    // update value in HITIPanel
    HC_analogDataWrite(ad_threshold_Low, threshold_Low);
  }
  if (threshold_High < threshold_Low)
  {
    threshold_High = threshold_Low;

    // update value in HITIPanel
    HC_analogDataWrite(ad_threshold_High, threshold_High);
  }
}


Control Panels

1) Display the IO Control Panels (“IO” button). 

2) The servo is at its initial position (10°) and the on-board LED is off. Move your hand over the photoresistor and check that its analog value changes accordingly.


 

3) Display the DATA Control Panels (“DATA” button). 

4) The current threshold settings are displayed.

 



Chart

1) Open the Chart window (CTRL+T or Tools\Chart).

2) Start data acquisition.



3) To perform the thresholds tuning, the sensor and threshold values are plotted. The on-board LED state is here to indicate when light or dark detection occurs. New data are added every 10ms and only the last 10s are displayed during the acquisition. 


 

 

Thresholds tuning

1) Move your hand over the sensor and try to completely hide it from the light. Do this several times. Then stop data acquisition. Note the upper min value you got when hiding the sensor from the light and note as well the lower max value you got when light hit your sensor (put your mouse over a point to display its coordinates). Zoom in if required by using the mouse wheel or by drag-and-dropping with your mouse on the area to zoom in.


 


2) In the ANALOG DATA Control Panel, enter a low threshold value that is well above the upper min value, and enter a high threshold value that is well under the lower max value. However, respect the fact that the high threshold must still be bigger than the lower threshold. In our example, the upper min value is 130, so we will choose 200 for the low threshold. And the lower max value is 475, so we will take 400 for the high threshold. The detection should now be active and correctly adjusted.

3) Go back to your Chart, clear the previous data, and start a new acquisition.




4) Move your hand over the photoresistor. You should now see the detection triggering the lighting of the on-board LED and the motion of your servo. Our plot shows that the detection is working as expected : 

  • Light is detected (orange curve is high) when sensor values are over the high threshold (blue curve over the red horizontal line).
  • Dark is detected (orange curve is low) when sensor values are below the low threshold (blue curve below the green horizontal line).
  • between the thresholds (between the two horizontal lines), no detection is done. The more distant the thresholds are, the less disturbed the detection is by noisy light.

 


5) Stop data acquisition, reset the zoom, and export your data.







Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons

Feedback sent

We appreciate your effort and will try to fix the article