16505| 7
|
如何制作GPS车速表? |
如何制作GPS车速表?我平时开公司的车时偶尔会遇到一个“小”问题,即车速表在汽车行驶过程中会回落至0 Km/h(过一段时间后会恢复正常)。 通常情况下,这不算是个大问题,因为你如果是老司机,就不用始终盯着车速表。你或多或少会清楚当下的车速。 但当你需要将车速降到驶入路段限速范围内,却发现“车速表停止运作”时,这个问题就比较明显了。 这是一个很好的契机,我们可借此新建一个项目——“GPS车速表”。 当然,最理想的解决方法是将汽车拉去修理、使用正规的GPS或有测速功能的应用程序,但这就是去了乐趣 :) 需准备的硬件组件:
手工工具和制作设备:
微处理器 GPS 显示器 电力 外壳 组件 连接组件 我刚开始并没有设计LED灯,因此最初的电路原理图长这样: 但最后如下图所示: 我忘了拍组装过程的照片,因此我能说的就是所有组件都是在万能电路板上进行组装的,一边是OLED显示器,另一边是微处理器和连接结构。为降低工作难度,可把OLED显示器留到最后进行组装,因为部分连接将在其背面完成。 代码 为运行代码,你需要在Arduino库 (Library) 文件夹中安装以下库。 U8glib – 用于OLED显示器 这段代码中可“打印”汽车速度、路线、GPS信号卫星数量、纬度和经度。 当然也可以显示更多信息,如:时间、日期、与某一地点的距离…… 查看TinyGPS++库的完整示例,了解所有基于GPS所获信息的可用选择。 另一大特色为超速LED提示灯。我将其最大值设置为190 Km/h。我住在德国,这里的部分高速公路不限制车速,否则我会应用+/-最大限速值。 只需将“地图”功能中的限速值改为符合你需求的数值即可。 总结相对而言,我仍是3D打印圈里的新手,打印的物件自然不甚完美 :) 总之,我没什么可抱怨的,我在这一领域还有很多地方需要提升。 虽然路线显示功能也不尽如意,但这只是一个小问题。我计划今后将其替换为更有用的信息,如:到达某一地方的时间(我的大部分车程为定点往返)。 如果你发现任何错误或有任何意见、建议、疑问,请随时给我评论或发送消息。 "Do not get bored, do something". 原理图
[mw_shl_code=cpp,true]#include "U8glib.h" U8GLIB_SSD1351_128X128_332 u8g(13, 11, 8, 9, 7); // Arduino UNO: SW SPI Com: SCK = 13, MOSI = 11, CS = 8, DC = 9, RESET = 7 #define u8g_logo_sat_width 20 #define u8g_logo_sat_height 20 //satellite logo const unsigned char u8g_logo_sat[] = { 0x00, 0x01, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x60, 0x30, 0x00, 0x60, 0x78, 0x00, 0xc0, 0xfc, 0x00, 0x00, 0xfe, 0x01, 0x00, 0xff, 0x01, 0x80, 0xff, 0x00, 0xc0, 0x7f, 0x06, 0xc0, 0x3f, 0x06, 0x80, 0x1f, 0x0c, 0x80, 0x4f, 0x06, 0x19, 0xc6, 0x03, 0x1b, 0x80, 0x01, 0x73, 0x00, 0x00, 0x66, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x70, 0x00, 0x00 }; // The serial connection to the GPS device #include <SoftwareSerial.h> static const int RXPin = 10, TXPin = 15; static const uint32_t GPSBaud = 9600; SoftwareSerial ss(RXPin, TXPin); //GPS Library #include <TinyGPS++.h> TinyGPSPlus gps; //Program variables double Lat; double Long; //int day, month, year; //int hour, minute, second; int num_sat, gps_speed; String heading; const int ledCount = 10; // the number of LEDs in the bar graph int ledPins[] = { 2, 3, 4, 5, 6, 14, A5, A4, A3, A2 }; // an array of pin numbers to which LEDs are attached void setup() { ss.begin(GPSBaud); // assign default color value if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255); // white } //Define ledpins as OUTPUT's for (int thisLed = 0; thisLed < ledCount; thisLed++) { pinMode(ledPins[thisLed], OUTPUT); } } void loop() { Get_GPS(); //Get GPS data Led_Bar();//Adjust the LED bar //Display info in the OLED u8g.firstPage(); do { print_speed(); } while ( u8g.nextPage() ); } void print_speed() { u8g.setFont(u8g_font_helvR24r); u8g.setPrintPos(2, 70); u8g.print(gps_speed , DEC); u8g.setPrintPos(60, 70); u8g.print("km/h"); u8g.setFont(u8g_font_unifont); u8g.setPrintPos(85, 15); u8g.print( num_sat, 5); u8g.setFont(u8g_font_unifont); u8g.setPrintPos(15, 100); u8g.print("Lat:"); u8g.setPrintPos(50, 100); u8g.print( Lat, 6); u8g.setPrintPos(10, 120); u8g.print("Long:"); u8g.setPrintPos(50, 120); u8g.print( Long, 6); u8g.setFont(u8g_font_unifont); u8g.setPrintPos(0, 15); u8g.print( heading); u8g.drawXBM(108, 0, u8g_logo_sat_width, u8g_logo_sat_height, u8g_logo_sat); } // This custom version of delay() ensures that the gps object // is being "fed". static void smartDelay(unsigned long ms) { unsigned long start = millis(); do { while (ss.available()) gps.encode(ss.read()); } while (millis() - start < ms); } void Get_GPS() { num_sat = gps.satellites.value(); if (gps.location.isValid() == 1) { Lat = gps.location.lat(); Long = gps.location.lng(); gps_speed = gps.speed.kmph(); heading = gps.cardinal(gps.course.value()); } /* if (gps.date.isValid()) { day = gps.date.day(); month = gps.date.month(); year = gps.date.year(); } if (gps.time.isValid()) { hour = gps.time.hour(); minute = gps.time.minute(); second = gps.time.second(); } */ smartDelay(1000); if (millis() > 5000 && gps.charsProcessed() < 10) { // Serial.println(F("No GPS detected: check wiring.")); } } void Led_Bar() { int ledLevel = map(gps_speed, 0, 190, 0, ledCount); for (int thisLed = 0; thisLed < ledCount; thisLed++) { // if the array element's index is less than ledLevel, // turn the pin for this element on: if (thisLed < ledLevel) { digitalWrite(ledPins[thisLed], HIGH); } else { // turn off all pins higher than the ledLevel: digitalWrite(ledPins[thisLed], LOW); } } }[/mw_shl_code] 此项目制作人为Hugo Gomes,点击这里查看原项目。 |
visionsl 发表于 2017-9-25 12:24 学习中,希望自己能成功做出一个来!谢谢分享! |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed