这个皮尺是老古董,国营上海井冈服装厂制,散发着一种革命浪漫主义气质,儿时母亲用它为我量体裁衣,放在口袋里,随时丈量着尺寸。时光随着日月的交替,旧时的人们逐渐成长、变老,但未来科技却不断向我们走来,对于测量距离这样的事情,也有了新颖的解读。于是,这时的我,用Arduino系统搭建了一个便携式超声波测量仪,也放在口袋里,随时扫描着前方的物体,及时了解我们的距离。

这个作品用到了LCD4884来显示距离,LCD4884的使用见《 我家的温湿度测量计 》,网址: http://www.eefocus.com/zhang700309/blog/12-06/280255_7a0b3.html。至于用于距离检测的超声波传感器,我曾写过多篇文章介绍。
《动手制作超声波测距仪》,网址: http://www.eefocus.com/zhang700309/blog/11-11/233953_e0cf6.html 。
《 超声波传感器与舵机结合实现扇面测距 》,网址:http://www.eefocus.com/zhang700309/blog/11-11/233967_839a6.html 。
《 魔术手控制Arduino小车(视频) 》,网址:http://www.eefocus.com/zhang700309/blog/11-11/233969_60ee7.html 。
《 Processing互动之彩圈阵列的超声波效应 》,网址:http://www.eefocus.com/zhang700309/blog/11-12/236613_9abb1.html 。
这个超声波型号为URM37 V3.2的测距传感器是一种智能传感器,所谓智能传感器就是信号采集,数字处理,和信息传送为一体。用户只要通过单片机TTL电平串口,向传感器发出四个 字节的信息读取命令,传感器接收命令后,会向单片机发回四个字节的信息,这四个字节里有两个字节就是16位被测距离信息。如果高位字节和低位字节都是 0xFF,这意味着测量无效,超出测量范围,否则,高位字节乘以256再加上低位字节就是被测距离,单位是厘米。以厘米为单位的距离值除以100,就是以米为单位的距离数据,这个数据保留小数点后两位,看下图实测的单位为米的距离值,与皮尺对照,可以看出URM37 V3.2的测距传感器的测量精度还是靠谱的。

上图LCD4884显示器板子直接插在Arduino UNO控制板的母槽引脚上,它与Arduino板子形成层叠关系,但是并未把Arduino可用的端口挡住,因为LCD4884板子上把Arduino的5个模拟端口和6个数字端口引出来了,并布局到LCD4884板子上,以便使用。 于是我把URM37 V3.2 超声波传感器的TTL串口线和电源线用四根杜邦线插在了LCD4884板子上数字端口的RX、TX、+、-端子上,完成了传感器与Arduino控制板的硬件连接。
把Arduino控制板和URM37 V3.2 传感器 用双面胶带粘在电池盒背面,再把电池盒的电源插头插到Arduino UNO的电源插座,于是便携式超声波测距仪的硬件系统就这样快速搭建完成。
视频:
URM37V3.2超声波测距模块与单片机是通过TTL模式的串口连接的,只需四根线:VCC、GND、RXD,TXD具体接线图如下:

看到上图,知道把URM37 V3.2传感器上标注的RXD、TXD、VCC和GND与LCD4884上的TX、RX、+和-用四根杜邦线连接就行了,是这样,但是厂家把LCD4884上的+和-的标记正好印颠倒了,应该按照下图的方法接线,红色的VCC线接在TX端口的中间那个端子上,褐色的GND线接在下边那个端子上。

硬件连接好了,软件我有详细注释,而且前面还有不少文章介绍,所以不再累述了。
程序:
//DFRobot公司的URM37V3.2超声波测距传感器测量范围是4~500厘米
#include "LCD4884.h" //声明LCD4884库函数
#include "Word1_cn.h" //内含汉字“超声波测距仪”的点阵数组的头文件
#include "Word2_cn.h" //内含汉字“米”的点阵数组的头文件
int USValue = 0;//定义存放超声波测量距离
int num1; //存储距离值百位
int num2; //存储距离值十位
int num3; //存储距离值个位
char string1[6];//距离值百位字符串变量
char string2[6];//距离值十位字符串变量
char string3[6];//距离值个位字符串变量
byte DMcmd[4] = {0x22, 0x00, 0x00, 0x22}; //距离命令
void setup()
{
Serial.begin(9600); //启动串口通信
lcd.LCD_init();//初始化LCD4884
lcd.LCD_clear(); //清屏
delay(200);
}
void loop( )
{
//先发送四个字节的测距命令
for(int i=0;i<4;i++)
{
Serial.print(DMcmd[i],BYTE);//发送超声波测距命令
}
delay(75); //一个延时
//再接受来自传感器包含距离信息的四个字节
if(Serial.available()>3) //查询串口有无数据
{
byte header=Serial.read(); //0x22开始接收距离数据
byte highbyte=Serial.read();//距离数据高8位
byte lowbyte=Serial.read();//距离数据低8位
byte sum=Serial.read();//sum校验和
if(highbyte==255) //数据无效
{
lcd.LCD_clear(); //清屏
USValue=999;//以999厘米标识测量无效
}
else
{
//把距离的高8位数据乘以256再加上低8位数据,合成为完整的距离值
USValue = highbyte*256+lowbyte;
}
//把距离值分解成百、十、个位
num1=USValue/100;
num2=(USValue%100)/10;
num3=USValue%10;
//把整数数值转换为字符串
itoa(num1,string1,10);
itoa(num2,string2,10);
itoa(num3,string3,10);
lcd.LCD_clear(); //清屏
//LCD第6列第1行,显示汉字“超声波测距仪”,字体12,显示六个汉字
lcd.LCD_write_chinese(6,1, Word1_cn,12,6,0,0);
//显示距离值,单位为米
//LCD第3行第8列开始,显示距离值整数部分,普通显示
lcd.LCD_write_string_big(8, 3,string1,MENU_NORMAL);
//显示小数点
lcd.LCD_write_string_big(20, 3,".",MENU_NORMAL);
//LCD第3行第28列开始,显示距离值小数部分,普通显示
lcd.LCD_write_string_big(28,3, string2,MENU_NORMAL);
lcd.LCD_write_string_big(40,3, string3,MENU_NORMAL);
//显示长度单位,汉字“米”,字体:16,显示汉字一个
lcd.LCD_write_chinese(56,4,Word2_cn,16,1,0,0);
}
delay(500); //延时0.5s
}
URM37 V3.2传感器的测量范围是4~500cm,超出范围它会反馈出“测量无效”的信息,我用显示9.99米,来标识“测量无效”。
我把超声波测距仪放在书架音箱上,测量与客厅对面墙壁的距离,显示值:3.87米。