Skip to main content
~4 min read|2023|Industrial Automation & Controls
Industrial Automation & ControlsCompleted control integration prototype2023

FarmBot OPC UA Control Integration

Built an OPC UA to serial control path that sent axis commands through a Raspberry Pi to real FarmBot hardware.

PythonOPC UARaspberry Pi 4FarmBot OSFarmduinoUaExpertThonnyG-code

This prototype turned OPC UA writes into serial G-code commands executed by FarmBot hardware.

Built

An OPC UA to G-code bridge between the client, Raspberry Pi, and FarmBot hardware.

My Role

Designed the control flow, wrote the Python bridge logic, and checked it with runtime captures and hardware tests.

Visuals

1 diagram + 8 supporting visuals

Runtime screenshots and hardware photos

Runtime screenshots and hardware photos

This page focuses on hardware images, runtime screenshots, and trimmed Python excerpts.

Project Scope

Control Model

OPC UA client writes axis values, Raspberry Pi server translates them into serial G-code, and FarmBot hardware executes the movement request.

Runtime Platform

Raspberry Pi 4 with FarmBot OS, Python OPC UA services, and serial communication to the Farmduino controller.

Operator Tooling

UaExpert and custom Python clients used to write values, verify node updates, and observe live command handling.

Evidence Base

Hardware photos, UaExpert and Thonny runtime captures, and Python files from the prototype.

Project Overview

This project explored how an OPC UA software interface could be connected to a small FarmBot prototype so movement requests could be sent from a client and executed by the hardware.

The setup used a Raspberry Pi control node, Python OPC UA services, serial communication to the motion controller, and runtime captures taken during testing.

For this page, the material was reorganized into one clear project page that explains the control path without exposing unnecessary background detail.

Why This Project Matters

The strongest part of the project is not the mechanical frame itself but the control integration: a higher-level software client writes values into an OPC UA namespace, and the local controller turns those values into concrete movement commands.

That is a useful pattern because it reflects the same separation seen in industrial environments where operator tooling, protocol layers, and device-level execution are distinct concerns.

It also shows work across several boundaries at once: protocol design, Python scripting, hardware connectivity, serial debugging, and documentation.

Control Flow

Software entry point

  • UaExpert and Python clients connect to the OPC UA endpoint exposed by the Raspberry Pi.
  • The writable namespace carries axis values or command data that the operator can change live during testing.

Controller bridge

  • The server loop checks for hardware readiness before issuing movement instructions.
  • Once the controller is ready, the Python service formats and sends approval and G-code commands over serial.

Physical execution

  • Farmduino and the downstream electronics interpret the command stream and drive the motion hardware.
  • Response values and validation screenshots document that the control path was exercised end-to-end during testing.

What I Implemented

  • Configured an OPC UA server namespace for command and response variables.
  • Built Python logic that checked the FarmBot ready state before sending motion commands.
  • Connected the OPC UA layer to serial output so entered axis values could become G-code.
  • Used UaExpert to validate node visibility, writes, and live value changes.
  • Captured hardware photos, protocol screenshots, and software runtime output for the final documentation.

Validation and Evidence

The visuals on this page come from the real prototype work rather than recreated mockups. They show the namespace in UaExpert, the server and client scripts in Thonny, the full communication poster, and the hardware used in the build.

That combination matters because it demonstrates both sides of the work: the code and protocol layer are visible, but so is the physical target system and controller stack.

The result is still a prototype and not a production industrial controller, but it clearly shows real integration work rather than a purely theoretical design.

Key Learnings

  • Protocol abstractions become much clearer when every logical node is mapped to a real device or action path.
  • Bridging from a clean software interface into serial hardware control requires explicit readiness checks and simple but reliable state handling.
  • Even small prototypes benefit from clear documentation because the architecture is easier to understand when the runtime output is preserved.

Control and Communication Flow

Overview of the client layer, Raspberry Pi bridge, serial command path, and FarmBot motion hardware.

The diagram breaks the prototype into the client layer, Raspberry Pi control node, and motion hardware so the OPC UA to serial bridge is easier to follow.

Client Layer

UaExpert and custom Python clients acted as the operator-facing control surface for writing axis values and observing feedback nodes.

Wireless Link

A local hotspot path connected the client side and the Raspberry Pi test environment during prototype validation.

Raspberry Pi Control Node

The Raspberry Pi 4 hosted the Python OPC UA server logic and served as the bridge between software commands and downstream motion hardware.

OPC UA Namespace

Writable nodes represented axis commands and response values so the prototype could expose a clean software interface to the operator.

Serial and G-code Bridge

Once the controller reported a ready state, the Python service sent approval and movement commands over serial using FarmBot-compatible G-code.

Motion Hardware

Farmduino, Arduino firmware, stepper motors, and encoder feedback represented the execution layer that turned software requests into physical movement.

Visuals

Includes one control diagram, four runtime screenshots, four hardware images, and three Python excerpts.

Step 01

Full poster showing the OPC UA client, hotspot, Raspberry Pi server, serial bridge, Arduino controller, and FarmBot hardware in one end-to-end view.

Step 02

UaExpert session used to verify writable OPC UA variables for X, Y, and Z axis commands together with corresponding response nodes.

Step 03

Split runtime view showing the Python OPC UA server and the interactive client during a live command session where axis values were entered and pushed into the namespace.

Step 04

Server-side Thonny output captured on the Raspberry Pi during testing, showing namespace setup and repeated handling of live values.

Step 05

Hardware photo from inside the FarmBot prototype showing the controller wiring and board-level integration used during testing.

Step 06

Raspberry Pi hardware used as the local control node for the Python server logic and FarmBot OS side of the prototype.

Step 07

Prototype body render used in the project material to present the physical motion platform that the control logic targeted.

Step 08

Arduino board image representing the lower-level motion controller side of the FarmBot stack.

Configuration Excerpts

python

OPC UA server namespace and writable axis nodes

Source: NewServerCode.py

from opcua import Server
import serial

server = Server()
url = 'opc.tcp://192.168.43.9:4840'
server.set_endpoint(url)

addspace = server.register_namespace('OPC_Fbot')
node = server.get_objects_node()
param = node.add_object(addspace, "Parameters")

x_node = param.add_variable(addspace, "X-Axis", 0)
y_node = param.add_variable(addspace, "Y-Axis", 0)
z_node = param.add_variable(addspace, "Z-Axis", 0)
x_resp_node = param.add_variable(addspace, "X-Axis-Response", "")
y_resp_node = param.add_variable(addspace, "Y-Axis-Response", "")
z_resp_node = param.add_variable(addspace, "Z-Axis-Response", "")

x_node.set_writable()
y_node.set_writable()
z_node.set_writable()

Excerpt from the Raspberry Pi server script showing the namespace, endpoint, and writable axis variables used by the prototype.

python

Ready-state check and serial G-code dispatch

Source: NewServerCode.py

ser = serial.Serial(port='/dev/ttyACM0', baudrate=115200, bytesize=8)

while True:
    info = ser.readline()
    if info == bytes('R00 Q0\r\n', encoding='utf-8'):
        x_cmd = x_node.get_value()
        y_cmd = y_node.get_value()
        z_cmd = z_node.get_value()

        ser.write(bytes('F22 P2 V1 Q0\r\n', encoding='utf-8'))
        time.sleep(2)
        ser.write(
            bytes('G00 X{} Y{} Z{} Q0\r\n'.format(x_cmd, y_cmd, z_cmd), encoding='utf-8')
        )

Core bridge logic from the prototype: wait for a ready response, then send the FarmBot approval command followed by a movement instruction built from live OPC UA values.

python

Interactive client loop for axis input

Source: newClient.py

from opcua import Client
import time

client = Client('opc.tcp://192.168.43.9:4840')
client.connect()

while True:
    x_cmd = input("Enter G-code command for x-axis: ")
    y_cmd = input("Enter G-code command for y-axis: ")
    z_cmd = input("Enter G-code command for z-axis: ")

    x_node = client.get_node("ns=2;i=2")
    y_node = client.get_node("ns=2;i=3")
    z_node = client.get_node("ns=2;i=4")

    x_node.set_value(x_cmd)
    y_node.set_value(y_cmd)
    z_node.set_value(z_cmd)

Client-side excerpt showing how axis values were entered and written to the OPC UA namespace during testing.