Home | pfodApps/pfodDevices | WebStringTemplates | Java/J2EE | Unix | Torches | Superannuation | CRPS Treatment | | About Us
 

Forward Logo (image)      

pfodWeb and pfodWebDesigner
Web page versions of pfodApp and pfodGUIdesigner

by Matthew Ford 24nd October 2025 (originally posted 17th July 2025)
© Forward Computing and Control Pty. Ltd. NSW Australia
All rights reserved.

How Design Interactive Arduino Web pages
with pfodWebDesigner

How Safe is pfodWeb, pfodWebServer and pfodWebDesigner?



24th October 2025 – V2.0.1 of pfodWebDesigner.zip fixed display of nested dwgs and added Load Drawing Directory
9th September 2025 – V1.1.3 of pfodWebDesigner.zip now includes all the necessary npm packages to avoid downloading possibly compromised packages. pfodWebServer.zip V1.1.3 now also includes all the necessary npm packages for hosting pfodWeb on your computer. pfodWeb served from your microprocessor does not use nodejs or any NPM packages. See How Safe is pfodWeb, pfodWebServer and pfodWebDesigner below for the details

Quick Overview of pfodWeb and pfodWebDesigner

pfodWeb is a free web based partial replacement for the paid Android app, pfodApp. pfodWeb runs in a browser and connects to your Arduino board via either Serial or BLE or HTTP. Using Serial you can connect to any Arduino board and display the interactive controls it serves. pfodWeb runs competely off-line. No internet connection is needed. Just install the pfodParser library and open the index.html in the pfodWeb sub-directory of the pfodParser library. The interactive controls are completely defined by the code (generated by pfodWebDesigner) in your Arduino. Very compact pfod messages are used to send the controls and receive the user's commands.

If your Arduino board supports HTTP and has a file system of 200Kb, then you can load the all pfodWeb files onto your microprocessor and serve them directly from there.

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 Serial, Bluetooth, BLE, SMS and WiFi, not just those that have WiFi support. See how to install pfodWebDesigner and Using pfodWeb Designer to Create GUI's. 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.

This introductory pfodWebDesigner tutorial will cover installing the web based pfodWebDesigner and building a simple press button example illustrates touchZone and touchAction.
You have complete control over the size, color, position and function of the controls you design using pfodWebDesigner.
The messages that create the GUI are very compact and can be served by any microprocessor that has a Serial, Bluetooth Classic, Bluetooth Low Energy (BLE) or WiFi connection.

Parts List

For the pfodWeb Designer
node,js from https://nodejs.org/
pfodWebDesigner.zip

For pfodDevice to serve your GUI - Arduino UNO has too little memory for all but the most trivial GUI's
FireBeetle 2 ESP32-E US$8.90 or Beetle ESP32 C3 US$7.90 or other ESP32 board
Adafruit Feather HUZZAH ESP8266 US$14.95 or other ESP8266 board
Pi PicoW US$4.95 or Pi Pico2W US$7.00
Other Arduino boards with a serial connection. Most modern boards have sufficient memory to server pfod GUIs.

Arduino IDE V2 (V2.3.6)
ESP32 board support V3.3.1 OR ESP8266 board support V3.1.2 OR Pi Pico board support V5.1.0 or other board support as needed for your board
Libraries - pfodParser and SafeString libraries – Install via Arduino or install the libraries.zip

Tutorial List

Introductory pfodWebDesigner Tutorial – This one. Covers installing pfodWebDesigner and creating a simple press button example that illustrates touchZone and touchAction.
Reusing Controls with InsertDwg – Covers copying dwgs and using insertDwg to insert multiple copies into the main drawing.
touchActions for Instant FeedbackCovers using touchActions to give instant feedback in a slider control.
TouchActionInput for text/number entryCovers using touchActionInput to input text / numbers to your micro
Building Reusable ControlsCovers building a re-usable popup help button component.

Background – Why pfodWeb?

pfodApp has been in development for 15 years. First as a J2ME application and since 2012 as an paid Android app.
This javascript web based, pfodWeb, provides a browser based version of pfodApp that can be run on any modern computer or mobile (including Apple IPhones)

The current release of pfodWeb concentrates on rendering pfod drawings which provide support flexible and interactive GUIs. Support for other pfodApp features is planned.

There will be three (3) introductory examples.
Hello World, a simple dwg displaying a text label.
Hello World Counter, a dwg with auto refresh and updates.
LedOnOff, a on/off button to control the board led. Shown at the top of this page. This example has an interactive / updateable button that responds instantly to mouse touches and updates with the current led state.

The two button example, pfodWeb_LedOnOff, will be covered in a later tutorial, Reusing Controls with InsertDwg.

Support pfodWeb

pfodWeb and pfodWebDesigner are 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.
Also see the free pfodDesigner Android app for creating menus and charts for pfodApp.

Installing pfodWebDesigner

pfodWebDesigner needs node.js installed.

Installing node.js

The web based pfodWebDesigner uses nodejs to provide the local server for the graphical designer.
First install node.js from https://nodejs.org/ Click on Get Node.js and scroll down to the prebuild node.js packages.
Choose the package that matches your OS and CPU.
(For windows use the .msi installer as the .zip file does not install npm correctly.)

On Windows, run the .msi installation package to install and setup node.js

Installing pfodWebDesigner

Having installed node.js, download the pfodWebDesigner.zip file and un-zip it to a convenient directory. To avoid the possibility of downloading compromised NPM packages, all necessary packages are including in the pfodWebDesigner.zip file. See How Safe is pfodWeb, pfodWebServer and pfodWebDesigner below
Go to that directory and run the pfodWebDesigner.bat (or pfodWebDesigner.sh) to start the local server. No additional npm packages are loaded or updated.
The server starts on port 3000 on the computer's IP.
Open a web browser and enter the URL http://localhost:3000 to open the pfodWebDesigner.
Once installed you can run pfodWebDesigner completely off-line, no internet connection required.

Installing pfodWeb

Install the Arduino pfodParser library and then run the index.html file in the pfodWeb sub-directory. pfodWeb is pure html / js and does not need node.js to be installed and does not use any external modules or downloads. Once the pfodParser library is downloaded, you can run pfodWeb completely off-line, no internet connection required.
See the pfodWeb tutorial.

Running the Sketches generated by pfodWebDesigner

pfodWebDesigner generates Arduino sketches that connect via Serial (at 115200). To display them with pfodWeb you need to use a recent version of Chrome, Edge or Opera browser (see Compatible Browsers for setup)
HTTP connections can be made by any browser, but require your Arduino board to support a web server that handles CORS requests. The pfodParser example sketch LedOnOff_http under File → Examples → pfodParser → pfodWeb provides an a suitable http web server and compiles on ESP32, ESP8266 and Pi PicoW/2W. You can use the LedOnOff_http.ino file as is and replace the other files with the new versions generated by pfodWebDesigner for your custom GUI

A first example using pfodWebDesigner to Create GUI's

This section covers starting pfodWebDesigner, loading an existing design, editing it and exporting the Arduino code that implements it.

Hello World Example

This simple example will open the HelloWorld dwg and edit it. Go to the directory where you install pfodWebDesigner and run the pfodWebDesigner.bat (or pfodWebDesigner.sh) which starts the local server.
The server starts on port 3000.

> start
> node server.js
Server running on http://localhost:3000

Opening http://localhost:3000 show the welcome screen

Clicking on the Control Panel Button shows the designer's main screen.

Unzip the HelloWorld_serial.zip to a convenient directory and from the json directory, load the json file HelloWorld.json

You can then view, edit, copy, etc. or generate an Arduino Sketch to connect via Serial, BLE or HTTP

Choosing Serial generates the HelloWorld_serial.zip file. This zip file contains a complete Arduino sketch that connects via Serial (at 115200) to pfodWeb to display your GUI
See Compatible Web Browsers for Serial and BLE connections. This GUI is small enough to run an UNO but all other examples in this tutorial need an Arduino board with more memory.

If you don't have a compatible browser, export the HTTP code, set your SSID and password and upload it to either an ESP8266 or ESP32 or Pi PicoW/2W and connect from any web browser.
See Running pfodWeb from pfodPaser .html files in your browser

All of these generated sketches need the pfodParser library to be installed.

Choosing Edit show the drawing edit screen

From here you can change the size of the canvas, the background colour, the auto refresh interval and add and edit drawing items.

Try editing and adding new items. The drawing preview will update as you make changes. Cancel if you don't want the changes and you can always reload the original drawing.
When you are finished go back to the Control Panel from which you can export Arduino code update your HelloWorld_serial sketch files using the Drawing Files Only export

Browser Caching

The pfodWeb.html page caches the drawing data with its version, so that when requesting updates to the GUI only the changes are sent, not the whole drawing. See the Raw Message Viewer
If the GUI does not seem to displaying your changes, either change the version string in the .ino file OR clear the browser's temporary cached files (only) OR more simply, open a new private browser which will not have any of the previous drawing data saved.

Saving Drawings

With Auto Save On you don't need to explicitly save the drawing. Each edit will save a new version of the drawing. However this can generate a lot of versions of the drawing file.
If you toggle Auto Save Off, you can use the Save buttons to save the latest drawing edits.

In any case when you use Arduino Export to generate Arduino code, the current drawing is also exported in the json sub-directory of the generated code.

The pfodWeb sketch framework

The pfodParser library V3.65.1+ includes the HelloWorld_serial example. This example consists of the main sketch, HelloWorld_serial.ino, the pfodMainMenu (.cpp/.h), the pfodMainDrawing (.cpp/.h) and the drawing (Dwg_xxx) files the main drawing needs. The .ino sketch file handles setting up the connection, either Serial, BLE or WiFi, depending on your board. The pfodMainMenu handles serving the main pfod menu in response to the {.} request. In this pfodWeb framework, the main menu consists of just a drawing, the mainDwg. The pfodWeb (or pfodApp if using the WiFi connection) then requests the main drawing and any inserted drawings to finally display the user interface.

When you modify your drawing, you only need to replace/update the Dwg_xxx files. The main sketch .ino, the pfodMainMenu and the pfodMainDrawing files can remain the same as long as the name of the main drawing is the same.

When you have finished editing the HelloWorld drawing and used Arduino Export to export the Drawing Files Only, Dwg_HelloWorld.zip file and unzip it to your HelloWorld_serial sketch directory to overwrite the old drawing files with the new versions. Remember to clear the browser cached images and files OR use a new private browser instance.

See the pfodSpecification.pdf, page 42 onwards, for all the details of pfod drawing items.

Auto Drawing Refresh – Hello World Counter Example

This example will modify the Hello World to add a loop counter and a 5sec auto-refresh which will request the current value every 5 seconds and display it.

Open pfodWebDesigner, load the HelloWorld.json file and then Copy to make a copy called HelloWorldCounter.
Click on Edit to open the dwg editor.
Then click Add New Item

From the Item Type drop down list select Label
Label lets you send a leading and trailing text with an embedded floating point number for display.
Value is similar but accepts integers and transforms (maps) them for display.

Set the Text as Count: with a trailing space and set the Units as loops with a leading space. Set the initial Value as 0. Value needs to be set to display the Units.
Set the Decimals as 0 and Alignment as Center. Position the text using the X and Y Position settings.

X and Y positions (and sizes) can be floating point numbers for precise positioning.
Font Size is an integer and is relative to the webpage / screen size. Increasing the number by 6 doubles the font size, decreasing by 6 (e.g. -6) halves it.

Most Important. Tick the Use Index button. Only indexed drawing items can be updated. The index is the variable name holding the unique reference to the item. In this case the count label.

The default color is BLACK_WHITE, which ever gives the best contrast, choose Color if you want to specify a particular color for the text.

Click Add Item to go back to the Edit Drawing Items page.

Note about BLACK_WHITE color

By default each new item is assigned the color BLACK_WHITE. That setting lets pfodApp and pfodWeb select either Black or White which ever gives the best contrast against the drawing's background color. This setting is particularly useful to keep text visible when that drawing is inserted into another drawing. Inserted drawings do not bring their background color with them, only their drawing items, which are merged with the main drawing. See the Reusing Controls with InsertDwg tutorial for more details.

Auto-Refresh

An auto-refresh interval can be set on the main drawing. Refresh intervals set on inserted drawings are ignored.

Setting a refresh interval on the main drawing causes it and any inserted dwgs to be re-requested at that interval. The pfodWebDesigner specifies the refresh in seconds. The pfod Arduino code uses ms.
To set the refresh interval, click Edit Canvas Properties and set 5 sec refresh.

Save Changes and go back to Control Panel and use the Arduino Export button to generate the serial sketch code, HelloWorldCounter_serial.zip

Added the loopCounter code

To add the real loop counter, in HelloWorldCounter_serial.ino add a loopCounter variable and increment it each loop

size_t loopCounter = 0;

void loop() {

  handle_pfodMainMenu(parser);

  loopCounter++;

}

Now the current value of the counter needs to replace the dummy value(0) in the Dwg_HelloWorldCounter.cpp file, add an extern reference to the counter and set it as the value( ) instead of sending 0 in sendIndexedItems()

extern size_t loopCounter;
void Dwg_HelloWorldCounter::sendIndexedItems() {
  dwgsPtr->label().idx(idx_1).color(dwgsPtr->BLACK_WHITE).text("Count: ").offset(25,31).center().units(" loops").decimals(0).value(loopCounter).send();
}

Then when you upload this code you will see the display update every 5sec with the current loop counter value. The completed sketch is in HelloWorldCounter.zip

touchZones and touchActions – LedOnOff

The LedOnOff example creates a new drawing and adds a button to turn the microprocessor's led on and off. It uses a touchZone to make part of the web page responsive to mouse actions and adds a touchAction which is triggered immediately the mouse action is detected to indicate the button has been clicked. The drawing update changes the button's text and color to indicate the current state of the led, on or off.

Open the pfodWebDesigner and Create Drawing, called LedOnOff with dimensions 50 x 25, background color Blue (12) with a 4 second refresh.

A note about drawing dimensions.

You can choose any convenient dimensions from 1 to 255 for the drawing width and height. When the drawing is displayed it will be scaled to fit the pfodWeb page / pfodApp screen. It is only the ratio of the width to the height that is important.
Later tutorials will cover choosing particular dimensions to set the mouse position resolution in touchZones.

Edit the drawing to add a rectangle for the button and some text indicating the Led's state, on or off.
Note: When adding the label, after positioning it in the button rectangle, the label will not be visible until Use Index is ticked. Un-indexed items are drawn first and then overlaid by indexed items in their listed order.

Important: Note that both the button rectangle and the label have Use Index ticked, as they will be both be updated when the button is clicked and when the led state is updated.

Add a touchZone over the button. The dotted outline indicates the touchZone. This outline will not be visible in pfodWeb / pfodApp. However pfodWebDesigner will display its outline.
If you choose pfodWebDebug, or if you tick Log Debug data in the pfodApp connection settings, then the touchZone will be displayed as a dotted outline.

Now you will add touchActions that will trigger immediately the mouse triggers the touchZone. Click on the touchZone's Show Details button


Then click on Add touchAction and then on Add touchAction Item

Clicking on the Show buttons will hide the respective drawing item so you can check what item your touchAction will replace.

Replace the Green rectangle with a GREY one in the same position and the same size, but without rounded corners. Mouse down on the touchZone in the preview to check the result.
Add Item and Accept Changes and Go back to the Control Panel and choose View to see what the button will look like and how it will respond to the mouse actions.

When you are satisfied with your design, export the Arduino serial sketch, LedOnOff_serial.zip

Modifying the Code to Turn the Led On/Off

The completed sketch files, with these modifications, are in LedOnOff_serial.zip

Two new files are added to control the Led, LedControls.cpp and LedControls.h. The LedControls.h file is (see the final sketch for the LedControls.cpp contents)

#ifndef LED_CONTROLS_H
#define LED_CONTROLS_H
#include <SafeString.h>
void turnLedOff();
void turnLedOn();
bool isLedOn();
void toggleLed();
SafeString &buttonText(); // changes with led on/off
int textColor(); // changes with led on/off from RED to WHITE
int buttonColor(); // changes with led on/off from LIME to BLACK
#endif


The LedOnOff.h is included in Dwg_LedOnOff.cpp and in LedOnOff_serial.ino and initializeLedControls(); called at the end of setup();


In Dwg_LedOnOff.cpp, the processDwgCmds() calls toggleLed(); when the touchZone send a command


bool Dwg_LedOnOff::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
  toggleLed();   // add your cmd handling code here
  sendUpdate();
  return true;
 }
 return false; // not handled
}

To see the details of the command the GUI touchZone sends, uncomment

#define DEBUG

and in the bool Dwg_LedOnOff::processDwgCmds() method uncomment the line

     parserPtr->printDwgCmdReceived(debugPtr); // does nothing if passed NULL 

and text like this will show up in the Raw Message View when you click the button

     touchZone cmd c2 at (9,2) touch type:TOUCHED

Finally the sendIndexedItems() which is called by both sendFullDrawing() and sendUpdate() needs to update the button color and text, based on the current led state

void Dwg_LedOnOff::sendIndexedItems() {
 dwgsPtr->rectangle().filled().centered().rounded().idx(idx_1).color(buttonColor()).size(18,7).offset(25,12).send();
 dwgsPtr->label().idx(idx_2).color(textColor()).text(buttonText().c_str()).offset(25,12).center().decimals(2).send();
}


This sendIndexedItems() method uses the LedControls methods to set the button color, text and text color based on whether the led is no or off.

The easiest way to create the update code is to edit the drawing items to the colour and text you want for led off versus on and then generate the new drawing files.


As far as possible put the processing code in another file (e.g. LedControl.cpp/.h) so that the Dwg_... files have minimal changes from what the pfodWebDesigner generated. This simplifies merging drawing revisions.


The result is the animated one button GUI at the top of this page. As you select the button it flashes a GREY color change and sends a command to your microprocessor to change the LED. When the microprocessor responds, its message sets the button's new color and the new text.

How Safe is the pfodWeb and pfodWebDesigner Code Base

pfodWeb is pure html / js and does not use any external packages or downloads. You can run pfodWeb completely off-line with no internet connection.
The entire source code is supplied with the pfodParser library downloaded.

pfodWebDesigner uses nodejs to run a local server on your computer. So you need to install nodejs on your computer, but no other modules need to be downloaded and once the main nodejs is installed you can run completely off-line with no internet connection. pfodWebDesigner.zip contains all the source code and comes with all necessary (un-compromised) nodejs packages it needs. pfodWebDesiger is also hosted on Github.

There have been a number of attacks on NPM packages recently, see Shai-Hulud malware campaign (local copy here) and NPM Supply Chain Attack (local copy here). None of the compromised packages are used by pfodWebDesigner.

Conclusion

This page covered installing the pfodWebDesigner server and using pfodWebDesigner to design interactive GUI's that can be displayed by either the pfodWeb browser page or pfodApp is using WiFi

This tutorial included three simple examples, HelloWorld, HelloWorldCounter which displayed the current loop count and LedOnOff which used a touchZone and touchAction to control an UNO onboard led.

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.


Forward home page link (image)

Contact Forward Computing and Control by
©Copyright 1996-2024 Forward Computing and Control Pty. Ltd. ACN 003 669 994