Home
| pfodApps/pfodDevices
| WebStringTemplates
| Java/J2EE
| Unix
| Torches
| Superannuation
| CRPS Treatment
|
| About
Us
|
![]() |
pfodWeb
|
by Matthew Ford 4th October 2025 (originally posted 27th August
2025)
© Forward Computing and Control Pty. Ltd. NSW
Australia
All rights reserved.
This is the fourth tutorial on using pfodWeb Designer to create
interactive and responsive GUI for pfodApp
and the free, open source, pfodWeb.
This
tutorial will cover touchActionInputs which when triggered popup a
single line text input dialog to allow the user to send text/numberic
data to the pfodDevice (microprocessor)
Your micro serves all the
necessary code to run the web page controls. No third party js
libraries or internet access is needed.
pfodWebDesigner is a free web based replacement for the free Android app, pfodGUIdesigner. pfodWebDesigner allows you to design interactive and responsive user interfaces for your microprocessor. pfodWebDesigner generates Arduino code that works with all pfodDevices that connect via Bluetooth, BLE, SMS and WiFi, not just those that have WiFi support. See how to install pfodWebDesigner in the previous tutorial. Individual pfodWebDesigner controls are stored as JSON files which you can duplicate, modify and reuse in other designs. Each reused control can be individually scaled and positioned in the final design.
pfodWeb is a free web based partial replacement for the paid Android app, pfodApp. pfodWeb runs in a browser and connects via http. ESP32, ESP8266 and Raspberry Pi Pico W microprocessors are supported. pfodWeb provides interactive and responsive web browser controls built with pfodWebDesigner. pfodWeb is a set of less than 200K of zipped javascript and html files that run in your browser and connect to your microprocessor, render the interface design and send the commands as the user interacts with it. The actual messages exchanged are tiny compared to a typical web page.
Introductory
Tutorial – Covers setting up the pfodWeb
Designer local server and install the pfodWeb support on an ESP32. A
simple press button example illustrates touchZone and
touchAction.
Reuse
Controls with insertDwg – Covers copying dwgs
and using insertDwg to insert multiple copies into the main
drawing.
touchActions
for Instant Feedback – Covers
using touchActions to give instant feedback in a slider
control.
TouchActionInput for text/number
entry – This one. Covers using touchActionInput to
input text / numbers to your micro
Building
Reusable Controls – Covers
building a re-usable popup help button component.
pfodWeb is free and open source. If you want to support this work,
purchase the Android pfodApp
which will work with the same code developed here and which provides
more features such as charting and data logging.
See the free
pfodDesigner
Android app for creating menus and charts for pfodApp.
See the Introductory Tutorial for the parts list and the Installation instructions. Physical parts consist of just an ESP32 / ESP8266 / Pi Pico W/2W board, e.g. Dfrobot ESP32 board.
touchActionInput is linked to a
touchZone. When the touchZone is triggered, the single line Dialog
box opens. The title of the dialog box and the initial text displayed
is configurable.
From the dialog box you can either Cancel or OK.
If you Cancel the dialog box nothing is set to the pfodDevice (your
microprocessor) and no touchActions are triggered.
If you OK the
dialog box, then the input is sent to the pfodDevice and any
touchActions for that touchZone are displayed until there is a
response from the pfodDevice.
The minimal touchActionInput opens with a blank input. If you link
the touchActionInput to a label, the current contents of the that
label are used as the initial value for the dialog input. This lets
you edit an existing label.
As was covered in previous tutorials,
labels (and values) can have prefix and suffix text which will also
be displayed in the dialog box. To edit just the numeric value, add
another label the holds just the current numeric value and then hide
that label. The touchActionInput can still access a hidden label as
its default input and the pfodDevice can update both the hidden label
and the displayed label with the updated value.
This tutorial extends the Slider example of the previous tutorial
to add a touchActionInput that accesses a hidden label which lets you
type in the required slider % and on OK updates the slider, the main
label and the hidden label.
Open pfodWebDesigner and load the
Slider.json from the previous tutorial and
make a copy of it called SliderInput
Edit the Drawing Item Value “Slider “ and
change it to a Label with 2 decimal places. Value items
only accept integers and here the slider percent setting will allow
decimal places.
Add a touchZone around the Label
with a Touch filter (default)
Add another Label, indexed, with 2 decimal places and some initial Value, but with no Text or Units. The color and position is not important as this label will be hidden in a later step.
Open the Show Details of the touchZone that encloses the Slider..% label, and click on Add touchActionInput.
Change the Prompt Text to something suitable and select idx_5: 50.00 from the drop down list of Indexed Labels
Choose a suitable color for the prompt text and background. You can then click on the Slider % touchZone in the preview to see the touchActionInput in action.
Click Add touchActionInput to accept these edits.
Add a hide Item. You can click Show for visible items to make them flash.
Click Hide for idx_5 to hide the 50.00 label that is
used for the touchActionInput.
Go back to the Control Panel
and use the Arduino Export to generate the code, Dwg_SliderInput.zip
Open the pfodParser example sketch, pfodWeb_HelloWorld and
save the sketch and save the sketch as SliderInput
Unzip
the Dwg_SliderInput.zip
to a temporary directory and merge the changes into to that
SliderInput sketch
directory. You can delete the old un-used Dwg_HelloWorld files if you
wish.
Edit SliderInput.ino to set your network's ssid and
password.
Remember to set the Flash Size to support the LittleFS
file system and to upload the data.
Compile and upload to
your microprocessor. That will display the basic GUI on either
pfodApp or pfodWeb.
The completed code is in SliderInput.zip In the previous tutorial, the slider position was an integer set by the touch X position. Here the slider_percent will be a float that can be set by either to touch X position or via the touchActionInput dialog box.
The current value of the slider_percent is used to
a) set the
width of the slider RED indicator,
b) set the visible label
“Slider … %” and
c) set the numeric value of
the hidded label that the touchActionInput will display on
opening.
In Dwg_SliderInput.cpp edit the code to
float slider_percent = 0; . . . void Dwg_SliderInput::sendIndexedItems() { dwgsPtr->rectangle().filled().idx(idx_1).color(dwgsPtr->RED).size(slider_percent,5).offset(0,16).send(); dwgsPtr->label().idx(idx_4).color(dwgsPtr->WHITE).text("Slider ").fontSize(8).offset(50,28.5).center().units("%").decimals(2).value(slider_percent).send(); dwgsPtr->label().idx(idx_5).color(dwgsPtr->BLACK_WHITE).text("").offset(1,2).left().decimals(2).value(slider_percent).send(); }
To collect the user's slider settings, edit the processDwgCmds().
The command contained in the variable cmd_c1 is the command
sent by the slider touchZone and as in the previous tutorial,
the touchedCol is assigned to the slider_percent.
command
contained in the variable cmd_c2 is the command sent by the
Slider .. % label touchZone after the touchActionInput
dialog box has been OKed.
A typical debug output in the Arduino console is
touchZone cmd c3 at (27,4) touch type:TOUCHED Edited text '48.5'
The pfodParser truncates the incoming msg at 255 chars. The Edited text is on the end of the incoming message and so is limited to less than 255 chars. See the pfodSpecification.pdf for more info on touchActionInput messages.
The touchActionInput dialog box does not do any validation. It is up to your Arduino code to do that. Here the SafeString library is used to a) safely copy the first 20 chars of the edited text and b) convert it to a float.
#include <SafeString.h> . . . cSF(sfText,20); . . . bool Dwg_SliderInput::processDwgCmds() { if (!(*(parserPtr->getDwgCmd()))) { // ==> getDwgCmd returned pointer to empty string return false; // not dwg cmd, not handled } if (parserPtr->dwgCmdEquals(cmd_c1)) { // handle touchZone cmd_c1 parserPtr->printDwgCmdReceived(debugPtr); // does nothing if passed NULL // add your cmd handling code here slider_percent = parserPtr->getTouchedCol(); // another name for getTouchedX() sendUpdate(); return true; } if (parserPtr->dwgCmdEquals(cmd_c2)) { // handle touchZone cmd_c2 parserPtr->printDwgCmdReceived(debugPtr); // does nothing if passed NULL // add your cmd handling code here sfText.clear(); sfText.readFrom((char*)parserPtr->getEditedText()); // reads at most 20 chars from the edited text if (sfText.toFloat(slider_percent)) { // if it is a valid float, limit it if (slider_percent < 0) { slider_percent = 0; } if (slider_percent > 100) { slider_percent = 100; } } else { // not a valid float. print/send an error. if (debugPtr) { debugPtr->print(sfText); debugPtr->println(" is not a valid float."); } } sendUpdate(); return true; } return false; // not handled }
If the user enters an invalid slider setting, it is helpful to display an error message to them.
Open pfodWebDesigner and copy SliderInput to SliderInputErr and edit it to add an indexed ErrMsg label
If there are no errors, the Arduino
Code will send a empty message which make the message invisible.
When
the user goes to correct an error, the previous error message will
still be displayed until the pfodDevice responds. To hide any
existing error message, add a touchAction to both touchZones
to clear the error msg.
That is replace idx_6 with an label
empty of text.
Go back to the Control Panel and use Arduino Export to generate the new code, Dwg_SliderInputErr.zip
Save the SliderInput Arduino sketch as SliderInputErr and unzip Dwg_SliderInputErr.zip to that sketch directory and merge the code from Dwg_SliderInput.cpp.
Note: If the Arduino linker complains of duplicate symbols, it has not cleared out the old cached compiled files. Change the board to a different one (any one) and start a compile. Then cancel the compile and change back to the correct board and re-compile.
Add the code to set the error msg on errors. The completed code is in SliderInputErr.zip
#include <SafeString.h> . . . cSF(sfText, 20); // a 20 char SafeString cSF(sfError, 30); // a 30 char SafeString . . . bool Dwg_SliderInputErr::processDwgCmds() { // byte dwgCmd = parserPtr->parseDwgCmd(); // pfodParse calls this automagically before calling this method if (!(*(parserPtr->getDwgCmd()))) { // ==> getDwgCmd returned pointer to empty string return false; // not dwg cmd, not handled } if (parserPtr->dwgCmdEquals(cmd_c1)) { // handle touchZone cmd_c1 parserPtr->printDwgCmdReceived(debugPtr); // does nothing if passed NULL // add your cmd handling code here sfError.clear(); // clear errors slider_percent = parserPtr->getTouchedCol(); // another name for getTouchedX() sendUpdate(); return true; } if (parserPtr->dwgCmdEquals(cmd_c2)) { // handle touchZone cmd_c2 parserPtr->printDwgCmdReceived(debugPtr); // does nothing if passed NULL // add your cmd handling code here sfError.clear(); // clear errors sfText.clear(); sfText.readFrom((char*)parserPtr->getEditedText()); // reads at most 20 chars from the edited text if (sfText.toFloat(slider_percent)) { // if it is a valid float, limit it if (slider_percent < 0) { slider_percent = 0; sfError.print(sfText); sfError.println(" limited to 0"); } if (slider_percent > 100) { slider_percent = 100; sfError.print(sfText); sfError.println(" limited to 100"); } } else { // not a valid float. print/send an error. sfError.print(sfText); sfError.println(" is not a valid float."); if (debugPtr) { debugPtr->println(sfError); } } sendUpdate(); return true; }
// if (debugPtr) { debugPtr->print("dwgCmd did not match:"); debugPtr->println(cmd_c1); }
return false; // not handled
}
Update the sendIndexedItems() to send the current errorMsg
contents with the updates
void Dwg_SliderInputErr::sendIndexedItems() { dwgsPtr->rectangle().filled().idx(idx_1).color(dwgsPtr->RED).size(slider_percent, 5).offset(0, 16).send(); dwgsPtr->label().idx(idx_4).color(dwgsPtr->WHITE).text("Slider ").fontSize(8).offset(50, 28.5).center().units("%").decimals(2).value(slider_percent).send(); dwgsPtr->label().idx(idx_5).color(dwgsPtr->BLACK_WHITE).text("").offset(1, 2).left().decimals(2).value(slider_percent).send(); dwgsPtr->label().idx(idx_6).color(197).text(sfError.c_str()).fontSize(4).bold().italic().offset(50, 8).center().decimals(2).send(); }
Finally you can automatically clear the last error msg by editing the drawing to refresh every 5 seconds.
static unsigned long dwgRefresh = 5000;
and by added
sfError.clear(); // clear errors
to the bottom of the sendIndexedItems() so that on that the
next refresh send the empty message to the pfodApp / pfodWeb to clear
it there.
Remember to change the the version string in
SliderInputErr.ino
const char version[] = "V2"; // need non blank version for auto refresh
That will force a reload of the drawing in pfodApp and updated dwgRefresh setting, or you can open the connection in pfodApp and use the top right menu to Clear the Menu Cache. In pfodWeb you can just reload the page to completely reload the drawing and its settings.
Note: If the Arduino linker complains of duplicate symbols, it has not cleared out the old cached compiled files. Change the board to a different one (any one) and start a compile. Then cancel the compile and change back to the correct board and re-compile.
This page covered using a touchActionInput to allow the use to send text data to the pfodDevice (ESP32 / ESP8266 / Pi PicoW/2W) . It showed how to add a hidden label to the drawing that does not display but which can be updated and provide the default value for the touchActionInput dialog box.
AndroidTM is a trademark of Google Inc. For use of the Arduino name see http://arduino.cc/en/Main/FAQ
The General Purpose Android/Arduino Control App.
pfodDevice™ and pfodApp™ are trade marks of Forward Computing and Control Pty. Ltd.
Contact Forward Computing and Control by
©Copyright 1996-2024 Forward Computing and Control Pty. Ltd.
ACN 003 669 994