LED on / off and blinking

pull/183/head
Karai Csaba 9 years ago committed by cskarai
parent 9a0a78d85e
commit cc8a5dd55b
  1. 83
      examples/arduino/EspLinkSample/EspLinkSample.ino
  2. 150
      examples/arduino/EspLinkSample/WebServer.cpp
  3. 75
      examples/arduino/EspLinkSample/WebServer.h
  4. 5
      web-server/web-server.c

@ -1,7 +1,88 @@
#include "WebServer.h"
#define LED_PIN 13
int8_t blinking = 0;
int8_t frequency = 10;
uint16_t elapse = 100;
uint32_t next_ts = 0;
void ledHtmlCallback(WebServerCommand command, char * data, int dataLen);
const char ledURL[] PROGMEM = "/LED.html.json";
const WebMethod PROGMEM methods[] = {
{ ledURL, ledHtmlCallback },
{ NULL, NULL },
};
WebServer webServer(Serial, methods);
void setup()
{
Serial.begin(57600);
webServer.init();
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, false);
}
void loop()
{
webServer.loop();
if( blinking )
{
if( next_ts <= millis() )
{
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
next_ts += elapse;
}
}
}
void ledHtmlCallback(WebServerCommand command, char * data, int dataLen)
{
switch(command)
{
case BUTTON_PRESS:
if( strcmp_P(data, PSTR("btn_on") ) == 0 )
{
blinking = 0;
digitalWrite(LED_PIN, true);
} else if( strcmp_P(data, PSTR("btn_off") ) == 0 )
{
blinking = 0;
digitalWrite(LED_PIN, false);
} else if( strcmp_P(data, PSTR("btn_blink") ) == 0 )
{
blinking = 1;
next_ts = millis() + elapse;
}
break;
case LOAD:
webServer.setArgNum(1);
case REFRESH:
if( command == REFRESH )
webServer.setArgNum(1);
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"));
break;
default:
break;
}
}
/*
#include "EspLink.h"
void packetReceived(CmdRequest *req);
EspLink espLink(Serial, packetReceived);
@ -97,4 +178,4 @@ void setup() {
void loop() {
espLink.readLoop();
}
*/

@ -0,0 +1,150 @@
#include "WebServer.h"
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)
{
instance = this;
}
void WebServer::init()
{
registerCallback();
}
void WebServer::loop()
{
// TODO: resubscribe periodically
espLink.readLoop();
}
void WebServer::registerCallback()
{
espLink.sendPacketStart(CMD_CB_ADD, 100, 1);
espLink.sendPacketArg(5, (uint8_t *)"webCb");
espLink.sendPacketEnd();
}
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:
{
/* TODO: iterate through fields */
}
return;
default:
break;
}
args_to_send = -1;
method->callback( reason == WS_LOAD ? LOAD : REFRESH, NULL, 0);
if( args_to_send == -1 )
{
espLink.sendPacketStart(CMD_WEB_JSON_DATA, 100, 2);
espLink.sendPacketArg(4, remote_ip);
espLink.sendPacketArg(2, (uint8_t *)&remote_port);
}
while( args_to_send-- > 0 )
espLink.sendPacketArg(0, NULL);
espLink.sendPacketEnd();
}
void WebServer::handleRequest(CmdRequest *req)
{
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_JSON_DATA, 100, 2);
espLink.sendPacketArg(4, remote_ip);
espLink.sendPacketArg(2, (uint8_t *)&remote_port);
espLink.sendPacketEnd();
}
void WebServer::setArgNum(uint8_t num)
{
espLink.sendPacketStart(CMD_WEB_JSON_DATA, 100, 2 + (args_to_send = num));
espLink.sendPacketArg(4, remote_ip);
espLink.sendPacketArg(2, (uint8_t *)&remote_port);
}
void WebServer::setArgString(const char * name, const char * value)
{
if( args_to_send <= 0 )
return;
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);
args_to_send--;
}
void WebServer::setArgStringP(const char * name, const char * value)
{
if( args_to_send <= 0 )
return;
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);
args_to_send--;
}

@ -1,11 +1,78 @@
#ifndef WEB_SERVER_H
#define WEB_SERVER_H
typedef enum {
LOAD=0,
#include "EspLink.h"
typedef enum
{
BUTTON_PRESS,
SET_FIELD,
REFRESH,
BUTTON,
SUBMIT,
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;
int16_t args_to_send;
protected:
EspLink espLink;
public:
WebServer(Stream &stream, const WebMethod * PROGMEM methods);
void init();
void loop();
void registerCallback();
static WebServer * getInstance() { return instance; }
uint8_t * getRemoteIp() { return remote_ip; }
uint16_t getRemotePort() { return remote_port; }
void setArgNum(uint8_t num);
void setArgString(const char * name, const char * value);
void setArgStringP(const char * name, const char * value);
};
#endif /* WEB_SERVER_H */

@ -272,6 +272,9 @@ int ICACHE_FLASH_ATTR WEB_CgiJsonHook(HttpdConnData *connData)
cmdPopArg(req, buf, len);
if(len == 0)
continue;
if( jsonPtr + 20 + len > sizeof(jsonBuf) )
{
errorResponse(connData, 500, "Response too large!");
@ -365,7 +368,7 @@ void ICACHE_FLASH_ATTR WEB_JsonData(CmdPacket *cmd)
CmdRequest req;
cmdRequest(&req, cmd);
if (cmdGetArgc(&req) < 3) return;
if (cmdGetArgc(&req) < 2) return;
uint8_t ip[4];
cmdPopArg(&req, ip, 4);

Loading…
Cancel
Save