Skip to main content

Overview

The Raspberry Pi acts as a bridge between the Arduino sensors and the MQTT broker. It reads sensor data from Arduino via USB serial connection and publishes it to specific MQTT topics for the Django backend to consume.

Architecture

Hardware Requirements

  • Raspberry Pi (any model with USB port)
  • USB cable (Type-A to Type-B for Arduino connection)
  • Network connection (Ethernet or WiFi)
  • Power supply for Raspberry Pi

Software Requirements

1

Install Python dependencies

Install required Python libraries:
pip install paho-mqtt pyserial
Or using apt:
sudo apt-get update
sudo apt-get install python3-pip
pip3 install paho-mqtt pyserial
2

Identify Arduino serial port

Connect Arduino via USB and identify the serial port:
ls /dev/tty*
Common ports:
  • /dev/ttyACM0 - Most common for Arduino
  • /dev/ttyUSB0 - USB-to-Serial adapters
The bridge script uses /dev/ttyACM0 by default. Update if your port differs.
3

Set serial permissions

Grant permission to access serial port:
sudo usermod -a -G dialout $USER
sudo chmod 666 /dev/ttyACM0
Log out and back in for group changes to take effect.

MQTT Bridge Configuration

The bridge script (mqtt-arduino.py) reads sensor data from Arduino and publishes to MQTT topics.

Connection Settings

Source: ~/workspace/source/Raspberry-pi/mqtt-arduino.py:6-11
import paho.mqtt.client as mqtt 
import serial
import time
from textwrap import wrap

# Broker MQTT Mosquito
broker = 'localhost'
port = 18083
client_id = 'aqua'
# username = '*****'
# password = '*****'
The default configuration uses localhost and port 18083. Update these values to match your MQTT broker configuration.

MQTT Topics

The bridge publishes to six different topics:
# MQTT Topics
topic_temp = "sensores/temperatura"
topic_hum = "sensores/umidade"
topic_ldr = "sensores/ldr"
topic_tds = "sensores/tds"
topic_temp_agua = "sensores/temperatura-agua"
topic_nivel = "sensores/nivel"
TopicDescriptionUnitsSensor
sensores/temperaturaPlant area temperature°CDHT11
sensores/umidadePlant area humidity%DHT11
sensores/ldrLight intensitylumenLDR
sensores/tdsWater quality (TDS)ppmGravity TDS
sensores/temperatura-aguaWater temperature°CDS18B20
sensores/nivelWater level distancecmHC-SR04

Complete Bridge Script

Source: ~/workspace/source/Raspberry-pi/mqtt-arduino.py
import paho.mqtt.client as mqtt 
import serial
import time
from textwrap import wrap

# Broker MQTT Mosquito
broker = 'localhost'
port = 18083
client_id = 'aqua'
# username = '*****'
# password = '*****'

# MQTT Topics
topic_temp = "sensores/temperatura"
topic_hum = "sensores/umidade"
topic_ldr = "sensores/ldr"
topic_tds = "sensores/tds"
topic_temp_agua = "sensores/temperatura-agua"
topic_nivel = "sensores/nivel"

# Connection callback
def on_connect(client, userdata, flags, rc):
   if rc == 0:
     print("Conetado ao broker")
      
# USB Serial Connection to Arduino
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
time.sleep(2)
       
client = mqtt.Client(client_id)            
client.on_connect = on_connect 
client.connect(broker) 

# Main loop
i = 0

while i < 1:
    # Read sensor data from serial
    line = ser.readline()   
    if line:
        string = line.decode() 
        # Split values (5 characters each)
        temp, hum, ldr, tds, temp_agua, nivel = wrap(string, 5)
        
        # Publish Temperature
        print(temp)                  
        client.publish(topic_temp, temp)
        print("Temperatura")
        
        # Publish Humidity
        print(hum)  
        client.publish(topic_hum, hum)
        print("Umidade")
        
        # Publish LDR
        print(ldr)  
        client.publish(topic_ldr, ldr)
        print("LDR")
        
        # Publish TDS
        print(tds)  
        client.publish(topic_tds, tds)
        print("TDS")
        
        # Publish Water Temperature
        print(temp_agua)                  
        client.publish(topic_temp_agua, temp_agua)
        print("Temperatura Agua")
        
        # Publish Water Level
        print(nivel)                  
        client.publish(topic_nivel, nivel)
        print("Nivel Agua")
        
ser.close()

Serial Communication Settings

The bridge expects serial data with these parameters:
  • Baud Rate: 9600 bps
  • Data Format: Text strings
  • Timeout: 1 second
  • Encoding: UTF-8
The script uses wrap(string, 5) to split sensor values assuming each value is 5 characters. Ensure Arduino serial output formats values consistently.

Running the Bridge

1

Start MQTT broker

Ensure your MQTT broker is running:
# If using Mosquitto
sudo systemctl status mosquitto

# Start if not running
sudo systemctl start mosquitto
2

Upload Arduino code

Upload the sensor code to Arduino and verify serial output:
# Monitor Arduino serial output
screen /dev/ttyACM0 9600
Press Ctrl+A then K to exit screen.
3

Run the bridge script

Execute the Python bridge:
python3 mqtt-arduino.py
Expected output:
Conetado ao broker
24.50
Temperatura
65.00
Umidade
...
4

Verify MQTT messages

In another terminal, subscribe to topics:
mosquitto_sub -h localhost -p 18083 -t "sensores/#" -v
You should see messages like:
sensores/temperatura 24.50
sensores/umidade 65.00
sensores/ldr 30
sensores/tds 450
sensores/temperatura-agua 23.50
sensores/nivel 12.5

Running as System Service

To run the bridge automatically on boot:
1

Create systemd service file

sudo nano /etc/systemd/system/aqua-mqtt-bridge.service
Add the following:
[Unit]
Description=Aqua-IoT MQTT Bridge
After=network.target mosquitto.service

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi
ExecStart=/usr/bin/python3 /home/pi/mqtt-arduino.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
2

Enable and start service

sudo systemctl daemon-reload
sudo systemctl enable aqua-mqtt-bridge.service
sudo systemctl start aqua-mqtt-bridge.service
3

Check service status

sudo systemctl status aqua-mqtt-bridge.service

Troubleshooting

Serial Port Permission Denied

serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyACM0
Solution:
sudo chmod 666 /dev/ttyACM0
sudo usermod -a -G dialout $USER

Cannot Connect to Broker

Connection refused
Solutions:
  • Verify MQTT broker is running: sudo systemctl status mosquitto
  • Check broker address and port in script
  • Test connection: mosquitto_pub -h localhost -p 18083 -t test -m "hello"

No Serial Data Received

Solutions:
  • Verify Arduino is connected: ls /dev/ttyACM*
  • Check baud rate matches (9600)
  • Monitor serial directly: screen /dev/ttyACM0 9600
  • Reset Arduino after connecting USB

Data Format Errors

ValueError: not enough values to unpack
Solutions:
  • Check Arduino serial output format
  • Verify wrap(string, 5) splits correctly
  • Add debug logging: print(repr(string))

MQTT Broker Setup

Configure Mosquitto MQTT broker

Arduino Sensors

Configure Arduino sensor code

Build docs developers (and LLMs) love