用Arduino兼容设备(M5Stack)和传感器制作迷你遥控车

第1部分:用小型Arduino兼容设备(M5Stack)享受电子制作的乐趣
第2部分:通过M5Stack使用电机驱动器
第3部分:通过M5Stack使用传感器实现自动驾驶和自动避让功能
剧终篇:实现M5Stack与智能手机联动控制

第一部分
这次我想用小型Arduino兼容设备“M5Stack”系列来制作一辆原创遥控车。这里使用的M5Stack是一种使用了ESP32的Arduino开发模块,自带传感器和显示器等配件,使用它可以轻松开始开发。我想为大家介绍一下使用这种M5Stack制作也可以从外部控制的迷你遥控车的过程。
arduino-m5stack-remote-control-car-16.jpg
本部分的流程

  • 关于Arduino兼容设备M5Stack系列
  • 制作本设备所需的部件
  • 遥控车的功能和可以学到的知识
  • M5Stack开发环境安装
  • 总结

1. 关于Arduino兼容设备M5Stack系列
M5Stack是由中国深圳硬件初创公司M5Stack推出的Arduino兼容开发模块之一。它使用Espressif公司内置有Wi-Fi和BLE的ESP32平台,使开发变得像Arduino一样简单。其特点是在小小的产品中,自带显示器、传感器、按钮、USB接口等。
M5Stack有多个系列,用户可以根据大小和用途进行选择。最容易上手的是“M5 Stack Core”,它带有较大的方形显示器。另外还有“M5 Stick-C”,它的外壳和显示器尺寸更小,更易于使用。2020年还推出了大概只有“M5 Stick-C”一半大小的超小型“ATOM”系列。
arduino-m5stack-remote-control-car-02-e1608133416785.jpg
M5Stack Core
arduino-m5stack-remote-control-car-03-e1608133468979.jpg
M5Stick-C
arduino-m5stack-remote-control-car-04.jpg
M5Stack ATOM Matrix

下表中将这几种产品的规格简单汇总了一下。请根据用途和尺寸选用。
系列M5StackM5StickM5Stack ATOM
名称M5Stack Core GrayM5Stick-CM5Stack ATOM Matrix
芯片ESP32-D0WDQ6
(Wifi, BLE)
ESP32-PICO
(Wifi, BLE)
ESP32-PICO
(Wifi, BLE)
存储器520KB RAM
16MB Flash
520KB RAM
4MB Flash
520KB RAM
4MB Flash
大小5.4 x 5.4 x 1.7 cm4.8 x 2.5 x 1.4 cm2.4 x 2.4 x 1.4 cm
显示器Color TFT LCD (2 inch)Color TFT LCD (0.96 inch)5 x 5 RGB LCD
传感器类MPU6886(加速度传感器)
BMM150(地磁传感器)
无麦克风
有扬声器
MPU6886(加速度传感器)
红外LED
有麦克风
无扬声器
MPU6886(加速度传感器)
红外LED
无麦克风
无扬声器
电池150mAh @3.7V80mAh @3.7V
参考价格4,800日元左右2,000日元左右2,000日元左右

2. 制作本设备所需的部件
这次我们将使用M5Stack和一些传感器来创建可以自动驾驶或远程控制的小型汽车,所需部件汇总如下。
车身部分
名称和说明部件
M5Stack Core
搭载了ESP32的Arduino兼容设备。不仅自带大型LED显示器,还自带BLE、Wifi和运动传感器等。
arduino-m5stack-remote-control-car-02-300x286.jpg
超声波距离传感器
发射超声波并通过其反弹声波来测量距离的模块。
arduino-m5stack-remote-control-car-05-300x227.jpg
ROHM照度/接近传感器
(RPR-0521RS)
(RPR-0521RS)
通过发射红外线并测量其反射光来测量光的强度和接近度。
arduino-m5stack-remote-control-car-06-300x88.jpg
Grove I2C电机驱动器
使用称为“I2C”的通信方式,与Grove引脚连接即可使用的电机驱动器。
arduino-m5stack-remote-control-car-07-300x300.jpg
车轮、外装件等 arduino-m5stack-remote-control-car-08-300x160.jpg
遥控部分:
名称和说明部件和应用
M5Stick-C
在M5Stack系列中尺寸更小的产品,具有BLE和Wi-Fi功能的ESP32 Arduino兼容模块
arduino-m5stack-remote-control-car-03-300x277.jpg
Blynk(智能手机应用程序)
可以通过Wi-Fi操作Arduino和Raspberry Pi的智能手机应用程序。
arduino-m5stack-remote-control-car-09.jpg
把这些部件备好后,就可以制作小型遥控车了。

3. 遥控车的功能和可以学到的知识
这次要做的遥控车分为汽车车身部分和遥控部分两部分。车身部分将使用传感器自动行驶。遥控器使用M5Stcick-C和智能手机来实现对汽车的控制。下面列出了车身部分和遥控部分可以实现的功能,以及可以学到的知识。
车身部分:
编号可以学到的知识
1使用Arduino IDE开发M5Stack的方法
2使用I2C电机驱动器、通过Arduino控制电机来制作小汽车的方法
3使用了距离传感器的物体避让机制
4使用照度/接近传感器而不会从桌子上等高处掉下来的机制
遥控部分
编号可以学到的知识
1使用M5Stack时的运动传感器使用方法
2Arduino(M5Stack)之间通过BLE进行通信和操作的方法
3从智能手机上操作Arduino(M5Stack)的方法

4. M5Stack开发环境安装
要想使用Arduino IDE进行M5Stack程序开发,需要进行一些必要的准备工作。请前往Arduino IDE下载页面(https://www.arduino.cc/en/main/software)下载并安装软件。另外,最好提前了解一下ESP-WROOM-32的使用方法。
arduino-m5stack-remote-control-car-10.jpg
[Arduino IDE的下载界面 https://www.arduino.cc/en/main/software ]
Arduino IDE安装完成后,需要设置ESP32开发板。从Arduino的菜单中,选择设置 > Preferencees,并在“ Additional Boards Manager URL”中输入以下地址:
https://dl.espressif.com/dl/package_esp32_index.json
arduino-m5stack-remote-control-car-11.jpg
然后通过Tools > Boards > Boards Manager搜索ESP32并安装开发包。
arduino-m5stack-remote-control-car-12.jpg
这样就可以选择M5Stack-Core-ESP32作为开发板了,请选择它。此外,从串口指定USB连接并连接电脑和M5Stack。
arduino-m5stack-remote-control-car-13.jpg
另外,还需要通过Sketch > Include Library > Manage Library管理来添加M5Stack的库。
arduino-m5stack-remote-control-car-14.jpg
现在,让我们用USB-C数据线连接电脑和M5Stack吧。刚刚下载的M5Stack库中附有一些示例程序,我们可以直接使用。从File > Sketch example > M5Stack中选择示例草图并将其导入。
arduino-m5stack-remote-control-car-15.jpg
arduino-m5stack-remote-control-car-01.jpg
[左起分别是:M5Stack Core Gray、M5Stcik-C、M5Stack ATOM Matrix]

5. 总结
在本系列连载中,我们将使用M5Stack制作遥控车。M5Stack系列有自带传感器的产品,也有带较大显示器的产品,请根据您的用途选用。传感器也可以从外部安装,因此还可以通过添加ROHM的传感器等器件来增加功能。
从下一部分开始,我将为大家介绍实际制作遥控车的过程,敬请期待!

(第二部分)

通过M5Stack使用电机驱动器


本系列连载将为您介绍使用小型Arduino兼容设备M5Stack制作遥控车的过程。在第二部分中,我们将连接M5Stack和电机驱动器,以使直流电机运转。由于使用一个名为“Grove”的标准引脚,而使看似复杂的电机驱动器设置变得非常简单。
arduino-m5stack-remote-control-car-02-01.jpg
使用M5Stack系列制作遥控车

本部分的流程

  • 电机驱动器的设置
  • M5Stack与电机的连接
  • 运行M5Stack的程序
  • 总结

本部分所需部件
M5Stack Core
搭载了ESP32、显示器、传感器等的Arduino兼容设备
arduino-m5stack-remote-control-car-02-e1608133416785.jpg
Grove I2C电机驱动器
使用“I2C”通信方式与Grove引脚连接即可使用的电机驱动器
arduino-m5stack-remote-control-car-07_01.jpg
9V电池和电池盒
arduino-m5stack-remote-control-car-02-02.jpg
小型电机、车轮等
arduino-m5stack-remote-control-car-08.jpg

1. 电机驱动器的设置
在制作迷你遥控车时,需要一个称为“电机驱动器”的IC器件来负责驱动直流电机并控制转速等工作。电机驱动器与Arduino之间的连接以及编程稍微有点复杂,但是M5Stack带有Grove引脚,通过使用可以与Grove相连接的电机驱动器,即可轻松进行电机控制。
这次我们将使用带有Grove引脚的、I2C控制方式的这款电机驱动器。
arduino-m5stack-remote-control-car-07_01.jpg
需要进入开发这款电机驱动器的SEEED公司的产品页面,并获取库文件。请单击下面页面中的Grove I2C Motor Driver,将其下载到您的计算机上。
https://wiki.seeedstudio.com/Grove-I2C_Motor_Driver_V1.3/
arduino-m5stack-remote-control-car-02-03.png
从菜单上的Sketch > Include library > Add .ZIP Library中选择前面提到的文件并应用。
arduino-m5stack-remote-control-car-02-04.png
现在已安装好了库和示例草图。在草图示例菜单中有一个名为“dcmotor_test”的示例,选择它并将其写入M5Stack。
arduino-m5stack-remote-control-car-02-05.png
需要连接电脑、M5Stack 和电机驱动器之后进行写入。当出现如画面中的消息时,表明电机驱动器的草图已经成功写入。
arduino-m5stack-remote-control-car-02-06.jpg
2. M5Stack与电机的连接
将直流电机连接到M5Stack和电机驱动器。对于驱动部分,我们使用车轮已经与非常小的电机连接好的齿轮电机。将这个齿轮电机固定到电池盒上,很容易就实现了一体化的迷你遥控车。
arduino-m5stack-remote-control-car-02-07.jpg
电机和车轮设置
arduino-m5stack-remote-control-car-02-08.jpg
将电机和电池盒固定(用螺丝拧紧)
将电机出来的2对线缆、电池盒出来的1对线缆分别与电机驱动器连接。
arduino-m5stack-remote-control-car-02-09.jpg
连接电机侧的引脚
arduino-m5stack-remote-control-car-02-10.jpg
连接电源侧的引脚
现在,电机驱动器、车轮和电池盒是这样的:
arduino-m5stack-remote-control-car-02-11.jpg
在M5Stack侧也要安装小车轮。使用Grove线缆连接电机驱动器和M5Stack。
arduino-m5stack-remote-control-car-02-12.jpg
整体如下:
arduino-m5stack-remote-control-car-02-13.jpg

3. 运行M5Stack的程序
最后,我们需要创建程序来运行M5Stack。M5Stack有一个显示器,所以我们让遥控车行驶过程中在屏幕上显示相应的内容。示例程序M5_Motor.ino如下:
#include "Grove_I2C_Motor_Driver.h"
  • #include <M5Stack.h>
  • #define I2C_ADDRESS 0x0f
  • void setup() {
  •     Serial.begin(9600);
  •     Motor.begin(I2C_ADDRESS);
  •     M5.begin();
  •     M5.Lcd.setTextSize(4);
  •     M5.lcd.print("GO M5!");
  • }
  • void loop() {
  •     // Set speed of MOTOR1, Clockwise, speed: -100~100
  •     Motor.speed(MOTOR1, 100);
  •     // Set speed of MOTOR2, Anticlockwise
  •     Motor.speed(MOTOR2, -100);
  •     M5.lcd.clear();
  •     M5.Lcd.setCursor(10,0);
  •     M5.lcd.print("GO M5!");
  •     M5.Lcd.setCursor(10,60);
  •     M5.lcd.print("Forward!");
  •     delay(2000);
  •     // Change speed and direction of MOTOR1
  •     Motor.speed(MOTOR1, -100);
  •     // Change speed and direction of MOTOR2
  •     Motor.speed(MOTOR2, 100);
  •     M5.Lcd.setCursor(10,60);
  •     M5.lcd.print("Backward!");
  •     delay(2000);
  •     // Stop MOTOR1 and MOTOR2
  •     Motor.stop(MOTOR1);
  •     Motor.stop(MOTOR2);
  •     M5.lcd.clear();
  •     M5.Lcd.setCursor(10,60);
  •     M5.lcd.print("Stop!");
  •     delay(2000);
  • }
  • 复制代码
    程序准备好后,将其导入 M5Stack。打开电源后,车轮应该开始转动了。
    arduino-m5stack-remote-control-car-02-14.jpg

    向前转动时显示“Forward”,向后转动时显示“Backword”。
    arduino-m5stack-remote-control-car-02-15.jpg
    arduino-m5stack-remote-control-car-02-16.jpg

    4. 总结
    这次我们用两个小型齿轮电机实现了前后左右行驶。虽然需要用电机驱动器来控制Arduino和直流电机,不过我想您已经了解到了,只需将其与Grove引脚连接即可轻松开始使用。
    M5Stack的Grove引脚可以连接各种驱动器和传感器等,因此您还可以尝试连接其他传感器。
    在下一部分中,我们将通过安装距离传感器等器件,来实现避让墙壁、避免从桌子上掉下来等目标。自动驾驶即将实现,敬请期待!

    (第三部分)


    通过M5Stack使用传感器实现自动驾驶和自动避让功能

    本系列连载将为您介绍使用小型Arduino兼容设备M5Stack制作遥控车的过程。这次我们将在M5Stack上添加各种传感器,以便实现自动控制。M5Stack有很多引脚,因此仅需插入接近传感器或距离传感器即可轻松增加相应的功能。
    arduino-m5stack-remote-control-car-03-01.jpg
    arduino-m5stack-remote-control-car-03-02.jpg
    在M5Stack上安装距离传感器和接近传感器,实现自动驾驶

    本部分的流程

    • 照度、接近一体型传感器的设置
    • 距离传感器的设置
    • 用传感器进行测量,同时自动驾驶
    • 总结

    本部分所需部件M5Stack Core
    搭载了ESP32、显示器、传感器等的Arduino兼容设备
    arduino-m5stack-remote-control-car-02-e1608133416785.jpg

    ROHM的照度、接近一体型传感器 (RPR-0521RS)
    通过发射红外光并测量其反射光来测量光强和接近程度。
    arduino-m5stack-remote-control-car-03-03.jpg
    超声波距离传感器 (HC-SR04)
    发射超声波并通过其反弹声波来测量距离的模块。
    arduino-m5stack-remote-control-car-03-04.jpg
    Grove I2C电机驱动器
    使用“I2C”通信方式与Grove引脚连接即可使用的电机驱动器
    arduino-m5stack-remote-control-car-07_01.jpg
    9V电池和电池盒
    arduino-m5stack-remote-control-car-02-02.jpg
    小型电机、车轮等
    arduino-m5stack-remote-control-car-08.jpg

    1. 照度、接近一体型传感器的设置
    我希望遥控车在行驶时,在即将撞到障碍物或即将从桌子上掉下来的情况下,能够自动避让并避免掉落。
    首先,我们使用接近传感器来判断是否即将掉落。接近传感器我们用ROHM传感器评估套件中的照度、接近一体型传感器模块(RPR-0521RS)。
    arduino-m5stack-remote-control-car-03-05.png
    该传感器通过发射红外LED光并检测其反射光来测量物体等的接近程度。另外,还可以通过亮度传感器来同时测量亮度。
    要使用该传感器,需要进入下面的ROHM传感器页面并下载Arduino用的库。
    https://www.rohm.com.cn/sensor-shield-support/ps-als-sensor
    在ROHM官网上下载zip文件后,通过其菜单安装Arduino IDE库。
    arduino-m5stack-remote-control-car-03-06.png
    接下来,我们把M5Stack和传感器连接起来。M5Stack上下有8个引脚,左右有15个引脚,背面写有引脚排列编号。Arduino的GPIO(输入输出引脚)与数字标注的引脚编号相对应。
    arduino-m5stack-remote-control-car-03-07.jpg
    M5Stack背面的引脚排列图
    照度、接近一体型传感器使用“I2C”通信方式。我们用M5Stack下方引脚中的SDA=G21和SCL=G22进行I2C通信。请按照下表连接传感器和M5Stack。
    传感器侧引脚
    (右起)
    M5Stack侧
    (下方)
    VDO3.3V (橙)
    GNDGND (蓝)
    SDAGPIO21 (黄)
    SCLGPIO22 (绿)
    INTNA
    arduino-m5stack-remote-control-car-03-08.jpg
    传感器和M5Stack连接好之后,从Arduino IDE的草图示例中选择前面安装的示例PRP-0521RS。
    添加到示例中之后还需要在M5Stack的显示器中显示等,所以要将其另存为“M5Stack_PRP-0521RS.ino”。在这里添加如下程序(第1、11〜14、20、29〜30、36、39行)。
    是M5Stack用的库。Wire.begin(21,22)是为了使M5Stack能够使用I2C通信方式的声明。
    [M5Stack_PRP-0521RS.ino]
    #include <M5Stack.h>
  • #include <Wire.h>
  • #include <RPR-0521RS.h>
  • RPR0521RS rpr0521rs;
  • void setup() {
  •   byte rc;  
  •   Serial.begin(115200);
  •   while (!Serial);  
  •   Wire.begin(21,22);
  •   M5.begin();
  •   M5.Lcd.setTextSize(2);
  •   M5.Lcd.setRotation(3);
  •   rc = rpr0521rs.init();
  • }
  • void loop() {
  •   Wire.begin(21,22);
  •   byte rc;
  •   unsigned short ps_val;
  •   float als_val;
  •   byte near_far;
  •   rc = rpr0521rs.get_psalsval(&ps_val, &als_val);
  •   if (rc == 0) {
  •     Serial.print(F("RPR-0521RS (Proximity)     = "));
  •     M5.Lcd.setCursor(10, 20);
  •     M5.Lcd.printf("RPR-0521RS: ");
  •     Serial.print(ps_val);
  •     Serial.print(F(" [count]"));
  •     near_far = rpr0521rs.check_near_far(ps_val);
  •     if (near_far == RPR0521RS_NEAR_VAL) {
  •       Serial.println(F(" Near"));
  •       M5.Lcd.printf("M5 Near!");
  •     } else {
  •       Serial.println(F(" Far"));
  •       M5.Lcd.printf("M5 Far !");
  •     }
  •   }
  •   delay(500);
  • }
  • 复制代码
    通过M5Stack使用该程序时,需要更改一项。打开文件“PRP-0521RS.cpp”并删除“#include”部分中的“avr/”(通常安装的库位于Arduino > Libraries > RPR-0521RS中)。进行该操作后,M5Stack就可以正常读取pgmspace.h了。
    [PRP-0521RS.cpp的位置,更改前。删除红框部分的“avr/”。 ]
    arduino-m5stack-remote-control-car-03-09.png
    完成该更改后,运行“M5Stack_PRP-0521RS.ino”。将会开始自动测量,当您将手指靠近设备时,屏幕上会出现如图所示的“Near!”消息。
    arduino-m5stack-remote-control-car-03-10.jpg
    当手指靠近时,会输出“Near”来告知附近有东西

    2. 距离传感器的设置
    接下来,我们在M5Stack上安装距离传感器,以便能够检测出并避让障碍物。我们使用这种名为“HC-SR04”的超声波距离传感器。这是一种能够发射超声波并通过其反弹声波来测量距离的模块。
    arduino-m5stack-remote-control-car-03-04.jpg
    按照下表和照片所示连接该超声波传感器。
    传感器侧引脚
    (左起)
    M5Stack侧
    (左侧侧面)
    VCC5V (红)
    TrigGPIO2 (橙)
    EchoGPIO5 (黄)
    GNDGND (黑)
    arduino-m5stack-remote-control-car-03-11.jpg
    驱动这个距离传感器的程序“M5Stack_Dist.ino”如下。由于G2与输出TRIG连接,G5与输入ECHO连接,因此程序中分别指定了GPIO编号。
    [M5Stack_Dist.ino]
  • #include <M5Stack.h>
  • #define TRIG 2
  • #define ECHO 5
  • int times;
  • int distance;
  • void setup() {
  •   Serial.begin(115200);
  •   while (!Serial);  
  •   pinMode(TRIG, OUTPUT);
  •   pinMode(ECHO, INPUT);
  •   M5.begin();
  •   M5.Lcd.setTextSize(2);
  •   M5.Lcd.setRotation(3);
  • }
  • void loop() {
  •   // 发射超声波
  •   digitalWrite(TRIG, HIGH);
  •   delayMicroseconds(10);
  •   digitalWrite(TRIG, LOW);
  •   // 接收超声波
  •   times = pulseIn(ECHO, HIGH);
  •   distance = (int)(times * 0.017);
  •   // 在监视器、显示器上显示
  •   Serial.println(distance);
  •   M5.Lcd.setCursor(0, 0);
  •   M5.Lcd.print(distance);
  •   delay(500);
  • }
  • 复制代码
    运行该程序,当将手指靠近距离传感器时,就会测量出距离。该距离数据表示串口监视器和M5Stack屏幕与手等障碍物之间的距离。
    arduino-m5stack-remote-control-car-03-12.jpg
    在串口监视器(左)和M5Stack屏幕(右)上显示测量到的距离

    3. 用传感器进行测量,同时自动驾驶
    最后,要能够根据传感器的测量结果进行控制,以避让障碍物并避免从桌子上掉落下来。首先,我们需要将电机驱动器、车轮等连同传感器重新连接起来。将电机驱动器连接在Grove引脚上,将距离传感器设置在容易捕捉前方情况的位置,将接近传感器设置在下方。
    arduino-m5stack-remote-control-car-03-13.jpg
    还要创建一个使传感器和电机联动的程序。在程序中,当距离传感器测到距离小于5cm时,即判断为“附近有障碍物”。另外,当接近传感器测量到与地板之间的接近程度变为“Far”时,即判断为“即将从桌子边缘掉落”。此时,电机将会反转,以避免掉落(避让障碍物)。否则将继续前进。
    示例程序“M5Stack_Near_Dist_Motor.ino”如下:
    #include <M5Stack.h>
  • #include <Wire.h>
  • #include <RPR-0521RS.h>
  • RPR0521RS rpr0521rs;
  • #define TRIG 2
  • #define ECHO 5
  • int times;
  • int distance;
  • #include "Grove_I2C_Motor_Driver.h"
  • #define I2C_ADDRESS 0x0f
  • void setup() {
  • Serial.begin(115200);
  • while (!Serial);
  • byte rc;
  • rc = rpr0521rs.init();
  • pinMode(TRIG, OUTPUT);
  • pinMode(ECHO, INPUT);
  • Motor.begin(I2C_ADDRESS);
  • Wire.begin(21,22);
  • M5.begin();
  • M5.Lcd.setTextSize(4);
  • M5.Lcd.setCursor(10,0);
  • M5.lcd.print("M5 Near Dist Motor");
  • }
  • void loop() {
  • Wire.begin(21,22);
  • byte rc;
  • unsigned short ps_val;
  • float als_val;
  • byte near_far;
  • M5.lcd.clear();
  • M5.Lcd.setCursor(10,0);
  • M5.lcd.print("M5 Near Dist Motor");
  • M5.Lcd.setCursor(10,50);
  • rc = rpr0521rs.get_psalsval(&ps_val, &als_val);
  • if (rc == 0) {
  • Serial.print(F("RPR-0521RS (Proximity) = "));
  • Serial.print(ps_val);
  • Serial.print(F(" [count]"));
  • near_far = rpr0521rs.check_near_far(ps_val);
  • if (near_far == RPR0521RS_NEAR_VAL) {
  • Serial.println(F(" Near"));
  • M5.lcd.print("Near!");
  • } else {
  • Serial.println(F(" Far"));
  • M5.lcd.print("Far!");
  • }
  • }
  • // 发射超声波
  • digitalWrite(TRIG, HIGH);
  • delayMicroseconds(10);
  • digitalWrite(TRIG, LOW);
  • // 接收超声波
  • times = pulseIn(ECHO, HIGH);
  • distance = (int)(times * 0.017);
  • // 在显示器上显示
  • Serial.println(distance);
  • M5.Lcd.setCursor(10, 100);
  • M5.Lcd.print(distance);
  • M5.Lcd.setCursor(10,150);
  • // 当距离小于6时,如果接近程度继续变大,将使电机反转
  • if ( ((distance > 0) and (distance < 6)) or (near_far != RPR0521RS_NEAR_VAL) ) {
  • Motor.speed(MOTOR1, 100);
  • Motor.speed(MOTOR2, -100);
  • delay(800);
  • Motor.speed(MOTOR1, 100);
  • Motor.speed(MOTOR2, 100);
  • M5.lcd.print("Danger!");
  • delay(800);
  • } else {
  • // 如果没有障碍物就继续前进
  • Motor.speed(MOTOR1, -100);
  • Motor.speed(MOTOR2, 100);
  • M5.lcd.print("Forward!");
  • }
  • delay(300);
  • }
  • 复制代码
    程序准备好后,将其导入M5Stack。当您接通电源后,车轮将开始转动并向前行驶。请您确认一下,在遥控车遇到障碍物或要从桌子上掉落下来时,电机能否反转。
    arduino-m5stack-remote-control-car-03-14.jpg

    4. 总结
    在这个连载系列中,将为您介绍使用M5Stack进行遥控并实现自动驾驶小车的制作过程。在第三部分中,我们使用距离传感器来确认了前方物体,并使用接近传感器来确认了接近情况。
    我们还让这两种传感器和电机的旋转联动实现了自动驾驶。怎么样,效果还不错吧?由于还需要微调与障碍物之间的距离设置、反转时间等参数,因此您需要一边试用一边调整数值。
    M5Stack仍然有可以使用的引脚,因此您还可以尝试添加其他传感器来实现相应的功能,这可能会更有趣。比如,可以让它在自由行驶的同时测量室内温度和空气清洁度。
    在下一部分中,我们将介绍通过智能手机等从外部来控制遥控车的方法,敬请期待!

    (剧终篇)

    实现M5Stack与智能手机联动控制

    本系列连载将为您介绍使用小型Arduino兼容设备M5Stack制作遥控车的过程。在前面的部分中,我们已经用电机驱动器让遥控车能够前后左右移动,并通过传感器实现了自动驾驶。在本文中,也就是本系列的最后一部分中,我们将实现从外部遥控这辆遥控车。这次,我们将会导入一种能够通过智能手机操作5Stack的名为“Blynk”的机制。
    arduino-m5stack-remote-control-car-04-01.jpg
    M5Stack和智能手机联动的遥控车

    本部分的流程

    • 导入智能手机应用程序“Blynk”
    • 在Wi-Fi环境下通过智能手机操作M5Stack
    • 添加操纵电机用的操纵杆
    • 总结

    本部分所需部件M5Stack Core
    搭载了ESP32的Arduino兼容设备
    arduino-m5stack-remote-control-car-02-e1608133416785.jpg
    Grove I2C电机驱动器
    与Grove引脚连接即可使用的电机驱动器
    arduino-m5stack-remote-control-car-07_01.jpg
    ROHM的照度、接近一体型传感器 (RPR-0521RS)
    通过发射红外光来测量光强和接近程度。
    arduino-m5stack-remote-control-car-04-02.jpg
    超声波距离传感器 (HC-SR04)
    通过发射超声波来测量距离的模块
    arduino-m5stack-remote-control-car-03-04.jpg
    小型电机、车轮等
    arduino-m5stack-remote-control-car-08.jpg
    9V电池和电池盒
    arduino-m5stack-remote-control-car-02-02.jpg

    1. 导入智能手机应用程序“Blynk”
    我们需要导入名为“Blynk”的应用程序,以便通过智能手机操作用M5Stack制作而成的遥控车。在iOS或Android系统中搜索并安装Blynk应用程序。
    arduino-m5stack-remote-control-car-04-03-e1610102039960.png
    下载后,打开应用程序,会被要求创建一个帐户,请用您的邮箱等注册并登录。在第一个画面中,会出现“New Project”,需要给它命名并创建新项目。
    arduino-m5stack-remote-control-car-04-04.png
    在详细设置中,Device请选择“ESP32 Dev Board”,Connection请选择“WiFi”。然后,将会出现一个空白的项目画面,这就表明智能手机的准备工作完成了。
    arduino-m5stack-remote-control-car-04-05.png
    接下来,在要编程的Arduino IDE中,获取Arduino用的Blynk库。从下面的链接下载库并通过图中菜单添加zip文件。
    Blynk的Github页面 https://github.com/blynkkk/blynk-library
    arduino-m5stack-remote-control-car-04-06.jpg
    现在,已经做好在手机和Arduino IDE上使用Blynk的准备了。

    2. 在Wi-Fi环境下通过智能手机操作M5Stack
    我们已经将M5Stack与智能手机关联起来了,下面需要在画面上添加一个操作功能。
    当点击Blynk应用程序的画面时,会出现可以从右侧添加的Widget(功能),我们先添加“Button”。
    arduino-m5stack-remote-control-car-04-07.png
    在这里,我希望在按下该按钮时能够从M5Stack的扬声器发出嘟嘟声。在按钮的详细设置画面上,OUTPUT选择“Virtual”并指定V1。稍后将在M5Stack上指定V1,所以请记住这里的设置。您还可以选择仅在按下时发送信号的“PUSH”,并设置标签名称(Beep)等。
    arduino-m5stack-remote-control-car-04-08.png
    arduino-m5stack-remote-control-car-04-09.png
    左:未按下按钮的状态 右:按下按钮的状态

    最后,要获取一个与M5Stack连接的令牌。令牌可以在项目创建时通过e-mail发送,也可通过打开“Project Settings”复制下方的“AUTH TOKEN”。稍后将通过Arduino IDE指定。
    arduino-m5stack-remote-control-car-04-10.png

    现在,需要使用Arduino IDE进行编程了。首先,拷贝一个名为“Speaker”的草图示例作为M5Stack的示例。
    在该示例中添加以下第3〜9、13〜22、28〜29、36行的内容。在草图的xxxx部分添加前面复制的AUTH TOKEN。yyyy和zzzz是您Wifi环境的用户名和密码。此外,当按下V1按钮时,要能听到嘟嘟声。
    [M5Stack_Speaker_Blynk.ino]
  • #include <M5Stack.h>
  • #include <WiFi.h>
  • #include <WiFiClient.h>
  • #include <BlynkSimpleEsp32.h>
  • char auth[] = "xxxx”; //输入Blynk应用程序的YourAuthToken
  • char ssid[] = "yyyy"; //输入Wifi的ID和密码
  • char pass[] = "zzzz";
  • #define NOTE_DH2 661
  • int BEEP_Flag = 0;
  • BLYNK_WRITE(V1)
  • {
  •   BEEP_Flag = param.asInt();
  •   if(BEEP_Flag == 1){
  •     M5.Lcd.printf("Blynk wasPressed \r\n");
  •     M5.Speaker.beep(); //beep
  •   }
  •   M5.update();
  • }
  • void setup() {
  •   // Initialize the M5Stack object
  •   M5.begin();
  •   
  •   M5.Lcd.setTextSize(3);
  •   Blynk.begin(auth, ssid, pass);
  •    
  •   M5.Power.begin();
  •   M5.Lcd.printf("M5Stack Speaker:\r\n");
  • }
  • void loop() {
  •   Blynk.run();
  •   
  •   if(M5.BtnA.wasPressed()) {
  •     M5.Lcd.printf("A wasPressed \r\n");
  •     M5.Speaker.beep(); //beep
  •   }
  •   if(M5.BtnB.wasPressed())
  •   {
  •     M5.Lcd.printf("B wasPressed \r\n");
  •     M5.Speaker.tone(NOTE_DH2, 200); //frequency 3000, with a duration of 200ms
  •   }
  •   M5.update();
  • }
  • 复制代码
    运行此程序后,当Wi-Fi连接完成时,在串口监视器上会显示下列画面。在与智能手机相同的Wifi环境下,将会从Blynk连接M5Stack。当按下屏幕上的按钮时,应该会发出嘟嘟声。
    arduino-m5stack-remote-control-car-04-11.jpg

    3. 添加操纵电机用的操纵杆
    现在,我们需要添加一个通过智能手机驱动M5Stack的电机的功能。有现成的“Joystick”(操纵杆)可以用来控制行进方向和旋转速度,我们可以在手机画面上对其进行设置。Joystick的输出为V0,将其输出范围设置为-50到50。
    arduino-m5stack-remote-control-car-04-12.png
    最后,需要编写通过Blynk控制M5Stack的程序。将Blynk的描述添加到在上一部分中创建的传感器与电机联动的程序“M5Stack_Near_Dist_Motor.ino”中。下面的第15〜31、96、116行是前面的扬声器所用的部分。在第33〜93、111〜112、123〜126、162〜163行添加了根据Joystick控制电机的描述。
    [M5Stack_Near_Dist_Motor_Blynk.ino]
  • #include <M5Stack.h>
  • #include <Wire.h>
  • #include <RPR-0521RS.h>
  • RPR0521RS rpr0521rs;
  • #define TRIG 2
  • #define ECHO 5
  • int times;
  • int distance;
  • #include "Grove_I2C_Motor_Driver.h"
  • #define I2C_ADDRESS 0x0f
  • #include <WiFi.h>
  • #include <WiFiClient.h>
  • #include <BlynkSimpleEsp32.h>
  • char auth[] = "xxxx”; //输入Blynk应用程序的YourAuthToken
  • char ssid[] = "yyyy"; //输入Wifi的ID和密码
  • char pass[] = "zzzz";
  • int BEEP_Flag = 0;
  • BLYNK_WRITE(V1)
  • {
  •   BEEP_Flag = param.asInt();
  •   if(BEEP_Flag == 1){
  •     M5.Lcd.printf("Blynk wasPressed \r\n");
  •     M5.Speaker.beep(); //beep
  •   }
  •   M5.update();
  • }
  • long Speed;
  • long Speed1, Speed2;
  • long SpeedL, SpeedR;
  • //接收操纵杆的数据
  • BLYNK_WRITE(V0) {
  •   M5.Lcd.setCursor(10,180);
  •   long x = param[0].asInt();
  •   long y = param[1].asInt();
  •   Speed = sqrt(x*x+y*y);
  •   if(Speed > 50){
  •     Speed = 50;
  •   }
  •   SpeedR = Speed - Speed1;
  •   SpeedL = Speed - Speed2;
  •   if(y >= 0){
  •     if(x >= 0){
  •       Speed1 = abs(x);
  •       Speed2 = 0;
  •     }else{
  •       Speed1 = 0;
  •       Speed2 = abs(x);
  •     }
  •     Serial.print("  R:");
  •     Serial.print(SpeedR);
  •     Serial.print("  L:");
  •     Serial.println(SpeedL);
  •    
  •     Motor.speed(MOTOR1, -SpeedR);
  •     Motor.speed(MOTOR2, SpeedL);
  •    
  •     M5.Lcd.print("Fwd!");
  •    
  •     delay(500);
  •     Motor.speed(MOTOR1, 0);
  •     Motor.speed(MOTOR2, 0);
  •    
  •   }else{
  •     if(x >= 0){
  •       Speed1 = abs(x);
  •       Speed2 = 0;
  •     }else{
  •       Speed1 = 0;
  •       Speed2 = abs(x);
  •     }
  •     Serial.print("  -R:");
  •     Serial.print(SpeedR);
  •     Serial.print("  -L:");
  •     Serial.println(SpeedL);
  •    
  •     Motor.speed(MOTOR1, SpeedR);
  •     Motor.speed(MOTOR2, -SpeedL);
  •    
  •     M5.Lcd.print("Back!");
  •     delay(500);
  •     Motor.speed(MOTOR1, 0);
  •     Motor.speed(MOTOR2, 0);
  •   }
  • }
  • void setup() {
  •   Blynk.begin(auth, ssid, pass);
  •   Serial.begin(115200);
  •   while (!Serial);
  •   
  •   byte rc;  
  •   rc = rpr0521rs.init();
  •   
  •   pinMode(TRIG, OUTPUT);
  •   pinMode(ECHO, INPUT);
  •   Motor.begin(I2C_ADDRESS);
  •   M5.begin();
  •   M5.Lcd.setTextSize(4);
  •   Wire.begin(21,22);
  •   M5.Lcd.setCursor(10,0);
  •   M5.Lcd.println(ssid);
  • }
  • void loop() {  
  •   Blynk.run();
  •   
  •   byte rc;
  •   unsigned short ps_val;
  •   float als_val;
  •   byte near_far;
  •   M5.lcd.clear();
  •   M5.Lcd.setCursor(10,0);
  •   M5.lcd.print("M5 Blynk");
  •   M5.Lcd.setCursor(10,50);
  •   
  •   rc = rpr0521rs.get_psalsval(&ps_val, &als_val);
  •   if (rc == 0) {
  •     Serial.print(F("RPR-0521RS (Proximity)     = "));
  •     Serial.print(ps_val);
  •     Serial.print(F(" [count]"));
  •     near_far = rpr0521rs.check_near_far(ps_val);
  •     if (near_far == RPR0521RS_NEAR_VAL) {
  •       Serial.println(F(" Near"));
  •       M5.lcd.print("Near!");
  •     } else {
  •       Serial.println(F(" Far"));
  •       M5.lcd.print("Far!");  
  •     }
  •   }
  •   digitalWrite(TRIG, HIGH);  // 发射超声波
  •   delayMicroseconds(10);
  •   digitalWrite(TRIG, LOW);
  •   times = pulseIn(ECHO, HIGH);  // 接收超声波
  •   distance = (int)(times * 0.017);
  •   Serial.println(distance);  // 在显示器上显示
  •   M5.Lcd.setCursor(10, 100);
  •   M5.Lcd.print(distance);
  •   if ( ((distance > 0) and (distance < 6)) or (near_far != RPR0521RS_NEAR_VAL) ) {
  •     Motor.speed(MOTOR1, 50);
  •     Motor.speed(MOTOR2, -50);
  •     delay(800);
  •     Motor.speed(MOTOR1, 50);
  •     Motor.speed(MOTOR2, 50);
  •     M5.Lcd.setCursor(10,150);
  •     M5.lcd.print("Danger!");
  •     delay(800);
  •   } else {
  •     Motor.speed(MOTOR1, 0);
  •     Motor.speed(MOTOR2, 0);
  •   }
  •   delay(300);
  • }
  • 复制代码
    下面我们来尝试操纵遥控车。和前面一样,进入相同的Wi-Fi环境,连接M5Stack。当您前后左右移动操纵杆时,M5Stack是否跟着做出了相应的移动?当遥控车接近墙壁或者要从桌子上掉落下来时,和上次一样,它会避开。
    arduino-m5stack-remote-control-car-04-13.jpg

    4. 总结
    在本系列连载中,为您介绍了使用M5Stack自动驾驶遥控车的制作过程。
    使用可以从智能手机连接M5Stack的应用程序Blynk,还能轻松添加通过智能手机操纵遥控车的功能。我们成功地使按钮与M5Stack扬声器联动起来,并实现了通过操纵杆的控制而前后左右移动。
    Blynk有各种各样的Widget,还可以根据M5Stack的传感器等来添加更多不同的功能,这样会更有趣。比如,您还可以考虑怎样将物体的接近程度以及温湿度传感器测量到的值等在显示器上显示出来。
    盼望您大胆尝试,让您的创意变成现实!感谢您阅读本系列文章!

    来源:/techclass.rohm