Return value from HTML page over wifi

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

There's also a weird glitch in it that see's the scrolling stop & the clock return to UTC for a short period. It wasn't doing that earlier today so I've broken something when I was playing with correcting from UTC by adding 39600 to the time to adjust for 11 hours.

Ultimately I want to have the person enter a value like 10 or 9.5 to adjust the timezone and just add that or subtract it from the time in hours to correct for timezones. Not a value in millis.

Here's a video of the symptoms. https://youtu.be/V6DBub8oHXc

DJ

why is that needed at all?
The ESP Core comes with a complete implementation of time, NTP retrival and includes DST correction.
Just define your timezone once and you get the correct localtime.

See:
https://werner.rothschopf.net/202011_arduino_esp8266_ntp_en.htm

if you really need an external RTC - consider something better than a DS1302.

I have an example also:
https://werner.rothschopf.net/microcontroller/202112_arduino_esp_ntp_rtc_en.htm

I need to be able to alter the time zone depending on which state of the country the device is being used in.

Each time it is started it only needs to be accurate for 6-8 hours. I’ll look at different RTC modules but I happened to have the 1302 on hand.

Dave

in this case I would hold such a file in the file system and make a listbox for the user:

and persist the chosen data in preferences.

Back from New Zealand & back on this again. Can you point me at any sites/pages showing how I'd integrate that into the HTML page to return the value required to make the time adjustment?

Thanks

Dave

https://werner.rothschopf.net/microcontroller/202310_esp_webserver_maxi_en.htm
Example 40

as a drop down with >450 entries is not really practicable I propose to filter the full list of zones in one drop down with the Area and one drop down with the location.

Something like:

selection2

the first drop down filters the content of the second drop down.

To get this working dynamically quite a lot of code is needed.
But it works.

More pictures and code can be found here:
http://werner.rothschopf.net/microcontroller/202402_arduino_esp_ntp_user_configuration.htm

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.