Step-by-Step Guide: Setting up an OPC UA Client-Server System with Raspberry Pi Pico, Raspberry Pi 4, and UaExpert
Overview
In this tutorial, we'll set up a system where a Raspberry Pi Pico 2W reads data from a Joystick HW-504 Module and sends that data to an OPC UA server running on a Raspberry Pi 4. An OPC UA client, UaExpert, will be used on a Windows laptop to connect to the server and visualize the data.
Hardware and Software Requirements
-
Hardware:
- Raspberry Pi Pico 2W
- Raspberry Pi 4
- Joystick HW-504 Module
- Windows laptop
-
Software:
- Raspberry Pi OS (on the Raspberry Pi 4)
- Python 3.x
asyncua
library for Python (on Raspberry Pi 4)- UaExpert (OPC UA client software)
Part 1: Setting Up the Raspberry Pi Pico 2W (Joystick Reader)
1. Install Thonny or any other IDE for Python Development
- Install Thonny or another Python IDE that supports Raspberry Pi Pico development.
2. Wiring a Joystick to Raspberry Pi Pico
-
Wire the joystick’s 5 pins to the Pico as follows:
- GND to GND (Any GND pin)
- +5V to 3V3 Out (physical pin 36). Yes, a 5V joystick will work with the 3V3 power of Pico.
- VRx to GP27 / ADC1 (physical pin 32)
- VRy to GP26 / ADC0 (physical pin 31)
- SW to GP16 (physical pin 21). This would work with most of the GPIo pins.
3. Set up the Raspberry Pi Pico 2W
- Connect your Raspberry Pi Pico to your computer via USB.
- Install the necessary libraries for controlling the joystick module.
machine
: Used to interact with GPIO pins.network
: To connect the Pico to Wi-Fi.urequests
: To send HTTP requests (used in WebSockets in this example).
4. Write the Code for Joystick Data Reading and Sending over WebSockets
Below is the Python code that will run on the Raspberry Pi Pico to read the joystick's X, Y, and button values and send them to the server over a socket connection.
import urequests
import json
import network
from time import sleep
from machine import Pin, ADC
import utime
import socket
from machine import Pin, Timer
import machine
# Initialize LED and timer for feedback
led = Pin("LED", Pin.OUT)
timer = Timer()
def blink(timer):
led.toggle()
timer.init(freq=5, mode=Timer.PERIODIC, callback=blink)
# Connect to Wi-Fi
ssid = '' # Replace with your SSID
password = '' # Replace with your Wi-Fi password
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
connection_timeout = 10
while connection_timeout > 0:
if wlan.status() >= 3:
break
connection_timeout -= 1
print('Waiting for Wi-Fi connection...')
sleep(1)
if wlan.status() != 3:
raise RuntimeError('Failed to establish a network connection')
else:
print('Connection successful!')
# Setup joystick pins
xAxis = ADC(Pin(27))
yAxis = ADC(Pin(26))
button = Pin(16, Pin.IN, Pin.PULL_UP)
# Sending data to the server over socket
while True:
led.on()
xValue = xAxis.read_u16()
yValue = yAxis.read_u16()
buttonValue = button.value()
# Determine joystick direction
xStatus = "middle"
yStatus = "middle"
buttonStatus = "not pressed"
if xValue <= 600:
xStatus = "left"
elif xValue >= 60000:
xStatus = "right"
if yValue <= 600:
yStatus = "up"
elif yValue >= 60000:
yStatus = "down"
if buttonValue == 0:
buttonStatus = "pressed"
print("X: " + xStatus + ", Y: " + yStatus + " -- button " + buttonStatus)
# Send joystick status over socket to server
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("<ip-address-of-your-pi>", 65431)) # Server IP and port
val = "X: " + xStatus + ", Y: " + yStatus + " -- button " + buttonStatus
client.sendall(val.encode())
client.close()
utime.sleep(0.1)
led.off()
5. Upload the Code to Raspberry Pi Pico
- Use Thonny to upload and run the code. Make sure to check the serial output to confirm if the joystick data is being read and sent.
Part 2: Setting Up the OPC UA Server on Raspberry Pi 4
1. Install Required Python Libraries on Raspberry Pi 4
Install the required libraries using pip
:
pip install asyncua
2. Write the OPC UA Server Code
Below is the Python code for the OPC UA server that listens for data from the Raspberry Pi Pico:
import asyncio
import logging
import socket
from asyncua import Server, ua
from asyncua.common.methods import uamethod
@uamethod
def func(parent, value):
return value * 2
async def main():
_logger = logging.getLogger(__name__)
# Setup OPC UA server
print("Server is listening...")
server = Server()
await server.init()
server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")
# Register the namespace
uri = "http://examples.freeopcua.github.io"
idx = await server.register_namespace(uri)
# Create the address space
myobj = await server.nodes.objects.add_object(idx, "MyObject")
myvar = await myobj.add_variable(idx, "MyVariable", "Omkar")
myvar1 = await myobj.add_variable(idx, "SampleVariable", "SampleValue")
await myvar.set_writable()
# Add method to the server
await server.nodes.objects.add_method(
ua.NodeId("ServerMethod", idx),
ua.QualifiedName("ServerMethod", idx),
func,
[ua.VariantType.Int64],
[ua.VariantType.String],
)
_logger.info("Starting server!")
# Listen for data from Raspberry Pi Pico
async with server:
socserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socserver.bind(("0.0.0.0", 65431))
socserver.listen(1)
while True:
await asyncio.sleep(0.1)
conn, addr = socserver.accept()
with conn:
data = conn.recv(1024)
if data:
received_message = data.decode()
await myvar.write_value(str(received_message))
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
asyncio.run(main(), debug=True)
3. Run the OPC UA Server
Run the server script on your Raspberry Pi 4:
python3 opcua_server.py
The server should now be listening for incoming connections from the Raspberry Pi Pico.
Part 3: Setting Up UaExpert on Windows (OPC UA Client)
1. Install UaExpert
Download and install UaExpert on your Windows laptop.
2. Configure UaExpert to Connect to the OPC UA Server
- Open UaExpert.
- Go to "File" -> "New Project" and add a new connection.
- In the "Server" field, enter the endpoint URL of your server (
opc.tcp://<ip-address-of-your-pi>:4840/freeopcua/server/
). - Click "Connect".
3. Browse the OPC UA Server Address Space
Once connected, you can browse the server's address space and monitor the variables, such as MyVariable
, that you set up in the Python server code.
Conclusion
You've now successfully set up an OPC UA client-server configuration using a Raspberry Pi Pico, Raspberry Pi 4, and UaExpert. The joystick data from the Pico is sent to the server, and the UaExpert client can visualize it. This setup can be expanded further by adding more sensors or making the OPC UA server more interactive.
Member discussion