Hi all,
I've spent the afternoon searching and trying to work out the relationship between a html page and returning values over WiFi without success.
I've worked out how to add a field to the web page to allow a value to be entered to correct the timezone on a MAX7219 clock. But I cant work out getting it out of the message string.
Does anyone know of a good video or tutorial on parsing values/strings back from a HTML page to a NodeMCU/Arduino to use that value?
I'm adapting a project from here:
Smart Notice Board with ESP8266 & Dot Matrix LED Display - Smart Notice Board with ESP8266 & Dot Matrix LED Display
to a two line display. I need to be able to enter the timezone correction into the webpage that collects the message & scroll settings.
I've modified the code to add the timezone field to the HTML page. If anyone can tell me how to make the message box larger to see a full 255 character message rather than having it overflow out of the small box that would be awesome also. I don't do much HTML and I've tried a few mods without success.
const char WebPage[] =
"<!DOCTYPE html>\n"
"<html>\n"
"<head>\n"
"<meta name='viewport' content='width=device-width, initial-scale=1'>\n"
"<title>TrapTronixAU Message Board</title>\n"
"<script>\n"
"strLine = '';\n"
"\n"
"function SendData() {\n"
" nocache = '/&nocache=' + Math.random() * 1000000;\n"
" var request = new XMLHttpRequest();\n"
" strLine = '&MSG=' + document.getElementById('data_form').Message.value;\n"
" strLine = strLine + '/&SD=' + document.getElementById('data_form').ScrollType.value;\n"
" strLine = strLine + '/&I=' + document.getElementById('data_form').Invert.value;\n"
" strLine = strLine + '/&SP=' + document.getElementById('data_form').Speed.value;\n"
" strLine = strLine + '/&TZ=' + document.getElementById('data_form').Timezone.value;\n" // added to get timezone value
" request.open('GET', strLine + nocache, false);\n"
" request.send(null);\n"
"}\n"
"</script>\n"
"<style>\n"
" body {\n"
" font-family: Arial, sans-serif;\n"
" margin: 10px;\n"
" padding: 10px;\n"
" }\n"
" \n"
" .container {\n"
" max-width: 600px;\n"
" margin: 0 auto;\n"
" text-align: center;\n"
" }\n"
" \n"
" p {\n"
" font-size: 30px;\n"
" margin-top: 10px;\n"
" }\n"
" \n"
" form {\n"
" margin-top: 10px;\n"
" display: inline-block;\n"
" text-align: left;\n"
" width: 60%;\n"
" }\n"
" \n"
" input[type='text'] {\n"
" padding: 10px;\n"
" font-size: 16px;\n"
" width: 100%;\n"
" margin-bottom: 20px;\n" // was 20
" box-sizing: border-box;\n"
" }\n"
" label {\n"
" font-size: 16px;\n"
" margin-bottom: 10px;\n"
" display: block;\n"
" }\n"
" input[type='radio'] {\n"
" margin-right: 10px;\n"
" }\n"
" input[type='submit'] {\n"
" padding: 10px 20px;\n"
" font-size: 18px;\n"
" background-color: #3F51B5;\n"
" color: #fff;\n"
" border: 0;\n"
" margin-top: 5px;\n"
" cursor: pointer;\n"
" }\n"
" @media only screen and (max-width: 600px) {\n"
" form {\n"
" width: 100%;\n"
" }\n"
" }\n"
"</style>\n"
"</head>\n"
"<body>\n"
" <div class='container'>\n"
" <p><b>TrapTronixAU Message Board & Clock</b></p>\n"
// " <h3><b><a href='https://iotprojectsideas.com'>https://iotprojectsideas.com</a></b></h3>\n"
" <form id='data_form' name='frmText'>\n"
" <label>Enter new message to display:<br><input type='text' name='Message' maxlength='255'></label>\n"
" <br><br>\n"
" <label>Enter timezone correction (eg AEST 10, AEDT11):<br><input type='number' name='Timezone' maxlength='4'></label>\n"
" <br><br>\n"
" <label>Invert:</label><br>\n"
" <input type = 'radio' name = 'Invert' value = '0' checked> Normal \n"
" <input type = 'radio' name = 'Invert' value = '1'> Inverse \n"
" <br><br>\n"
" <label>Scroll Type:</label><br>\n"
" <input type='radio' name='ScrollType' value='L' checked>Left \n"
"<input type='radio' name='ScrollType' value='R'>Right \n"
"<br><br>\n"
"<label>Speed:</label><br>\n"
"<div style='display: flex; justify-content: space-between;'>\n"
"<span style='text-align: left;'>Fast</span>\n"
"<span style='text-align: right;'>Slow</span>\n"
"</div>\n"
"<input type='range' name='Speed' min='10' max='200'>\n"
"<br><br>\n"
"<input type='submit' value='Send Data' onclick='SendData()'>\n"
"</form>\n"
"<style>\n"
"body {\n"
" font-family: Arial, sans-serif;\n"
" text-align: center;\n"
"}\n"
"form {\n"
" display: inline-block;\n"
" text-align: left;\n"
" padding: 20px;\n"
" background-color: #f2f2f2;\n"
" border: 1px solid #ccc;\n"
" border-radius: 5px;\n"
" box-shadow: 2px 2px 5px #bbb;\n"
"}\n"
"label {\n"
" display: block;\n"
" margin-bottom: 10px;\n"
" font-weight: bold;\n"
"}\n"
"input[type='text'], input[type='range'] {\n"
" width: 100%;\n"
" padding: 10px;\n"
" margin-bottom: 2px;\n"
" box-sizing: border-box;\n"
" border: 1px solid #ccc;\n"
" border-radius: 5px;\n"
" font-size: 16px;\n"
"}\n"
"input[type='submit'] {\n"
" padding: 10px 20px;\n"
" background-color: #4CAF50;\n"
" color: white;\n"
" border: none;\n"
" border-radius: 5px;\n"
" font-size: 16px;\n"
" cursor: pointer;\n"
"}\n"
"input[type='submit']:hover {\n"
" background-color: #3e8e41;\n"
"}\n"
"@media (max-width: 600px) {\n"
"form {\n"
"width: 90%;\n"
"}\n"
"}\n"
"</style>\n"
"</body>\n"
"</html>\n";
It creates the page fields as follows:
The code that I've tried to adapt that takes the values returned including text message, scroll direction, speed & timezone adjustment is
void getData(char *szMesg, uint16_t len)
// Message may contain data for:
// New text (/&MSG=)
// Scroll direction (/&SD=)
// Invert (/&I=)
// Speed (/&SP=)
// Timezone (/&TZ=)
{
char *pStart, *pEnd; // pointer to start and end of text
// check text message
pStart = strstr(szMesg, "/&MSG=");
if (pStart != NULL)
{
char *psz = newMessage;
pStart += 6; // skip to start of data
pEnd = strstr(pStart, "/&");
if (pEnd != NULL)
{
while (pStart != pEnd)
{
if ((*pStart == '%') && isxdigit(*(pStart + 1)))
{
// replace %xx hex code with the ASCII character
char c = 0;
pStart++;
c += (htoi(*pStart++) << 4);
c += htoi(*pStart++);
*psz++ = c;
}
else
*psz++ = *pStart++;
}
*psz = '\0'; // terminate the string
newMessageAvailable = (strlen(newMessage) != 0);
PRINT("\nNew Msg: ", newMessage);
}
}
// check scroll direction
pStart = strstr(szMesg, "/&SD=");
if (pStart != NULL)
{
pStart += 5; // skip to start of data
PRINT("\nScroll direction: ", *pStart);
scrollEffect = (*pStart == 'R' ? PA_SCROLL_RIGHT : PA_SCROLL_LEFT);
PTOP.setTextEffect(scrollEffect, scrollEffect);
PTOP.displayReset();
// PBOT.setTextEffect(scrollEffect, scrollEffect);
// PBOT.displayReset();
}
// check invert
pStart = strstr(szMesg, "/&I=");
if (pStart != NULL)
{
pStart += 4; // skip to start of data
PRINT("\nInvert mode: ", *pStart);
PTOP.setInvert(*pStart == '1');
PBOT.setInvert(*pStart == '1');
}
// check speed
pStart = strstr(szMesg, "/&SP=");
if (pStart != NULL)
{
pStart += 5; // skip to start of data
int16_t speed = atoi(pStart);
PRINT("\nSpeed: ", PTOP.getSpeed());
PTOP.setSpeed(speed);
// PRINT("\nSpeed: ", PBOT.getSpeed()); /// come back to here
// PBOT.setSpeed(speed);
frameDelay = speed;
}
// check timezone
pStart = strstr(szMesg, "/&TZ=");
if (pStart != NULL)
{
pStart += 5; // skip to start of data
int16_t Timezone = atoi(pStart);
PRINT("\nTimezone correction: ", Timezone()); // timezone was PTOP.getSpeed
// PTOP.setSpeed(speed);
// PRINT("\nSpeed: ", PBOT.getSpeed());
// PBOT.setSpeed(speed);
uint8_t timeadjust = Timezone;
// PRINT("\nTimezone correction: ", Timezone()); // timezone was PTOP.getSpeed
}
}
I've added and played with variations of the bottom bit
// check timezone
pStart = strstr(szMesg, "/&TZ=");
if (pStart != NULL)
{
pStart += 5; // skip to start of data
int16_t Timezone = atoi(pStart);
PRINT("\nTimezone correction: ", Timezone()); // timezone was PTOP.getSpeed
// PTOP.setSpeed(speed);
// PRINT("\nSpeed: ", PBOT.getSpeed());
// PBOT.setSpeed(speed);
uint8_t timeadjust = Timezone;
// PRINT("\nTimezone correction: ", Timezone()); // timezone was PTOP.getSpeed
I don't understand the pStart += # in the code fetching the information from the message that the webpage returns. Why is it 4 or 5 in different sections? It doesn't appear to relate to the length of the name of the variable the page is collecting?
I'm so close to getting this working. The last thing is to be able to use it in different timezones just by entering a value in that field on the webpage.
I did have it working in an earlier prototype but the value was entered on the WiFi setup page that was created and managed by the WiFiManager. If I don't have to reset the WiFi credentials each time that page isn't accessed.
Any help appreciated. Full code available here - Smart_Notice_Board_inc_clock_v1.3 - code for forum.txt - pCloud
Thanks
Dave