1

1 Commits

Author SHA1 Message Date
eleksir
352dc5fa4c Added photoresistor and amb. light compensation
+ Added ambient light compensation logic
+ Added photocell on scheme
+ Added photoresitor to README.md

--HG--
branch : phtoresistor
2019-05-21 16:00:01 +03:00
6 changed files with 87 additions and 26 deletions

6
.gitignore vendored
View File

@@ -1,6 +0,0 @@
.vscode/*
*.swp
*.bak
*.old
*.orig
*.clang-format

6
.hgignore Normal file
View File

@@ -0,0 +1,6 @@
^\.vscode
\.swp$
\.bak$
\.old$
\.orig$
\.clang-format

3
.hgtags Normal file
View File

@@ -0,0 +1,3 @@
ee4999ebdd2d1b54512facafdd03c8a530ea4bfa v1.0
1167bd4b622768ed17e116a4cbac3db90031e6f8 v1.1
109112211e454e608911949914eaa2722fbfed7d v1.2

View File

@@ -12,6 +12,8 @@
* usb phone charger as power supply * usb phone charger as power supply
* 2 push buttons * 2 push buttons
* 1 on/off switch * 1 on/off switch
* 1 photoresistor
* 1 resistor to make secund shoulder of photosensitive "bridge", 10 kOhms, 0.25 watts
* Gainta G521G enclosure (92x66.5x28мм) * Gainta G521G enclosure (92x66.5x28мм)
* 5m power cord * 5m power cord
@@ -24,12 +26,3 @@
### Additional Notes: ### Additional Notes:
My RTC module is not very accurate due to bad quartz chrystal calibration, looks like it is not exactly 32768 Hz and clock runs faster than it should be, giving about 5-8 seconds runaway per day. So i have to implement time correction in software (temperature changes during day/month/year is not very big - about 10 degrees Celsius, so we can use software compensation without thermal compensation). My RTC module is not very accurate due to bad quartz chrystal calibration, looks like it is not exactly 32768 Hz and clock runs faster than it should be, giving about 5-8 seconds runaway per day. So i have to implement time correction in software (temperature changes during day/month/year is not very big - about 10 degrees Celsius, so we can use software compensation without thermal compensation).
This project split into 2 branches:
* **default** that contains generic clock without any additional elements
* **photoresistor** that contains additional hardware - photocell bridge - and software algorithm that compensates ambient light sensed by photocell basing on LED display charachteristics.
### Stable tags for branches:
v1.5 - default
v1.4 - photoresistor

Binary file not shown.

View File

@@ -6,6 +6,33 @@
* 2 buttons for adjusting time. * 2 buttons for adjusting time.
*/ */
/* This software distributed under BSD 2 Clause License
*
* Copyright (c) Sergei Fedosoff, All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this listof conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITYOF SUCH DAMAGE.
*/
/* DS1307 lib by FrankieChu for Seeed RTC module, in my case /* DS1307 lib by FrankieChu for Seeed RTC module, in my case
* Grove___RTC_DS1307-1.0.0.zip */ * Grove___RTC_DS1307-1.0.0.zip */
#include <DS1307.h> #include <DS1307.h>
@@ -16,7 +43,7 @@ SevSeg Display;
/* push button stuff */ /* push button stuff */
const long initial_delay = 600; // wait a bit before spin numbers const long initial_delay = 600; // wait a bit before spin numbers
const long adjust_interval = 200; // delay between consecutive number increments const long adjust_interval = 200; // delay between consecutive number increnents
const long bounce_delay = 20; // contact bounce compensation const long bounce_delay = 20; // contact bounce compensation
const int hrs_btn = A0; // put hour adjusting button on A0 lane const int hrs_btn = A0; // put hour adjusting button on A0 lane
const int min_btn = A1; // put minute adjusting button on A1 lane const int min_btn = A1; // put minute adjusting button on A1 lane
@@ -33,7 +60,11 @@ const long interval = 500;
bool dot = true; bool dot = true;
/* time inaccuracy compensation flag */ /* time inaccuracy compensation flag */
bool compflag = true; uint8_t compflag = 0;
const uint8_t timeSkew = 6; // assume that clock runs faster than should
/* ambient light compensation aka night mode */
const int photoPin = A2;
void setup() void setup()
{ {
@@ -43,14 +74,19 @@ void setup()
byte digitPins[] = {9, 10, 11, 12}; byte digitPins[] = {9, 10, 11, 12};
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 13}; byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 13};
bool resistorsOnSegments = true; // 8 resistors, 330 Ohms each bool resistorsOnSegments = true; // 8 resistors, 330 Ohms each
bool updateWithDelays = false; // Default. Recommended /* updateWithDelays defaults to false and it is recommended value,
* but i was unable to make my display to change brightness with
* recommended value, so i have to use updateWithDelays=true,
* in this case brightness gets changed.
*/
bool updateWithDelays = true; // Default. Recommended
/* without it there is visual bug at 0 o'clock, and in current version /* without it there is visual bug at 0 o'clock, and in current version
* of SevSeg' setChars() does not dots at all */ * of SevSeg' setChars() does not dots at all */
bool leadingZeros = false; bool leadingZeros = false;
Display.begin(hardwareConfig, numDigits, digitPins, segmentPins, Display.begin(hardwareConfig, numDigits, digitPins, segmentPins,
resistorsOnSegments, updateWithDelays, leadingZeros); resistorsOnSegments, updateWithDelays, leadingZeros);
Display.setBrightness(100); Display.setBrightness(100);
// setup clock // setup clock
@@ -69,6 +105,9 @@ void setup()
// setup control buttons // setup control buttons
pinMode(hrs_btn, INPUT_PULLUP); pinMode(hrs_btn, INPUT_PULLUP);
pinMode(min_btn, INPUT_PULLUP); pinMode(min_btn, INPUT_PULLUP);
// setup brigtness sensor
pinMode(photoPin, INPUT);
} }
void loop() void loop()
@@ -77,12 +116,13 @@ void loop()
currentPushTimer = currentMillis; currentPushTimer = currentMillis;
char str[4]; char str[4];
float d; float d;
unsigned int ambLight = analogRead(photoPin);
clock.getTime(); clock.getTime();
// push button magic // push button magic
if ((!btn_pushed) and if ((!btn_pushed) and
((digitalRead(hrs_btn) == LOW) or (digitalRead(min_btn) == LOW))) { ((digitalRead(hrs_btn) == LOW) or (digitalRead(min_btn) == LOW))) {
if (currentPushTimer - previousPushTimer >= initial_delay) { if (currentPushTimer - previousPushTimer >= initial_delay) {
previousPushTimer = currentPushTimer; previousPushTimer = currentPushTimer;
btn_pushed = true; btn_pushed = true;
@@ -90,7 +130,7 @@ void loop()
} }
if (btn_pushed and if (btn_pushed and
(digitalRead(hrs_btn) != LOW) and (digitalRead(min_btn) != LOW)) { (digitalRead(hrs_btn) != LOW) and (digitalRead(min_btn) != LOW)) {
// compensate possible contact bounce with delay // compensate possible contact bounce with delay
if (currentPushTimer - previousPushTimer >= bounce_delay) { if (currentPushTimer - previousPushTimer >= bounce_delay) {
btn_pushed = false; btn_pushed = false;
@@ -134,15 +174,15 @@ void loop()
*/ */
if ((clock.hour == 21) and (clock.minute == 21) and if ((clock.hour == 21) and (clock.minute == 21) and
(clock.second == 21) and (compflag)) { (clock.second == 21) and (compflag == 0)) {
clock.fillByHMS(clock.hour, clock.minute, 14); clock.fillByHMS(clock.hour, clock.minute, (clock.second - timeSkew));
clock.setTime(); clock.setTime();
compflag = false; compflag = 1;
} }
if ((clock.hour == 21) and (clock.minute == 21) and if ((clock.hour == 21) and (clock.minute == 21) and
(clock.second == 23) and (!compflag)) { (clock.second == 23) and (compflag == 1)) {
compflag = true; compflag = 0;
} }
// make blinking dot // make blinking dot
@@ -164,6 +204,31 @@ void loop()
} }
} }
/* ambient light compensation
* ambLight can be in range of 0..1023, if it 800, it has point to use fullbright
*/
if (ambLight >= 940) {
Display.setBrightness(100);
} else if ((ambLight < 900) and (ambLight >= 840)) {
Display.setBrightness(95);
} else if ((ambLight < 800) and (ambLight >= 735)) {
Display.setBrightness(70);
} else if ((ambLight < 700) and (ambLight >= 635)) {
Display.setBrightness(25);
} else if ((ambLight < 600) and (ambLight >= 530)) {
Display.setBrightness(15);
} else if ((ambLight < 500) and (ambLight >= 430)) {
Display.setBrightness(12);
} else if ((ambLight < 400) and (ambLight >= 325)) {
Display.setBrightness(10);
} else if ((ambLight < 300) and (ambLight >= 220)) {
Display.setBrightness(8);
} else if ((ambLight < 200) and (ambLight >= 110)) {
Display.setBrightness(7);
} else if (ambLight < 100) {
Display.setBrightness(6);
}
Display.refreshDisplay(); Display.refreshDisplay();
} }