| 最近忙生活琐事,很少搞这些小东东,今天闲了一下就发表一个Arduino控制GP2D12的小实例,仅供大家参考!
器材:Arduino开发板,GP2D12,1602字符液晶,连接线若干。
Arduino开发板和1602字符液晶我就不多介绍了,前面都提到过。
GP2D12是日本SHARP公司生产的红外距离传感器,价格便宜,测距效果还不错,主要用于模型或机器人制作。
技术规格如下:
探测距离:10-80cm
工作电压:4-5.5V
标准电流消耗:33-50 mA
输出量:模拟量输出,输出电压和探测距离成比例
 从曲线图中我们可以看出,输出电压并非是线性的,所以这个测距也就只能测个大概,如果要精度高的话就需要做非线性校正,这里我们就不讨论这个问题了。
实验原理:
GP2D12根据距离的远近输出相应的电压,经Arduino开发板0号模拟口输入,转换成数字量,根据公式计算得到需要显示的数据。
实验原理图:

实验实物图:

没有障碍物,显示范围超出。

有障碍物时显示测量距离。

经实验,需要在GP2D12的电源端加个10UF以上的电解电容,稳定供电电压,以保证输出模拟电压更稳定。
实验代码:
/********************************************************************/ int GP2D12=0;
int ledpin = 13;
int LCD1602_RS=12;
int LCD1602_RW=11;
int LCD1602_EN=10;
int DB[] = {6, 7, 8, 9};
char str1[]="www.DFRobot.cn";
char str2[]="Renge:00cm";
char str3[]="Renge Over"; /********************************************************************/
/********************************************************************/ void LCD_Command_Write(int command) { int i,temp; digitalWrite( LCD1602_RS,LOW); digitalWrite( LCD1602_RW,LOW); digitalWrite( LCD1602_EN,LOW);
temp=command & 0xf0; for (i=DB[0]; i <= 9; i++) { digitalWrite(i,temp & 0x80); temp <<= 1; } digitalWrite( LCD1602_EN,HIGH); delayMicroseconds(1); digitalWrite( LCD1602_EN,LOW);
temp=(command & 0x0f)<<4; for (i=DB[0]; i <= 10; i++) { digitalWrite(i,temp & 0x80); temp <<= 1; }
digitalWrite( LCD1602_EN,HIGH); delayMicroseconds(1); digitalWrite( LCD1602_EN,LOW); }
/********************************************************************/ void LCD_Data_Write(int dat) { int i=0,temp; digitalWrite( LCD1602_RS,HIGH); digitalWrite( LCD1602_RW,LOW); digitalWrite( LCD1602_EN,LOW);
temp=dat & 0xf0; for (i=DB[0]; i <= 9; i++) { digitalWrite(i,temp & 0x80); temp <<= 1; }
digitalWrite( LCD1602_EN,HIGH); delayMicroseconds(1); digitalWrite( LCD1602_EN,LOW);
temp=(dat & 0x0f)<<4; for (i=DB[0]; i <= 10; i++) { digitalWrite(i,temp & 0x80); temp <<= 1; }
digitalWrite( LCD1602_EN,HIGH); delayMicroseconds(1); digitalWrite( LCD1602_EN,LOW); }
/********************************************************************/ void LCD_SET_XY( int x, int y ) { int address; if (y ==0) address = 0x80 + x; else address = 0xC0 + x; LCD_Command_Write(address); }
/********************************************************************/ void LCD_Write_Char( int x,int y,int dat) { LCD_SET_XY( x, y ); LCD_Data_Write(dat); }
/********************************************************************/ void LCD_Write_String(int x,int y,char *s) { LCD_SET_XY( x, y ); //设置地址 while (*s) //写字符串 { LCD_Data_Write(*s); s ++; } }
/********************************************************************/ void setup (void) { int i = 0; for (i=6; i <= 13; i++) { pinMode(i,OUTPUT); } LCD_Command_Write(0x28);//4线 2行 2x7 delay(50); LCD_Command_Write(0x06); delay(50); LCD_Command_Write(0x0c); delay(50); LCD_Command_Write(0x80); delay(50); LCD_Command_Write(0x01); }
/********************************************************************/ void loop (void) { float temp; int val; char i,a,b; LCD_Command_Write(0x02); delay(50); LCD_Write_String(1,0,str1); delay(50); LCD_Write_String(3,1,str2); delay(50); while(1) { val = analogRead(GP2D12); temp=val/5.8;//改变被除数,可以减小一点误差。 val=95-temp;//由于GP2D12的输出电压与距离成反比,所以需要用一个常量相减,改变这个常量,可以减小一点误差。 if(val>80) { LCD_Write_String(3,1,str3); } else { LCD_Write_String(3,1,str2); a=0x30+val/10; b=0x30+val%10; LCD_Write_Char(9,1,a); LCD_Write_Char(10,1,b); } delay(500); } }
|