现在我们组装好了硬件设备,并对L298N和HC-SR04这两个芯片有了一定的了解,接下来我们就要进入程序的编写工作了。在本例中我们的系统环境为Linux x86-64发行版为Fedora 23,我们可以在PC机上做程序编写和调试工作,之后再移植到树莓派上。当然如果你直接在树莓派上写代码也没有任何问题。采用gcc编译器,我们使用的gcc版本为5.3.1,使用的树莓派GPIO接口函数库为WiringPi。关于Linux和gcc部分我们不做说明,只对树莓派的相关操作做一些简介,首先下载并安装WiringPi:
git clone git://git.drogon.net/wiringPi cd wiringPi ./build
WiringPi对树莓派的GPIO引脚做了重新编号,它们没有本质上的区别,只是编号不同:

另外,在使用gcc编译WiringPi库时需要加入-lwiringPi编译选项。
前面我们介绍了L298N和HC-SR04的使用方法,那么我们现在就来编程驱动程序来操控它们。先来看看L298N的测试例子:
#include <wiringPi.h>
//定义左侧L298N引脚
#define PORT_LEFT_ENV (2)
#define PORT_LEFT_IN1 (3)
#define PORT_LEFT_IN2 (4)
//定义右侧L298N引脚
#define PORT_RIGHT_IN1 (12)
#define PORT_RIGHT_IN2 (13)
#define PORT_RIGHT_ENV (14)
//左侧前进
void driver_left_forward()
{
digitalWrite(PORT_LEFT_IN1, HIGH);
digitalWrite(PORT_LEFT_IN2, LOW);
}
//左侧后退
void driver_left_back()
{
digitalWrite(PORT_LEFT_IN1, LOW);
digitalWrite(PORT_LEFT_IN2, HIGH);
}
//左侧停止
void driver_left_stop()
{
digitalWrite(PORT_LEFT_IN1, LOW);
digitalWrite(PORT_LEFT_IN2, LOW);
}
//右侧前进
void driver_right_forward()
{
digitalWrite(PORT_RIGHT_IN1, HIGH);
digitalWrite(PORT_RIGHT_IN2, LOW);
}
//右侧后退
void driver_right_back()
{
digitalWrite(PORT_RIGHT_IN1, LOW);
digitalWrite(PORT_RIGHT_IN2, HIGH);
}
//右侧停止
void driver_right_stop()
{
digitalWrite(PORT_RIGHT_IN1, LOW);
digitalWrite(PORT_RIGHT_IN2, LOW);
}
int main(int argc, char *argv[])
{
//初始化
wiringPiSetup();
//设置引脚为输出引脚
pinMode(PORT_LEFT_IN1, OUTPUT);
pinMode(PORT_LEFT_IN2, OUTPUT);
pinMode(PORT_LEFT_ENV, OUTPUT);
//设置引脚为输出引脚
pinMode(PORT_RIGHT_IN1, OUTPUT);
pinMode(PORT_RIGHT_IN2, OUTPUT);
pinMode(PORT_RIGHT_ENV, OUTPUT);
//左右同时前进
driver_left_forward();
driver_right_forward();
sleep(3);
//左右同时后退
driver_left_back();
driver_right_back();
sleep(3);
//向右转向
driver_left_forward();
driver_right_back();
sleep(3);
//向左转向
driver_left_back();
driver_right_forward();
sleep(3);
//左右同时停止
driver_left_stop();
driver_right_stop();
return 0;
}
Makefile(由于Makefile并不是我们学习的重点,并且本例中Makefile都大同小异,之后的内容不再给出Makefile的内容)如下:
all: gcc test.c -lwiringPi -o test clean: rm test
如果我们硬件接线没有问题,将这段代码copy到树莓派上编译并运行,就可以看见小车前进、后退、向右转向、向左转向、停止。
下面来看一下HC-SR04测距代码:
#include <stdio.h>
#include <time.h>
#include <wiringPi.h>
//定义HC-SR04引脚
#define PORT_CS_TRIG (1)
#define PORT_CS_ECHO (0)
int main(int argc, char *argv[])
{
//初始化
wiringPiSetup();
//设置引脚为输出引脚
pinMode(PORT_CS_TRIG, OUTPUT);
pinMode(PORT_CS_ECHO, INPUT);
//初始化HC-SR04
digitalWrite(PORT_CS_TRIG, HIGH);
//持续15微秒
usleep(15);
digitalWrite(PORT_CS_TRIG, LOW);
//计时时间
long long time_use = 0;
//距离
double distance = 0;
int ret = 0;
//定义计时开始和结束
struct timeval start;
struct timeval end;
//定时开始,超时用
gettimeofday(&start, NULL);
do
{
gettimeofday(&end, NULL);
//计时
time_use = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
//从ECHO引脚读取数据
ret = digitalRead(PORT_CS_ECHO);
//如果超过0.1秒
if (time_use > 100 * 1000)
{
//设置为10米,因为HC-SR04最远只能测试4米距离
distance = 10;
break;
}
}
//一旦出现高电压(ret为1)表示计时结束
while (ret == 0);
//接收到反射声波
if (ret == HIGH)
{
//计时开始
gettimeofday(&start, NULL);
do
{
//从ECHO引脚读取数据
ret = digitalRead(PORT_CS_ECHO);
gettimeofday(&end, NULL);
//计时
time_use = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
//如果超过0.1秒
if (time_use > 100 * 1000)
{
//设置为10米,因为HC-SR04最远只能测试4米距离
distance = 10;
break;
}
}
//一旦出现低电压(ret为0)表示计时结束
while (ret == HIGH);
distance = time_use * 340 / 2.0;
}
printf("测试距离:%f\n", distance);
return 0;
}
如果不出意外,运行结果会显示出“测试距离:1.24”之类的数值,表示HC-SR04芯片前方障碍物的距离。
有了L298N直流电机驱动程序和HC-SR04距离检测程序,我们就可以按自己的方式来编写小车的行驶程序了。
Copyright © 2015-2023 问渠网 辽ICP备15013245号