
[FireBeetle 2 ESP32 P4 Development Kit] Home Assistant IoT Stepper Motor Control
This article presents the project design of DFRobot FireBeetle 2 ESP32 P4 Development Kit for remote stepper motor rotation control via Home Assistant, utilizing WiFi module and MQTT protocol.
Includes project introduction, flowchart, hardware connections, flowchart, engineering code, HA dashboard design, and operational demonstrations.
Project Introduction
Environment Setup: Docker, EMQX, HA deployment;
Engineering Testing: Flowchart, MicroPython code, MQTTX communication testing;
HA Testing: Configuration files, dashboard card design, debugging;
Environment Setup
Download and install Docker Desktop software;
Deploy EMQX platform and HA platform;
Hardware Connections
Stepper Motor
Step Motor Board
IN1 4
IN2 5
IN3 20
IN4 21
VCC 5V
GND GND
Connect the Type-C data cable to the USB-CDC port for both program debugging and system power supply.

Engineering Testing
Includes flowchart, code, MQTTX software testing, etc.
Flowchart

From top to bottom is as follows:
1.Start
2.Connect WiFi
3.Connect MQTT
4.Receive JSON Command
5.Parse Angle & Speed
6.Drive Motor Rotation
7.Return Status Feedback
Project Code
Run Thonny IDE software, configure the interpreter and device port, create a new file, and add the following code:
import json
import time
import random
import network
from machine import Pin
import uasyncio as asyncio
from umqtt.simple import MQTTClient
# ------------- User Configuration -------------
WIFI_SSID = "Xiaomi_8ABD"
WIFI_PWD = "15836035036"
MQTT_SERVER = "192.168.31.160"
MQTT_PORT = 32768
MQTT_CLIENT_ID = 'micropython-client-{id}'.format(id=random.getrandbits(8))
MQTT_USER = "LJL"
MQTT_PWD = "4421989g"
SUB_TOPIC = "esp/stepper/cmd"
PUB_TOPIC = "esp/stepper/status"
# Motor pins (A B C D)
MOTOR_PINS = [4, 5, 20, 21]
# ------------------------------------
def wifi_connect(ssid, pwd):
sta = network.WLAN(network.STA_IF)
sta.active(True)
if not sta.isconnected():
print("Connecting Wi-Fi...")
sta.connect(ssid, pwd)
for _ in range(20):
if sta.isconnected():
break
time.sleep(1)
print("Wi-Fi connected:", sta.ifconfig())
# --------------Stepper-------------------------------------
class Stepper28BYJ48:
STEP_SEQ = [
[1,0,0,1], [1,0,0,0], [1,1,0,0], [0,1,0,0],
[0,1,1,0], [0,0,1,0], [0,0,1,1], [0,0,0,1]
]
def __init__(self, pins):
self.coils = [Pin(p, Pin.OUT) for p in pins]
self.release()
def _write(self, pattern):
for coil, v in zip(self.coils, pattern):
coil.value(v)
def step(self, steps, delay_ms=2):
direction = 1 if steps > 0 else -1
for _ in range(abs(steps)):
for phase in range(8)[::direction]:
self._write(self.STEP_SEQ[phase])
time.sleep_ms(delay_ms)
self.release()
def angle(self, deg, delay_ms=2):
steps = int(deg * (509 / 360))
self.step(steps, delay_ms)
def release(self):
for c in self.coils:
c.value(0)
motor = Stepper28BYJ48(MOTOR_PINS)
# Connect MQTT
def mqtt_connect():
c = MQTTClient(MQTT_CLIENT_ID, MQTT_SERVER, MQTT_PORT, MQTT_USER, MQTT_PWD)
c.set_callback(on_msg)
c.connect()
c.subscribe(SUB_TOPIC)
print("[MQTT] connected & subscribed")
return c
# Receive control command
def on_msg(topic, msg):
try:
cmd = json.loads(msg)
angle = cmd.get("angle", 0)
speed = max(1, min(10, cmd.get("speed", 2))) # Limit speed range 1-10
delay_ms = 11 - speed # Higher value = faster speed (less delay)
motor.angle(angle, delay_ms)
# Return status
stat = {"angle_done": angle, "speed_set": speed}
client.publish(PUB_TOPIC, json.dumps(stat))
except Exception as e:
print("Bad msg:", e)
# Main coroutine
async def main():
wifi_connect(WIFI_SSID, WIFI_PWD)
global client
client = mqtt_connect()
while True:
client.check_msg()
await asyncio.sleep_ms(100)
asyncio.run(main())
Save the code and run it.
MQTTX Testing
Create new connection, input local computer IP address, port number, MQTT Broker username, password, etc.;
Run connection, add subscription topic esp/stepper/status to monitor messages;
On the sending interface, input topic esp/stepper/cmd to send command messages to EMQX.

Define rotation angle and speed, stepper motor rotates 20°, speed range 1-10;

HA testing
Enter the HA directory, open the configuration.yaml configuration file, add numeric display control and button control.
mqtt:
number:
- name: "Step Motor"
unique_id: stepper_angle
command_topic: "esp/stepper/cmd"
state_topic: "esp/stepper/status"
value_template: "{{ value_json.angle_done }}"
min: -360
max: 360
step: 1
unit_of_measurement: "°"
optimistic: false
button:
- name: "CW 90°"
command_topic: "esp/stepper/cmd"
payload_press: '{"angle":90,"speed":10}'
unique_id: stepper_cw_90
- name: "CCW 90°"
command_topic: "esp/stepper/cmd"
payload_press: '{"angle":-90,"speed":10}'
unique_id: stepper_ccw_90
Save changes and reload configuration to apply modifications;
Navigate to the HA Overview page, edit the dashboard, add cards, locate the newly added Step Motor entity and rotation direction buttons, then add them.
Flowchart

From top to bottom is as follows:
1.Status Feedback
2.Rotation Complete
3.Parse JSON
4.Drive Stepper Motor
5.Rotation Complete
6.Status Feedback
Control Panel
Click HA dashboard button to achieve remote network control of stepper motor bidirectional rotation;
Confirm hardware connections are complete and MQTTX communication tests successful;

Summary
This article presented the project design of remotely controlling stepper motor rotation via Home Assistant using the DFRobot FireBeetle 2 ESP32 P4 development kit's WiFi module and MQTT protocol, providing a reference for applications of this development board in IoT and remote control fields.
Original article by Makelog. Unauthorized reproduction prohibited.
Original text:【FireBeetle 2 ESP32 P4 开发套件】Home Assistant 物联网步进电机控制- Makelog(造物记)
