Thanks dougp!
I have tried to implement the new setup menu but i have a problem.
- If i keep the encoder button pressed for 3 seconds i get into the setup menu "encoder_alarm", this is ok
- i can toggle "select" boolean to be able to chose digits to set (when select = true) and to adjust the values of digits set (select = false)
- one thing i do not know how to do is how to exit the "encoder_alarm" loop once i have finished setting up the alarm.
as i have 4 groups of digits to set: hour start, minute start, hour end and minute end, each 2 digit groups I have set up the 5th "menu item" which when selected, and button clicked, should exit the loop, but not sure how to do that.
full code below, keep in mind this code is test WIP and a bit messy:
#include <EEPROM.h>
#include <ezButton.h>
#include <LedControl.h>
#include <TimeLib.h>
#include <RTClib.h>
#include <OneWire.h>
#include <DS1307RTC.h>
#include <SPI.h>
#define MAXIMCCLD 10 // output - CS/LOAD
#define MAXIMCCCLK 11 // output - CLOCK
#define MAXIMCCDATA 9 // output - DATA
#define DS1307_I2C_ADDRESS 0x68 // define the RTC I2C address
#define ENCODER_SW 8
ezButton button(8); // create ezButton object that attach to pin 7;
LedControl MaximCC=LedControl(MAXIMCCDATA, MAXIMCCCLK, MAXIMCCLD, 1); // Define pins for Maxim 72xx and how many 72xx we use
int LED = 4;
int LED2 = 119;
volatile signed int counter_hour_start = EEPROM.read(2);
volatile signed int counter_minute_start = EEPROM.read(3);
volatile signed int counter_hour_end = EEPROM.read(4);
volatile signed int counter_minute_end = EEPROM.read(5);
volatile signed int counter;
// usually the rotary encoders three pins have the ground pin in the middle
enum PinAssignments {
encoderPinA = 2, // right DT
encoderPinB = 3, // left CLK
};
// a counter for the dial
signed int lastReportedPos_hour_start = 1; // change management
signed int lastReportedPos_minute_start = 1; // change management
signed int lastReportedPos_hour_end = 1; // change management
signed int lastReportedPos_minute_end = 1; // change management
signed int lastReportedPos_brightness_count = 1; // change management
// interrupt service routine vars
boolean A_set = false;
boolean B_set = false;
int previousSecond = 0;
int tensofhours, singlehours, tensofminutes, singleminutes,tensofhours1, singlehours1, tensofminutes1, singleminutes1,singlecounts,tensofcounts;
const int SHORT_PRESS_TIME = 1000; // 1000 milliseconds
const int LONG_PRESS_TIME = 1000; // 1000 milliseconds
unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
bool isPressing = false;
bool isLongDetected = false;
unsigned long count0 = true;
unsigned long count1;
unsigned long count2;
unsigned long count3;
unsigned long count4;
unsigned long count5;
unsigned long count6;
unsigned long largerThanZero;
int period = 20;
unsigned long time_now = 0;
signed int lastReportedPos_setupMenuCounter = 1;
signed int setupMenuCounter = 1; // counter goes from 1 to 3 or whatever the number of menu items is. Counter cycles so after 3 we get 1 or if we go to less than 1 we get 3
signed int lastReportedPos_sleepWakeCounter = 1;
signed int sleepWakeCounter = 1;
int oldEncoderButtonState = LOW;
int encoderButtonState = LOW;
bool select = false;
volatile unsigned int encoderPos = 0; // a counter for the dial
unsigned int lastReportedPos = 1; // change management
static boolean rotating = false; // debounce management
//==============================================================================
// SETUP
//==============================================================================
void setup() {
pinMode(LED, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(53, OUTPUT);
pinMode(ENCODER_SW, INPUT);
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
// Initialize RTC and set as SyncProvider.
// Later RTC will be synced with DCF time
setSyncProvider(RTC.get); // the function to get the time from the RTC
// check if RTC has set the system time
if (timeStatus() != timeSet)
{ // Unable to sync with the RTC - activate RTCError LED
}
MaximCC.shutdown(0,false);
MaximCC.setIntensity(0,15);
MaximCC.clearDisplay(0);
button.setDebounceTime(10); // set debounce time to 50 milliseconds
button.setCountMode(COUNT_FALLING);
// turn on pullup resistors
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, doEncoderB, CHANGE);
tensofhours = counter_hour_start / 10;
singlehours = counter_hour_start % 10;
tensofminutes = counter_minute_start / 10;
singleminutes = counter_minute_start % 10;
tensofhours1 = counter_hour_end / 10;
singlehours1 = counter_hour_end % 10;
tensofminutes1 = counter_minute_end / 10;
singleminutes1 = counter_minute_end % 10;
}
//==============================================================================
// LOOP
//==============================================================================
void loop() {
tasksEverySecond();
// check if there was a short or a long press of a bottom //
button.loop(); // MUST call the loop() function first
if(button.isPressed()){
pressedTime = millis();
isPressing = true;
isLongDetected = false;
}
if(button.isReleased()) {
isPressing = false;
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
if( pressDuration < SHORT_PRESS_TIME ) // on short button press, keep resetting the counter to zero so it does not count before long press
if (count0 == true){
button.resetCount();
}
}
if(isPressing == true && isLongDetected == false) {
long pressDuration = millis() - pressedTime;
if( pressDuration > LONG_PRESS_TIME ) {
isLongDetected = true;
}
}
if (count0 == true){
if(millis() > time_now + period){
time_now = millis();
manual_brightness_control();
}
} else {
if(millis() > time_now + period){
time_now = millis();
encoder_alarm ();
}
}
if (isLongDetected == true){
button_press();
}
digitalWrite(53, LOW); // set pin 0 low when leaving ISR()
}
//==============================================================================
// tasksEverySecond
//==============================================================================
void tasksEverySecond()
{
if (second() != previousSecond)
{
previousSecond = second();
displayRtcTime();
ledTest();
}
}
//==============================================================================
// ENCODER INTERRUP ROUTINE
//==============================================================================
// Interrupt on A changing state
void doEncoderA() {
// debounce
if ( rotating ) delay (1); // wait a little until the bouncing is done
// Test transition, did things really change?
if ( digitalRead(encoderPinA) != A_set ) { // debounce once more
A_set = !A_set;
// adjust counter + if A leads B
if ( A_set && !B_set )
if (count0 == true)
counter +=1;
else if (select == true)
sleepWakeCounter +=1;
else if ((sleepWakeCounter == 0) && (select == false))
counter_hour_start +=1;
else if ((sleepWakeCounter == 1) && (select == false))
counter_minute_start +=1;
else if ((sleepWakeCounter == 2) && (select == false))
counter_hour_end +=1;
else if ((sleepWakeCounter == 3) && (select == false))
counter_minute_end +=1;
rotating = false; // no more debouncing until loop() hits again
}
}
// Interrupt on B changing state, same as A above
void doEncoderB() {
// debounce
if ( rotating ) delay (1); // wait a little until the bouncing is done
if ( digitalRead(encoderPinB) != B_set ) {
B_set = !B_set;
// adjust counter - 1 if B leads A
if ( B_set && !A_set )
if (count0 == true)
counter -=1;
else if (select == true)
sleepWakeCounter -=1;
else if ((sleepWakeCounter == 0) && (select == false))
counter_hour_start -=1;
else if ((sleepWakeCounter == 1) && (select == false))
counter_minute_start -=1;
else if ((sleepWakeCounter == 2) && (select == false))
counter_hour_end -=1;
else if ((sleepWakeCounter == 3) && (select == false))
counter_minute_end -=1;
rotating = false; // no more debouncing until loop() hits again
}
}
//==============================================================================
// button_press
//==============================================================================
void button_press (){
unsigned long count = button.getCount();
if (count == 0) {
count0 = true;
} else {
count0 = false;
}
}
//==============================================================================
// ENCODER ALARM
//==============================================================================
void encoder_alarm(){
button.loop(); // MUST call the loop() function first
unsigned long count = button.getCount();
// toggle boolean state to choose between cycling the setup positions and changing the values
encoderButtonState = digitalRead(ENCODER_SW);
if (( encoderButtonState != oldEncoderButtonState ) && (encoderButtonState == HIGH) ) {
select = !select;
Serial.println(select);
}
oldEncoderButtonState = encoderButtonState;
//--------------------- HOURS alarm STARTS at ------------------------//
if (lastReportedPos_hour_start != counter_hour_start) {
if (counter_hour_start>23) {(counter_hour_start = 0);}
if (counter_hour_start<0) {(counter_hour_start = 23);}
tensofhours = counter_hour_start / 10;
singlehours = counter_hour_start % 10;
lastReportedPos_hour_start = counter_hour_start;
}
EEPROM.update(2,counter_hour_start);
//--------------------- MINUTES alarm STARTS at ------------------------//
if (lastReportedPos_minute_start != counter_minute_start) {
if (counter_minute_start>59) {(counter_minute_start = 0);}
if (counter_minute_start<0) {(counter_minute_start = 59);}
tensofminutes = counter_minute_start / 10;
singleminutes = counter_minute_start % 10;
lastReportedPos_minute_start = counter_minute_start;
EEPROM.update(3,counter_minute_start);
}
//--------------------- HOURS alarm ENDS at ------------------------//
if (lastReportedPos_hour_end != counter_hour_end) {
if (counter_hour_end>23) {(counter_hour_end = 0);}
if (counter_hour_end<0) {(counter_hour_end = 23);}
tensofhours1 = counter_hour_end / 10;
singlehours1 = counter_hour_end % 10;
lastReportedPos_hour_end = counter_hour_end;
}
EEPROM.update(4,counter_hour_end);
//--------------------- MINUTES alarm ENDS at ------------------------//
if (lastReportedPos_minute_end != counter_minute_end) {
if (counter_minute_end>59) {(counter_minute_end = 0);}
if (counter_minute_end<0) {(counter_minute_end = 59);}
tensofminutes1 = counter_minute_end / 10;
singleminutes1 = counter_minute_end % 10;
lastReportedPos_minute_end = counter_minute_end;
EEPROM.update(5,counter_minute_end);
}
//--------------------- 7 Segment display ------------------------//
MaximCC.setChar(0,7,tensofhours,false);
MaximCC.setChar(0,6,singlehours,false);
MaximCC.setChar(0,5,tensofminutes,false);
MaximCC.setChar(0,4,singleminutes,false);
MaximCC.setChar(0,3,tensofhours1,false);
MaximCC.setChar(0,2,singlehours1,false);
MaximCC.setChar(0,1,tensofminutes1,false);
MaximCC.setChar(0,0,singleminutes1,false);
if (select == true) {
if (lastReportedPos_sleepWakeCounter != sleepWakeCounter) {
if (sleepWakeCounter>4) {(sleepWakeCounter = 0);}
if (sleepWakeCounter<0) {(sleepWakeCounter = 4);}
lastReportedPos_sleepWakeCounter = sleepWakeCounter;
}
}
if ((sleepWakeCounter == 0) || (sleepWakeCounter == 1) || (sleepWakeCounter == 2) || (sleepWakeCounter == 3)) {
if(button.isPressed()) {
select = false;
}
}
if (sleepWakeCounter == 4) {
if(button.isPressed()) {
count0 = true;
}
}
if (sleepWakeCounter == 0) {
MaximCC.setChar(0,7,tensofhours,false);
MaximCC.setChar(0,6,singlehours,true);
} else {
MaximCC.setChar(0,6,singlehours,false);
}
if (sleepWakeCounter == 1) {
MaximCC.setChar(0,5,tensofminutes,false);
MaximCC.setChar(0,4,singleminutes,true);
} else {
MaximCC.setChar(0,4,singleminutes,false);
}
if (sleepWakeCounter == 2) {
MaximCC.setChar(0,3,tensofhours1,false);
MaximCC.setChar(0,2,singlehours1,true);
} else {
MaximCC.setChar(0,2,singlehours1,false);
}
if (sleepWakeCounter == 3) {
MaximCC.setChar(0,1,tensofminutes1,false);
MaximCC.setChar(0,0,singleminutes1,true);
} else {
MaximCC.setChar(0,0,singleminutes1,false);
}
}
//==============================================================================
// manual_brightness_control
//==============================================================================
void manual_brightness_control()
{
if (lastReportedPos_brightness_count != counter) {
if (counter>15) {(counter = 15);}
if (counter<0) {(counter = 0);}
singlecounts = counter / 10;
singlecounts = counter % 10;
lastReportedPos_brightness_count = counter;
MaximCC.setIntensity(0,counter);
}
}
//==============================================================================
// displayRtcTime
//==============================================================================
void displayRtcTime()
{
if (count0 == true){
MaximCC.setChar(0, 7, (hour() / 10), false);
MaximCC.setChar(0, 6, (hour() % 10), false);
MaximCC.setChar(0, 5, '-', false);
MaximCC.setChar(0, 4, (minute() / 10), false);
MaximCC.setChar(0, 3, (minute() % 10), false);
MaximCC.setChar(0, 2, '-', false);
MaximCC.setChar(0, 1, (second() / 10), false);
MaximCC.setChar(0, 0, (second() % 10), false);
}
}
//==============================================================================
// ledTest
//==============================================================================
void ledTest(){
int midnight;
int powersaving;
int startTime = counter_hour_start * 100 + counter_minute_start;
int endTime = counter_hour_end * 100 + counter_minute_end;
int timeNow = hour() * 100 + minute();
if (endTime == 0000 && startTime != 0000){
endTime = 2359;
}
if (timeNow >= startTime && timeNow < endTime) {
powersaving = true;
} else {
powersaving = false;
}
if (powersaving == true){
digitalWrite(LED2, HIGH);
} else {
digitalWrite(LED2, LOW);
}
}
many thanks for any help,
Alek