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

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

 

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

 

大家好,我是吉田!

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

arduino-m5stack-remote-control-car-04-01

M5Stack和智能手机联动的遥控车

 

本部分的流程

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

 

本部分所需部件

M5Stack Core

搭载了ESP32的Arduino兼容设备

arduino-m5stack-remote-control-car-02

 

Grove I2C电机驱动器

与Grove引脚连接即可使用的电机驱动器

arduino-m5stack-remote-control-car-07_01

 

ROHM的照度、接近一体型传感器 (RPR-0521RS)

通过发射红外光来测量光强和接近程度。

arduino-m5stack-remote-control-car-04-02

 

超声波距离传感器 (HC-SR04)

通过发射超声波来测量距离的模块

arduino-m5stack-remote-control-car-03-04

 

小型电机、车轮

arduino-m5stack-remote-control-car-08

 

9V电池电池盒

arduino-m5stack-remote-control-car-02-02

 

1. 导入智能手机应用程序“Blynk”

我们需要导入名为“Blynk”的应用程序,以便通过智能手机操作用M5Stack制作而成的遥控车。在iOS或Android系统中搜索并安装Blynk应用程序。

arduino-m5stack-remote-control-car-04-03

 

下载后,打开应用程序,会被要求创建一个帐户,请用您的邮箱等注册并登录。在第一个画面中,会出现“New Project”,需要给它命名并创建新项目。

arduino-m5stack-remote-control-car-04-04

 

在详细设置中,Device请选择“ESP32 Dev Board”,Connection请选择“WiFi”。然后,将会出现一个空白的项目画面,这就表明智能手机的准备工作完成了。

arduino-m5stack-remote-control-car-04-05

 

接下来,在要编程的Arduino IDE中,获取Arduino用的Blynk库。从下面的链接下载库并通过图中菜单添加zip文件。
Blynk的Github页面

arduino-m5stack-remote-control-car-04-06

 

现在,已经做好在手机和Arduino IDE上使用Blynk的准备了。

 

2. 在Wi-Fi环境下通过智能手机操作M5Stack

我们已经将M5Stack与智能手机关联起来了,下面需要在画面上添加一个操作功能。
当点击Blynk应用程序的画面时,会出现可以从右侧添加的Widget(功能),我们先添加“Button”。

arduino-m5stack-remote-control-car-04-07

 

在这里,我希望在按下该按钮时能够从M5Stack的扬声器发出嘟嘟声。在按钮的详细设置画面上,OUTPUT选择“Virtual”并指定V1。稍后将在M5Stack上指定V1,所以请记住这里的设置。您还可以选择仅在按下时发送信号的“PUSH”,并设置标签名称(Beep)等。

arduino-m5stack-remote-control-car-04-08

arduino-m5stack-remote-control-car-04-09

左:未按下按钮的状态 右:按下按钮的状态

 

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

arduino-m5stack-remote-control-car-04-10

 

现在,需要使用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

 

3. 添加操纵电机用的操纵杆

现在,我们需要添加一个通过智能手机驱动M5Stack的电机的功能。有现成的“Joystick”(操纵杆)可以用来控制行进方向和旋转速度,我们可以在手机画面上对其进行设置。Joystick的输出为V0,将其输出范围设置为-50到50。

arduino-m5stack-remote-control-car-04-12

 

最后,需要编写通过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

 

实际行驶的视频如下。您可以根据电机的连接方法来调整旋转方向、转数、转速等。

 

4. 总结

在本系列连载中,为您介绍了使用M5Stack自动驾驶遥控车的制作过程。

使用可以从智能手机连接M5Stack的应用程序Blynk,还能轻松添加通过智能手机操纵遥控车的功能。我们成功地使按钮与M5Stack扬声器联动起来,并实现了通过操纵杆的控制而前后左右移动。

Blynk有各种各样的Widget,还可以根据M5Stack的传感器等来添加更多不同的功能,这样会更有趣。比如,您还可以考虑怎样将物体的接近程度以及温湿度传感器测量到的值等在显示器上显示出来。

盼望您大胆尝试,让您的创意变成现实!感谢您阅读本系列文章!

 

 

吉田 显一(Yoshiken)

在普通公司工作的上班族,非常喜欢创作的周末创客,出版了电子书MESHBOOK,平时也写写博客。

http://blog.ktrips.net

相关文章

  1. arduino-h02_14

    用Arduino制作的太阳能电池板供电数字养殖箱【后篇】

  2. 用Spresense扩大电子制作的广度!【第5篇】

  3. 用Spresense扩大电子制作的广度!【第4篇】

  4. 用Spresense扩大电子制作的广度!【第3篇】

  5. spresense_2

    用Spresense扩大电子制作的广度!【第2篇】

  6. title_image

    用Spresense扩大电子制作的广度!【第1篇】

  7. learning-electronics-03-00

    超越LED闪烁!更多了解电子制作“N讲”【第3篇】

  8. learning-electronics-02-08

    超越LED闪烁!更多了解电子制作“N讲”【第2篇】

  9. learning-electronics-01-09

    超越LED闪烁!更多了解电子制作“N讲”【第1篇】

TECH INFO

  • Sugiken老师的电机驱动器课堂
  • 重点必看
  • 技术分享
  • Arduino入门指南

基础知识

  • Si功率元器件
  • IGBT功率元器件
  • 热设计
  • 电路仿真
  • 开关噪声-EMC
  • AC/DC
  • DC/DC
  • 电机
  • 传递函数

工程技巧


Sugiken老师的电机驱动器课堂

PICK UP

PAGE TOP