- Passing the hand over a spot as demostrated in the Video (use a 1K resistor).
- Touch a button (use a 10k resistor), by pausing a finger on the light sensor it would completely hide all light and trigger the event.
Watch the Video
How does it work?
All the code is nicely encapsulated in a class named LightSensorButton.- At start time, every 15 seconds or after each trigger the class calibrate the button for the current light in the room
- If we detect at least +-20% light change, then we wait for 1/4 of a second and check
- If the light is back to the reference light, if yes then we raise an Activate event.
- If the light is not back to the reference light, we will wait and retry 5 time and give up.
If we give up this mean somebody turned on or shut the light in the room. We then recalibrate.
- During the day (Sun light), because we recalibrate every 15 seconds
- A person shutting down the light
There is an issue: if a person would stop and start the light in the room, this would trigger one of the 2 buttons. So may be that is not such a great idea after all.
The main program
#include "fArduino.h"
boolean _ledState = false;
// Pins Usage
#define LEFT_PHOTO_RESISTOR_ANALOG_PIN 0
#define RIGHT_PHOTO_RESISTOR_ANALOG_PIN 1
#define ONBOARD_LED_PIN 13
#define RED_LED_PIN 11
#define MAX_SENSOR 2
LightSensorButton _rightLightSensorButton(RIGHT_PHOTO_RESISTOR_ANALOG_PIN, "LeftLightSensor");
LightSensorButton _leftLightSensorButton(LEFT_PHOTO_RESISTOR_ANALOG_PIN, "RightLightSensor");
LightSensorButton* _lightSensorButtons[MAX_SENSOR];
void setup() {
_lightSensorButtons[0] = &_rightLightSensorButton;
_lightSensorButtons[1] = &_leftLightSensorButton;
Board.InitializeComputerCommunication(9600, NULL);
Board.TraceHeader("Photo Resistor as button");
Board.SetPinMode(ONBOARD_LED_PIN, OUTPUT);
Board.SetPinMode(RED_LED_PIN, OUTPUT);
}
void loop() {
for (int s = 0; s < MAX_SENSOR; s++) {
// Recalibrate the light reference every 15 seconds or on demand
if (_lightSensorButtons[s]->NeedReference || _lightSensorButtons[s]->ReferenceTimeOut()) {
_lightSensorButtons[s]->UpdateReferences();
Board.Trace(Board.Format("Getting reference - %s - Ready.", _lightSensorButtons[s]->ToString().c_str()));
}
}
for (int s = 0; s < MAX_SENSOR; s++) {
if (_lightSensorButtons[s]->Activated()) {
_ledState = !_ledState;
Board.LedOn(ONBOARD_LED_PIN, _ledState);
Board.LedOn(RED_LED_PIN, _ledState);
Board.Trace(Board.Format("Changed detected - %s", _lightSensorButtons[s]->ToString().c_str()));
_lightSensorButtons[s]->NeedReference = true;
}
}
}
Breadboard
The LightSensorButton class
class LightSensorButton {
public:
byte UPDATE_REFERENCE_EVERY_X_SECONDS; // Update light reference every 15 seconds
byte MAX_REFERENCES; // Capture the average of 3 light value to compute the lght reference
byte REFERENCE_ACQUISITION_TIME;
byte DETECTION_PERCENT; // If the light change more than +-24% we detected a possible change
byte DETECTION_PERCENT_BACK; // if the light go back +-ReferenceValue, the button was activated by a human (Hopefully, not 100% guaranteed)
byte DETECTION_BACK_WAIT_TIME; // Wait time before we check if the light value went back to the reference value
// Set to true to notify we need to update the light reference
boolean NeedReference;
LightSensorButton(byte pin);
~LightSensorButton();
// Compute and return the new reference light value
int UpdateReferences();
// Return true if it is time to update the reference light
boolean ReferenceTimeOut();
// Return true if the button was activated
boolean Activated();
// Return internal information about the state of button
String ToString();
boolean FingerUp();
boolean FingerDown();
};


No comments:
Post a Comment