零知四轮小车高级版(零知mini主控)教程-程序控制电机开跑

本系列教程讲解零知小车套件以零知迷你板为主控,使用零知开源平台进行智能小车开发。
使用的硬件:-零知智能小车套件(点击购买)

实现的功能:红外循迹、超声波避障、直线运行、手机蓝牙控制、灭火等基本功能。

扩展:可以在小车上加入其它传感器模块进行扩展,比如加入摄像头模块进行监控、加入更多超声波模块实现自动跟随...

高级版系列教程将使用多文件编程的方式来编写程序,教程主要包含以下几个部分:

零知四轮小车高级版(零知mini主控)系列教程-小车组装

零知四轮小车高级版(零知mini主控)系列教程-程序控制电机开跑

零知四轮小车高级版(零知mini主控)系列教程-加入蓝牙实现手机控制

零知四轮小车高级版(零知mini主控)系列教程-红外循迹走S弯

零知四轮小车高级版(零知mini主控)系列教程-超声波自动避障

零知四轮小车高级版(零知mini主控)系列教程-灭火小车

一、工具原料
(1)组装好的智能小车

二、电机驱动说明

这里使用电机驱动为DRV8833型号,我们需要根据它的逻辑表来驱动电机:


其完整的datasheet文件:http://www.ti.com/lit/ds/symlink/drv8833.pdf

三、程序代码
高级版教程将使用多文件编程的方式来编写代码,将电机的控制以及其它模块封装成多个类,部分内容如下:


				
/*
 * @文件: \motor.cpp
 * @作者:零知实验室
 * -^^- 零知开源,让电子制作变得更简单! -^^-
 * @时间: 2019-12-05 13:53:55
 * @说明: 
 */
#include "motor.h"
  
LZSmartCarMotor::LZSmartCarMotor(bool is2WD)
{
    if (is2WD)
    {
        _wheelNum = 2;
        pinMode(MotorIN1, OUTPUT);
        pinMode(MotorIN2, OUTPUT);
        pinMode(MotorIN3, OUTPUT);
        pinMode(MotorIN4, OUTPUT);
    }
    else
    {
        _wheelNum = 4;
        pinMode(MotorIN1, OUTPUT);
        pinMode(MotorIN2, OUTPUT);
        pinMode(MotorIN3, OUTPUT);
        pinMode(MotorIN4, OUTPUT);
  
        pinMode(MotorIN5, OUTPUT);
        pinMode(MotorIN6, OUTPUT);
        pinMode(MotorIN7, OUTPUT);
        pinMode(MotorIN8, OUTPUT);
    }
}
  
void LZSmartCarMotor::speedGo(byte number, int speed, bool reverse)
{
    if (speed < 0)
    {
        speed = 0;
    }
    if (speed > 255)
    {
        speed = 255;
    }
    speed = 255 - speed;
  
    if(number > _wheelNum){
        Serial.println("轮子个数是否正确?");
        return;
    }
  
    if (number == 1)
    {
        if (reverse)
        {
            analogWrite(MotorIN1, speed);
            analogWrite(MotorIN2, 255);
        }
        else
        {
  
            analogWrite(MotorIN1, 255);
            analogWrite(MotorIN2, speed);
        }
    }
  
    if (number == 2)
    {
        if (reverse)
        {
            analogWrite(MotorIN3, speed);
            analogWrite(MotorIN4, 255);
        }
        else
        {
            analogWrite(MotorIN3, 255);
            analogWrite(MotorIN4, speed);
        }
    }
  
    if (number == 3)
    {
  
        if (reverse)
        {
            analogWrite(MotorIN5, 255);
  
            analogWrite(MotorIN6, speed);
        }
        else
        {
  
            analogWrite(MotorIN5, speed);
  
            analogWrite(MotorIN6, 255);
        }
    }
    if (number == 4)
    {
  
        if (reverse)
        {
  
            analogWrite(MotorIN7, speed);
  
            analogWrite(MotorIN8, 255);
        }
        else
        {
  
            analogWrite(MotorIN7, 255);
  
            analogWrite(MotorIN8, speed);
        }
    }
}
  
void LZSmartCarMotor::stop()
{
  
    analogWrite(MotorIN1, 255);
    analogWrite(MotorIN2, 255);
    analogWrite(MotorIN3, 255);
    analogWrite(MotorIN4, 255);
  
    analogWrite(MotorIN5, 255);
    analogWrite(MotorIN6, 255);
    analogWrite(MotorIN7, 255);
    analogWrite(MotorIN8, 255);
}
  
void LZSmartCarMotor::goWithDirec(carDirec cmd)
{
    switch(cmd){
                case carForward:
                speedGo(1,MotorSpeedNormal);
                speedGo(2,MotorSpeedNormal);
                speedGo(3,MotorSpeedNormal);
                speedGo(4,MotorSpeedNormal);
                break;
                case carForwardSlow:
                speedGo(1,MotorSpeedSlow);
                speedGo(2,MotorSpeedSlow);
                speedGo(3,MotorSpeedSlow);
                speedGo(4,MotorSpeedSlow);
                break;
                case carBack:
                speedGo(1,MotorSpeedNormal,true);
                speedGo(2,MotorSpeedNormal,true);
                speedGo(3,MotorSpeedNormal,true);
                speedGo(4,MotorSpeedNormal,true);
                break;
                case carLeft:
                speedGo(1,MotorSpeedRotate);
                speedGo(2,MotorSpeedFast);
                speedGo(3,MotorSpeedRotate);
                speedGo(4,MotorSpeedFast);
                break;
                case carRight:
                speedGo(1,MotorSpeedFast);
                speedGo(2,MotorSpeedRotate);
                speedGo(3,MotorSpeedFast);
                speedGo(4,MotorSpeedRotate);
                break;
                case carForLeft:
                speedGo(1,MotorSpeedRotate);
                speedGo(2,MotorSpeedNormal);
                speedGo(3,MotorSpeedRotate);
                speedGo(4,MotorSpeedNormal);
                break;
                case carForRight:
                speedGo(1,MotorSpeedNormal);
                speedGo(2,MotorSpeedRotate);
                speedGo(3,MotorSpeedNormal);
                speedGo(4,MotorSpeedRotate);
                break;
                  case carLeftFast:
        speedGo(1,MotorSpeedTrace);
        speedGo(2,MotorSpeedRoFast);
        speedGo(3,MotorSpeedTrace);
        speedGo(4,MotorSpeedRoFast);
        break;
        case carLeftSlow:
        speedGo(1,MotorSpeedTrace);
        speedGo(2,MotorSpeedRoSlow);
        speedGo(3,MotorSpeedTrace);
        speedGo(4,MotorSpeedRoSlow);
        break;
        case carRightFast:
        speedGo(1,MotorSpeedRoFast);
        speedGo(2,MotorSpeedTrace);
        speedGo(3,MotorSpeedRoFast);
        speedGo(4,MotorSpeedTrace);
        break;
        case carRightSlow:
        speedGo(1,MotorSpeedRoSlow);
        speedGo(2,MotorSpeedTrace);
        speedGo(3,MotorSpeedRoSlow);
        speedGo(4,MotorSpeedTrace);
        break;
                case carStop:
                stop();
                break;
                default:
                stop();
                break;
        }
}
  
LZSmartCarMotor::~LZSmartCarMotor()
{
}
				

完整工程可在下面下载


电机的控制都封装起来了,所以四轮小车的程序和是差不多的,主程序代码如下:


				
/**********************************************************
*    文件: .ino      by 零知实验室([url=http://www.lingzhilab.com]www.lingzhilab.com[/url])
*    -^^- 零知开源,让电子制作变得更简单! -^^-
*    时间: 2019/12/11 10:33
*    说明: 
************************************************************/
#include "pinsdefine.h"
#include "motor.h"
  
LZSmartCarMotor myMotor(false);
  
// 复位或上电后运行一次:
void setup() {
    //在这里加入初始化相关代码,只运行一次:
        Serial.begin(9600);
        Serial.println("开车啦...");
          
        myMotor.stop();
  
}
  
//一直循环执行:
void loop() {
    // 在这里加入主要程序代码,重复执行:
         if(Serial.available()){
        char cmd = Serial.read();
                Serial.print("cmd:");Serial.write(cmd);Serial.println();
        if(cmd == '1'){
            myMotor.goWithDirec(carForward);
        }
        else if(cmd == '2'){
            myMotor.goWithDirec(carForLeft);
        }
        else if(cmd == '3'){
            myMotor.goWithDirec(carForRight);
        }
        else if(cmd == '4'){
            myMotor.goWithDirec(carBack);
        }
        else{
            myMotor.goWithDirec(carStop);
        }
    }
  
}			
				

完整工程:  lzsmartcar_v2.zip 

将以上代码验证上传至小车,然后我们在串口调试窗口发送不同的命令,看小车是否按照我们预期的动作运转,如果有冲突是很正常的,因为有时候安装电机的方向不一样,这时候我们就可以根据实际情况修改上述代码,使之和我们安装好的小车运行情况一致。