Skip to content

Commit a164acc

Browse files
committed
Version: 1.3.2 - 2018-07-02 by James Newton
-DEBUG levels: 1 for serial only, 2 for serial and display. -User config device baudrate, poweron initialization string, data extraction and display: -- New /device.html page to configure all connected device options -- Send config.pwronstr to device pwrondelay seconds after startup -- Extract up to 3 data items returned from device for local display via scanf code: http://www.cplusplus.com/reference/cstdio/scanf/ -- Extracted values multiplied by slope plus offset and shown with name on the display -global.h config load/save simplified with EEPROM.get / EEPROM.put. -CONFIG_VER version number added. This update will clear prior config data to default! -txbuf to hold data waiting to be sent to the device so we can send this in a debug message -Support "hidden" /update page to upload web/js/css/etc files into SPIFFS for web server. This allows customization and rebranding for your solution without the need for Arduino code development. Put your own html/javascript in the device for user interface. -Default web page is index.htm from SPIFFS. /root is handle_root from Page_Root.h i.e. http://ip/ will display nothing until index.htm is uploaded via http://ip/update. If you want to use the built in homepage, go to http://ip/root TODO: serve root automatically if no index.htm in SPIFFS -Built in /root page converted from jquery to raw javascript for increased reliability and smaller size. This is critical when working in poor RF environments while directly connected to the device. -Use template processor in ESPAsyncWebServer for config pages. There are problems with this, see: -- me-no-dev/ESPAsyncWebServer#333 Must change TEMPLATE_PLACEHOLDER to '`' in \libraries\ESPAsyncWebServer\src\WebResponseImpl.h and trigger library re-compile -- me-no-dev/ESPAsyncWebServer#374 Must use "AI-THINKER" ESP-12E units -- Network setup /config.html NOT updated to templates for this reason. -Moving to a single general tag processor function "send_tag_values" -Moving to standard linking to .css and .js resources from config pages instead of the javascript window.onload functions. -Add debugq macro to append to debugbuf for later output. This avoids delays when debugging web responses -Increase max string length of ReadStringFromEEPROM from 60 to 65 -urldecode, avoids Strings, returns char*, expects length. -urlencode, expects char* vs String (still returns String). Simplified via nibble2hex. -HTMLencode added inorder to support all strings for scanf codes. -Optional support for NeoPixel LEDs. NOT enabled by default. -Start on a command processor language from server response or user input BUGFIX: IO pin 10 is NOT usable as SERIAL_ENABLE_PIN, back to IO5 D1 parseServer p1,p2 had not been initialized. Data returned from server for device could be lost.
1 parent ef2faaa commit a164acc

File tree

7 files changed

+167
-59
lines changed

7 files changed

+167
-59
lines changed

Page_Root.h

+41-35
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
*/
66

77
const char PAGE_Root[] PROGMEM = R"=====(
8-
<!doctype html>
8+
<!DOCTYPE html>
99
<meta name="viewport" content="width=device-width, initial-scale=1" />
10-
<script src="microajax.js"></script>
1110
<html>
1211
<head>
1312
<title>ESP8266 IOT Serial to Web</title>
@@ -17,46 +16,53 @@ const char PAGE_Root[] PROGMEM = R"=====(
1716
<meta charset="utf-8" />
1817
</head>
1918
<body>
20-
<pre><div id='log'></div></pre>
21-
<p>
22-
<form id='msg' action='data' method='get'>
23-
<input id='txt' name='text' type='text'></input><input id='crlf' type='checkbox' checked>+cr?</input>
24-
</form></p>
25-
<p><a href="/admin.html">Settings</a> <a href="/file?start=1">Stream</a></p>
26-
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js'></script>
27-
<script type='text/javascript'>
28-
$('#msg').submit(function(){
29-
var clientmsg = $('#txt').val();
30-
if ($('#crlf').is(':checked')) clientmsg+='\r';
31-
var log=$('#log');
32-
log.html(log.html()+'<b>'+clientmsg+'</b>');
33-
$.get('data', {text: clientmsg}, function(html){
34-
log.html(log.html()+html);
35-
});
36-
$('#txt').attr('value', '');
37-
loadLog(); //instantly pick up any response.
38-
return false;
39-
});
40-
function loadLog(){
41-
var log=$('#log');
42-
$.ajax({
43-
url: 'data',
44-
cache: false,
45-
success: function(html){
46-
log.html(log.html()+html);
47-
},
19+
<script>
20+
function ajax(data, callback) {
21+
var xhttp = new XMLHttpRequest();
22+
xhttp.onreadystatechange = function() {
23+
if (this.readyState == 4 && this.status == 200) {
24+
callback(this.responseText);
25+
};
26+
};
27+
xhttp.open("GET", data, true);
28+
xhttp.send();
29+
}
30+
31+
function getData() {
32+
ajax("/data", function(reply) {
33+
document.getElementById("log").innerHTML += reply;
34+
});
35+
setTimeout(function(){getData()},1000);
36+
}
37+
38+
function sendData(form) {
39+
var msg = form.txt.value;
40+
form.txt.value = "";
41+
var response = "";
42+
if (form.crlf.checked) msg+='\r';
43+
//console.log(form.crlf.checked);
44+
ajax("/data?text="+escape(msg), function(reply) {
45+
document.getElementById("log").innerHTML += escape(reply);
4846
});
47+
setTimeout(function(){getData()},200);
48+
return false;
4949
};
50-
setInterval (loadLog, 2500);
51-
</script>
52-
</body>
53-
</html>
5450

51+
</script>
52+
53+
<pre><div id='log'></div></pre>
54+
<p>
55+
<form id='msg' action='data' method='get' onSubmit="sendData(this);return false;">
56+
<input id='txt' name='text' type='text'><input id='crlf' type='checkbox' checked><label for="crlf">+cr?</label>
57+
</form>
58+
<p><a href="/admin.html">Settings</a>
59+
60+
</body>
61+
</html>
5562
)=====";
5663

5764
void handle_root(AsyncWebServerRequest *request) {
5865
request->send(200, "text/html", PAGE_Root);
59-
//delay(100); //why is this here? TODO: try without.
6066
debugbuf+="/";
6167
}
6268
//Change the setInterval number above for faster or slower updates from serial to web

Pages.h

+21-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,17 @@ String send_tag_values(const String& tag) {
2323
if (tag == "dataoffset3") return String(config.dataoffset3,7);
2424
if (tag == "dataname3") return (String) config.dataname3;
2525
if (tag == "datacount") return (String) config.datacount;
26+
if (tag == "pwronstr") return (String) config.pwronstr;
27+
if (tag == "pwrondelay") return (String) config.pwrondelay;
28+
29+
2630
if (tag == "directory") {
2731
String dirlist = "";
2832
Dir dir = SPIFFS.openDir("/");
2933
while (dir.next()) {
34+
dirlist += "<a href=\"/update?delete=";
35+
dirlist += String(dir.fileName());
36+
dirlist += "\">x</a> ";
3037
dirlist += String(dir.fileName());
3138
dirlist += "\t ";
3239
File f = dir.openFile("r");
@@ -83,7 +90,7 @@ const char PAGE_AdminGeneralSettings[] PROGMEM = R"=====(
8390
<tr><td align="right"> Enabled:</td><td><input type="checkbox" id="logging" name="logging" `logging`></td></tr>
8491
<tr><td align="right"> Interval:</td><td><input type="text" id="interval" name="interval" size="6" value="`interval`"> Seconds</td></tr>
8592
<tr><td align="right"> Check in every:</td><td><input type="text" id="wakecount" name="wakecount" size="6" value="`wakecount`"> intervals</td></tr>
86-
<tr><td colspan="2">Stream Server:<br><input type="text" id="server" name="server" size="65" value="`server`"></td></tr>
93+
<tr><td colspan="2">Server:<br><input type="text" id="server" name="server" size="65" value="`server`"></td></tr>
8794
<tr><td colspan="2" align="center"><input id="save" type="submit" style="width:150px" class="btn btn--m btn--blue" value="Save"></td></tr>
8895
</table>
8996
</form>
@@ -213,6 +220,7 @@ const char PAGE_FileSystem[] PROGMEM = R"=====(
213220
Upload: <br><input type="file" name="name">
214221
<input class="button" type="submit" value="Upload">
215222
</form>
223+
Delete: Press 'x' before file, then append '&now' to url to actually remove the file.
216224
</BODY>
217225
</HTML>
218226
)=====";
@@ -245,7 +253,10 @@ static File fsUploadFile; //Used with SPIFFS to upload files.
245253
void send_fs_html(AsyncWebServerRequest *request){
246254
if (request->args() > 0 ) { // Work to do
247255
for ( uint8_t i = 0; i < request->args(); i++ ) {
248-
if (request->argName(i) == "delete") debugbuf+= "delete"+ request->arg(i);
256+
if (request->argName(i) == "delete") {
257+
debugbuf+= "delete:" + request->arg(i)+".\n";
258+
if (request->hasArg("now")) SPIFFS.remove(request->arg(i));
259+
}
249260
}
250261
}
251262
debugbuf+=__FUNCTION__;
@@ -268,9 +279,14 @@ const char PAGE_AdminDeviceSettings[] PROGMEM = R"=====(
268279
<form action="" method="post">
269280
<table border="0" cellspacing="0" cellpadding="3" >
270281
<tr><td align="right">Baud rate</td><td><input type="text" id="baud" name="baud" value="`baud`"></td></tr>
271-
<tr><td align="right"> Enable Connection:</td><td><input type="checkbox" id="connect" name="connect" `Connect`></td></tr>
282+
<tr><td align="right"> Connection:</td><td><input type="checkbox" id="connect" name="connect" `Connect`>Enabled</input></td></tr>
272283
<tr><td align="right"> Blink?:</td><td><div id="blinked">`blinked`</div></td></tr>
273284
<tr><td align="left" colspan="2"><hr></td></tr>
285+
<tr><td align="right"> Initialization:</td><td>
286+
Send: <input type="text" id="pwronstr" name="pwronstr" value="`pwronstr`" size=6>
287+
after <input type="text" id="pwrondelay" name="pwrondelay" value="`pwrondelay`" size=3 title="zero to disable"> Seconds
288+
</td></tr>
289+
<tr><td align="left" colspan="2"><hr></td></tr>
274290
<tr><td align="left" colspan="2">Extracted Data Reading: (<a href="http://www.cplusplus.com/reference/cstdio/scanf/">Data Pattern help</a>)</td></tr>
275291
<tr><td align="right"> Trigger:</td><td>
276292
<input type="text" id="datatrigger" name="datatrigger" value="`datatrigger`" size=6>
@@ -325,6 +341,8 @@ void send_device_html(AsyncWebServerRequest *request){
325341
else if (request->argName(i) == "dataoffset3") config.dataoffset3 = request->arg(i).toFloat();
326342
else if (request->argName(i) == "dataname3") strlcpy( config.dataname3, request->arg(i).c_str(), sizeof(config.dataname3));
327343
else if (request->argName(i) == "datacount") config.datacount = request->arg(i).toInt();
344+
else if (request->argName(i) == "pwronstr") strlcpy( config.pwronstr, request->arg(i).c_str(), sizeof(config.pwronstr));
345+
else if (request->argName(i) == "pwrondelay") config.pwrondelay = request->arg(i).toInt();
328346
}
329347
WriteConfig();
330348
if (config.Connect) {

README.md

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
11
# esp8266WebSerial
22
Put anything with a TTL serial connection on the local network with browser access or log to a server... for under 10 bucks
33

4-
- ESPAsyncWebServer for reliable operation
5-
- Support for ST7735 and ILI9341 and other LCD displays via TFT_eSPI
4+
- ESPAsyncWebServer for reliable operation, local config in browser, direct web based serial "terminal", etc...
5+
- File system support to upload custom default web page, libraries, css, etc... via "hidden" page to avoid end user confusion.
6+
This allows customization and rebranding for your solution without the need for Arduino code development. Put your own html/javascript in the device for user interface.
67
- Log incoming data / status to server, stream commands from server out to the connected device
78
- Low power cycle config: sleep for x seconds, wake send data / status to server as available or every x wake cycles.
89
- "Blink Detect" input to watch error lights, etc... on remote devices (with optional photodiode and flipflop for detection during sleep)
910
- Wake without radio for very low power input monitoring
1011
- "Pico Jason" interpreter for commands from server to ESP to configure power cycles, logging.
12+
- Support for ST7735 and ILI9341 and other LCD displays via [TFT_eSPI](https://github.com/Bodmer/TFT_eSPI#tft_espi) _in overlap mode only_ for MAC, SSID / IP address display and
13+
device data extraction / display via scanf codes, slope, and offset.
14+
- Device uses alternate TX/RX pins so power up bootloader messages are NOT sent to device and debug messages are available on Serial Monitor.
15+
- Basic X-ON/X-OFF support to avoid buffer overruns on connected device (TODO: CTS monitoring)
16+
- Configurable device port enable / disable to avoid powering level converters or triggering device connect power up.
17+
- Configurable device baud rate, power on initialization message, and data extraction triggers.
18+
- Optional support for "NeoPixel" LEDs (commented out by default).
19+
20+
Notes:
21+
22+
23+
Due to a [bug / limitation in ESPAsyncWebServer's template system](https://github.com/me-no-dev/ESPAsyncWebServer/issues/333#issuecomment-370595466), and the fact that % is often used in the device configuration, you have to edit the /src/WebResponseImpl.h file in that library to change:
24+
````
25+
#define TEMPLATE_PLACEHOLDER '%'
26+
````
27+
to
28+
````
29+
#define TEMPLATE_PLACEHOLDER '`'
30+
````
31+
32+
P.S. Don't even try to get this to work with an ESP-8266 module that wasn't made by AI-THINKER. [The knock offs will NOT work](https://github.com/me-no-dev/ESPAsyncWebServer/issues/374).
1133

1234
See:
1335
http://techref.massmind.org/techref/ESP8266/WebSerial.htm for documentation, screenshots, and examples

data/jquery-3.3.1.min.js

-2
This file was deleted.

0 commit comments

Comments
 (0)