This tutorial will guide you through the process of transforming an ESP32 into a functional IoT lock controlled via a Flutter app. You’ll learn about hardware setup, ESP32 programming, and Flutter app development, with detailed code snippets and explanations to build a fully operational system.
Part 1: Hardware Setup and ESP32 Programming
Hardware Required:
- ESP32 development board
- Solenoid lock or motorized lock
- NPN transistor (e.g., 2N2222)
- Diode (e.g., 1N4007 for EMF protection)
- Power supply appropriate for the lock
- Jumper wires and breadboard
- 1kΩ resistor
- (Optional) Pull-down resistor
ESP32 Circuit Setup:
- Connect the Solenoid Lock:
- Connect the solenoid lock’s positive wire to the power supply’s positive terminal.
- Connect the solenoid lock’s negative wire to the collector of the NPN transistor.
- Transistor Connections:
- Connect the emitter of the NPN transistor to the ground of the power supply.
- Connect the base of the NPN transistor to a GPIO pin on the ESP32 (e.g., GPIO 23) through a 1kΩ resistor.
- Diode Placement:
- Place the diode across the solenoid’s terminals, with the cathode connected to the positive side.
- Optional:
- Add a pull-down resistor between the GPIO pin and ground to prevent unintended triggering of the transistor due to floating states.
ESP32 Code:
- Install Necessary Tools:
- Install Arduino IDE and add ESP32 support.
- Install the PubSubClient library for MQTT communication.
- Programming the ESP32:
- 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.
#include <WiFi.h>
#include <PubSubClient.h>
// WiFi credentials
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
// MQTT Broker details
const char* mqtt_broker = "broker.hivemq.com";
const char* topic = "lock/control";
const char* mqtt_username = "user"; // Not needed for public brokers
const char* mqtt_password = "pass"; // Not needed for public brokers
const int mqtt_port = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
void setup_wifi() {
delay(10);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
void callback(char* topic, byte* message, unsigned int length) {
String messageTemp;
for (int i = 0; i < length; i++) {
messageTemp += (char)message[i];
}
if (messageTemp == "LOCK") {
digitalWrite(23, HIGH); // Lock the lock
} else if (messageTemp == "UNLOCK") {
digitalWrite(23, LOW); // Unlock the lock
}
}
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP32Client", mqtt_username, mqtt_password)) {
client.subscribe(topic);
} else {
client.loop();
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
pinMode(23, OUTPUT); // Set GPIO 23 as output for lock control
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
- Modify the callback function to control the lock:
- Use
digitalWrite(23, HIGH);
to lock anddigitalWrite(23, LOW);
to unlock based on the received message.
- Use
Part 2: Flutter App Development
Flutter App Setup:
- Install Flutter SDK:
- Ensure Flutter SDK is installed on your development machine.
- Create a New Project:
- Create a new Flutter project using your preferred IDE or the command line.
- Add MQTT Client Package:
- Open
pubspec.yaml
and addmqtt_client
and optionallyflutter_bloc
for state management.
- Open
yamlCopy codedependencies:
flutter:
sdk: flutter
mqtt_client: ^9.0.0
flutter_bloc: ^7.0.0
Flutter MQTT Service:
- Create a Service for MQTT:
- This service will manage the MQTT connection, subscription, and message publishing.
dartCopy codeimport 'package:mqtt_client/mqtt_client.dart' as mqtt;
class MQTTService {
late mqtt.MqttClient client;
late mqtt.MqttConnectionState connectionState;
void connect() async {
client = mqtt.MqttClient('broker.hivemq.com', '');
client.port = 1883;
client.keepAlivePeriod = 60;
try {
await client.connect();
} catch (e) {
print('Exception: $e');
client.disconnect();
}
client.updates!.listen((List<mqtt.MqttReceivedMessage<mqtt.MqttMessage>> c) {
final mqtt.MqttPublishMessage message = c[0].payload as mqtt.MqttPublishMessage;
final payload = mqtt.MqttPublishPayload.bytesToStringAsString(message.payload.message);
print('Received message:$payload from topic: ${c[0].topic}>');
});
}
void publish(String topic, String message) {
final builder = mqtt.MqttClientPayloadBuilder();
builder.addString(message);
client.publishMessage(topic, mqtt.MqttQos.exactlyOnce, builder.payload!);
}
}
Flutter UI for Lock Control:
- Build a Simple UI:
- Create a UI with buttons to send “LOCK” and “UNLOCK” commands to your ESP32 via MQTT.
dartCopy codeimport 'package:flutter/material.dart';
import 'mqtt_service.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final MQTTService _mqttService = MQTTService();
@override
void initState() {
super.initState();
_mqttService.connect();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('IoT Lock Control'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () => _mqttService.publish("lock/control", "LOCK"),
child: Text('Lock'),
),
ElevatedButton(
onPressed: () => _mqttService.publish("lock/control", "UNLOCK"),
child: Text('Unlock'),
),
],
),
),
),
);
}
}
Conclusion
This tutorial has guided you through setting up an IoT lock with an ESP32 and controlling it via a Flutter app using MQTT. The ESP32 code handles the lock mechanism and communicates with an MQTT broker to receive commands, while the Flutter app acts as a client, sending lock/unlock commands. By following these steps, you can integrate hardware with mobile applications for IoT solutions.
Safety Note: Always be cautious when handling electrical components and power supplies to avoid injury or damage.
Final Testing:
Verify that the MQTT messages are being sent and received correctly.
Ensure your ESP32 is properly connected and powered.
Test the lock and unlock functionality using the Flutter app.