IoT Lock: Raspberry Pi 5 with Flutter App Tutorial

Overview: In this tutorial, you’ll learn how to transform your Raspberry Pi 5 into a functional IoT lock controlled via a Flutter app. We will cover hardware setup, programming the Raspberry Pi, and Flutter app development. By following this step-by-step guide, you’ll create a fully operational IoT lock system.

Part 1: Hardware Setup and Raspberry Pi Programming

Hardware Required:

  • Raspberry Pi 5 (with Raspberry Pi OS installed)
  • Solenoid lock or motorized lock (12V recommended)
  • NPN transistor (e.g., 2N2222)
  • Diode (e.g., 1N4007 for EMF protection)
  • External power supply matching the lock’s voltage (e.g., 12V for a 12V solenoid)
  • Jumper wires and breadboard
  • 1kΩ resistor
  • (Optional) 10kΩ Pull-down resistor

Raspberry Pi Circuit Setup:

Step 1: Solenoid Lock Connections

  1. Connect the solenoid’s positive wire to the positive terminal of the external power supply.
  2. Connect the solenoid’s negative wire to the collector of the NPN transistor.

Step 2: Transistor Connections

  1. Connect the emitter of the transistor to the ground of the external power supply.
  2. Connect the base of the transistor to a GPIO pin (e.g., GPIO 23) on the Raspberry Pi via a 1kΩ resistor.

Step 3: Diode Placement

  • Place the diode in parallel with the solenoid, ensuring the cathode (striped end) faces the solenoid’s positive terminal.

Step 4 (Optional): Pull-Down Resistor

  • Add a 10kΩ resistor between the GPIO pin and ground to prevent accidental triggering.

Raspberry Pi Code:

  1. Install Necessary Libraries: Ensure your Raspberry Pi is up-to-date and install the necessary libraries:
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install python3-pip -y
pip3 install paho-mqtt RPi.GPIO
  1. Programming the Raspberry Pi:
    • Connect to WiFi.
    • Connect to an MQTT broker.
    • Subscribe to a topic for receiving lock commands (e.g., lock/control).
    • Use a GPIO pin to control the lock.

Create a file iot_lock.py with the following code:

import paho.mqtt.client as mqtt
import RPi.GPIO as GPIO
import time

# GPIO Configuration
LOCK_PIN = 23
GPIO.setmode(GPIO.BCM)
GPIO.setup(LOCK_PIN, GPIO.OUT, initial=GPIO.LOW)  # Start in unlocked state

# MQTT Configuration
MQTT_BROKER = "broker.hivemq.com"
MQTT_PORT = 1883
MQTT_TOPIC = "lock/control"

def on_connect(client, userdata, flags, rc):
    print(f"Connected to MQTT broker with code {rc}")
    client.subscribe(MQTT_TOPIC)

def on_message(client, userdata, msg):
    command = msg.payload.decode().strip().upper()
    if command == "LOCK":
        GPIO.output(LOCK_PIN, GPIO.HIGH)
        print("Lock engaged")
    elif command == "UNLOCK":
        GPIO.output(LOCK_PIN, GPIO.LOW)
        print("Lock disengaged")

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

try:
    client.connect(MQTT_BROKER, MQTT_PORT, 60)
    client.loop_forever()
except KeyboardInterrupt:
    print("Exiting...")
    GPIO.cleanup()
  1. Running the Script: python3 iot_lock.py

Part 2: Flutter App Development

Flutter App Setup:

  1. Install the Flutter SDK.
  2. Create a new project:
flutter create iot_lock_app

Add Dependencies

Update pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  mqtt_client: ^9.6.3

Flutter MQTT Service

Create mqtt_service.dart:

import 'package:mqtt_client/mqtt_client.dart';

class MQTTService {
  late MqttClient _client;
  bool _isConnected = false;

  Future<void> connect() async {
    _client = MqttClient('broker.hivemq.com', 'flutter_client_${DateTime.now().millisecondsSinceEpoch}');
    _client.port = 1883;
    _client.keepAlivePeriod = 30;

    try {
      await _client.connect();
      _isConnected = true;
    } catch (e) {
      _isConnected = false;
      print('Connection error: $e');
    }
  }

  void publish(String topic, String message) {
    if (!_isConnected) {
      print("Not connected to MQTT broker");
      return;
    }
    final builder = MqttClientPayloadBuilder();
    builder.addString(message);
    _client.publishMessage(topic, MqttQos.atLeastOnce, builder.payload!);
  }

  void disconnect() => _client.disconnect();
}

Flutter UI

Update main.dart:

import 'package:flutter/material.dart';
import 'mqtt_service.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final MQTTService _mqttService = MQTTService();
  bool _isConnected = false;

  @override
  void initState() {
    super.initState();
    _connectToBroker();
  }

  Future<void> _connectToBroker() async {
    await _mqttService.connect();
    setState(() => _isConnected = true);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('IoT Lock Control')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                _isConnected ? "Connected" : "Disconnected",
                style: TextStyle(color: _isConnected ? Colors.green : Colors.red),
              ),
              const SizedBox(height: 20),
              ElevatedButton(
                onPressed: () => _mqttService.publish("lock/control", "LOCK"),
                child: const Text("LOCK"),
              ),
              ElevatedButton(
                onPressed: () => _mqttService.publish("lock/control", "UNLOCK"),
                child: const Text("UNLOCK"),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

    Flutter MQTT Service:

    1. Create a Service for MQTT:
      • This service will manage the MQTT connection, subscription, and message publishing.

    Flutter UI for Lock Control:

    1. Build a Simple UI:
      • Create a UI with buttons to send “LOCK” and “UNLOCK” commands to your Raspberry Pi via MQTT.

    Conclusion

    You’ve now built an IoT lock system using a Raspberry Pi 5 and Flutter. The Raspberry Pi controls the lock via MQTT commands, while the Flutter app sends lock/unlock requests.

    Key Improvements

    • Added connection status feedback in the Flutter app.
    • Used unique MQTT client IDs to avoid broker conflicts.
    • Simplified QoS to atLeastOnce for reliability without overhead.
    • Included GPIO cleanup on script exit.

    Safety Notes

    • Always disconnect power before modifying the circuit.
    • Use a relay module instead of a transistor for high-current locks.
    • Secure your MQTT broker with credentials in production.

    Testing

    1. Power on the Raspberry Pi and run iot_lock.py.
    2. Launch the Flutter app and test lock/unlock functionality.
    3. Monitor debug logs for MQTT message confirmation.

    Next Steps: Add features like authentication, encryption, or status feedback from the lock to the app!

    Common Pitfalls

    1. Hardware Issues

    • Incorrect Wiring: Misplaced transistor pins (collector/emitter) or reversed diode polarity will prevent the lock from activating.
    • Underpowered Lock: If your solenoid requires 12V but you use a 5V power supply, it won’t work.
    • GPIO Pin Conflicts: Using a reserved GPIO pin (e.g., UART-enabled pins) can cause errors.

    2. Software/Configuration

    • Python Dependency Conflicts: Outdated RPi.GPIO or paho-mqtt libraries.
    • Flutter Package Version Mismatches: Using an incompatible version of mqtt_client.
    • Firewall/Network Issues: The Raspberry Pi or mobile device might block MQTT traffic (port 1883).

    3. MQTT Broker Problems

    • If broker.hivemq.com is down or overloaded, the app and Pi won’t communicate.

    Step-by-Step Troubleshooting

    If the system doesn’t work:

    1. Test the Circuit
      • Temporarily replace the solenoid with an LED to confirm GPIO control.
      • Verify the transistor is wired correctly (use a multimeter to check continuity).
    2. Check MQTT Communication
      • Use an MQTT client like MQTT Explorer to confirm messages are sent/received.
    3. Debug the Flutter App
      • Ensure the app connects to the broker (check logs for onConnected callbacks).
    4. Validate Power Supply
      • Test the solenoid with a standalone power source (bypass the Pi) to rule out insufficient current.

    Safety & Recommendations

    • Use a Relay Module Instead of Transistor for high-current locks (simpler and safer).
    • Secure Your MQTT Broker in production (e.g., use Mosquitto with TLS/authentication).
    • Add Error Handling in the Flutter app (e.g., connection retries, status feedback).

    Final Verdict

    The tutorial will work if:

    • The hardware is wired correctly.
    • Software dependencies are properly installed.
    • The MQTT broker is accessible.

    If you encounter issues, focus on isolating the problem (hardware vs. software vs. network). Let me know where you’re stuck, and I’ll help troubleshoot!