You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
5.2 KiB
227 lines
5.2 KiB
#include <ELClientWebServer.h> |
|
|
|
// the PIN to flash |
|
#define LED_PIN 13 |
|
|
|
int8_t blinking = 0; // whether LED is blinking |
|
uint8_t blinking_duty = 2; // blinking duty |
|
int8_t blinking_frequency = 10; // blinking frequency |
|
|
|
uint32_t blinking_next_ts = 0; // the next timestamp to blink |
|
uint16_t blinking_phase = 100; // blinking phase |
|
uint16_t blinking_period = 200; // blinking period (2000 / frequency) |
|
|
|
#define MAX_LOGS 5 |
|
uint32_t log_ts[MAX_LOGS]; // log timestamp |
|
uint8_t log_msg[MAX_LOGS]; // log message |
|
uint8_t log_ptr = 0; // log pointer |
|
|
|
typedef enum |
|
{ |
|
LOG_DUTY_25_75 = 0xE1, |
|
LOG_DUTY_50_50, |
|
LOG_DUTY_75_25, |
|
LOG_SET_LED_ON = 0xF0, |
|
LOG_SET_LED_BLINKING, |
|
LOG_SET_LED_OFF, |
|
} LogMessage; |
|
|
|
// LED loop code |
|
void ledLoop() |
|
{ |
|
if( blinking ) // if blinking is enabled |
|
{ |
|
if( blinking_next_ts <= millis() ) |
|
{ |
|
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // blink LED |
|
blinking_next_ts += blinking_phase; |
|
blinking_phase = blinking_period - blinking_phase; |
|
} |
|
} |
|
} |
|
|
|
// adds a new log message |
|
void ledAddLog(uint8_t msg) |
|
{ |
|
// check if max log is reached |
|
if( log_ptr >= MAX_LOGS ) |
|
log_ptr = MAX_LOGS - 1; |
|
|
|
// move logs back with one and delete the oldest log |
|
for(int8_t i=log_ptr-1; i >= 0; i--) |
|
{ |
|
log_ts[i+1] = log_ts[i]; |
|
log_msg[i+1] = log_msg[i]; |
|
} |
|
|
|
log_msg[0] = msg; // log message |
|
log_ts[0] = millis(); // log timestamp |
|
log_ptr++; // a new log was added |
|
} |
|
|
|
// create log messages to string |
|
String ledHistoryToLog() |
|
{ |
|
String str = "["; |
|
|
|
for(uint8_t i=0; i < log_ptr; i++) |
|
{ |
|
if( i != 0 ) |
|
str += ','; |
|
|
|
str += '\"'; |
|
str += (log_ts[i] / 1000); |
|
str += "s: "; |
|
|
|
switch(log_msg[i]) // log message |
|
{ |
|
case LOG_DUTY_25_75: |
|
str += F("set duty to 25%-75%"); |
|
break; |
|
case LOG_DUTY_50_50: |
|
str += F("set duty to 50%-50%"); |
|
break; |
|
case LOG_DUTY_75_25: |
|
str += F("set duty to 75%-25%"); |
|
break; |
|
case LOG_SET_LED_ON: |
|
str += F("set led on"); |
|
break; |
|
case LOG_SET_LED_BLINKING: |
|
str += F("set led blinking"); |
|
break; |
|
case LOG_SET_LED_OFF: |
|
str += F("set led off"); |
|
break; |
|
default: |
|
str += F("set frequency to "); |
|
str += (int)log_msg[i]; |
|
str += F(" Hz"); |
|
break; |
|
} |
|
str += '\"'; |
|
} |
|
str += ']'; |
|
|
|
return str; |
|
} |
|
|
|
// called at button pressing |
|
void ledButtonPressCb(const char * button) |
|
{ |
|
String btn = button; |
|
if( btn == F("btn_on") ) |
|
{ |
|
if( blinking || digitalRead(LED_PIN) == false ) |
|
ledAddLog(LOG_SET_LED_ON); |
|
blinking = 0; |
|
digitalWrite(LED_PIN, true); |
|
} |
|
else if( btn == F("btn_off") ) |
|
{ |
|
if( blinking || digitalRead(LED_PIN) == true ) |
|
ledAddLog(LOG_SET_LED_OFF); |
|
blinking = 0; |
|
digitalWrite(LED_PIN, false); |
|
} |
|
else if( btn == F("btn_blink") ) |
|
{ |
|
if( !blinking ) |
|
ledAddLog(LOG_SET_LED_BLINKING); |
|
blinking = 1; |
|
blinking_next_ts = millis() + blinking_phase; |
|
} |
|
} |
|
|
|
// setting the value of a field |
|
// |
|
// handle data as fast as possible |
|
// - huge HTML forms can arrive in multiple packets |
|
// - if this method is slow, UART receive buffer may overrun |
|
void ledSetFieldCb(const char * field) |
|
{ |
|
String fld = field; |
|
if( fld == F("frequency") ) |
|
{ |
|
int8_t oldf = blinking_frequency; |
|
blinking_frequency = webServer.getArgInt(); |
|
|
|
blinking_period = 2000 / blinking_frequency; |
|
blinking_phase = blinking_duty * blinking_period / 4; |
|
|
|
if( oldf != blinking_frequency ) |
|
{ |
|
ledAddLog(blinking_frequency); |
|
if( blinking ) |
|
digitalWrite(LED_PIN, false); |
|
} |
|
} |
|
else if( fld == F("duty") ) |
|
{ |
|
int8_t oldp = blinking_duty; |
|
String arg = webServer.getArgString(); |
|
|
|
if( arg == F("25_75") ) |
|
blinking_duty = 1; |
|
else if( arg == F("50_50") ) |
|
blinking_duty = 2; |
|
else if( arg == F("75_25") ) |
|
blinking_duty = 3; |
|
|
|
if( blinking ) |
|
digitalWrite(LED_PIN, false); |
|
|
|
blinking_phase = blinking_duty * blinking_period / 4; |
|
|
|
if( oldp != blinking_duty ) |
|
ledAddLog(LOG_DUTY_25_75 - 1 + blinking_duty); |
|
} |
|
} |
|
|
|
// called at page refreshing |
|
void ledRefreshCb(const char * url) |
|
{ |
|
if( blinking ) |
|
webServer.setArgString(F("text"), F("LED is blinking")); |
|
else |
|
webServer.setArgString(F("text"), digitalRead(LED_PIN) ? F("LED is turned on") : F("LED is turned off")); |
|
|
|
String log = ledHistoryToLog(); |
|
webServer.setArgJson(F("led_history"), log.begin()); |
|
} |
|
|
|
// called at page loading |
|
void ledLoadCb(const char * url) |
|
{ |
|
webServer.setArgInt(F("frequency"), blinking_frequency); |
|
|
|
switch(blinking_duty) |
|
{ |
|
case 1: |
|
webServer.setArgString(F("duty"), F("25_75")); |
|
break; |
|
case 2: |
|
webServer.setArgString(F("duty"), F("50_50")); |
|
break; |
|
case 3: |
|
webServer.setArgString(F("duty"), F("75_25")); |
|
break; |
|
} |
|
|
|
ledRefreshCb( url ); |
|
} |
|
|
|
// LED setup code |
|
void ledInit() |
|
{ |
|
// set mode to output and turn LED off |
|
pinMode(LED_PIN, OUTPUT); |
|
digitalWrite(LED_PIN, false); |
|
|
|
URLHandler *ledHandler = webServer.createURLHandler(F("/LED.html.json")); |
|
ledHandler->buttonCb.attach(ledButtonPressCb); |
|
ledHandler->setFieldCb.attach(ledSetFieldCb); |
|
ledHandler->loadCb.attach(ledLoadCb); |
|
ledHandler->refreshCb.attach(ledRefreshCb); |
|
} |
|
|
|
|