Bluetooth Communication with Palm OS -
Processing and displaying the collected data (Part 2/2)
In the last part, we configured a PHP-Server, which is now able to deliver the data, which needs to be displayed on a (bluetooth enabled) Palm PDA. So a connection is needed to transfer the collected data to the Palm. An ESP32 is perfect for transferring the data from the PHP server to the Palm, since it is able to talk "legacy" bluetooth and can access the Wifi simultaneously.
This article is grouped in two parts: this first part is about the setup of the "transfer-unit" and second part about wirting the Palm OS Application, which displays the fetched data on a PalmOS device.
These parts are required for transferring the collected data and display it on a Palm:
- A bluetooth enabled Palm OS device (e.g. a Tungsten T3, but also Palm OS 4.1 devices with a Bluetooth SDIO card will work.)
- One ESP32 (here an "ESP32 Dev Module" is used)
Setting up an ESP32
At this point, I will again skip the part of explaining how to set up an ESP32 with the Arduino IDE. There are already good tutorials, which explains this very well, like this one: https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
Make sure these drivers for the ESP, like mentioned in the linked article, are installed:
Also these Arduino IDE Settings worked fine for me:
("Keine" can be translated with "none".)
Since there is no wiring needed for the ESP32 (except the power supply), the only important part is the code.
The only task, which must be done by the ESP is to receive a request from the Palm, process it, requesting the needed data from the PHP server and send it back to the Palm.
First we need to include the libraries for Wifi, Bluetooth and a http-client. In line 5 and 6, the credentials for the own Wifi are set. After instantiate the BluetoothSerial class, in line 9 is the pin defined, which is used for authentication. In line 14 the serial port is opened for the debugging-output of the serial monitor of the arduino IDE, we then give the script some time (line 16) to power up completely. With line 18 and 19, everything is prepared for a bluetooth connection. After this point only the wifi connection gets established.
In the loop-function, we wait for the request from the Palm PDA (line 44), after we got one, the requested data (from the corresponding sensor - line 48) is getting trimmed, so we get no unwanted whitespaces (line 49). After we checked, that the wifi-connection is still present (line 52) (or we restart the connection in the lines 79 and 80), we are using the HTTP client (line 56) to fetch the needed data from the PHP server (line 58 - 67). Here is important, that the correct IP address is provided (192.168.1.55 is only a sample IP). Then we simply redirect the data via the bluetooth connection to our Palm PDA (line 69).
The Palm OS Application
The last and the biggest part is about the Palm OS Application. We will establish a bluetooth connection to the ESP32,
receiving data, processing it and display it on the screen. We will also handle lost connections. The complete project is
available here: BluetoothComm source code and can be build with Codewarrior 9.3.
(The debug-target has some problems, but the release target works fine.)
If you just want to try it out, here is the prebuild .prc file: bluetoothComm.prc
But keep in mind, that at least a ESP32, which sends some mocked data, is needed for a test.
The application is divided in four parts:
- Main-Programm with all Palm OS specific functions (BluetoothComm.c)
- Library with all bluetooth related functions (BtAppLib.c)
- Library with all serial related functions (SrAppLib.c)
- Library with all user interface related functions (UiAppLib.c)
The first function is the PilotMain. This is the start point of our application. Here we check if Palm OS 4 or higher is available.
Since there is also a SDIO bluetooth card for Palm OS 4 devices with a SDIO slot, the application can also run on these PDAs
(e.g. the Palm m125).
After the check,
startApplication() gets called, where the bluetooth stack gets started with:
This function is defined in the BtAppLib.c.
The AppEventLoop simply receives new events and redirects them to the according functions. The most important is:
AppHandleEvent "only" handles the menu events. (Of course, this could be more important if we wanted it to be.)
In the MainFormHandleEvent, we are telling the user what he or she should do ("Please select a data point.") after the "frmOpenEvent" was fired
and the active (current) form was drawn.
Next, we handle the button press events. There are three buttons:
- The clear button, which clears the field, in which the fetched data from the ESP32 will be displayed.
- The bedroom button, which fetches the bedroom temp- and humidity data from the ESP32.
- The basement button, which fetches the basement temp- and humidity data from the ESP32.
UiAppLib.c, which replaces the content of the big text field with an empty string. The bedroom and basement buttons only sending a request to the ESP32 via the (serial) bluetooth interface.
SendDataSerialis defined in
SrAppLib.c. If the request was sent, we are waiting 10x 250ms for an answer from the ESP. If we get an answer, we process and display it with
ProcessSerialData(rawData). If we do not get an answer within this time, we assume, that the connection got lost and displaying a alert form via
UiAppLib.c. The "exit" and "reconnect" functionality is handled inside of
handleConnectionLostsince we need this functionality at another place in the code, too. But we cannot be really sure, if the ESP32 doesn't take longer than the given time to process the request. So at this point the user has also the option to retry the request. We are simply waiting a little bit longer for an answer from the ESP32. If it takes too long again, we are displaying the same alert form again.
stopApplicationfunction actually only shuts down the Bluetooth stack. The
setErrorExitfunctions are used for leaving the application, when an error occurred.
ProcessSerialData, like already mentioned, processes the incoming data from the ESP32 and display it. Since the data has always a fixed length, splitting the data can be done with fixed positions. It is not nice but it is working.
This BtAppLib.c library only contains two functions:
startBluetoothStack. The first function uses the Palm OS
Feature Manager (
FtrGet) to provide the Bluetooth Port where ever it is needed. The second function (
collects all needed parameters to be able to start the bluetooth stack and also starts it. At the end of this funciton, the opened bluetooth port is then stored via the
Feature Manager (
FtrSet(appFileCreator, 9811, port);).
Also SrAppLib.c does only contain two functions, which are related to the serial communication. Bluetooth acts like a serial interface in Palm OS,
so fetching and sending data is similar to a real serial interface on Palm OS.
ReadSerial is for reading data from the port, when
the ESP32 sends data to the PDA and
SendDataSerial for sending data to the ESP32.
UiAppLib.c handles the user interface actions like an alert from and the main display area for the data from the ESP32. The first function is called
handleConnectionLost and handles a lost connection. If the connection lost is detected in
MainFormHandleEvent (see BluetoothComm.c)
or while sending (
SendDataSerial) or receiving (
ReadSerial) data (see SrAppLib.c), this function is called. It shows an alert form
and provides two functions: "Reconect" and "Exit". If "Reconnect" is selected, the bluetooth connection gets shut down and started again. If "Exit" is
selected "setErrorExit" will be set 1, which is being processed in
AppEventLoop and will terminate the application if this value is 1.
The ESP8266 and ESP32 as well as the PHP Server are working very well. Only the Palm OS application is far away from perfect. But since this is a hobby project
and not a professional one, it is good enough. Maybe I will find in the future some time for optimizations, like making the "request buttons" in the application
dynamic by replacing them with a dropdown. So it would be possible to fetch all data points first and then showing them in the dropwdown list.
It would be also nice to see in the main field from which room the data came. Or to have a proper error handling when the application gets started on a none-bluetooth-enabled device.
Besides from that, the Palm OS application has one known bug: When the device is turned off, while the application is running, it can crash or terminate with an alert, which is triggered in the
PilotMain function. Also the ESP8266 will maybe also not return valid values every time. The last problem appears
not very often. So I think both problems are acceptable.