- 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