This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
arduino:art-clockbell [2019/03/01 11:39] Ilias Iliopoulos [Schematic] Socket pins |
arduino:art-clockbell [2024/02/02 21:47] (current) Ilias Iliopoulos |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Arduino Art - Town Hall Bell clock - Real Time clock with LCD display and Bell functionality ====== | ====== Arduino Art - Town Hall Bell clock - Real Time clock with LCD display and Bell functionality ====== | ||
+ | |||
+ | {{htmlmetatags>metatag-keywords=(arduino, nano,art, bell clock, RTC, ) | ||
+ | metatag-description=(Arduino Art - Town Hall Bell clock - Real Time clock with LCD display and Bell functionality) | ||
+ | }} | ||
===== Introduction ===== | ===== Introduction ===== | ||
Line 8: | Line 12: | ||
On the other hand, the programming methods for creating pulses with duration of several seconds, far beyond the period of a normal Arduino loop, may be found useful by the community. That was the main reason for deciding to publish this article. | On the other hand, the programming methods for creating pulses with duration of several seconds, far beyond the period of a normal Arduino loop, may be found useful by the community. That was the main reason for deciding to publish this article. | ||
- | A picture of the prototype is shown below. | + | Pictures of the prototype are shown below. |
{{arduino:20190228_arduino_bell_board.jpg?600}} | {{arduino:20190228_arduino_bell_board.jpg?600}} | ||
+ | |||
+ | {{arduino:20190314_111606.jpg?200}} | ||
+ | {{arduino:20190314_111611.jpg?200}} | ||
+ | {{arduino:20190314_111620.jpg?200}} | ||
+ | {{arduino:20190314_111707.jpg?200}} | ||
+ | |||
+ | |||
===== Components ===== | ===== Components ===== | ||
Line 36: | Line 47: | ||
===== Schematic ===== | ===== Schematic ===== | ||
- | {{arduino:20190228_arduino_bell_schematic.jpg?1000}} | + | {{arduino:arduino_bell_schematic.jpg?1000}} |
//Handmade schematic?// [[wiki:handmade_schematics|See why..]] | //Handmade schematic?// [[wiki:handmade_schematics|See why..]] | ||
Line 71: | Line 82: | ||
When the time is exactly on the hour, the system produces a number of "hour" pulses. Especially for hours after 12 (p.m for USA), 12 is subtracted from the 24hour number. So at 13:00 the bell sounds once, at 14:00 the bells sound twice, etc. | When the time is exactly on the hour, the system produces a number of "hour" pulses. Especially for hours after 12 (p.m for USA), 12 is subtracted from the 24hour number. So at 13:00 the bell sounds once, at 14:00 the bells sound twice, etc. | ||
- | The value of TIME_BELL_ON defines the time the relay will be at the ON state. Because we want to send a short pulse to the actuator, such as a mini solenoid electromagnet, 300 milliseconds are OK. The value of TIME_BELL_ON is multiplied by 100 to produce the number of milliseconds. | + | The value of TIME_BELL_ON defines the time the relay will be at the ON state. Because we want to send a short pulse to the actuator, such as a mini solenoid electromagnet, 100 milliseconds are OK. The value of TIME_BELL_ON is multiplied by 100 to produce the number of milliseconds. |
- | The value of TIME_BELL_OFF defines the time the relay will be at the ON state. We want the bell to reverberate for a while, so the value of 30 produces 3000 milliseconds which is 3 seconds. | + | The value of TIME_BELL_OFF defines the time the relay will be at the ON state. We want the bell to reverberate for a while, so the value of 35 produces 3500 milliseconds which is 3.5 seconds. |
<code> | <code> | ||
Line 100: | Line 111: | ||
Install a CR2032 coin battery into the RTC socket. | Install a CR2032 coin battery into the RTC socket. | ||
- | When powering the device for the first time, the RTC will have an undefined date and time. Load any example sketch that will allow you to set it manually. I used the one provide with the MD_3231 library. Most important is to set the date, because we will not be able to correct it via the switches. | + | When powering the device for the first time, the RTC will have an undefined date and time. Load any example sketch that will allow you to set it manually. I used [[arduino:md_ds3231_set_clock.ino|the one provided with the MD_3231 library]]. Most important is to set the date, because we will not be able to correct it via the switches. |
Of course, it will not be possible to set the exact time with this method. You will definitely be off, at least by a few seconds. | Of course, it will not be possible to set the exact time with this method. You will definitely be off, at least by a few seconds. | ||
Line 135: | Line 146: | ||
===== Source Code ===== | ===== Source Code ===== | ||
- | <file c++ arduino_art_clock_bell.ino> | + | The source code of the project [[arduino:art-clockbell-code|can be found here]]. |
- | /* | + | |
- | * 10/9/2017 = 27/9/2019 | + | |
- | * CLOCK BELL project | + | |
- | * | + | |
- | * Maintains time, synchronized with a Real Time Clock (RTC) and | + | |
- | * rings a bell on the hour and on half hours | + | |
- | * | + | |
- | * Modification so that triggered events may last not seconds but deci seconds | + | |
- | * | + | |
- | * Example for ringing hour 02:00:00 and 14:00:00 (num_bells = 2) | + | |
- | * ______________ ______________ | + | |
- | * I I I I | + | |
- | * I I I I | + | |
- | * ______I I____________I I____________ | + | |
- | * | + | |
- | * <--bell_on--><---bell_off-><--bell_on--><--bell_off-> | + | |
- | * <------------------ ring_on = true -----------------> | + | |
- | * | + | |
- | * Daylight Saving DST is still not supported | + | |
- | * | + | |
- | * To display characters on the LCD display I use the libary | + | |
- | * LiquidCrystal I2C version 1.2 Author Frank de Brabander | + | |
- | * Maintainer Marco Schwartz Websitehttps://github.com/marcoschwartz/LiquidCrystal_I2C | + | |
- | * which I downloaded from https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c | + | |
- | * WARNING: This library uses the pins of the PCF8574 driver differently than other libraries | + | |
- | * I have used in the past. I had to modify my wiring between PCF8574 and the LCD display. | + | |
- | * Currently, you can buy LCD displays which include a PCF8574 module at almost the same | + | |
- | * price as the LCD itself. Prefer this to save a lot of wiring. If the library does not work | + | |
- | * properly, try the library LiquidCrystal_PCF8574 by Mattias Hertel | + | |
- | * http://www.mathertel.de/Arduino/LiquidCrystal_PCF8574.aspx | + | |
- | * | + | |
- | * | + | |
- | * 27/2/2019 Added NightMode, meaning that if active, the bell will not ring | + | |
- | * on late night hours (actually on selected hours, but NightMode was a catchy phrase!!). | + | |
- | * | + | |
- | * When the last character of the first line shows a Lock symbol, this means that | + | |
- | * clock is in silent mode and will not ring on silent hours. | + | |
- | * If the bell character is shown, the bell will sound for all hours | + | |
- | * | + | |
- | * When the last character of the second line shows a music/note symbol | + | |
- | * this means that this is not a silent hour. If it is blank, it is a silent hour. | + | |
- | * | + | |
- | * | + | |
- | */ | + | |
- | + | ||
- | // To use an I2C LCD 2 lines by 16 columns, at I2C address 0x38 | + | |
- | #include <Wire.h> | + | |
- | #include <LiquidCrystal_I2C.h> | + | |
- | + | ||
- | #define LCD_ADDRESS 0x38 | + | |
- | + | ||
- | #include "RTClib.h" //RTClib by NeiroN | + | |
- | DS1307 rtc; | + | |
- | //DS3231 rtc; | + | |
- | + | ||
- | DateTime now; | + | |
- | + | ||
- | #define LED_PIN LED_BUILTIN // LED that flashes every sec. If you want to use another pin rather than the built-in led, set it here | + | |
- | #define BELL_PIN 7 // Output that controls the bell | + | |
- | #define BELL_HALF_PIN 7 // Output that controls the half hour bell. Can be same as hour pin | + | |
- | + | ||
- | + | ||
- | // Input switches | + | |
- | #define SET_HOURS_PIN 6 // Pressing the button increases hours by one | + | |
- | #define SET_MINUTES_PIN 5 // Pressing the button once increases minutes by one | + | |
- | #define SET_SECONDS_PIN 4 // Pressing the button once sets seconds to zero | + | |
- | + | ||
- | // The name NIGHT_MODE_PIN was probably taken by some library and caused error | + | |
- | // Had to name it NIGHT_PIN | + | |
- | #define NIGHT_PIN 3 // If set to LOW, by connecting the two pin headers, night mode will be inactive | + | |
- | + | ||
- | #define DEBOUNCING_TIME 2 // Debouncing time for reading switches in msec | + | |
- | + | ||
- | #define CLOCK_CORRECTION 0 // msec If crystal gains or lags, we can fix the clock making it run faster (negative value) or slower (positive value) | + | |
- | + | ||
- | /* | + | |
- | * One ring is composed of several bells. | + | |
- | * Each bell has a bell_on time of duration SEC_BELL_ON (in sec) | + | |
- | * and a bell_off time of duration SEC_BELL_OFF (in sec) | + | |
- | * | + | |
- | */ | + | |
- | #define TIME_BELL_ON 3 // times 100 milliseconds. The max achieved time is 25,5 sec for a value of 255 | + | |
- | #define TIME_BELL_OFF 30 // times 100 milliseconds. The max achieved time is 25,5 sec for a value of 255 | + | |
- | + | ||
- | // Define the silent hours, i.e. those that the bell will not ring | + | |
- | int silent_hours[] = { 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7 }; | + | |
- | + | ||
- | // Definition of a custom bell, speaker and sound images | + | |
- | // from https://lastminuteengineers.com/arduino-1602-character-lcd-tutorial/ | + | |
- | byte Bell[8] = { | + | |
- | 0b00100, | + | |
- | 0b01110, | + | |
- | 0b01110, | + | |
- | 0b01110, | + | |
- | 0b11111, | + | |
- | 0b00000, | + | |
- | 0b00100, | + | |
- | 0b00000 | + | |
- | }; | + | |
- | + | ||
- | byte Speaker[8] = { | + | |
- | 0b00001, | + | |
- | 0b00011, | + | |
- | 0b01111, | + | |
- | 0b01111, | + | |
- | 0b01111, | + | |
- | 0b00011, | + | |
- | 0b00001, | + | |
- | 0b00000 | + | |
- | }; | + | |
- | + | ||
- | + | ||
- | byte Sound[8] = { | + | |
- | 0b00001, | + | |
- | 0b00011, | + | |
- | 0b00101, | + | |
- | 0b01001, | + | |
- | 0b01001, | + | |
- | 0b01011, | + | |
- | 0b11011, | + | |
- | 0b11000 | + | |
- | }; | + | |
- | + | ||
- | byte Lock[8] = { | + | |
- | 0b01110, | + | |
- | 0b10001, | + | |
- | 0b10001, | + | |
- | 0b11111, | + | |
- | 0b11011, | + | |
- | 0b11011, | + | |
- | 0b11111, | + | |
- | 0b00000 | + | |
- | }; | + | |
- | + | ||
- | // Volatile variables because they can be used in the interrupt service routine | + | |
- | + | ||
- | // Declares the time variables and set to initial value. | + | |
- | volatile int hours = 00; | + | |
- | volatile int minutes = 00; | + | |
- | volatile int seconds = 05; | + | |
- | volatile int deci_seconds = 00; | + | |
- | + | ||
- | // In order to set the RTC, I need those | + | |
- | volatile int myyear; | + | |
- | volatile int mymonth; | + | |
- | volatile int myday; | + | |
- | + | ||
- | volatile unsigned long current_time; | + | |
- | volatile unsigned long previous_time = millis(); | + | |
- | volatile unsigned long deci_previous_time = millis(); | + | |
- | + | ||
- | // Variables to represent the timing of each hit of the hammer to the bell | + | |
- | // Values are in seconds | + | |
- | volatile int t_bell_on = 0; | + | |
- | volatile int t_bell_off = 0; | + | |
- | + | ||
- | // Boolean to monitor if a ringing process (several bells) is active | + | |
- | boolean ring_on = false; | + | |
- | + | ||
- | // Indicates that ringing is taking place for the half hour | + | |
- | // Used only to select the bell pin | + | |
- | boolean ring_30min = false; | + | |
- | + | ||
- | boolean bell_on = false; // Indicates that we are at the HIGH period of the bell pulse | + | |
- | boolean bell_off = false;// Indicates that we are at the LOW period of the bell pulse | + | |
- | + | ||
- | int num_bells = 0; | + | |
- | + | ||
- | int correction = CLOCK_CORRECTION; | + | |
- | int interval = 100 + correction; | + | |
- | + | ||
- | boolean night_mode = true; // Indicates if night mode is set, by reading the input pin | + | |
- | + | ||
- | LiquidCrystal_I2C lcd(LCD_ADDRESS,16,2); | + | |
- | + | ||
- | void setup() | + | |
- | { | + | |
- | + | ||
- | + | ||
- | lcd.init(); | + | |
- | lcd.backlight(); | + | |
- | + | ||
- | pinMode(LED_PIN, OUTPUT); | + | |
- | pinMode(BELL_PIN, OUTPUT); | + | |
- | digitalWrite(BELL_PIN, LOW); | + | |
- | pinMode(BELL_HALF_PIN, OUTPUT); | + | |
- | digitalWrite(BELL_HALF_PIN, LOW); | + | |
- | + | ||
- | pinMode(SET_HOURS_PIN, INPUT_PULLUP); | + | |
- | pinMode(SET_MINUTES_PIN, INPUT_PULLUP); | + | |
- | pinMode(SET_SECONDS_PIN, INPUT_PULLUP); | + | |
- | + | ||
- | pinMode(NIGHT_PIN, INPUT_PULLUP); | + | |
- | + | ||
- | lcd.createChar(0, Bell); | + | |
- | lcd.createChar(1, Speaker); | + | |
- | lcd.createChar(2, Sound); | + | |
- | lcd.createChar(3, Lock); | + | |
- | + | ||
- | sync_from_RTC(); | + | |
- | + | ||
- | Serial.begin(9600); | + | |
- | + | ||
- | } | + | |
- | + | ||
- | // Runs every interval (100msec = 1ds) | + | |
- | void every_interval() | + | |
- | { | + | |
- | // Handle the bell timing | + | |
- | // Decrement all bell timers. We do not care if they are active or not | + | |
- | if (t_bell_on > 0) | + | |
- | t_bell_on --; | + | |
- | + | ||
- | if (t_bell_off > 0) | + | |
- | t_bell_off --; | + | |
- | + | ||
- | deci_seconds ++; | + | |
- | if (deci_seconds >= 10) { | + | |
- | deci_seconds = 0; | + | |
- | every_second(); | + | |
- | } | + | |
- | return; | + | |
- | } | + | |
- | + | ||
- | + | ||
- | void every_second() | + | |
- | { | + | |
- | seconds ++; | + | |
- | if (seconds >= 60) { | + | |
- | seconds = 0; | + | |
- | minutes ++; | + | |
- | if (minutes >= 60) { | + | |
- | minutes = 0; | + | |
- | hours ++; | + | |
- | if (hours >= 24) { | + | |
- | hours = 0; | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | // IT IS WRONG TO PLACE HERE show_time_on_lcd(); . IT DISTURBS TIMING | + | |
- | // IT STEELS TIME (approx 4msec) FROM TIME_BELL_ON | + | |
- | // LCD handling must be placed in loop2() | + | |
- | } | + | |
- | + | ||
- | + | ||
- | // Presents the time on the LCD | + | |
- | void show_time_on_lcd() | + | |
- | { | + | |
- | + | ||
- | // print date on line 1 of LCD | + | |
- | lcd.setCursor(2,0); | + | |
- | if (myday < 10) | + | |
- | lcd.print("0"); | + | |
- | lcd.print(myday); | + | |
- | lcd.print("."); | + | |
- | if (mymonth < 10); | + | |
- | lcd.print("0"); | + | |
- | lcd.print(mymonth); | + | |
- | lcd.print("."); | + | |
- | lcd.print(myyear); | + | |
- | + | ||
- | // print hour on line 2 of LCD | + | |
- | lcd.setCursor(3,1); | + | |
- | if (hours < 10) | + | |
- | lcd.print("0"); | + | |
- | lcd.print(hours); | + | |
- | lcd.print(":"); | + | |
- | if (minutes < 10) | + | |
- | lcd.print("0"); | + | |
- | lcd.print(minutes); | + | |
- | lcd.print(":"); | + | |
- | if (seconds < 10) | + | |
- | lcd.print("0"); | + | |
- | lcd.print(seconds); | + | |
- | + | ||
- | // Prints an indication for Night Mode | + | |
- | lcd.setCursor(15,0); | + | |
- | if (night_mode) | + | |
- | lcd.write(byte(3)); // Lock symbol | + | |
- | else | + | |
- | lcd.write(byte(0)); // Bell symbol | + | |
- | + | ||
- | // Prints an indication if the hour is in the list of silent hours | + | |
- | lcd.setCursor(15,1); | + | |
- | if (silent_hour(hours)) | + | |
- | lcd.print(" "); | + | |
- | else | + | |
- | lcd.write(byte(2)); // Sound symbol | + | |
- | + | ||
- | return; | + | |
- | } | + | |
- | + | ||
- | /* | + | |
- | * Do not use loop() for user code, because it handles timing. | + | |
- | * Use loop2() instead | + | |
- | */ | + | |
- | void loop() | + | |
- | { | + | |
- | current_time = millis(); | + | |
- | if (current_time - previous_time >= interval) { | + | |
- | every_interval(); | + | |
- | previous_time = current_time; | + | |
- | } | + | |
- | + | ||
- | // do the normal work | + | |
- | loop2(); | + | |
- | } | + | |
- | + | ||
- | + | ||
- | + | ||
- | // User code goes here | + | |
- | void loop2() | + | |
- | { | + | |
- | // Synchronize with RTC every minute at xx:50:00:00 | + | |
- | // Close to the end of the minute to avoid interacting with | + | |
- | // actions that normally occur at xx:00:00:00 | + | |
- | if (seconds == 50 && deci_seconds == 0) { | + | |
- | sync_from_RTC(); | + | |
- | + | ||
- | } | + | |
- | + | ||
- | if (ring_on) | + | |
- | process_ringing(); | + | |
- | else { | + | |
- | if (seconds == 0 && deci_seconds == 0) { | + | |
- | // Addition for night mode | + | |
- | if (minutes == 0 && night_mode && !silent_hour(hours)) | + | |
- | ring(hours); | + | |
- | + | ||
- | else { | + | |
- | + | ||
- | if (minutes == 30 && night_mode && !silent_hour(hours)) | + | |
- | ring_half(); | + | |
- | + | ||
- | } | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | // LCD handling | + | |
- | static int previous_seconds; | + | |
- | if (seconds != previous_seconds) { | + | |
- | show_time_on_lcd(); | + | |
- | previous_seconds = seconds; | + | |
- | } | + | |
- | + | ||
- | // Set time manually via switches | + | |
- | read_switches(); | + | |
- | + | ||
- | return; | + | |
- | } | + | |
- | + | ||
- | void read_switches() | + | |
- | { | + | |
- | if (digitalRead(SET_HOURS_PIN) == LOW) { | + | |
- | delay(DEBOUNCING_TIME); | + | |
- | if (digitalRead(SET_HOURS_PIN) == LOW) { | + | |
- | hours = (hours + 1) % 24; | + | |
- | } | + | |
- | while (digitalRead(SET_HOURS_PIN) == LOW){ | + | |
- | } | + | |
- | set_RTC(); | + | |
- | } | + | |
- | + | ||
- | if (digitalRead(SET_MINUTES_PIN) == LOW) { | + | |
- | delay(DEBOUNCING_TIME); | + | |
- | if (digitalRead(SET_MINUTES_PIN) == LOW) { | + | |
- | minutes = (minutes + 1) % 60; | + | |
- | } | + | |
- | while (digitalRead(SET_MINUTES_PIN) == LOW) { | + | |
- | } | + | |
- | set_RTC(); | + | |
- | } | + | |
- | + | ||
- | if (digitalRead(SET_SECONDS_PIN) == LOW) { | + | |
- | delay(DEBOUNCING_TIME); | + | |
- | if (digitalRead(SET_SECONDS_PIN) == LOW) { | + | |
- | seconds = 00; | + | |
- | deci_seconds = 0; | + | |
- | } | + | |
- | while (digitalRead(SET_SECONDS_PIN) == LOW) { | + | |
- | } | + | |
- | set_RTC(); | + | |
- | } | + | |
- | + | ||
- | if (digitalRead(NIGHT_PIN) == LOW) { | + | |
- | night_mode = false; // Headers are connected, bells ring all round the clock | + | |
- | } else { | + | |
- | night_mode = true; | + | |
- | } | + | |
- | return; | + | |
- | } | + | |
- | + | ||
- | void set_RTC() | + | |
- | { | + | |
- | + | ||
- | rtc.adjust(DateTime(myyear, mymonth, myday, hours, minutes, seconds)); | + | |
- | return; | + | |
- | } | + | |
- | + | ||
- | void start_bell() | + | |
- | { | + | |
- | int bell_pin; | + | |
- | if (ring_30min) | + | |
- | bell_pin = BELL_HALF_PIN; | + | |
- | else | + | |
- | bell_pin = BELL_PIN; | + | |
- | digitalWrite(bell_pin, HIGH); | + | |
- | digitalWrite(LED_PIN, HIGH); | + | |
- | bell_on = true; | + | |
- | bell_off = false; | + | |
- | t_bell_on = TIME_BELL_ON; | + | |
- | return; | + | |
- | } | + | |
- | + | ||
- | void stop_bell() | + | |
- | { | + | |
- | int bell_pin; | + | |
- | if (ring_30min) | + | |
- | bell_pin = BELL_HALF_PIN; | + | |
- | else | + | |
- | bell_pin = BELL_PIN; | + | |
- | digitalWrite(bell_pin, LOW); | + | |
- | digitalWrite(LED_PIN, LOW); | + | |
- | bell_on = false; | + | |
- | bell_off = true; | + | |
- | t_bell_off = TIME_BELL_OFF; | + | |
- | return; | + | |
- | } | + | |
- | + | ||
- | /* Rings the bell, depending on the hour provided. | + | |
- | The hours variable works on the 24 hour format | + | |
- | but we want to ring the bell as per the 12 hour | + | |
- | + | ||
- | Skips ringing if previous hours is same. | + | |
- | This condition may happen if we have a ring and after some time, | + | |
- | the RTC synchronizes the internal clock and we go back to xx:00:00 | + | |
- | This functionality is only for full hours. Half hours and 01:00:00 are | + | |
- | totally separated | + | |
- | + | ||
- | */ | + | |
- | void ring(int num_hours) | + | |
- | { | + | |
- | static int previous_hours = 0; | + | |
- | + | ||
- | // protect from setting back hours via switches or sync with RTC | + | |
- | if (num_hours == previous_hours) | + | |
- | return; | + | |
- | + | ||
- | previous_hours = num_hours; | + | |
- | ring_on = true; | + | |
- | if (num_hours > 12) | + | |
- | num_bells = num_hours - 12; | + | |
- | else if (num_hours == 0) | + | |
- | num_bells = 12; | + | |
- | else | + | |
- | num_bells = num_hours; | + | |
- | start_bell(); | + | |
- | return; | + | |
- | } | + | |
- | + | ||
- | // Ring at half hour | + | |
- | void ring_half() | + | |
- | { | + | |
- | // Is there a way to protect from syncing back to xx:30:00 ???? | + | |
- | + | ||
- | ring_30min = true; | + | |
- | ring_on = true; | + | |
- | num_bells = 1; | + | |
- | start_bell(); | + | |
- | return; | + | |
- | } | + | |
- | + | ||
- | void process_ringing() | + | |
- | { | + | |
- | if (bell_on && t_bell_on <= 0) | + | |
- | stop_bell(); | + | |
- | + | ||
- | if (bell_off && t_bell_off <= 0) { | + | |
- | num_bells --; | + | |
- | if (num_bells > 0) | + | |
- | start_bell(); | + | |
- | else { | + | |
- | bell_off = false; | + | |
- | ring_on = false; | + | |
- | ring_30min = false; | + | |
- | } | + | |
- | } | + | |
- | return; | + | |
- | } | + | |
- | + | ||
- | void send_time_to_serial() | + | |
- | { | + | |
- | Serial.print("Time: "); | + | |
- | if (hours , 10) | + | |
- | Serial.print("0"); | + | |
- | Serial.print(hours); | + | |
- | Serial.print(":"); | + | |
- | if (minutes < 10) | + | |
- | Serial.print("0"); | + | |
- | Serial.print(minutes); | + | |
- | Serial.print(":"); | + | |
- | if (seconds < 10) | + | |
- | Serial.print("0"); | + | |
- | Serial.println(seconds); | + | |
- | } | + | |
- | + | ||
- | // Presents variables on LCD for debugging | + | |
- | void show_state_on_lcd() | + | |
- | { | + | |
- | // Clear line 1 | + | |
- | lcd.setCursor(0,1); | + | |
- | lcd.print(" "); | + | |
- | + | ||
- | lcd.setCursor(0,1); | + | |
- | lcd.print("R:"); | + | |
- | if (ring_on) { | + | |
- | lcd.print("ON"); | + | |
- | lcd.print(" B="); | + | |
- | lcd.print(num_bells); | + | |
- | lcd.print(" TB="); | + | |
- | lcd.print(t_bell_on); | + | |
- | lcd.print(" TBO="); | + | |
- | lcd.print(t_bell_off); | + | |
- | + | ||
- | } | + | |
- | else | + | |
- | lcd.print("OFF"); | + | |
- | + | ||
- | + | ||
- | } | + | |
- | + | ||
- | void sync_from_RTC() | + | |
- | { | + | |
- | now = rtc.now(); | + | |
- | + | ||
- | myyear = now.year(); | + | |
- | mymonth = now.month(); | + | |
- | myday = now.day(); | + | |
- | hours = now.hour(); | + | |
- | minutes = now.minute(); | + | |
- | seconds = now.second(); | + | |
- | } | + | |
- | + | ||
- | // checks if an int value is included in an array of ints | + | |
- | boolean in_int_array(int value, const int *arr, int num_elements) { | + | |
- | + | ||
- | for (int i=0; i< num_elements ; ++i ) { | + | |
- | if (value == arr[i]) | + | |
- | return true; | + | |
- | } | + | |
- | return false; | + | |
- | } | + | |
- | + | ||
- | // check if a given hour is silent | + | |
- | boolean silent_hour(int this_hour) { | + | |
- | + | ||
- | if (in_int_array(this_hour, silent_hours, sizeof(silent_hours)/sizeof(int))) | + | |
- | return true; | + | |
- | else | + | |
- | return false; | + | |
- | } | + | |
- | </file> | + | ~~DISQUS~~ |