With more devices than ever being Internet enabled, I wanted to look at linking up a Mendix application to a microcontroller and seeing if I could control it remotely. I decided to use a Raspberry Pi Pico W.
What is the Raspberry Pi Pico W?
The Raspberry Pi Pico W is a microcontroller board that is an upgraded version of the original Raspberry Pi Pico, incorporating wireless capabilities, and costing less than £6. Released in 2022, the Pico W is built around the RP2040 microcontroller, a custom-designed chip from Raspberry Pi. It features a dual-core Arm Cortex-M0+ processor running at up to 133 MHz, 264 KB of SRAM, and 2 MB of onboard flash memory. This powerful combination allows it to handle a wide range of tasks, from controlling sensors and actuators to performing moderate computational tasks like signal processing.
One of the key features that sets the Pico W apart from its predecessor is the inclusion of wireless connectivity, specifically Wi-Fi. It uses the Infineon CYW43439 chip to provide 2.4 GHz 802.11n wireless networking. This opens up new possibilities for IoT (Internet of Things) applications, where devices need to communicate with each other or with the cloud. The wireless capability makes it ideal for projects like home automation, remote sensing, and wireless data logging, where connectivity is crucial.
Despite its powerful capabilities, the Raspberry Pi Pico W remains highly affordable, maintaining the same low-cost philosophy as other Raspberry Pi products. Its compact size and efficient power usage also make it suitable for battery-powered or embedded projects. The board supports a variety of programming languages, including MicroPython, C/C++, and CircuitPython, making it accessible to both beginners and experienced developers. Overall, the Raspberry Pi Pico W is a versatile, cost-effective solution for projects that require both local processing and wireless connectivity.
Building a simple REST service
In this example, I’m going to use MicroPython to create a REST service than my Mendix application can consume.
The Raspberry Pi Pico W has a couple of built in features we can expose to our REST service. The first is the built in LED. We can add REST endpoints to turn this on and off. The second is the built in Analog to Digital Converter (ADC) that we can use to take a temperature reading. We can add a REST endpoint to return the current temperature.
The easiest way to build a REST service on the Raspberry Pi Pico W that I have found is to use the Phew library. This allows us to define endpoints that run specific Python defs to return data.
You will need to install an application called Thonny on your computer to be able to upload the MicroPython code to your Raspberry Pi Pico W. You can find full instructions on the Thonny website. https://thonny.org/
This isn’t a MicroPython tutorial, so I won’t explain the code in depth. The main parts to look at are the endpoints and their return values. For example, I define the temperature I use the following line…
@server.route("/api/temperature", methods=["GET"])
This defines the endpoint to respond to GET requests to /api/temperature.
The data is returned as JSON using the following line…
return json.dumps({"temperature" : temperature}), 200, {"Content-Type": "application/json"}
There are similar endpoints and return values to turn the LED on and off.
Here’s the code to upload to your Raspberry Pi Pico W if you are following along.
from phew import server, connect_to_wifi
import machine
import json
# Connect to WIFI
ip = connect_to_wifi("YOUR-WIFI-NAME", "YOUR-WIFI-PASSWORD")
# Get the onboard LED
led = machine.Pin("LED", machine.Pin.OUT)
print("connected to IP ", ip)
# Setup the temperature endpoint.
@server.route("/api/temperature", methods=["GET"])
def get_temperature(request):
adc = machine.ADC(4) # Use ADC pin GP4
conversion_factor = 3.3 / (65535) # ADC conversion factor
sensor_value = adc.read_u16() * conversion_factor
temperature = 27 - (sensor_value - 0.706) / 0.001721 # Convert sensor value to temperature (formula may vary)
return json.dumps({"temperature" : temperature}), 200, {"Content-Type": "application/json"}
# Setup the LED ON endpoint.
@server.route("/api/led/on", methods=["GET"])
def ledCommand(request):
led.value(1)
return json.dumps({"message" : "Command sent successfully!"}), 200, {"Content-Type": "application/json"}
# Setup the LED OFF endpoint.
@server.route("/api/led/off", methods=["GET"])
def ledCommand(request):
led.value(0)
return json.dumps({"message" : "Command sent successfully!"}), 200, {"Content-Type": "application/json"}
# Setup a catchall for all other requests we can't handle.
@server.catchall()
def catchall(request):
return json.dumps({"message" : "URL not found!"}), 404, {"Content-Type": "application/json"}
# Start the REST service.
server.run()
Upload and run this MicroPython program to your Raspberry Pi Pico W using Thonny. When you run it, it will connect to the specified Wifi network using the username and password you supplied in the code, and it will return an IP address that you can use in your Mendix application to talk to the Pico.
MPY: soft reboot
2024-09-30 21:17:28 [debug / 163kB] - connecting
2024-09-30 21:17:31 [debug / 161kB] - connecting
connected to IP 192.168.178.84
2024-09-30 21:17:33 [info / 169kB] > starting web server on port 80
We can quickly test if everything is working by connecting to our REST service using a web browser. My Pico returned it was connected to 192.168.178.84 (your IP address may be different), so I can turn the LED on by going to http://192.168.178.84/api/led/on . The LED will turn on, and the following JSON will have been returned.
{"message": "Command sent successfully!"}
Now, lets write a Mendix application do this.
Building the Mendix application
Firstly, create a new Mendix application. I’ve called mine PicoWIOT.
Mendix has a new feature called Consumed REST Services which is currently in Beta. This makes it really easy to consume external web services. To use it, create a Consumed Web Service. I called mine CWS_PicoW.
In the Configuration and authentication tab, set the Base URL to be http://192.168.178.84/api/ . We don’t have any Authentication, so leave that as “No Authentication”.
To add the LED On endpoint, set the Request name to be “LEDOn”, the Method to be “GET”, and the URL to be “/led/on”. If you then click the Send button to test the request you should see the LED light up and the JSON data be returned. We can use this to create a response entity if we want.
We can add the LED Off endpoint by doing the same again, but this time changing the URL to be “/led/off”. Clicking Send this time will turn the LED off.
We can add the Temperature endpoint by doing the same again, but this time changing the URL to be “/temperature”. Clicking Send will now read the temperature and return it in the JSON response. We should create a new entity to store this by going into the Response Structure tab and clicking Create Entity. I called my entity “RootTemperature”.
Now we need to be able to call these endpoints from our application. We do this using Mendix microflows.
To turn the LED On, we can create a new microflow called ACT_LEDOn. Add an action, and look for Send REST Request. You should see the LEDOn call we created earlier, so select that. Finally make sure the microflow has a suitable User Role selected so it can be executed and save it.
Do the same for LED Off.
On a page, drag the ACT_LEDOn microflow somewhere suitable to create a button, and also do the same for ACT_LEDOff. I renamed mine to LEDOn and LEDOff.
Now run the application and open it in your browser.
You should get a page with the two buttons on. Pressing them should turn the LED on and off on the Raspberry Pi Pico W.
To read the temperature on the Pico, first create a new Page in Mendix called Temperature. I used a Popup layout.
Add a DataView to the page, and use the RootTemperature entity we created earlier. Let it automatically populate the page for you. I removed the Save and Cancel buttons and replaced them with a single Close page button.
Now create a new microflow called ACT_Temperature. Add a Send REST Request action, and call the Temperature endpoint. Use the Return Value, I called mine RootTemperature, and pass this as the parameter to a Show Page action that calls the Temperature Popup page we just created. Save the microflow, and remember to give it a suitable User Role. Drag the ACT_Temperature microflow onto the same page as the LED buttons to create a new button. I renamed mine to Temperature.
Run the app, and you should have three buttons. Click Temperature and you should get a popup with the current temperature according to the ADC on your Raspberry Pi Pico W.
Conclusion
Congratulations, you have successfully integrated Mendix with your very own Internet of Things (IoT) device!
Hopefully this article has shown how easy it is for a modern low code application to interact with a cheap microcontroller so it can interact with sensors and output devices.
We’ve also seen how to easy it is to integrate REST services with Mendix using the new Consumed REST Service functionality.