1

15 Commits
v1.0 ... v1.5

Author SHA1 Message Date
eleksir
c29c1ee876 Added info about tags in default branch. 2019-06-02 15:30:06 +03:00
eleksir
68b8702396 Bring changes from tag v1.4 2019-06-02 15:27:04 +03:00
eleksir
9c800ee335 Added info about photoresistor branch to README.md 2019-05-21 16:13:41 +03:00
eleksir
c7ed04e987 Added tag v1.2 for changeset 109112211e45 2019-05-15 18:28:34 +03:00
eleksir
ac646f6ac0 Replaced clock_schem.pdf with more correct 2019-05-15 18:28:09 +03:00
eleksir
d501cce0f1 Updated README.md 2019-05-15 18:25:59 +03:00
eleksir
be82b11537 Time adjust algo changed
+ Added 600ms pause before spin numbers if button pressed
* Changed increment delay 500ms -> 200ms
* Button bounce compensation code
2019-05-14 20:52:37 +03:00
eleksir
757210bfc5 Now compensation hack should work. 2019-05-12 07:55:17 +03:00
eleksir
2900e78ca4 Bits of cleanup, fix indentaion and coding style 2019-05-12 07:52:44 +03:00
eleksir
825c3096f2 Implement software time inaccuracy compensation hack
32768 Hz quartz chrystal resonator tends to be a bit inaccurate giving
about 5-10 seconds per day time skew
2019-04-20 12:04:05 +03:00
eleksir
f46a294535 Converted to unix EOL file 2019-04-20 11:52:00 +03:00
eleksir
72bd8ec064 Added hgignore file :) 2019-04-20 11:48:24 +03:00
eleksir
a93fcbfa80 Added tag v1.1 for changeset 1167bd4b6227 2019-03-01 01:27:27 +03:00
eleksir
f18e0a1166 Make it possible to display time without explicit leading zeroes 2019-03-01 01:27:07 +03:00
eleksir
5440f7852a Added tag v1.0 for changeset ee4999ebdd2d 2019-02-28 22:33:36 +03:00
5 changed files with 201 additions and 140 deletions

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

@@ -4,13 +4,32 @@
### Component base is very simple:
* Arduino NANO v3 chinese replica
* 7 segment 4 digit LED indicator with common anode, FYQ-5641BG-21
* Arduino NANO v3 chinese replica (on Atmega-168 chip)
* 7 segment 4 digit LED indicator with common anode, FYQ-5641BD-21 (red LEDs)
* 8 resistors that limiting current on LED segments, 330 Ohms, 0.25 watts
* RTC Module GEEGROW with DS1307 chip
* RTC Module GEEGROW with DS1307 chip (very basic, only RTC chip, quartz resonator, button battery, no additional memory chip)
* 5x7 cm single side prototyping board
* usb phone charger as power supply
* 2 push buttons
* 1 on/off switch
* Gainta G521G enclosure (92x66.5x28мм)
* 5m power cord
### Optionally you may need:
* Capasitor with well capacity if your charger has small capasitor on output
* Fuse, to protect your device
* DC/DC transformer if you have power supply that gives more than 5 volts or less than 4.5 volts (this will give additional surge protection if your power supply dies, this can happen after 3-5 years of uninterrupted work)
### 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).
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

@@ -1,137 +1,170 @@
/*
* 7 Segment 4 Digits clock with digit point separator
*
* It uses display module with common anode and DS1307
* RTC module to enhance time keeping ability of
* Atmega 328p based Arduino nano microcontroller and
* 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 list
of 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 POSSIBILITY
OF SUCH DAMAGE.
*/
#include <SevSeg.h>
#include <Wire.h>
#include <TimeLib.h>
// DS1307 lib by FrankieChu for Seeed RTC module
#include <DS1307.h>
DS1307 clock;
SevSeg Display;
unsigned long currentMillis;
unsigned long previousMillis = 0;
const long interval = 500;
const int hrs_btn = A0;
const int min_btn = A1;
bool dot = true;
uint8_t minutes;
uint8_t hours;
void setup()
{
// setup display
byte hardwareConfig = COMMON_ANODE;
byte numDigits = 4;
byte digitPins[] = {9, 10, 11, 12};
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 13};
bool resistorsOnSegments = true; // 8 resistors, 330 Ohms each
bool updateWithDelays = false; // Default. Recommended
/* without it there is visual bug at 0 o'clock, and in current version of
* SevSeg' setChars() does not dots at all */
bool leadingZeros = true;
Display.begin(hardwareConfig, numDigits, digitPins, segmentPins,
resistorsOnSegments, updateWithDelays, leadingZeros);
Display.setBrightness(90);
// setup clock
clock.begin();
// if rtc returns incorrect time, reset it to some default value
clock.getTime();
if (( clock.hour > 23 ) || (clock.minute > 59))
{
clock.fillByYMD(2019,2,23); // 23 Feb 2013
clock.fillByHMS(15,52,30); // 15:52 30"
clock.fillDayOfWeek(SAT); // Saturday
clock.setTime(); // put date to rtc
}
// setup control buttons
pinMode(hrs_btn, INPUT_PULLUP);
pinMode(min_btn, INPUT_PULLUP);
}
void loop()
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
if (dot == false)
{
dot = true;
if (digitalRead(hrs_btn) == LOW)
{
clock.getTime();
hours = clock.hour + 1;
(hours > 23)? hours = 0: hours;
clock.fillByHMS(hours, clock.minute, 0);
clock.setTime();
}
if (digitalRead(min_btn) == LOW)
{
clock.getTime();
minutes = clock.minute + 1;
(minutes > 59)? minutes = 0: minutes;
clock.fillByHMS(clock.hour, minutes, 0);
clock.setTime();
}
}
else
{
dot = false;
}
}
clock.getTime();
// make blinking dot
if (dot == true) {
Display.setNumber((clock.hour * 100 + clock.minute), 2);
} else {
Display.setNumber((clock.hour * 100 + clock.minute));
}
Display.refreshDisplay();
}
/* vim: set filetype=cpp: */
/*
* 7 Segment 4 Digits clock with digit point separator
*
* It uses display module with common anode and DS1307 RTC module to enhance
* time keeping ability of Atmega 328p based Arduino Nano microcontroller and
* 2 buttons for adjusting time.
*/
/* DS1307 lib by FrankieChu for Seeed RTC module, in my case
* Grove___RTC_DS1307-1.0.0.zip */
#include <DS1307.h>
#include <SevSeg.h>
DS1307 clock;
SevSeg Display;
/* push button stuff */
const long initial_delay = 600; // wait a bit before spin numbers
const long adjust_interval = 200; // delay between consecutive number increments
const long bounce_delay = 20; // contact bounce compensation
const int hrs_btn = A0; // put hour adjusting button on A0 lane
const int min_btn = A1; // put minute adjusting button on A1 lane
bool btn_pushed = false; // is button pushed?
unsigned long currentPushTimer;
unsigned long previousPushTimer = 0;
uint8_t minutes;
uint8_t hours;
/* dot blinking stuff */
unsigned long currentMillis;
unsigned long previousMillis = 0;
const long interval = 500;
bool dot = true;
/* time inaccuracy compensation flag */
bool compflag = true;
void setup()
{
// setup display
byte hardwareConfig = COMMON_ANODE;
byte numDigits = 4;
byte digitPins[] = {9, 10, 11, 12};
byte segmentPins[] = {2, 3, 4, 5, 6, 7, 8, 13};
bool resistorsOnSegments = true; // 8 resistors, 330 Ohms each
bool updateWithDelays = false; // Default. Recommended
/* without it there is visual bug at 0 o'clock, and in current version
* of SevSeg' setChars() does not dots at all */
bool leadingZeros = false;
Display.begin(hardwareConfig, numDigits, digitPins, segmentPins,
resistorsOnSegments, updateWithDelays, leadingZeros);
Display.setBrightness(100);
// setup clock
clock.begin();
// if rtc returns incorrect time, reset it to some default value
clock.getTime();
if ((clock.hour > 23) || (clock.minute > 59)) {
clock.fillByYMD(2019, 2, 23); // 23 Feb 2019
clock.fillByHMS(15, 52, 30); // 15:52:30"
clock.fillDayOfWeek(SAT); // Saturday
clock.setTime(); // put date to rtc
}
// setup control buttons
pinMode(hrs_btn, INPUT_PULLUP);
pinMode(min_btn, INPUT_PULLUP);
}
void loop()
{
currentMillis = millis();
currentPushTimer = currentMillis;
char str[4];
float d;
clock.getTime();
// push button magic
if ((!btn_pushed) and
((digitalRead(hrs_btn) == LOW) or (digitalRead(min_btn) == LOW))) {
if (currentPushTimer - previousPushTimer >= initial_delay) {
previousPushTimer = currentPushTimer;
btn_pushed = true;
}
}
if (btn_pushed and
(digitalRead(hrs_btn) != LOW) and (digitalRead(min_btn) != LOW)) {
// compensate possible contact bounce with delay
if (currentPushTimer - previousPushTimer >= bounce_delay) {
btn_pushed = false;
}
}
if (btn_pushed) {
if (currentPushTimer - previousPushTimer >= adjust_interval) {
previousPushTimer = currentPushTimer;
if (digitalRead(hrs_btn) == LOW) {
hours = clock.hour + 1;
(hours > 23) ? hours = 0 : hours;
clock.fillByHMS(hours, clock.minute, 0);
clock.setTime();
}
if (digitalRead(min_btn) == LOW) {
minutes = clock.minute + 1;
(minutes > 59) ? minutes = 0 : minutes;
clock.fillByHMS(clock.hour, minutes, 0);
clock.setTime();
}
}
}
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (dot)
dot = false;
else
dot = true;
}
/*
* Let's implement time compenstion for individual rtc module time
* charachteristics. In in my case quartz resonator as inaccurate as
* +/- about 5-8 seconds per 24 hours, maybe its require more EMI
* shielding?
*/
if ((clock.hour == 21) and (clock.minute == 21) and
(clock.second == 21) and (compflag)) {
clock.fillByHMS(clock.hour, clock.minute, 14);
clock.setTime();
compflag = false;
}
if ((clock.hour == 21) and (clock.minute == 21) and
(clock.second == 23) and (!compflag)) {
compflag = true;
}
// make blinking dot
if (clock.hour > 0) {
if (dot) {
Display.setNumber((clock.hour * 100 + clock.minute), 2);
} else {
Display.setNumber((clock.hour * 100 + clock.minute));
}
} else {
/* 0 o'clock is an exception, we don't want to see "00.00", we
want see "0.00" or "0 00", so we have to use this "hack" */
if (dot) {
d = float(clock.minute) / 100;
Display.setNumber(d, 2);
} else {
sprintf(str, "%2d%02d", clock.hour, clock.minute);
Display.setChars(str);
}
}
Display.refreshDisplay();
}
/* vim: set filetype=cpp: */