在工业生成中,电机是重要的电器元件。本文我们基于MQTT协议实现对电机的远程控制,让其实现正转、反转、定时运转等功能。

硬件准备
线路连接:
连接方向 | L298N 引脚 | Arduino 引脚 | 功能描述 |
|---|---|---|---|
电源输入 | 12V 输入 | 12V | 为 L298N 提供工作电压 |
接地 | GND | GND | 建立共同参考地 |
控制信号(方向) | IN1 | 2 | 控制电机正反转 |
控制信号(方向) | IN2 | 3 | 控制电机正反转 |
控制信号(速度) | ENA(PWM 输入) | 9 | 调节电机转速(PWM 调速) |
电机连接 | OUT1 和 OUT2 | - | 连接至直流电机 |
MQTT指令格式:
定时正转5秒
{"on":"1", "duration":5}
定时反转5秒
{"on":"0", "duration":5}
代码中,{"on":"1"}表示正转,{"on":"0"}表示反转。duration表示运行时间。可自定义! 若duration为0则表示一直运行。
一直正转
{"on":"1", "duration":0}
#或
{"on":"1"}
一直反转
{"on":"0", "duration":0}
#或
{"on":"0"}
停止
{"off":true}
#include <WiFiS3.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// WiFi配置
const char* ssid = "WiFi账号";
const char* password = "WiFi密码";
// MQTT配置
const char* mqtt_server = "MQTT服务器地址";
const char* mqtt_username = "admin";//mqtt账号
const char* mqtt_password = "admin";//mqtt密码
const char* mqtt_topic = "dianji"; //订阅主题
// 电机引脚定义
const int IN1 = 2; // 连接到L298N的IN1
const int IN2 = 3; // 连接到L298N的IN2
const int ENA = 9; // 连接到L298N的ENA(PWM速度控制)
// 电机状态变量
enum MotorState {
MOTOR_STOP,
MOTOR_FORWARD,
MOTOR_REVERSE
};
MotorState currentMotorState = MOTOR_STOP;
unsigned long motorStartTime = 0;
unsigned long motorDuration = 0; // 0表示一直运行
bool isTimedOperation = false;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
void setup() {
Serial.begin(9600);
// 初始化电机控制引脚
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENA, OUTPUT);
// 初始状态:电机停止
stopMotor();
// 连接WiFi
connectWiFi();
// 设置MQTT
mqttClient.setServer(mqtt_server, 1883);
mqttClient.setCallback(mqttCallback);
// 连接MQTT
connectMQTT();
}
void loop() {
if (!mqttClient.connected()) {
connectMQTT();
}
mqttClient.loop();
// 检查定时运行是否到期
checkMotorTimer();
delay(100);
}
void connectWiFi() {
Serial.print("正在连接WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWiFi连接成功!");
Serial.print("IP地址: ");
Serial.println(WiFi.localIP());
}
void connectMQTT() {
while (!mqttClient.connected()) {
Serial.print("正在连接MQTT服务器...");
if (mqttClient.connect("ArduinoR4Client", mqtt_username, mqtt_password)) {
Serial.println("MQTT连接成功!");
// 订阅主题
if (mqttClient.subscribe(mqtt_topic)) {
Serial.println("主题订阅成功: " + String(mqtt_topic));
} else {
Serial.println("主题订阅失败!");
}
} else {
Serial.print("MQTT连接失败, 错误代码: ");
Serial.print(mqttClient.state());
Serial.println(" 5秒后重试...");
delay(5000);
}
}
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("收到消息 [");
Serial.print(topic);
Serial.print("]: ");
// 将payload转换为字符串
String message;
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
// 解析JSON消息
DynamicJsonDocument doc(256);
DeserializationError error = deserializeJson(doc, message);
if (error) {
Serial.print("JSON解析错误: ");
Serial.println(error.c_str());
return;
}
// 处理电机控制指令
processMotorCommand(doc);
}
void processMotorCommand(JsonDocument& doc) {
if (doc.containsKey("on")) {
String direction = doc["on"];
int duration = 0;
// 检查是否包含持续时间参数
if (doc.containsKey("duration")) {
duration = doc["duration"];
}
if (direction == "1") {
// 正转
startMotor(MOTOR_FORWARD, duration);
Serial.print("电机正转");
if (duration > 0) {
Serial.println(",持续时间: " + String(duration) + "秒");
} else {
Serial.println(",持续运行直到收到停止指令");
}
} else if (direction == "0") {
// 反转
startMotor(MOTOR_REVERSE, duration);
Serial.print("电机反转");
if (duration > 0) {
Serial.println(",持续时间: " + String(duration) + "秒");
} else {
Serial.println(",持续运行直到收到停止指令");
}
}
} else if (doc.containsKey("off")) {
// 停止电机
stopMotor();
Serial.println("电机关闭");
}
}
void startMotor(MotorState state, unsigned long duration) {
currentMotorState = state;
motorDuration = duration * 1000; // 转换为毫秒
motorStartTime = millis();
isTimedOperation = (duration > 0);
switch(state) {
case MOTOR_FORWARD:
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, 255); // 全速
break;
case MOTOR_REVERSE:
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, 255); // 全速
break;
default:
stopMotor();
break;
}
}
void stopMotor() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
analogWrite(ENA, 0);
currentMotorState = MOTOR_STOP;
isTimedOperation = false;
motorDuration = 0;
}
void checkMotorTimer() {
if (isTimedOperation && currentMotorState != MOTOR_STOP) {
unsigned long currentTime = millis();
// 检查是否超时(考虑millis()溢出)
if ((currentTime - motorStartTime) >= motorDuration) {
stopMotor();
Serial.println("定时时间到,电机已自动停止");
// 发送MQTT反馈(可选)
String feedback = "{\"status\":\"stopped\",\"reason\":\"timeout\"}";
mqttClient.publish("dianji/status", feedback.c_str());
}
}
}
使用
连接MQTT客户端,发送相关代码即可控制电机运转。

更多精彩文章 欢迎关注我们