今天硬创邦给大家带来的产品是一款GPS速度计,当然,它可不是计算步行速度的,它可以用在车里。听到这儿肯定许多人会感到奇怪,车里不是有仪表盘吗?难道你开的是自行车啊?是啊,但很多人的单任务运行的大脑总觉得简单易懂的数字速度计更符合我的要求,而且可以直接把它固定在面前。
此外,本次教程的作者做的GPS版本并不会像其他人改装车一样,把车里弄的乱七八糟的。接下来我们就看一下教程吧。
1. Arduino Uno开发板(其他版本的Arduino开发板也可以使用)。
2.GPS模块,购买地址:https://www.dfrobot.com/wiki/index.php?title=GPS_M...
3.液晶显示屏,购买地址:http://www.aliexpress.com/item/20PIN-LCD12864-Graphic-LCD-Module-KS0107-KS0108-Drive-IC-5V-Yellow-Backlight/2037961119.html?spm=2114.01020208.3.40.olQVGl&ws_ab_test=searchweb201556_7_79_78_77_80,searchweb201644_5,searchweb201560_9
4.一个10K的微调电位,用来调整LCD的对比度。
5.4.7k的电位计,用来调整LCD的亮度。
6.100欧姆的电阻器,用来限制通过LCD的电流。
7.线材,吸盘,自粘魔术贴,厨房铝箔或类似的东西,烙铁,钳子和热熔胶枪等等。
可选配件:
8.可为Arduino开发板和LCD等设备供电的USB线。
9.两个5V的USB车载电源适配器,电流输出至少要达到1A。
10.塑料外壳(你也可以自己做一个)。
11.当然,首先你得有辆车。
请各位注意:
我建议你在正式制作前先试做一个,在完成测试工作后再正式开始制作。
想要顺利将sketch上传至Arduino开发板,你需要先断开GPS模块的连接,因为它和Arduino IDE用的是相同的RX和TX接口。我试过不断开就上传,但一直都没能成功。
此外,上传过程中还要断开LCD的电源连接,因为重置接口会对Arduino IDE造成干扰。有人说,连接Arduino上的+5V电源也能完成上传,不过我觉得上传时拔掉线缆貌似更简单。
首先,之前因为快递不给力,我的LCD还没到,所以我只能用LED显示屏先测试GPS模块了。
好不容易盼来了LCD,我又发现了个蛋疼的问题,这线也太难接了。好嘛,我只好去翻了那本意大利语的教程(链接:http://www.mauroalfieri.it/elettronica/lcd-grafico-128x64-arduino.html)。不过最终我也没能找到正确的方法,所以我只好做了些许变通:
-在10k微调电位的布线上,我做了一些调整。
-我将另一个4.7k的电位计和100欧姆的电阻器串联了起来,这样就可以控制LCD的亮度了。
另外,为了使用方便,我希望引擎启动时速度计就会开始显示,不过这样做耗电量可能会有些大。所以只有引擎启动时Arduino开发板和LCD才会开始工作,不过GPS模块会一直处于开机状态(这样就不用每次启动都要等着GPS去搜星了)。
不过,你也可以根据需要自行决定供电方式。
只需一个车载电源适配器就能稳定的给GPS模块供电,另一个电源适配器则可在车辆启动后为Arduino开发板和LCD供电。
还有一个点需要注意:连接电源适配器时我用了保险丝,所以如果发生短路它们会即使熔断,以防损坏其他车载电子元件。
这一步我测试了LCD的线路。不过当时我还没用电阻器替代微调电位。
如图所示,我在备好的塑料外壳上打了个洞,这样就能把LCD装进去了,下一步点上热熔胶固定好LCD,接着在上面铺一层铝箔,对了,记得在塑料壳周围也加一层铝箔。此外,你要将Arduino开发板封在一个简易的法拉第笼中,这样就能避免来自其他设备的干扰。这玩意真的这么有用吗?实话说,我也不知道,不过照做就是了。
但可要记得理好线路,省的引起LCD或者Arduino开发板短路。
这个项目里的线是真不少,除了两个电源适配器需要连接,我们还需要通过电位计来调整屏幕亮度,这下一共就有4根线了,所以我决定将这些线换成USB线,以便后期检查。
我将Arduino开发板里的USB接口拔了下来(当时我只有这一个接口,不过在那之前我已经上传了sketch而且对速度计进行了初步的测试),而且在塑料盒上又开了个口,留给所需的电源连接。如果你想后期给开发板升级sketch,一定要再去买个USB接口。
当然,你还可以选择其他类型的接口。我这样处理是为了将这四根线都放进盒子里收纳整齐,这样会比较美观。
正好我手边有个闲置的导航,它上面有个吸盘,所以我就直接用它将速度计吸在了前挡风玻璃上。此外,我用魔术贴将GPS模块绑在速度计的塑料外壳上。不过可要记得在外壳上给四条线缆留口哦。
此时,速度计的硬件就组装完成了,现在我们需要用USB线将它连接到电源适配器上。而电位计则安装在方向盘旁边(请各位注意,我开的是右舵车,如果你的车是左舵车,请对电位计的位置作相应调整)。
好啦,该搞定代码的问题了。
首先,你得先去下载两个库(确认你的Arduino开发板里没有这两个库)。
OpenGLCD,下载链接:https://code.google.com/p/glcd-arduino/downloads/list
更多详细信息请参阅:http://playground.arduino.cc/Code/GLCDks0108和https://bitbucket.org/bperrybap/openglcd/wiki/Home。
TinyGPS,下载地址:http://arduiniana.org/libraries/tinygps/
解压下载好的文件并将它们放入你的Arduino库文件夹中(一般为C:\Program Files (x86)\Arduino\libraries\)。如果Arduino IDE处于开机状态,请关掉并重启,这样才能加载出新的库。
刚刚解决了库的问题后,我又发现了新问题,那就是生成的新字体看起来很违和。于是我创建了一个新的位图,它会直接显示在LCD上。
安装了OpenGLCD库之后,请找到那个名为"glcdMakeBitmap.pde"的文件,一般情况下它都保存在:
C:\Program Files (x86)\Arduino\libraries\openGLCD\bitmaps\utils\glcdMakeBitmap\
想要运行这个文件,你需要下载并安装另一款名叫Processing的免费软件,它和Arduino IDE非常相似。下面附上下载地址:https://processing.org/download/
在软件中打开"glcdMakeBitmap.pde"并点击左上角的运行按键。
"glcdMakeBitmap.pde"可以让你不断喂给OpenGLCD库新的图片文档,随后一些.h文档就会自动在新的位图文件夹中生成,最终它们将成为LCD上不断跳动的数字。
在第八步的最下方我还贴了一个名为"numbers.zip"的文件,你可以下载后解压,随后将其中的.BMP文件拖到运行中的"glcdMakeBitmap.pde"中去,这样就可以创建11个头文件(0到9,还有空格)。不过如果你是这方面的大神,你还可以设计自己的字体并保存为BMP或其他文档,随后再创建出独一无二的头文件,这样你的速度计就会变得狂拽酷炫叼炸天了。
备注:你们可能会觉得很奇怪,为什么我不直接用.h文档来替代.BMP文档,留给你们一个烂摊子(下载安装Processing并运行"glcdMakeBitmap.pde")来收拾呢?因为只是简单的将.h文档复制粘贴到位图文件夹中的话,一个名为"allBitmaps.h" 的文件就会自动更新。此外,这样你们也能学会怎么设计字体,创造自己的个性速度计了。
最后我们要搞定sketch,这一步不是很复杂,我就不详细来讲了。
下面我会附上.ino sketch供大家参考。
#include //math library to use for round function
#include "TinyGPS.h" //GPS module library
#include // LCD library
TinyGPS gps; //create a gps object
float fLat, fLong; //floats for longitude and latitude; will be used to determine whether the GPS data is up to date or not
unsigned long fix_age; // returns +- latitude/longitude in degrees
int digit1, digit2, digit3; //integers to hold the three digits making up the speed
int iSpeed; //integer to hold the speed value from the GPS module
void setup()
{
Serial.begin(9600); //start the serial communication
// initialise the library, non inverted writes pixels onto a clear screen
GLCD.Init(NON_INVERTED);
}
void loop()
{
while (Serial.available())
{
//incoming serial data from GPS
int c = Serial.read();
if (gps.encode(c))
{
// process new gps info here, in case you want to display more details
}
}
gps.f_get_position(&fLat, &fLong, &fix_age); //get longitude and latitude, used to find if data is up to date
if (fix_age == TinyGPS::GPS_INVALID_AGE || fix_age > 2000)
{
//data was not updated for some time, assume that GPS connection is lost
iSpeed = 0;
}
else
{
//GPS connection is up to date, get the speed information, and round it to closest integer value
iSpeed = round(gps.f_speed_kmph()); // speed in km/h
}
//when not moving, the GPS module will still read some "speed" value, not necessarily zero
//in that case assume the car is not moving; only display values greater than 2
if (iSpeed == 1) iSpeed = 0;
displaySpeed(iSpeed); //call function to display the speed, digit by digit
}
void displaySpeed(int iSpeed)
{
//"simple" maths to extract each digit value
digit1 = iSpeed / 100;
iSpeed = iSpeed - (digit1 * 100);
digit2 = iSpeed / 10;
digit3 = iSpeed - (digit2 *10);
//display "blank" bitmap when necessary, instead of number zero
if (digit2 == 0 && digit1 == 0) digit2 = -1; //digit 2 is blank
if (digit1 == 0) digit1 = -1; //digit 1 is blank
//call function to display each digit, at their required position
drawDigit(digit1, 0);
drawDigit(digit2, 45);
drawDigit(digit3, 90);
}
void drawDigit(int digit, int pos)
{
switch (digit)
{
case 0:
GLCD.DrawBitmap(Number0, pos, 0);
break;
case 1:
GLCD.DrawBitmap(Number1, pos, 0);
break;
case 2:
GLCD.DrawBitmap(Number2, pos, 0);
break;
case 3:
GLCD.DrawBitmap(Number3, pos, 0);
break;
case 4:
GLCD.DrawBitmap(Number4, pos, 0);
break;
case 5:
GLCD.DrawBitmap(Number5, pos, 0);
break;
case 6:
GLCD.DrawBitmap(Number6, pos, 0);
break;
case 7:
GLCD.DrawBitmap(Number7, pos, 0);
break;
case 8:
GLCD.DrawBitmap(Number8, pos, 0);
break;
case 9:
GLCD.DrawBitmap(Number9, pos, 0);
break;
default:
GLCD.DrawBitmap(NumberBlank, pos, 0);
break;
}
}
2015-2016赛季全球创客马拉松深圳大学站已经开始接受报名啦!关注“硬创邦”(微信号:leiphone_bang),回复“深大”即可参与报名!此外还可加入全球创客马拉松主群(群号:259592983),参与我们的互动讨论~