首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于MQTT协议 远程控制电机

基于MQTT协议 远程控制电机

作者头像
逍遥子大表哥
发布2025-11-17 16:44:43
发布2025-11-17 16:44:43
860
举报
文章被收录于专栏:kali blogkali blog

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

实现准备

  • Arduino R4 WIFI开发板
  • L298N电机控制模块
  • 微型直流减速马达
硬件准备
硬件准备

硬件准备

线路连接:

连接方向

L298N 引脚

Arduino 引脚

功能描述

电源输入

12V 输入

12V

为 L298N 提供工作电压

接地

GND

GND

建立共同参考地

控制信号(方向)

IN1

2

控制电机正反转

控制信号(方向)

IN2

3

控制电机正反转

控制信号(速度)

ENA(PWM 输入)

9

调节电机转速(PWM 调速)

电机连接

OUT1 和 OUT2

-

连接至直流电机

实现功能

MQTT指令格式:

定时正转5秒

代码语言:javascript
复制
{"on":"1", "duration":5}

定时反转5秒

代码语言:javascript
复制
{"on":"0", "duration":5}

代码中,{"on":"1"}表示正转,{"on":"0"}表示反转。duration表示运行时间。可自定义! 若duration0则表示一直运行

一直正转

代码语言:javascript
复制
{"on":"1", "duration":0}
#或
{"on":"1"}

一直反转

代码语言:javascript
复制
{"on":"0", "duration":0}
#或
{"on":"0"}

停止

代码语言:javascript
复制
{"off":true}

示例代码

代码语言:javascript
复制
#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客户端,发送相关代码即可控制电机运转。

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 kali笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现准备
  • 实现功能
  • 示例代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档