remove arduino client code

pull/193/head
Thorsten von Eicken 8 years ago
parent f220122ca8
commit 8a8649aab6
  1. 207
      arduino/libraries/EspLink/EspLink.cpp
  2. 91
      arduino/libraries/EspLink/EspLink.h
  3. 214
      arduino/libraries/EspLink/WebServer.cpp
  4. 91
      arduino/libraries/EspLink/WebServer.h
  5. 35
      arduino/libraries/EspLink/examples/EspLinkWebApp/EspLinkWebApp.ino
  6. 188
      arduino/libraries/EspLink/examples/EspLinkWebApp/LedPage.ino
  7. 8
      arduino/libraries/EspLink/examples/EspLinkWebApp/Makefile.webpage
  8. 17
      arduino/libraries/EspLink/examples/EspLinkWebApp/Pages.h
  9. 84
      arduino/libraries/EspLink/examples/EspLinkWebApp/UserPage.ino
  10. 125
      arduino/libraries/EspLink/examples/EspLinkWebApp/VoltagePage.ino
  11. BIN
      arduino/libraries/EspLink/examples/EspLinkWebApp/web-page.espfs.img
  12. 36
      arduino/libraries/EspLink/examples/EspLinkWebApp/web-page/LED.html
  13. 24
      arduino/libraries/EspLink/examples/EspLinkWebApp/web-page/User.html
  14. 15
      arduino/libraries/EspLink/examples/EspLinkWebApp/web-page/Voltage.html
  15. 49
      arduino/libraries/EspLink/examples/EspLinkWebSimpleLedControl/EspLinkWebSimpleLedControl.ino
  16. 7
      arduino/libraries/EspLink/examples/EspLinkWebSimpleLedControl/SimpleLED.html
  17. 1
      arduino/libraries/readme.txt

@ -1,207 +0,0 @@
#include "EspLink.h"
#define READ_BUF_DFLT_SIZE 64
// Standard SLIP escape chars from RFC
#define SLIP_END 0300 // indicates end of packet
#define SLIP_ESC 0333 // indicates byte stuffing
#define SLIP_ESC_END 0334 // ESC ESC_END means END data byte
#define SLIP_ESC_ESC 0335 // ESC ESC_ESC means ESC data byte
EspLink::EspLink(Stream &streamIn, CmdRequestCB callback):stream(streamIn),requestCb(callback)
{
readBuf = NULL;
readLastChar = 0;
}
EspLink::~EspLink()
{
if( readBuf != NULL )
free( readBuf );
readBuf = NULL;
}
void EspLink::writeChar(uint8_t data)
{
switch(data)
{
case SLIP_END:
stream.write(SLIP_ESC);
stream.write(SLIP_ESC_END);
break;
case SLIP_ESC:
stream.write(SLIP_ESC);
stream.write(SLIP_ESC_ESC);
break;
default:
stream.write(data);
}
crc16_add(data, &crc16_out);
}
/* CITT CRC16 polynomial ^16 + ^12 + ^5 + 1 */
/*---------------------------------------------------------------------------*/
void EspLink::crc16_add(uint8_t b, uint16_t *crc)
{
*crc ^= b;
*crc = (*crc >> 8) | (*crc << 8);
*crc ^= (*crc & 0xff00) << 4;
*crc ^= (*crc >> 8) >> 4;
*crc ^= (*crc & 0xff00) >> 5;
}
void EspLink::writeBuf(uint8_t * buf, uint16_t len)
{
while(len-- > 0)
writeChar(*buf++);
}
void EspLink::sendPacketStart(uint16_t cmd, uint32_t value, uint16_t argc)
{
crc16_out = 0;
stream.write( SLIP_END );
writeBuf((uint8_t*)&cmd, 2);
writeBuf((uint8_t*)&argc, 2);
writeBuf((uint8_t*)&value, 4);
}
void EspLink::sendPacketArg(uint16_t len, uint8_t * data)
{
writeBuf((uint8_t*)&len, 2);
writeBuf(data, len);
uint16_t pad = ((len+3)&~3) - len; // get to multiple of 4
if (pad > 0) {
uint32_t temp = 0;
writeBuf((uint8_t*)&temp, pad);
}
}
void EspLink::sendPacketEnd() {
uint16_t crc = crc16_out;
writeBuf((uint8_t*)&crc, 2);
stream.write(SLIP_END);
}
void EspLink::parseSlipPacket()
{
CmdRequest req;
req.cmd = (CmdPacket *)readBuf;
req.arg_num = 0;
req.arg_ptr = readBuf + sizeof(CmdPacket);
requestCb(&req);
free(readBuf);
readBuf = NULL;
}
void EspLink::checkPacket()
{
if( readBufPtr <= 3 )
return;
uint16_t crc = 0;
for(uint16_t i=0; i < readBufPtr - 2; i++)
crc16_add(readBuf[i], &crc);
uint16_t crcpacket = *(uint16_t*)(readBuf + readBufPtr - 2);
if( crc == crcpacket )
{
readBufPtr -= 2;
parseSlipPacket();
}
}
void EspLink::readLoop()
{
if( stream.available() > 0 )
{
int byt = stream.read();
switch(readState)
{
case WAIT_FOR_SLIP_START:
if( byt == SLIP_END )
{
if(readBuf != NULL)
free(readBuf);
readBufPtr = 0;
readBufMax = READ_BUF_DFLT_SIZE;
readBuf = (uint8_t *)malloc(readBufMax);
readState = READ_SLIP_PACKAGE;
}
break;
case READ_SLIP_PACKAGE:
if( byt == SLIP_END )
{
readState = WAIT_FOR_SLIP_START;
checkPacket();
break;
}
if( byt == SLIP_ESC )
break;
if( readLastChar == SLIP_ESC && byt == SLIP_ESC_END )
byt = SLIP_END;
else if( readLastChar == SLIP_ESC && byt == SLIP_ESC_ESC )
byt = SLIP_ESC;
if( readBufPtr >= readBufMax )
{
readBufMax = readBufMax + READ_BUF_DFLT_SIZE;
readBuf = (uint8_t *)realloc(readBuf, readBufMax);
if( readBuf == NULL )
{
readState = WAIT_FOR_SLIP_START; // TODO
break;
}
}
readBuf[readBufPtr++] = byt;
break;
}
readLastChar = byt;
}
}
// Return the number of arguments given a command struct
uint32_t EspLink::cmdGetArgc(CmdRequest *req) {
return req->cmd->argc;
}
// Copy the next argument from a command structure into the data pointer, returns 0 on success
// -1 on error
int32_t EspLink::cmdPopArg(CmdRequest *req, void *data, uint16_t len) {
uint16_t length;
if (req->arg_num >= req->cmd->argc)
return -1;
length = *(uint16_t*)req->arg_ptr;
if (length != len) return -1; // safety check
memcpy(data, req->arg_ptr + 2, length);
req->arg_ptr += (length+5)&~3; // round up to multiple of 4
req->arg_num ++;
return 0;
}
// Skip the next argument
void EspLink::cmdSkipArg(CmdRequest *req) {
uint16_t length;
if (req->arg_num >= req->cmd->argc) return;
length = *(uint16_t*)req->arg_ptr;
req->arg_ptr += (length+5)&~3;
req->arg_num ++;
}
// Return the length of the next argument
uint16_t EspLink::cmdArgLen(CmdRequest *req) {
return *(uint16_t*)req->arg_ptr;
}

@ -1,91 +0,0 @@
#ifndef ESP_LINK_H
#define ESP_LINK_H
#include <inttypes.h>
#include <Stream.h>
typedef struct __attribute__((__packed__)) {
uint16_t len; // length of data
uint8_t data[0]; // really data[len]
} CmdArg;
typedef struct __attribute__((__packed__)) {
uint16_t cmd; // command to perform, from CmdName enum
uint16_t argc; // number of arguments to command
uint32_t value; // callback pointer for response or first argument
CmdArg args[0]; // really args[argc]
} CmdPacket;
typedef struct {
CmdPacket *cmd; // command packet header
uint32_t arg_num; // number of args parsed
uint8_t *arg_ptr; // pointer to ??
} CmdRequest;
typedef void (* CmdRequestCB)(CmdRequest *);
typedef enum {
CMD_NULL = 0,
CMD_SYNC, // synchronize and clear
CMD_RESP_V, // response with a value
CMD_RESP_CB, // response with a callback
CMD_WIFI_STATUS, // get the current wifi status
CMD_CB_ADD,
CMD_CB_EVENTS,
CMD_GET_TIME, // get current time in seconds since the unix epoch
CMD_MQTT_SETUP = 10, // set-up callbacks
CMD_MQTT_PUBLISH, // publish a message
CMD_MQTT_SUBSCRIBE, // subscribe to a topic
CMD_MQTT_LWT, // set the last-will-topic and messge
CMD_REST_SETUP = 20,
CMD_REST_REQUEST,
CMD_REST_SETHEADER,
CMD_WEB_DATA = 30,
CMD_WEB_REQ_CB,
} CmdName;
typedef enum
{
WAIT_FOR_SLIP_START,
READ_SLIP_PACKAGE,
} ReadState;
class EspLink
{
private:
uint16_t crc16_out;
Stream &stream;
ReadState readState;
uint8_t * readBuf;
uint16_t readBufPtr;
uint16_t readBufMax;
int readLastChar;
CmdRequestCB requestCb;
void crc16_add(uint8_t b, uint16_t *crc);
void writeChar(uint8_t chr);
void writeBuf(uint8_t * buf, uint16_t len);
void checkPacket();
void parseSlipPacket();
public:
EspLink(Stream &stream, CmdRequestCB callback);
~EspLink();
void sendPacketStart(uint16_t cmd, uint32_t value, uint16_t argc);
void sendPacketArg(uint16_t len, uint8_t * data);
void sendPacketEnd();
void readLoop();
uint32_t cmdGetArgc(CmdRequest *req);
int32_t cmdPopArg(CmdRequest *req, void *data, uint16_t len);
void cmdSkipArg(CmdRequest *req);
uint16_t cmdArgLen(CmdRequest *req);
};
#endif /* ESP_LINK_H */

@ -1,214 +0,0 @@
#include "WebServer.h"
#include "Arduino.h"
#define RESUBSCRIBE_LIMIT 1000
WebServer * WebServer::instance = NULL;
void webServerCallback(CmdRequest *req)
{
WebServer::getInstance()->handleRequest(req);
}
WebServer::WebServer(Stream &streamIn, const WebMethod * PROGMEM methodsIn):espLink(streamIn, webServerCallback),methods(methodsIn),stream(streamIn),esplink_cb(NULL)
{
instance = this;
}
void WebServer::init()
{
registerCallback();
}
void WebServer::loop()
{
// resubscribe periodically
uint32_t elapsed = millis() - last_connect_ts;
if( elapsed > RESUBSCRIBE_LIMIT )
registerCallback();
espLink.readLoop();
}
void WebServer::registerCallback()
{
espLink.sendPacketStart(CMD_CB_ADD, 100, 1);
espLink.sendPacketArg(5, (uint8_t *)"webCb");
espLink.sendPacketEnd();
last_connect_ts = millis();
}
void WebServer::invokeMethod(RequestReason reason, WebMethod * method, CmdRequest *req)
{
switch(reason)
{
case WS_BUTTON:
{
uint16_t len = espLink.cmdArgLen(req);
char bf[len+1];
bf[len] = 0;
espLink.cmdPopArg(req, bf, len);
method->callback(BUTTON_PRESS, bf, len);
}
break;
case WS_SUBMIT:
{
int arg_len = espLink.cmdGetArgc( req );
int cnt = 4;
while( cnt < arg_len )
{
uint16_t len = espLink.cmdArgLen(req);
char bf[len+1];
bf[len] = 0;
espLink.cmdPopArg(req, bf, len);
value_ptr = bf + 2 + strlen(bf+1);
method->callback(SET_FIELD, bf+1, strlen(bf+1));
cnt++;
}
}
return;
case WS_LOAD:
case WS_REFRESH:
break;
default:
return;
}
espLink.sendPacketStart(CMD_WEB_DATA, 100, 255);
espLink.sendPacketArg(4, remote_ip);
espLink.sendPacketArg(2, (uint8_t *)&remote_port);
method->callback( reason == WS_LOAD ? LOAD : REFRESH, NULL, 0);
espLink.sendPacketArg(0, NULL);
espLink.sendPacketEnd();
}
void WebServer::handleRequest(CmdRequest *req)
{
if( req->cmd->cmd != CMD_WEB_REQ_CB )
{
if( esplink_cb != NULL )
esplink_cb(req);
return;
}
uint16_t shrt;
espLink.cmdPopArg(req, &shrt, 2);
RequestReason reason = (RequestReason)shrt;
espLink.cmdPopArg(req, &remote_ip, 4);
espLink.cmdPopArg(req, &remote_port, 2);
{
uint16_t len = espLink.cmdArgLen(req);
char bf[len+1];
bf[len] = 0;
espLink.cmdPopArg(req, bf, len);
const WebMethod * meth = methods;
do
{
WebMethod m;
memcpy_P(&m, meth, sizeof(WebMethod));
if( m.url == NULL || m.callback == NULL )
break;
if( strcmp_P(bf, m.url) == 0 )
{
invokeMethod(reason, &m, req);
return;
}
meth++;
}while(1);
}
if( reason == WS_SUBMIT )
return;
// empty response
espLink.sendPacketStart(CMD_WEB_DATA, 100, 2);
espLink.sendPacketArg(4, remote_ip);
espLink.sendPacketArg(2, (uint8_t *)&remote_port);
espLink.sendPacketEnd();
}
void WebServer::setArgString(const char * name, const char * value)
{
uint8_t nlen = strlen(name);
uint8_t vlen = strlen(value);
char buf[nlen + vlen + 3];
buf[0] = WEB_STRING;
strcpy(buf+1, name);
strcpy(buf+2+nlen, value);
espLink.sendPacketArg(nlen+vlen+2, (uint8_t *)buf);
}
void WebServer::setArgStringP(const char * name, const char * value)
{
uint8_t nlen = strlen(name);
uint8_t vlen = strlen_P(value);
char buf[nlen + vlen + 3];
buf[0] = WEB_STRING;
strcpy(buf+1, name);
strcpy_P(buf+2+nlen, value);
espLink.sendPacketArg(nlen+vlen+2, (uint8_t *)buf);
}
void WebServer::setArgBoolean(const char * name, uint8_t value)
{
uint8_t nlen = strlen(name);
char buf[nlen + 4];
buf[0] = WEB_BOOLEAN;
strcpy(buf+1, name);
buf[2 + nlen] = value;
espLink.sendPacketArg(nlen+3, (uint8_t *)buf);
}
void WebServer::setArgJson(const char * name, const char * value)
{
uint8_t nlen = strlen(name);
uint8_t vlen = strlen(value);
char buf[nlen + vlen + 3];
buf[0] = WEB_JSON;
strcpy(buf+1, name);
strcpy(buf+2+nlen, value);
espLink.sendPacketArg(nlen+vlen+2, (uint8_t *)buf);
}
void WebServer::setArgInt(const char * name, int32_t value)
{
uint8_t nlen = strlen(name);
char buf[nlen + 7];
buf[0] = WEB_INTEGER;
strcpy(buf+1, name);
memcpy(buf+2+nlen, &value, 4);
espLink.sendPacketArg(nlen+6, (uint8_t *)buf);
}
int32_t WebServer::getArgInt()
{
return (int32_t)atol(value_ptr);
}
char * WebServer::getArgString()
{
return value_ptr;
}
uint8_t WebServer::getArgBoolean()
{
if( strcmp_P(value_ptr, PSTR("on")) == 0 )
return 1;
if( strcmp_P(value_ptr, PSTR("true")) == 0 )
return 1;
if( strcmp_P(value_ptr, PSTR("yes")) == 0 )
return 1;
if( strcmp_P(value_ptr, PSTR("1")) == 0 )
return 1;
return 0;
}

@ -1,91 +0,0 @@
#ifndef WEB_SERVER_H
#define WEB_SERVER_H
#include "EspLink.h"
typedef enum
{
BUTTON_PRESS,
SET_FIELD,
REFRESH,
LOAD,
} WebServerCommand;
typedef void (*WebServerCallback)(WebServerCommand command, char * data, int dataLen);
typedef struct
{
const char * PROGMEM url;
WebServerCallback callback;
} WebMethod;
typedef enum {
WS_LOAD=0,
WS_REFRESH,
WS_BUTTON,
WS_SUBMIT,
} RequestReason;
typedef enum
{
WEB_STRING=0,
WEB_NULL,
WEB_INTEGER,
WEB_BOOLEAN,
WEB_FLOAT,
WEB_JSON
} WebValueType;
class WebServer
{
friend void webServerCallback(CmdRequest *req);
private:
const WebMethod * PROGMEM methods;
Stream &stream;
static WebServer * instance;
void invokeMethod(RequestReason reason, WebMethod * method, CmdRequest *req);
void handleRequest(CmdRequest *req);
uint8_t remote_ip[4];
uint16_t remote_port;
char * value_ptr;
uint32_t last_connect_ts;
CmdRequestCB esplink_cb;
protected:
EspLink espLink;
public:
WebServer(Stream &stream, const WebMethod * PROGMEM methods);
void init();
void loop();
void registerCallback();
void setEspLinkCallback(CmdRequestCB cb) { esplink_cb = cb; }
static WebServer * getInstance() { return instance; }
uint8_t * getRemoteIp() { return remote_ip; }
uint16_t getRemotePort() { return remote_port; }
void setArgInt(const char * name, int32_t value);
void setArgJson(const char * name, const char * value);
void setArgString(const char * name, const char * value);
void setArgStringP(const char * name, const char * value);
void setArgBoolean(const char * name, uint8_t value);
int32_t getArgInt();
char * getArgString();
uint8_t getArgBoolean();
EspLink * getEspLink() { return &espLink; }
};
#endif /* WEB_SERVER_H */

@ -1,35 +0,0 @@
#include "EspLink.h"
#include "WebServer.h"
#include "Pages.h"
const char ledURL[] PROGMEM = "/LED.html.json";
const char userURL[] PROGMEM = "/User.html.json";
const char voltageURL[] PROGMEM = "/Voltage.html.json";
const WebMethod PROGMEM methods[] = {
{ ledURL, ledHtmlCallback },
{ userURL, userHtmlCallback },
{ voltageURL, voltageHtmlCallback },
{ NULL, NULL },
};
WebServer webServer(Serial, methods);
void setup()
{
Serial.begin(57600);
webServer.init();
ledInit();
userInit();
voltageInit();
}
void loop()
{
webServer.loop();
ledLoop();
voltageLoop();
}

@ -1,188 +0,0 @@
#include "WebServer.h"
#define LED_PIN 13
int8_t blinking = 0;
int8_t frequency = 10;
uint8_t pattern = 2;
uint16_t elapse = 100;
uint16_t elapse_delta = 200;
uint32_t next_ts = 0;
#define MAX_LOGS 5
uint32_t log_ts[MAX_LOGS];
uint8_t log_msg[MAX_LOGS];
uint8_t log_ptr = 0;
void ledInit()
{
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, false);
}
void ledLoop()
{
if( blinking )
{
if( next_ts <= millis() )
{
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
next_ts += elapse;
elapse = elapse_delta - elapse;
}
}
}
void ledAddLog(uint8_t msg)
{
if( log_ptr >= MAX_LOGS )
log_ptr = MAX_LOGS - 1;
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_ts[0] = millis();
log_ptr++;
}
void ledHistoryToLog(char * buf)
{
buf[0] = 0;
strcat(buf, "[");
for(uint8_t i=0; i < log_ptr; i++)
{
if( i != 0 )
strcat(buf, ",");
char bf[20];
sprintf(bf, "\"%lds: ", log_ts[i] / 1000);
strcat(buf, bf);
uint8_t msg = log_msg[i];
if( msg == 0xE1 )
{
strcat_P(buf, PSTR("set pattern to 25%-75%"));
}
else if( msg == 0xE2 )
{
strcat_P(buf, PSTR("set pattern to 50%-50%"));
}
else if( msg == 0xE3 )
{
strcat_P(buf, PSTR("set pattern to 75%-25%"));
}
else if( msg == 0xF0 )
{
strcat_P(buf, PSTR("set led on"));
}
else if( msg == 0xF1 )
{
strcat_P(buf, PSTR("set led blinking"));
}
else if( msg == 0xF2 )
{
strcat_P(buf, PSTR("set led off"));
}
else
{
strcat_P(buf, PSTR("set frequency to "));
sprintf(bf, "%d Hz", msg);
strcat(buf, bf);
}
strcat(buf, "\"");
}
strcat(buf, "]");
}
void ledHtmlCallback(WebServerCommand command, char * data, int dataLen)
{
switch(command)
{
case BUTTON_PRESS:
if( strcmp_P(data, PSTR("btn_on") ) == 0 )
{
if( blinking || digitalRead(LED_PIN) == false )
ledAddLog(0xF0);
blinking = 0;
digitalWrite(LED_PIN, true);
} else if( strcmp_P(data, PSTR("btn_off") ) == 0 )
{
if( blinking || digitalRead(LED_PIN) == true )
ledAddLog(0xF2);
blinking = 0;
digitalWrite(LED_PIN, false);
} else if( strcmp_P(data, PSTR("btn_blink") ) == 0 )
{
if( !blinking )
ledAddLog(0xF1);
blinking = 1;
next_ts = millis() + elapse;
}
break;
case SET_FIELD:
if( strcmp_P(data, PSTR("frequency") ) == 0 )
{
int8_t oldf = frequency;
frequency = webServer.getArgInt();
digitalWrite(LED_PIN, false);
elapse_delta = 2000 / frequency;
elapse = pattern * elapse_delta / 4;
if( oldf != frequency )
ledAddLog(frequency);
}
else if( strcmp_P(data, PSTR("pattern") ) == 0 )
{
int8_t oldp = pattern;
char * arg = webServer.getArgString();
if( strcmp_P(arg, PSTR("25_75")) == 0 )
pattern = 1;
else if( strcmp_P(arg, PSTR("50_50")) == 0 )
pattern = 2;
else if( strcmp_P(arg, PSTR("75_25")) == 0 )
pattern = 3;
digitalWrite(LED_PIN, false);
elapse = pattern * elapse_delta / 4;
if( oldp != pattern )
ledAddLog(0xE0 + pattern);
}
break;
case LOAD:
webServer.setArgInt("frequency", frequency);
switch(pattern)
{
case 1:
webServer.setArgStringP("pattern", PSTR("25_75"));
break;
case 2:
webServer.setArgStringP("pattern", PSTR("50_50"));
break;
case 3:
webServer.setArgStringP("pattern", PSTR("75_25"));
break;
}
case REFRESH:
{
if( blinking )
webServer.setArgStringP("text", PSTR("LED is blinking"));
else
webServer.setArgStringP("text", digitalRead(LED_PIN) ? PSTR("LED is turned on") : PSTR("LED is turned off"));
char buf[255];
ledHistoryToLog(buf);
webServer.setArgJson("led_history", buf);
}
break;
default:
break;
}
}

@ -1,8 +0,0 @@
all: user_img
clean:
rm -rf web-page.espfs.img
user_img:
../../../../../createEspFs.pl web-page web-page.espfs.img

@ -1,17 +0,0 @@
#ifndef PAGES_H
#define PAGES_H
void ledHtmlCallback(WebServerCommand command, char * data, int dataLen);
void ledLoop();
void ledInit();
void userHtmlCallback(WebServerCommand command, char * data, int dataLen);
void userInit();
void voltageHtmlCallback(WebServerCommand command, char * data, int dataLen);
void voltageLoop();
void voltageInit();
#endif /* PAGES_H */

@ -1,84 +0,0 @@
#include <EEPROM.h>
#include "WebServer.h"
#define MAGIC 0xABEF
#define MAX_STR_LEN 32
#define POS_MAGIC 0
#define POS_FIRST_NAME (POS_MAGIC + 2)
#define POS_LAST_NAME (POS_FIRST_NAME + MAX_STR_LEN)
#define POS_AGE (POS_LAST_NAME + MAX_STR_LEN)
#define POS_GENDER (POS_AGE+1)
#define POS_NOTIFICATIONS (POS_GENDER+1)
void userInit()
{
uint16_t magic;
EEPROM.get(POS_MAGIC, magic);
if( magic != MAGIC )
{
magic = MAGIC;
EEPROM.put(POS_MAGIC, magic);
EEPROM.update(POS_FIRST_NAME, 0);
EEPROM.update(POS_LAST_NAME, 0);
EEPROM.update(POS_AGE, 0);
EEPROM.update(POS_GENDER, 'f');
EEPROM.update(POS_NOTIFICATIONS, 0);
}
}
void userWriteStr(char * str, int ndx)
{
for(uint8_t i=0; i < MAX_STR_LEN-1; i++)
{
EEPROM.update(ndx + i, str[i]);
if( str[i] == 0 )
break;
}
EEPROM.update(ndx + MAX_STR_LEN - 1, 0);
}
void userReadStr(char * str, int ndx)
{
for(uint8_t i=0; i < MAX_STR_LEN; i++)
{
str[i] = EEPROM[ndx + i];
}
}
void userHtmlCallback(WebServerCommand command, char * data, int dataLen)
{
switch(command)
{
case SET_FIELD:
if( strcmp_P(data, PSTR("first_name")) == 0 )
userWriteStr(webServer.getArgString(), POS_FIRST_NAME);
if( strcmp_P(data, PSTR("last_name")) == 0 )
userWriteStr(webServer.getArgString(), POS_LAST_NAME);
if( strcmp_P(data, PSTR("age")) == 0 )
EEPROM.update(POS_AGE, (uint8_t)webServer.getArgInt());
if( strcmp_P(data, PSTR("gender")) == 0 )
EEPROM.update(POS_GENDER, (strcmp_P(webServer.getArgString(), PSTR("male")) == 0 ? 'm' : 'f'));
if( strcmp_P(data, PSTR("notifications")) == 0 )
EEPROM.update(POS_NOTIFICATIONS, (uint8_t)webServer.getArgBoolean());
break;
case LOAD:
{
char buf[MAX_STR_LEN];
userReadStr( buf, POS_FIRST_NAME );
webServer.setArgString("first_name", buf);
userReadStr( buf, POS_LAST_NAME );
webServer.setArgString("last_name", buf);
webServer.setArgInt("age", (uint8_t)EEPROM[POS_AGE]);
webServer.setArgStringP("gender", (EEPROM[POS_GENDER] == 'm') ? PSTR("male") : PSTR("female"));
webServer.setArgBoolean("notifications", EEPROM[POS_NOTIFICATIONS] != 0);
}
break;
case REFRESH:
// do nothing
break;
}
}

@ -1,125 +0,0 @@
#include "WebServer.h"
#include <avr/io.h>
#define SAMPLE_COUNT 100
#define PERIOD_COUNT (135 * SAMPLE_COUNT)
uint16_t smin = 0xFFFF;
uint16_t smax = 0;
uint32_t savg = 0;
uint16_t count;
uint32_t voltage = 0;
uint16_t measured_voltage = 0;
#define MAX_HISTORY 3
uint8_t history_cnt = 0;
uint32_t h_ts[MAX_HISTORY];
uint16_t h_min[MAX_HISTORY];
uint16_t h_max[MAX_HISTORY];
uint16_t h_avg[MAX_HISTORY];
uint16_t calibrate = 0x128; // calibrate this manually
void voltageInit()
{
analogReference(DEFAULT);
count = 0;
}
void voltageLoop()
{
uint16_t adc = analogRead(A0);
if( adc < smin )
smin = adc;
if( adc > smax )
smax = adc;
savg += adc;
voltage += adc;
count++;
if( (count % SAMPLE_COUNT) == 0 )
{
voltage /= SAMPLE_COUNT;
measured_voltage = voltage * calibrate / 256;
voltage = 0;
}
if( count == PERIOD_COUNT )
{
for(int8_t i=MAX_HISTORY-2; i >=0; i-- )
{
h_ts[i+1] = h_ts[i];
h_min[i+1] = h_min[i];
h_max[i+1] = h_max[i];
h_avg[i+1] = h_avg[i];
}
h_ts[0] = millis();
h_min[0] = (uint32_t)smin * calibrate / 256;
h_max[0] = (uint32_t)smax * calibrate / 256;
h_avg[0] = (savg / PERIOD_COUNT) * calibrate / 256;
smin = 0xFFFF;
smax = 0;
savg = 0;
if( history_cnt < MAX_HISTORY )
history_cnt++;
count = 0;
}
}
void voltageHtmlCallback(WebServerCommand command, char * data, int dataLen)
{
switch(command)
{
case BUTTON_PRESS:
// no buttons
break;
case SET_FIELD:
/* TODO */
break;
case LOAD:
case REFRESH:
{
char buf[20];
uint8_t int_part = measured_voltage / 256;
uint8_t float_part = ((measured_voltage & 255) * 100) / 256;
sprintf(buf, "%d.%02d V", int_part, float_part);
webServer.setArgString("voltage", buf);
char tab[256];
tab[0] = 0;
strcat_P(tab, PSTR("[[\"Time\",\"Min\",\"AVG\",\"Max\"]"));
for(uint8_t i=0; i < history_cnt; i++ )
{
uint8_t min_i = h_min[i] / 256;
uint8_t min_f = ((h_min[i] & 255) * 100) / 256;
uint8_t max_i = h_max[i] / 256;
uint8_t max_f = ((h_max[i] & 255) * 100) / 256;
uint8_t avg_i = h_avg[i] / 256;
uint8_t avg_f = ((h_avg[i] & 255) * 100) / 256;
sprintf(buf, ",[\"%d s\",", h_ts[i] / 1000);
strcat(tab, buf);
sprintf(buf, "\"%d.%02d V\",", min_i, min_f);
strcat(tab, buf);
sprintf(buf, "\"%d.%02d V\",", avg_i, avg_f);
strcat(tab, buf);
sprintf(buf, "\"%d.%02d V\"]", max_i, max_f);
strcat(tab, buf);
}
strcat_P(tab, PSTR("]"));
webServer.setArgJson("table", tab);
}
break;
}
}

@ -1,36 +0,0 @@
<!-- EspLink will add header here -->
<div class="header">
<h1>LED configuration</h1>
</div>
<div class="content">
<div class="pure-g"><div class="pure-u-1 pure-u-md-1-2">
<div class="card">
<h1>Control</h1>
<button id="btn_on" type="button">Turn on</button>
<button id="btn_blink" type="button">Start blinking</button>
<button id="btn_off" type="button">Turn off</button>
<p id="text"/>
</div>
<div class="card">
<h1>Frequency and pattern</h1>
<form>
<b>Pattern:</b><br/>
<input type="radio" name="pattern" value="25_75">25% on 75% off</input><br/>
<input type="radio" name="pattern" value="50_50">50% on 50% off</input><br/>
<input type="radio" name="pattern" value="75_25">75% on 25% off</input><br/>
<b>Frequency:</b><br/>
<input type="range" name="frequency" min="1" max="25"><br/>
<input type="submit">
</form>
</div></div>
<div class="pure-u-1 pure-u-md-1-2">
<div class="card" style="min-height: 400px">
<h1>Logs</h1>
<ul id="led_history"/>
</div>
</div></div>
</div>
</body></html>

@ -1,24 +0,0 @@
<!-- EspLink will add header here -->
<div class="header">
<h1>User setup</h1>
</div>
<div class="content">
<form>
First name:<br/><input name="first_name" type="text"/>
Last name:<br/><input name="last_name" type="text"/>
Age:
<input name="age" type="number"/>
Gender:
<select name="gender">
<option value="female">Female</option>
<option value="male">Male</option>
</select>
<br>
Notifications<input name="notifications" type="checkbox"/>
<br>
<input type="submit">
</form>
</div>
</body></html>

@ -1,15 +0,0 @@
<!-- EspLink will add header here -->
<meta name="refresh-rate" content="500" />
<div class="header">
<h1>Voltage measurement</h1>
</div>
<div class="content">
<p id="voltage" align="center" style="font-size: 800%"/>
<table class="pure-table pure-table-bordered" align="center" id="table"/>
</div>
</body></html>

@ -1,49 +0,0 @@
#include "EspLink.h"
#include "WebServer.h"
#define LED_PIN 13
void simpleLedHtmlCallback(WebServerCommand command, char * data, int dataLen);
const char simpleLedURL[] PROGMEM = "/SimpleLED.html.json";
const WebMethod PROGMEM methods[] = {
{ simpleLedURL, simpleLedHtmlCallback },
{ NULL, NULL },
};
WebServer webServer(Serial, methods);
void simpleLedHtmlCallback(WebServerCommand command, char * data, int dataLen)
{
switch(command)
{
case BUTTON_PRESS:
if( strcmp_P(data, PSTR("btn_on") ) == 0 )
digitalWrite(LED_PIN, true);
else if( strcmp_P(data, PSTR("btn_off") ) == 0 )
digitalWrite(LED_PIN, false);
break;
case SET_FIELD:
// no fields to set
break;
case LOAD:
case REFRESH:
if( digitalRead(LED_PIN) )
webServer.setArgString("text", "LED is on");
else
webServer.setArgString("text", "LED is off");
break;
}
}
void setup()
{
Serial.begin(57600);
webServer.init();
}
void loop()
{
webServer.loop();
}

@ -1,7 +0,0 @@
<!-- EspLink will add header here -->
<h1 class="header">Simple LED control</h1>
<h2><div id="text"/></h2>
<button id="btn_on" type="button">Turn on</button>
<button id="btn_off" type="button">Turn off</button>
</body></html>

@ -1 +0,0 @@
For information on installing libraries, see: http://www.arduino.cc/en/Guide/Libraries
Loading…
Cancel
Save