From b7de0cf71085d2ee779dd54f6b6adad24e3f420e Mon Sep 17 00:00:00 2001 From: Gregg Date: Sat, 26 Sep 2020 16:23:44 -0500 Subject: [PATCH] Created Generic PushButton Wll be used for control button. Nothing to do with buttons that control Accessories, which are handled by SpanButton. --- src/Blinker.cpp | 94 ------------------------- src/Blinker.h | 61 ---------------- src/HAP.cpp | 1 - src/HomeSpan.cpp | 3 +- src/HomeSpan.h | 5 +- src/Network.cpp | 1 - src/Settings.h | 5 ++ src/Utils.cpp | 177 +++++++++++++++++++++++++++++++++++++++++++++++ src/Utils.h | 104 ++++++++++++++++++++++++++++ 9 files changed, 290 insertions(+), 161 deletions(-) delete mode 100644 src/Blinker.cpp delete mode 100644 src/Blinker.h diff --git a/src/Blinker.cpp b/src/Blinker.cpp deleted file mode 100644 index 4872132..0000000 --- a/src/Blinker.cpp +++ /dev/null @@ -1,94 +0,0 @@ - -#include -#include "Blinker.h" - -//////////////////////////////// -// Blinker // -//////////////////////////////// - -Blinker::Blinker(int pin, int timerNum){ - this->pin=pin; - pinMode(pin,OUTPUT); - digitalWrite(pin,0); - - group=((timerNum/2)%2==0)?TIMER_GROUP_0:TIMER_GROUP_1; - idx=(timerNum%2==0)?TIMER_0:TIMER_1; - - timer_config_t conf; - conf.alarm_en=TIMER_ALARM_EN; - conf.counter_en=TIMER_PAUSE; - conf.intr_type=TIMER_INTR_LEVEL; - conf.counter_dir=TIMER_COUNT_UP; - conf.auto_reload=TIMER_AUTORELOAD_EN; - conf.divider=8000; // 80 MHz clock / 8,000 = 10 kHz clock (0.1 ms pulses) - - timer_init(group,idx,&conf); - timer_isr_register(group,idx,Blinker::isrTimer,(void *)this,0,NULL); - timer_enable_intr(group,idx); - -} - -void Blinker::isrTimer(void *arg){ - - Blinker *b=(Blinker *)arg; - - if(b->group){ - if(b->idx) - TIMERG1.int_clr_timers.t1=1; - else - TIMERG1.int_clr_timers.t0=1; - } else { - if(b->idx) - TIMERG0.int_clr_timers.t1=1; - else - TIMERG0.int_clr_timers.t0=1; - } - - if(!digitalRead(b->pin)){ - digitalWrite(b->pin,1); - timer_set_alarm_value(b->group,b->idx,b->onTime); - b->count--; - } else { - digitalWrite(b->pin,0); - if(b->count){ - timer_set_alarm_value(b->group,b->idx,b->offTime); - } else { - timer_set_alarm_value(b->group,b->idx,b->delayTime); - b->count=b->nBlinks; - } - } - - timer_set_alarm(b->group,b->idx,TIMER_ALARM_EN); -} - -void Blinker::start(int period, float dutyCycle){ - - start(period, dutyCycle, 1, period-dutyCycle*period); -} - -void Blinker::start(int period, float dutyCycle, int nBlinks, int delayTime){ - - period*=10; - onTime=dutyCycle*period; - offTime=period-onTime; - this->delayTime=delayTime*10; - this->nBlinks=nBlinks; - count=nBlinks; - timer_set_counter_value(group,idx,0); - timer_set_alarm_value(group,idx,0); - timer_start(group,idx); -} - -void Blinker::stop(){ - timer_pause(group,idx); -} - -void Blinker::on(){ - stop(); - digitalWrite(pin,1); -} - -void Blinker::off(){ - stop(); - digitalWrite(pin,0); -} diff --git a/src/Blinker.h b/src/Blinker.h deleted file mode 100644 index 17cbc93..0000000 --- a/src/Blinker.h +++ /dev/null @@ -1,61 +0,0 @@ - -#include - -//////////////////////////////// -// Blinker // -//////////////////////////////// - -class Blinker { - - timer_group_t group; - timer_idx_t idx; - int pin; - - int nBlinks; - int onTime; - int offTime; - int delayTime; - int count; - - static void isrTimer(void *arg); - - public: - - Blinker(int pin, int timerNum=0); - -// Creates a generic blinking LED on specified PIN controlled -// in background via interrupts generated by an ESP32 Alarm Timer. -// -// pin: Pin mumber to control. Blinker will set pinMode to OUTPUT automatically -// timerNum: ESP32 Alarm Timer to use. 0=Group0/Timer0, 1=Group0/Timer1, 2=Group1/Timer0, 3=Group1/Timer1 - - void start(int period, float dutyCycle=0.5); - -// Starts simple ON/OFF blinking. -// -// period: ON/OFF blinking period, in milliseconds -// dutyCycle: Fraction of period that LED is ON (default=50%) - - void start(int period, float dutyCycle, int nBlinks, int delayTime); - -// Starts ON/OFF blinking pattern. -// -// period: ON/OFF blinking period, in milliseconds, used for blinking portion of pattern -// dutyCycle: Fraction of period that LED is ON (default=50%) -// nBlinks: Number of blinks in blinking portion of pattern -// delayTime: delay, in milliseconds, during which LED is off before restarting blinking pattern - - - void stop(); - -// Stops current blinking pattern. - - void on(); - -// Stops current blinknig pattern and turns on LED - - void off(); - -// Stops current blinknig pattern and turns off LED - -}; diff --git a/src/HAP.cpp b/src/HAP.cpp index 1cb1572..9b1c90d 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -3,7 +3,6 @@ #include #include "HAP.h" -#include "Utils.h" ////////////////////////////////////// diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 7d072d0..232012f 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -3,7 +3,6 @@ #include #include -#include "Utils.h" #include "HAP.h" #include "Network.h" @@ -35,7 +34,7 @@ void Span::begin(Category catID, char *displayName, char *hostNameBase, char *mo "************************************************************\n\n" "** Please ensure serial monitor is set to transmit \n\n"); - Serial.print("Device Control: Pin "); + Serial.print("Device Control: Pin "); Serial.print(resetPin); Serial.print("\nHomeSpan Version: "); Serial.print(HOMESPAN_VERSION); diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 0edbcfd..b8115f0 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -7,7 +7,7 @@ #include #include "Settings.h" -#include "Blinker.h" +#include "Utils.h" using std::vector; using std::unordered_map; @@ -55,7 +55,8 @@ struct Span{ int resetPressed=0; // tracks pressing of reset button unsigned long resetTime; // tracks time once reset button is pressed - Blinker statusLED=Blinker(LED_BUILTIN); // indicates HomeSpan status + Blinker statusLED{LED_BUILTIN}; // indicates HomeSpan status + PushButton controlButton{DEFAULT_CONTROL_PIN}; // controls HomeSpan configuration and resets SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found vector Accessories; // vector of pointers to all Accessories diff --git a/src/Network.cpp b/src/Network.cpp index d30672e..753e8be 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -2,7 +2,6 @@ #include #include "Network.h" -#include "Utils.h" #include "HAP.h" using namespace Utils; diff --git a/src/Settings.h b/src/Settings.h index d10c6bc..f4c4108 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -13,6 +13,11 @@ const char HOMESPAN_VERSION[]="1.0.0"; const char DEFAULT_SETUP_CODE[]="46637726"; +////////////////////////////////////////////////////// +// DEFAULT CONTROL BUTTON PIN // + +const int DEFAULT_CONTROL_PIN=21; + ////////////////////////////////////////////////////// // Maximum number of simultaenous IP connections // // HAP requires at least 8 // diff --git a/src/Utils.cpp b/src/Utils.cpp index f364a30..0b49ff9 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -1,6 +1,18 @@ #include "Utils.h" +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Contains various generic utility functions and classes: +// +// Utils::readSerial - reads all characters from Serial port and saves only up to max specified +// Utils::mask - masks a string with asterisks (good for displaying passwords) +// +// class PushButton - tracks Long and Short presses of a pushbutton that connects a specified pin to ground +// class Blinker - creates customized blinking patterns on an LED connected to a specified pin +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + char *Utils::readSerial(char *c, int max){ int i=0; char buf; @@ -41,3 +53,168 @@ String Utils::mask(char *c, int n){ return(s); } // mask + +//////////////////////////////// +// PushButton // +//////////////////////////////// + +PushButton::PushButton(uint8_t pin){ + this->pin=pin; + status=0; + pinMode(pin, INPUT_PULLUP); +} + +////////////////////////////////////// + +boolean PushButton::triggered(uint16_t shortTime, uint16_t longTime){ + + switch(status){ + + case 0: + if(!digitalRead(pin)){ // button is pressed + status=1; + shortAlarm=millis()+shortTime; + longAlarm=millis()+longTime; + } + break; + + case 1: + if(digitalRead(pin)){ // button is released + status=0; + if(millis()>shortAlarm){ + isLongPress=false; + return(true); + } + } else + + if(millis()>longAlarm){ // button is long-pressed + status=2; + isLongPress=true; + return(true); + } + break; + + case 2: + if(digitalRead(pin)) // button has been released after a long press + status=0; + break; + + } + + return(false); +} + +////////////////////////////////////// + +boolean PushButton::longPress(){ + return(isLongPress); +} + +////////////////////////////////////// + +void PushButton::reset(){ + status=0; +} + +//////////////////////////////// +// Blinker // +//////////////////////////////// + +Blinker::Blinker(int pin, int timerNum){ + this->pin=pin; + pinMode(pin,OUTPUT); + digitalWrite(pin,0); + + group=((timerNum/2)%2==0)?TIMER_GROUP_0:TIMER_GROUP_1; + idx=(timerNum%2==0)?TIMER_0:TIMER_1; + + timer_config_t conf; + conf.alarm_en=TIMER_ALARM_EN; + conf.counter_en=TIMER_PAUSE; + conf.intr_type=TIMER_INTR_LEVEL; + conf.counter_dir=TIMER_COUNT_UP; + conf.auto_reload=TIMER_AUTORELOAD_EN; + conf.divider=8000; // 80 MHz clock / 8,000 = 10 kHz clock (0.1 ms pulses) + + timer_init(group,idx,&conf); + timer_isr_register(group,idx,Blinker::isrTimer,(void *)this,0,NULL); + timer_enable_intr(group,idx); + +} + +////////////////////////////////////// + +void Blinker::isrTimer(void *arg){ + + Blinker *b=(Blinker *)arg; + + if(b->group){ + if(b->idx) + TIMERG1.int_clr_timers.t1=1; + else + TIMERG1.int_clr_timers.t0=1; + } else { + if(b->idx) + TIMERG0.int_clr_timers.t1=1; + else + TIMERG0.int_clr_timers.t0=1; + } + + if(!digitalRead(b->pin)){ + digitalWrite(b->pin,1); + timer_set_alarm_value(b->group,b->idx,b->onTime); + b->count--; + } else { + digitalWrite(b->pin,0); + if(b->count){ + timer_set_alarm_value(b->group,b->idx,b->offTime); + } else { + timer_set_alarm_value(b->group,b->idx,b->delayTime); + b->count=b->nBlinks; + } + } + + timer_set_alarm(b->group,b->idx,TIMER_ALARM_EN); +} + +////////////////////////////////////// + +void Blinker::start(int period, float dutyCycle){ + + start(period, dutyCycle, 1, period-dutyCycle*period); +} + +////////////////////////////////////// + +void Blinker::start(int period, float dutyCycle, int nBlinks, int delayTime){ + + period*=10; + onTime=dutyCycle*period; + offTime=period-onTime; + this->delayTime=delayTime*10; + this->nBlinks=nBlinks; + count=nBlinks; + timer_set_counter_value(group,idx,0); + timer_set_alarm_value(group,idx,0); + timer_start(group,idx); +} + +////////////////////////////////////// + +void Blinker::stop(){ + timer_pause(group,idx); +} + +////////////////////////////////////// + +void Blinker::on(){ + stop(); + digitalWrite(pin,1); +} + +////////////////////////////////////// + +void Blinker::off(){ + stop(); + digitalWrite(pin,0); +} diff --git a/src/Utils.h b/src/Utils.h index a6cbf3b..2d3ab6e 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -1,5 +1,6 @@ #include +#include namespace Utils { @@ -31,3 +32,106 @@ struct TempBuffer { } }; + +//////////////////////////////// +// PushButton // +//////////////////////////////// + +class PushButton{ + + int status; + uint8_t pin; + uint32_t shortAlarm; + uint32_t longAlarm; + boolean isLongPress; + + public: + + PushButton(uint8_t pin); + +// Creates generic pushbutton functionality on specified pin +// that is wired to connect to ground when the button is pressed. +// +// pin: Pin mumber to which pushbutton is connects to ground when pressed + + void reset(); + +// Resets state of pushbutton. Should be called once before any loops that will +// repeatedly check the button for a trigger event. + + boolean triggered(uint16_t shortTime, uint16_t longTime); + +// Returns true if button has been triggered by either a Long Press or Short Press, where a +// Long Press is a press and hold for at least longTime milliseconds, and a Short Press is +// a press and release of at least shortTime milliseconds but less than longTime milliseconds. +// +// shortTime: the minimum time required for the button to be pressed before releasing to trigger a Short Press +// longtime: the minimum time required for the button to be pressed and held to trigger a Long Press +// +// If shortTime>longTime, only Long Press triggers will occur. Once triggered() returns true, if will subsequently +// return false until there is a new trigger. After a Long Press, the button must be released to permit a subsequent +// trigger. + + boolean longPress(); + +// Returns true if last trigger event was a Long Press, or false if last trigger was a Short Press + +}; + +//////////////////////////////// +// Blinker // +//////////////////////////////// + +class Blinker { + + timer_group_t group; + timer_idx_t idx; + int pin; + + int nBlinks; + int onTime; + int offTime; + int delayTime; + int count; + + static void isrTimer(void *arg); + + public: + + Blinker(int pin, int timerNum=0); + +// Creates a generic blinking LED on specified pin controlled +// in background via interrupts generated by an ESP32 Alarm Timer. +// +// pin: Pin mumber to control. Blinker will set pinMode to OUTPUT automatically +// timerNum: ESP32 Alarm Timer to use. 0=Group0/Timer0, 1=Group0/Timer1, 2=Group1/Timer0, 3=Group1/Timer1 + + void start(int period, float dutyCycle=0.5); + +// Starts simple ON/OFF blinking. +// +// period: ON/OFF blinking period, in milliseconds +// dutyCycle: Fraction of period that LED is ON (default=50%) + + void start(int period, float dutyCycle, int nBlinks, int delayTime); + +// Starts ON/OFF blinking pattern. +// +// period: ON/OFF blinking period, in milliseconds, used for blinking portion of pattern +// dutyCycle: Fraction of period that LED is ON (default=50%) +// nBlinks: Number of blinks in blinking portion of pattern +// delayTime: delay, in milliseconds, during which LED is off before restarting blinking pattern + + void stop(); + +// Stops current blinking pattern. + + void on(); + +// Stops current blinking pattern and turns on LED + + void off(); + +// Stops current blinking pattern and turns off LED + +};