现在我们组装好了硬件设备,并对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号