Nodejs+espjs+flutter+mqtt+esp8266 +L298N 电机驱动板控制直流电机

550 阅读3分钟

Nodejs+espjs+flutter+mqtt+esp8266 +L298N 电机驱动板控制直流电机

一、硬件材料

esp8266 NodeMCU 开发板一个

image-20230322200843974.png

L298N电机驱动板一个

image-20230401223929126.png

直流电机一个

image-20230322201032637.png

5V的外置电源一个

image-20230401224125486.png

我这里拆了一个USB的线,使用USB接口来给驱动板供电

各种线若干,我这里用的就是杜邦线

二、电路图

​ 老规矩,在制作之前,我们先要画好电路图确定我们整体的接线,以下就是我的电路图

接线图工程——NodeMcu-1.png

三、软件部分

首先是espjs代码


// 我们这里设置 D5引脚为信号 和D6引脚 输出模式
NodeMCU.D5.mode('output')
NodeMCU.D6.mode('output')

//导入wifi模块
var wifi = require('Wifi');
var mqtt = require('modules/MQTT.min.js');
// wifi名称
// var WIFI_NAME = "Tenda_E2E390";
var WIFI_NAME = "X30_5G";
// wifi 参数
var WIFI_OPTIONS = {
  // password: "hjy15285109962",
  password: "12345678",
};
console.log("connecting...");
//已连接wifi的事件
wifi.on('connected', function () {
  wifi.getIP((err, info) => {
    if (err !== null) {
      throw err;
    }
    //获取一下所在wifi下的局域网IP地址
    console.log(info.ip, 'connected');
    connectServer();
  });
});
// 连接wifi
wifi.connect(WIFI_NAME, WIFI_OPTIONS, err => {
  if (err !== null) {
    throw err;
  }
});

/**
@description 连接MQTT服务器
 */
function connectServer() {
  //初始化mqtt
  var client = mqtt.connect({
    host: '192.168.186.174',
    port: 1883,
    username: "user",
    password: '123456'
  });
  // 监听连接成功 回调
  client.on('connect', () => {
    console.log('connected success ...');
     //订阅三个主题
    let subs = [
      'topic/DCMotor/advance',
      'topic/DCMotor/retreat',
      'topic/DCMotor/off',
    ];
    client.subscribe(subs, {
      qos: 1
    });
  });
  //监听消息
  client.on('message', (topic, message) => {
    console.log('message success ...');
    // 前进信号
    if (topic == 'topic/DCMotor/advance') {
      console.log("前进...")
      digitalWrite(NodeMCU.D5, 1);
      digitalWrite(NodeMCU.D6, 0);
    }
      
    // 后退信号
    if (topic == 'topic/DCMotor/retreat') {
      console.log("后退...")
      digitalWrite(NodeMCU.D5, 0);
      digitalWrite(NodeMCU.D6, 1);
    }

    // 关闭
    if (topic == 'topic/DCMotor/off') {
      console.log("关闭...")
      digitalWrite(NodeMCU.D5, 0);
      digitalWrite(NodeMCU.D6, 0);
    }
  })

}

其次是搭建Nodejs的MQTT服务,这个之前的文章说了,这里就不重复了

APP端的话我这里使用的是flutter技术构建

我这里就写了一个很简单界面代码进行控制 如下

a1f19ec415c05010a610216126885f1.jpg

import 'package:flutter/material.dart';
import 'package:flutter_mqtt/alert.dart';
import 'package:flutter_mqtt/globalContext.dart';
import 'dart:io';
import 'package:flutter_mqtt/mqtt.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  //
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //获取全局上下文
      navigatorKey: navigatorKey,
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: const MyHomePage(title: '控制电机'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  //局域网地址
  String url = "192.168.186.174";
  MqttQos qos = MqttQos.atLeastOnce;

  late MqttServerClient _client;

  //关闭信号
  void off() {
    publish('topic/DCMotor/off', "");
  }

  // 前进信号
  void advance() {
    publish("topic/DCMotor/advance", '');
  }

  //后退信号
  void retreat() {
    publish("topic/DCMotor/retreat", "");
  }

  @override
  void initState() {
    //初始化
    _client = MqttServerClient(url, '123');

    /// 设置协议
    _client.setProtocolV311();

    /// If you intend to use a keep alive you must set it here otherwise keep alive will be disabled.
    _client.keepAlivePeriod = 20;

    /// 设置连接超时时间
    _client.connectTimeoutPeriod = 20000; // milliseconds

    /// 创建连接配置
    final connMessage = MqttConnectMessage()

        /// 设置wiil遗嘱主题
        .withWillTopic("willTopic")

        /// 设置will遗嘱消息
        .withWillMessage("willMessage")

        /// 开启Clean Session.每次连接都是一个新的Session.
        .startClean()

        /// 设置will消息的qos模式。
        .withWillQos(qos);

    /// 连接成功的回调函数
    _client.onConnected = onConnected;
    //启用连接
    _client.connect("user", '123456');

    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Column(
          children: [
            Container(
              padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
              width: double.infinity,
              height: 100,
              child: Center(
                  widthFactor: 100,
                  heightFactor: 100,
                  child: GestureDetector(
                      // 按下发送前进信号
                    onTapDown: (_) => advance(),
                    child: ElevatedButton(
                       // 松开就关闭
                      onPressed: off,
                      child: const Text('前进'),
                    ),
                  )),
            ),
            Container(
              padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
              width: double.infinity,
              height: 100,
              child: Center(
                  widthFactor: 100,
                  heightFactor: 100,
                  child: GestureDetector(
                      //按下前进信号
                    onTapDown: (_) => retreat(),
                    child: ElevatedButton(
                        //松开就关闭
                      onPressed: off,
                      child: const Text('后退'),
                    ),
                  )),
            ),
          ],
        ));
  }

  onConnected() {
    print("连接成功Mqtt");
    String msg = "连接mqtt服务连接成功 $url";
    showAlert(content: msg);
  }

  // 发布主题消息
  publish(String pubTopic, String data) {
    print("publish");
    final builder = MqttClientPayloadBuilder();
    builder.addString(data);
    _client.publishMessage(pubTopic, qos, builder.payload!);
  }
}

最终的效果如下

其实这个L298N电机驱动板可以同时带两个电机并能控制电机的转速,感兴趣的话可以自行研究一下,可以扩展做一个遥控车

f5e591c7beb7a34d905eb5e50e11d5c8.gif