Created Generic PushButton

Wll be used for control button.  Nothing to do with buttons that control Accessories, which are handled by SpanButton.
This commit is contained in:
Gregg 2020-09-26 16:23:44 -05:00
parent 6a2d0741aa
commit b7de0cf710
9 changed files with 290 additions and 161 deletions

View File

@ -1,94 +0,0 @@
#include <Arduino.h>
#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);
}

View File

@ -1,61 +0,0 @@
#include <driver/timer.h>
////////////////////////////////
// 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
};

View File

@ -3,7 +3,6 @@
#include <sodium.h>
#include "HAP.h"
#include "Utils.h"
//////////////////////////////////////

View File

@ -3,7 +3,6 @@
#include <nvs_flash.h>
#include <sodium.h>
#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 <newlines>\n\n");
Serial.print("Device Control: Pin ");
Serial.print("Device Control: Pin ");
Serial.print(resetPin);
Serial.print("\nHomeSpan Version: ");
Serial.print(HOMESPAN_VERSION);

View File

@ -7,7 +7,7 @@
#include <unordered_map>
#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<SpanAccessory *> Accessories; // vector of pointers to all Accessories

View File

@ -2,7 +2,6 @@
#include <DNSServer.h>
#include "Network.h"
#include "Utils.h"
#include "HAP.h"
using namespace Utils;

View File

@ -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 //

View File

@ -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);
}

View File

@ -1,5 +1,6 @@
#include <Arduino.h>
#include <driver/timer.h>
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
};