Arduino智能小车实践学习报告

参与人员:

20135316 王剑桥

20135312 吴汉彦

20135319 朱锂

一、 背景了解:

  1. 单片机:将中央处理单元CPU(进行运算、控制)、随机存储器RAM(数据存储)、存储器ROM(程序存储)、输入/输出设备I/O(串行口、并行输出口等)全部做到一块集成电路芯片中,即单片(单芯片)机。一些单片机中除了上述部份外,还集成了其它部份如模拟量/数字量转换(A/D)和数字量/模拟量转换(D/A)等。
  2. Arduino:这是一个能够用来感应和控制现实物理世界的一套工具。 它由一个基于单片机并且开放源码的硬件平台,和一套为Arduino板编写程序 的开发环境组成。
    Arduino编程语言可以通过C++库进行扩展,如果有人想去了解技术上的细节,可以跳过Arduino语言而直接使用AVR C 编程语言(因为Arduino语言实际上是基于AVR C的)。

性能

Digital I/O 数字输入/输出端口0—13。

Analog I/O 模拟输入/输出端口0-5。

支持ICSP下载,支持TX/RX。

输入电压:USB接口供电或者5V-12V外部电源供电。

输出电压:支持3.3V级5V DC输出。

处理器:使用Atmel Atmega168 328处理器

二、 编程知识总结

1、基础C语言

(1)关键字

  • if
  • if...else
  • for
  • switch case
  • while
  • do... while
  • break
  • continue
  • return
  • goto

(2)语法符号

  • ;
  • {}
  • //
  • /* */

(3)运算符

  • =
  • +
  • -
  • *
  • /
  • %
  • ==
  • !=
  • <
  • >
  • <=
  • >=
  • &&
  • ||
  • !
  • ++
  • --
  • +=
  • -=
  • *=
  • /=

(4)数据类型

  • boolean 布尔类型
  • char
  • byte 字节类型
  • int
  • unsigned int
  • long
  • unsigned long
  • float
  • double
  • string
  • array
  • void

(5)数据类型转换

  • char()
  • byte()
  • int()
  • long()
  • float()

(6)常量

HIGH | LOW 表示数字IO口的电平,HIGH 表示高电平(1),LOW 表示低电平(0)。

INPUT | OUTPUT 表示数字IO口的方向,INPUT 表示输入(高阻态),OUTPUT 表示输出(AVR能提供5V电压 40mA电流)。

true | false true 表示真(1),false表示假(0)。

2、Arduino 语言

(1)结构

void setup() 初始化变量,管脚模式,调用库函数等

void loop() 连续执行函数内的语句

(2)功能 数字 I/O

pinMode(pin, mode) 数字IO口输入输出模式定义函数,pin表示为0~13, mode表示为INPUT或OUTPUT。

digitalWrite(pin, value) 数字IO口输出电平定义函数,pin表示为0~13,value表示为HIGH或LOW。比如定义HIGH可以驱动LED。

int digitalRead(pin) 数字IO口读输入电平函数,pin表示为0~13,value表示为HIGH或LOW。比如可以读数字传感器。

模拟 I/O
int analogRead(pin) 模拟IO口读函数,pin表示为0~5(Arduino Diecimila为0~5,Arduino nano为0~7)。比如可以读模拟传感器(10位AD,0~5V表示为0~1023)。

analogWrite(pin, value) - PWM 数字IO口PWM输出函数,Arduino数字IO口标注了PWM的IO口可使用该函数,pin表示3, 5, 6, 9, 10, 11,value表示为0~255。比如可用于电机PWM调速或音乐播放。

扩展 I/O

shiftOut(dataPin, clockPin, bitOrder, value) SPI外部IO扩展函数,通常使用带SPI接口的74HC595做8个IO扩展,dataPin为数据口,clockPin为时钟口,bitOrder为数据传输方向(MSBFIRST高位在前,LSBFIRST低位在前),value表示所要传送的数据(0~255),另外还需要一个IO口做74HC595的使能控制。

unsigned long pulseIn(pin, value) 脉冲长度记录函数,返回时间参数(us),pin表示为0~13,value为HIGH或LOW。比如value为HIGH,那么当pin输入为高电平时,开始计时,当pin输入为低电平时,停止计时,然后返回该时间。

时间函数

unsigned long millis() 返回时间函数(单位ms),该函数是指,当程序运行就开始计时并返回记录的参数,该参数溢出大概需要50天时间。

delay(ms) 延时函数(单位ms)。

delayMicroseconds(us) 延时函数(单位us)。

(3)数学函数 min(x, y) 求最小值

max(x, y) 求最大值

abs(x) 计算绝对值

constrain(x, a, b) 约束函数,下限a,上限b,x必须在ab之间才能返回。

map(value, fromLow, fromHigh, toLow, toHigh) 约束函数,value必须在fromLow与toLow之间和fromHigh与toHigh之间。

pow(base, exponent) 开方函数,base的exponent次方。

sq(x) 平方

sqrt(x) 开根号

(4)三角函数

sin(rad)

cos(rad)

tan(rad)

(5)随机数函数

randomSeed(seed) 随机数端口定义函数,seed表示读模拟口analogRead(pin)函数 。

long random(max) 随机数函数,返回数据大于等于0,小于max。

long random(min, max) 随机数函数,返回数据大于等于min,小于max。

(5)外部中断函数

attachInterrupt(interrupt, , mode) 外部中断只能用到数字IO口2和3,interrupt表示中断口初始0或1,表示一个功能函数,mode:LOW低电平中断,CHANGE有变化就中断,RISING上升沿中断,FALLING 下降沿中断。

detachInterrupt(interrupt) 中断开关,interrupt=1 开,interrupt=0 关。

(6)中断使能函数

interrupts() 使能中断

noInterrupts() 禁止中断

(7)串口收发函数

Serial.begin(speed) 串口定义波特率函数,speed表示波特率,如9600,19200等。

int Serial.available() 判断缓冲器状态。

int Serial.read() 读串口并返回收到参数。

Serial.flush() 清空缓冲器。

Serial.print(data) 串口输出数据。

Serial.println(data) 串口输出数据并带回车符。

3、Arduino语言库文件

官方库文件

EEPROM - EEPROM读写程序库

Ethernet - 以太网控制器程序库

LiquidCrystal - LCD控制程序库

Servo - 舵机控制程序库

SoftwareSerial - 任何数字IO口模拟串口程序库

Stepper - 步进电机控制程序库

Wire - TWI/I2C总线程序库

Matrix - LED矩阵控制程序库

Sprite - LED矩阵图象处理控制程序库

三、 实验所用主要代码

1、 黑线循迹

//#include <Servo.h> 
int Left_motor_back=8;     //左电机后退(IN1)
int Left_motor_go=9;     //左电机前进(IN2)
int Right_motor_go=10;    // 右电机前进(IN3)
int Right_motor_back=11;    // 右电机后退(IN4)

int key=7;//定义按键 数字7 接口
int beep=12;//定义蜂鸣器 数字12 接口

const int SensorRight = 3;   	//右循迹红外传感器(P3.2 OUT1)
const int SensorLeft = 4;     	//左循迹红外传感器(P3.3 OUT2)

int SL;    //左循迹红外传感器状态
int SR;    //右循迹红外传感器状态

void setup()
{
  //初始化电机驱动IO为输出方式
  pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
  pinMode(Left_motor_back,OUTPUT); // PIN 9 (PWM)
  pinMode(Right_motor_go,OUTPUT);// PIN 10 (PWM) 
  pinMode(Right_motor_back,OUTPUT);// PIN 11 (PWM)
  pinMode(key,INPUT);//定义按键接口为输入接口
  pinMode(beep,OUTPUT);
  pinMode(SensorRight, INPUT); //定义右循迹红外传感器为输入
  pinMode(SensorLeft, INPUT); //定义左循迹红外传感器为输入
}

//=======================智能小车的基本动作=========================
//void run(int time)     // 前进
void run()
{
  digitalWrite(Right_motor_go,HIGH);  // 右电机前进
  digitalWrite(Right_motor_back,LOW);     
  analogWrite(Right_motor_go,150);//PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_back,0);
  digitalWrite(Left_motor_go,HIGH);  // 左电机前进
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,150);//PWM比例0~255调速,左右轮差异略增减
  analogWrite(Left_motor_back,0);
  //delay(time * 100);   //执行时间,可以调整  
}

//void brake(int time)  //刹车,停车
void brake()
{
  digitalWrite(Right_motor_go,LOW);
  digitalWrite(Right_motor_back,LOW);
  digitalWrite(Left_motor_go,LOW);
  digitalWrite(Left_motor_back,LOW);
  //delay(time * 100);//执行时间,可以调整  
}

//void left(int time)         //左转(左轮不动,右轮前进)
void left()
{
  digitalWrite(Right_motor_go,HIGH);	// 右电机前进
  digitalWrite(Right_motor_back,LOW);
  analogWrite(Right_motor_go,150); 
  analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);   //左轮后退
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,0); 
  analogWrite(Left_motor_back,0);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整  
}

void spin_left(int time)         //左转(左轮后退,右轮前进)
{
  digitalWrite(Right_motor_go,HIGH);	// 右电机前进
  digitalWrite(Right_motor_back,LOW);
  analogWrite(Right_motor_go,200); 
  analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);   //左轮后退
  digitalWrite(Left_motor_back,HIGH);
  analogWrite(Left_motor_go,0); 
  analogWrite(Left_motor_back,200);//PWM比例0~255调速
  delay(time * 100);	//执行时间,可以调整  
}

//void right(int time)        //右转(右轮不动,左轮前进)
void right()
{
  digitalWrite(Right_motor_go,LOW);   //右电机后退
  digitalWrite(Right_motor_back,LOW);
  analogWrite(Right_motor_go,0); 
  analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,HIGH);//左电机前进
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,150); 
  analogWrite(Left_motor_back,0);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整  
}

void spin_right(int time)        //右转(右轮后退,左轮前进)
{
  digitalWrite(Right_motor_go,LOW);   //右电机后退
  digitalWrite(Right_motor_back,HIGH);
  analogWrite(Right_motor_go,0); 
  analogWrite(Right_motor_back,200);//PWM比例0~255调速
  digitalWrite(Left_motor_go,HIGH);//左电机前进
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,200); 
  analogWrite(Left_motor_back,0);//PWM比例0~255调速
  delay(time * 100);	//执行时间,可以调整    
}

//void back(int time)          //后退
void back(int time)
{
  digitalWrite(Right_motor_go,LOW);  //右轮后退
  digitalWrite(Right_motor_back,HIGH);
  analogWrite(Right_motor_go,0);
  analogWrite(Right_motor_back,150);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);  //左轮后退
  digitalWrite(Left_motor_back,HIGH);
  analogWrite(Left_motor_go,0);
  analogWrite(Left_motor_back,150);//PWM比例0~255调速
  delay(time * 100);     //执行时间,可以调整  
}
//==========================================================

void keysacn()//按键扫描
{
  int val;
  val=digitalRead(key);//读取数字7 口电平值赋给val
  while(!digitalRead(key))//当按键没被按下时,一直循环
  {
    val=digitalRead(key);//此句可省略,可让循环跑空
  }
  while(digitalRead(key))//当按键被按下时
  {
    delay(10);	//延时10ms
    val=digitalRead(key);//读取数字7 口电平值赋给val
    if(val==HIGH)  //第二次判断按键是否被按下
    {
      digitalWrite(beep,HIGH);		//蜂鸣器响
      while(!digitalRead(key))	//判断按键是否被松开
        digitalWrite(beep,LOW);		//蜂鸣器停止
    }
    else
      digitalWrite(beep,LOW);//蜂鸣器停止
  }
}

void loop()
{ 
  keysacn();//调用按键扫描函数  
  while(1)
  {
  //有信号为LOW  没有信号为HIGH
  SR = digitalRead(SensorRight);//有信号表明在白色区域,车子底板上L3亮;没信号表明压在黑线上,车子底板上L3灭
  SL = digitalRead(SensorLeft);//有信号表明在白色区域,车子底板上L2亮;没信号表明压在黑线上,车子底板上L2灭
  if (SL == LOW&&SR==LOW)
    run();   //调用前进函数
  else if (SL == HIGH & SR == LOW)// 左循迹红外传感器,检测到信号,车子向右偏离轨道,向左转 
    left();
  else if (SR == HIGH & SL == LOW) // 右循迹红外传感器,检测到信号,车子向左偏离轨道,向右转  
    right();
  else // 都是白色, 停止
  brake();
  }
}

2、 带后退调头避障

//#include <Servo.h> 
int Left_motor_back=8;     //左电机后退(IN1)
int Left_motor_go=9;     //左电机前进(IN2)

int Right_motor_go=10;    // 右电机前进(IN3)
int Right_motor_back=11;    // 右电机后退(IN4)

int key=7;//定义按键 数字7 接口
int beep=12;//定义蜂鸣器 数字12 接口

const int SensorRight = 3;   	//右循迹红外传感器(P3.2 OUT1)
const int SensorLeft = 4;     	//左循迹红外传感器(P3.3 OUT2)

const int SensorRight_2 = 6;   	//右红外传感器(P3.5 OUT4)
const int SensorLeft_2 = 5;     //左红外传感器(P3.4 OUT3)

int SL;    //左循迹红外传感器状态
int SR;    //右循迹红外传感器状态
int SL_2;    //左红外传感器状态
int SR_2;    //右红外传感器状态

void setup()
{
  //初始化电机驱动IO为输出方式
  pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
  pinMode(Left_motor_back,OUTPUT); // PIN 9 (PWM)
  pinMode(Right_motor_go,OUTPUT);// PIN 10 (PWM) 
  pinMode(Right_motor_back,OUTPUT);// PIN 11 (PWM)
  pinMode(key,INPUT);//定义按键接口为输入接口
  pinMode(beep,OUTPUT);
  pinMode(SensorRight, INPUT); //定义右循迹红外传感器为输入
  pinMode(SensorLeft, INPUT); //定义左循迹红外传感器为输入
  pinMode(SensorRight_2, INPUT); //定义右红外传感器为输入
  pinMode(SensorLeft_2, INPUT); //定义左红外传感器为输入
}
//=======================智能小车的基本动作=========================
//void run(int time)     // 前进
void run()     // 前进
{
  digitalWrite(Right_motor_go,HIGH);  // 右电机前进
  digitalWrite(Right_motor_back,LOW);     
  analogWrite(Right_motor_go,100);//PWM比例0~255调速,左右轮差异略增减
  analogWrite(Right_motor_back,0);
  digitalWrite(Left_motor_go,HIGH);  // 左电机前进
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,100);//PWM比例0~255调速,左右轮差异略增减
  analogWrite(Left_motor_back,0);
  //delay(time * 100);   //执行时间,可以调整  
}

void brake(int time)  //刹车,停车
{
  digitalWrite(Right_motor_go,LOW);
  digitalWrite(Right_motor_back,LOW);
  digitalWrite(Left_motor_go,LOW);
  digitalWrite(Left_motor_back,LOW);
  delay(time * 100);//执行时间,可以调整  
}

//void left(int time)         //左转(左轮不动,右轮前进)
void left()         //左转(左轮不动,右轮前进)
{
  digitalWrite(Right_motor_go,HIGH);	// 右电机前进
  digitalWrite(Right_motor_back,LOW);
  analogWrite(Right_motor_go,100); 
  analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);   //左轮后退
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,0); 
  analogWrite(Left_motor_back,0);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整  
}

void spin_left(int time)         //左转(左轮后退,右轮前进)
{
  digitalWrite(Right_motor_go,HIGH);	// 右电机前进
  digitalWrite(Right_motor_back,LOW);
  analogWrite(Right_motor_go,100); 
  analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);   //左轮后退
  digitalWrite(Left_motor_back,HIGH);
  analogWrite(Left_motor_go,0); 
  analogWrite(Left_motor_back,100);//PWM比例0~255调速
  delay(time * 100);	//执行时间,可以调整  
}

//void right(int time)
void right()        //右转(右轮不动,左轮前进)
{
  digitalWrite(Right_motor_go,LOW);   //右电机后退
  digitalWrite(Right_motor_back,LOW);
  analogWrite(Right_motor_go,0); 
  analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,HIGH);//左电机前进
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,100); 
  analogWrite(Left_motor_back,0);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整  
}

void spin_right(int time)        //右转(右轮后退,左轮前进)
{
  digitalWrite(Right_motor_go,LOW);   //右电机后退
  digitalWrite(Right_motor_back,HIGH);
  analogWrite(Right_motor_go,0); 
  analogWrite(Right_motor_back,100);//PWM比例0~255调速
  digitalWrite(Left_motor_go,HIGH);//左电机前进
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,100); 
  analogWrite(Left_motor_back,0);//PWM比例0~255调速
  delay(time * 100);	//执行时间,可以调整    
}

void back(int time)          //后退
{
  digitalWrite(Right_motor_go,LOW);  //右轮后退
  digitalWrite(Right_motor_back,HIGH);
  analogWrite(Right_motor_go,0);
  analogWrite(Right_motor_back,100);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);  //左轮后退
  digitalWrite(Left_motor_back,HIGH);
  analogWrite(Left_motor_go,0);
  analogWrite(Left_motor_back,150);//PWM比例0~255调速
  delay(time * 100);     //执行时间,可以调整  
}
//==========================================================

void keysacn()//按键扫描
{
  int val;
  val=digitalRead(key);//读取数字7 口电平值赋给val
  while(!digitalRead(key))//当按键没被按下时,一直循环
  {
    val=digitalRead(key);//此句可省略,可让循环跑空
  }
  while(digitalRead(key))//当按键被按下时
  {
    delay(10);	//延时10ms
    val=digitalRead(key);//读取数字7 口电平值赋给val
    if(val==HIGH)  //第二次判断按键是否被按下
    {
      digitalWrite(beep,HIGH);		//蜂鸣器响
      while(!digitalRead(key))	//判断按键是否被松开
        digitalWrite(beep,LOW);		//蜂鸣器停止
    }
    else
      digitalWrite(beep,LOW);//蜂鸣器停止
  }
}

void loop()
{
  keysacn();	   //调用按键扫描函数
  while(1)
  {
    //有信号为LOW  没有信号为HIGH
    SR_2 = digitalRead(SensorRight_2);
    SL_2 = digitalRead(SensorLeft_2);
    if (SL_2 == HIGH&&SR_2==HIGH)
      run();   //调用前进函数
    else if (SL_2 == HIGH & SR_2 == LOW)// 右边探测到有障碍物,有信号返回,向左转 
        left();
    else if (SR_2 == HIGH & SL_2 == LOW) //左边探测到有障碍物,有信号返回,向右转  
      right();
    else // 都是有障碍物, 后退
    {
      back(4.5);//后退
      spin_right(4.5);//有旋转,调整方向
    }
  }
}

3、红外遥控

#include <IRremote.h>//包含红外库
int RECV_PIN = A4;//端口声明
IRrecv irrecv(RECV_PIN);
decode_results results;//结构声明
int on = 0;//标志位
unsigned long last = millis();

long run_car = 0x00FF18E7;//按键2
long back_car = 0x00FF4AB5;//按键8
long left_car = 0x00FF10EF;//按键4
long right_car = 0x00FF5AA5;//按键6
long stop_car = 0x00FF38C7;//按键5
long left_turn = 0x00ff30CF;//按键1
long right_turn = 0x00FF7A85;//按键3
//==============================
int Left_motor_back=8;     //左电机后退(IN1)
int Left_motor_go=9;     //左电机前进(IN2)

int Right_motor_go=10;    // 右电机前进(IN3)
int Right_motor_back=11;    // 右电机后退(IN4)

void setup()
{
  //初始化电机驱动IO为输出方式
  pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
  pinMode(Left_motor_back,OUTPUT); // PIN 9 (PWM)
  pinMode(Right_motor_go,OUTPUT);// PIN 10 (PWM) 
  pinMode(Right_motor_back,OUTPUT);// PIN 11 (PWM)
  pinMode(13, OUTPUT);////端口模式,输出
  Serial.begin(9600);	//波特率9600
  irrecv.enableIRIn(); // Start the receiver
}
void run()     // 前进
{
  digitalWrite(Right_motor_go,HIGH);  // 右电机前进
  digitalWrite(Right_motor_back,LOW);     
  //analogWrite(Right_motor_go,200);//PWM比例0~255调速,左右轮差异略增减
  //analogWrite(Right_motor_back,0);
  digitalWrite(Left_motor_go,HIGH);  // 左电机前进
  digitalWrite(Left_motor_back,LOW);
  //analogWrite(Left_motor_go,200);//PWM比例0~255调速,左右轮差异略增减
  //analogWrite(Left_motor_back,0);
  //delay(time * 100);   //执行时间,可以调整  
}

void brake()         //刹车,停车
{
  digitalWrite(Right_motor_go,LOW);
  digitalWrite(Right_motor_back,LOW);
  digitalWrite(Left_motor_go,LOW);
  digitalWrite(Left_motor_back,LOW);
  //delay(time * 100);//执行时间,可以调整  
}

void left()         //左转(左轮不动,右轮前进)
{
  digitalWrite(Right_motor_go,HIGH);	// 右电机前进
  digitalWrite(Right_motor_back,LOW);
  //analogWrite(Right_motor_go,200); 
  //analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);   //左轮不动
  digitalWrite(Left_motor_back,LOW);
  //analogWrite(Left_motor_go,0); 
  //analogWrite(Left_motor_back,0);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整  
}

void spin_left()         //左转(左轮后退,右轮前进)
{
  digitalWrite(Right_motor_go,HIGH);	// 右电机前进
  digitalWrite(Right_motor_back,LOW);
  //analogWrite(Right_motor_go,200); 
  //analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);   //左轮后退
  digitalWrite(Left_motor_back,HIGH);
  //analogWrite(Left_motor_go,0); 
  //analogWrite(Left_motor_back,200);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整  
}

void right()        //右转(右轮不动,左轮前进)
{
  digitalWrite(Right_motor_go,LOW);   //右电机不动
  digitalWrite(Right_motor_back,LOW);
  //analogWrite(Right_motor_go,0); 
  //analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go,HIGH);//左电机前进
  digitalWrite(Left_motor_back,LOW);
  //analogWrite(Left_motor_go,200); 
  //analogWrite(Left_motor_back,0);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整  
}

void spin_right()        //右转(右轮后退,左轮前进)
{
  digitalWrite(Right_motor_go,LOW);   //右电机后退
  digitalWrite(Right_motor_back,HIGH);
  //analogWrite(Right_motor_go,0); 
  //analogWrite(Right_motor_back,200);//PWM比例0~255调速
  digitalWrite(Left_motor_go,HIGH);//左电机前进
  digitalWrite(Left_motor_back,LOW);
  //analogWrite(Left_motor_go,200); 
  //analogWrite(Left_motor_back,0);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整  
}

void back()          //后退
{
  digitalWrite(Right_motor_go,LOW);  //右轮后退
  digitalWrite(Right_motor_back,HIGH);
  //analogWrite(Right_motor_go,0);
  //analogWrite(Right_motor_back,150);//PWM比例0~255调速
  digitalWrite(Left_motor_go,LOW);  //左轮后退
  digitalWrite(Left_motor_back,HIGH);
  //analogWrite(Left_motor_go,0);
  //analogWrite(Left_motor_back,150);//PWM比例0~255调速
  //delay(time * 100);     //执行时间,可以调整  
}

void dump(decode_results *results)
{
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) 
  {
    //Serial.println("Could not decode message");
    brake();
  } 
//串口打印,调试时可以打开,实际运行中会影响反应速度,建议屏蔽
/*
  else 
  {

    if (results->decode_type == NEC) 
    {
      Serial.print("Decoded NEC: ");
    } 
    else if (results->decode_type == SONY) 
    {
      Serial.print("Decoded SONY: ");
    } 
    else if (results->decode_type == RC5) 
    {
      Serial.print("Decoded RC5: ");
    } 
    else if (results->decode_type == RC6) 
    {
      Serial.print("Decoded RC6: ");
    }
    Serial.print(results->value, HEX);
    Serial.print(" (");
    Serial.print(results->bits, DEC);
    Serial.println(" bits)");
    
  }
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");

  for (int i = 0; i < count; i++) 
  {
    if ((i % 2) == 1) 
    {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    } 
    else  
    {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println("");
*/
}

void loop()
{
  if (irrecv.decode(&results)) //调用库函数:解码
  {
    // If it's been at least 1/4 second since the last
    // IR received, toggle the relay
    if (millis() - last > 250) //确定接收到信号
    {
      on = !on;//标志位置反
      digitalWrite(13, on ? HIGH : LOW);//板子上接收到信号闪烁一下led
      dump(&results);//解码红外信号
    }
    if (results.value == run_car )//按键2
      run();//前进
    if (results.value == back_car )//按键8
      back();//后退
    if (results.value == left_car )//按键4
      left();//左转
    if (results.value == right_car )//按键6
      right();//右转
    if (results.value == stop_car )//按键5
      brake();//停车
    if (results.value == left_turn )//按键1
      spin_left();//左旋转
    if (results.value == right_turn )//按键3
      spin_right();//右旋转
    last = millis();      
    irrecv.resume(); // Receive the next value
  }
}

四、实验故障排除解决

在我们小组实验进行到一半的时候,突然出现意料之外状况:led亮度明显变暗,并且电机出现空转现象,即马达在内部运动,却无法驱动轮子。针对这种状况,我们使用了电工实习时自己组装的万用电表,调到了欧姆档进行故障检测。
我们分别对各个零件,泡沫板与导线进行了测量,发现正常,这时候,我们怀疑是电池出现了问题。经检测,电池电压远远小于3.7V。事后我们认为可能是前一天晚上给电池充电时,时间过长,导致电池寿命极具缩短,引起故障。

五、实验总结与体会

经过这次智能小车单片机实验,我们又对于计算机的底层原理结构有了进一步的了解,并且对于所学C语言编程和电工知识的结合有了新的体会。
我们最大的收获是,又了解了一种新的平台和编程学习方向,提高了动手实践能力和灵活应用已有知识的能力。这对于我们的基础知识的积累与拓展有很大的帮助。