极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 22495|回复: 10

做的GPS和陀螺仪的越野E表 请各位帮忙优化下代码

[复制链接]
发表于 2013-9-6 09:58:43 | 显示全部楼层 |阅读模式
本人新手一枚,从今年7月刚开始接触单片机,喜欢旅游,突发奇想做一个车载的陀螺仪,搜遍淘宝,只有一种越野E表,价格不菲,1960大米{:soso_e141:} ;又看HUD,淘宝上没有能够显示坡度的HUD,有的只是读取OBD中的速度、油耗等信息。
下定决心,自己做个出来,接下来就是买各种模块,尤其是各种显示模块,先后买了数码管、LCD1602、LCD2402、LCD4002,又买了两块9位的VFD,可投到前挡玻璃上还是差强人意,晚上看清晰无比,白天狗P看不到{:soso_e118:} ,只能用LCD正向显示。
现在又看好了VFD的2002,还没入手,各位前辈有什么建议,不妨给个!
下面是面包板接线图和视频。代码是东拼西凑的,哪位前辈有时间给优化下,在此表示感谢!




  1. #include "SoftwareSerial.h"
  2. #include "TinyGPS.h"
  3. #include "LiquidCrystal.h"
  4. #include "Wire.h"
  5. #include "I2Cdev.h"
  6. #include "MPU6050_6Axis_MotionApps20.h"
  7. MPU6050 mpu(0x68);
  8. LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
  9. TinyGPS gps;
  10. SoftwareSerial nss(4, 5);

  11. byte up[8] = {
  12.   B00100,
  13.   B01010,
  14.   B10101,
  15.   B00100,  
  16.   B00100,
  17.   B00100,
  18.   B00100,
  19. };
  20. byte down[8] = {
  21.   B00100,
  22.   B00100,
  23.   B00100,
  24.   B00100,
  25.   B10101,
  26.   B01010,
  27.   B00100,
  28. };
  29. bool dmpReady = false;  // set true if DMP init was successful
  30. uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
  31. uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
  32. uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
  33. uint16_t fifoCount;     // count of all bytes currently in FIFO
  34. uint8_t fifoBuffer[64]; // FIFO storage buffer

  35. Quaternion q;           // [w, x, y, z]         quaternion container
  36. VectorFloat gravity;    // [x, y, z]            gravity vector
  37. float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
  38. volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high

  39. static void gpsdump(TinyGPS &gps);
  40. static bool feedgps();
  41. static void print_float(float val, float invalid, int len, int prec);
  42. static void print_int(unsigned long val, unsigned long invalid, int len);
  43. static void print_str(const char *str, int len);
  44. //int kk=0;
  45. void dmpDataReady()
  46. {
  47.   mpuInterrupt = true;
  48. }

  49. void setup()
  50. {
  51.   lcd.createChar(1, up);
  52.   lcd.createChar(2, down);
  53.   Wire.begin();
  54.   nss.begin(9600);
  55.   lcd.begin(24, 2);
  56.   //pinMode(3,INPUT);
  57.   lcd.print ("---Storm GPS---");
  58.   lcd.setCursor(0, 1);
  59.   lcd.print ("Initializing......");
  60.   mpu.initialize();
  61.   delay(5);
  62.   lcd.clear();
  63.   devStatus = mpu.dmpInitialize();
  64.   if (devStatus == 0)
  65.   {
  66.     mpu.setDMPEnabled(true);
  67.     attachInterrupt(0, dmpDataReady, RISING);
  68.     mpuIntStatus = mpu.getIntStatus();
  69.     dmpReady = true;
  70.     packetSize = mpu.dmpGetFIFOPacketSize();
  71.   }   
  72. }

  73. void loop()
  74. {
  75.     float pitch,roll;
  76.   /***************MPU-6050*****************/
  77.   if (!dmpReady)  
  78.     return;
  79.   if (!mpuInterrupt && fifoCount < packetSize)
  80.     return;
  81.   mpuInterrupt = false;
  82.   mpuIntStatus = mpu.getIntStatus();
  83.   fifoCount = mpu.getFIFOCount();
  84.   if ((mpuIntStatus & 0x10) || fifoCount == 1024)
  85.   {
  86.     mpu.resetFIFO();
  87.   }
  88.   else if (mpuIntStatus & 0x02)
  89.   {
  90.     while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
  91.     mpu.getFIFOBytes(fifoBuffer, packetSize);
  92.     fifoCount -= packetSize;

  93.     mpu.dmpGetQuaternion(&q, fifoBuffer);
  94.     mpu.dmpGetGravity(&gravity, &q);
  95.     mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);  //从DMP中取出Yaw、Pitch、Roll三个轴的角度,放入数组ypr。单位:弧度
  96.     pitch=ypr[1] * 180/M_PI;
  97.     roll=ypr[2] * 180/M_PI;
  98.   /***************GPS*****************/
  99.   bool newdata = false;
  100.   unsigned long start = millis();
  101.   // Every second we print an update
  102.   while (millis() - start < 250)
  103.   {
  104.     if (feedgps())
  105.       newdata = true;
  106.   }   
  107.    /***************Display****************/
  108.     gpsdump(gps);
  109.     tly_lcd(pitch,1);
  110.     tly_lcd(roll,2);         
  111.   }
  112. }
  113. void tly_lcd(float tly,int k_tly)  //(tly):MPU6050传递的pitch\roll值,先要转换成int;(k_tly)1为pitch; 2为roll;
  114. {
  115.    int i_tly;
  116.    i_tly=(int)tly;
  117.    switch (k_tly)
  118.    {
  119.      case 1:
  120.               lcd.setCursor(0,0);
  121.         if(i_tly<0)
  122.           {lcd.write (2);}
  123.         else
  124.           {lcd.write (1);}      
  125.         if(abs(i_tly)<10)
  126.               {
  127.                 lcd.print("0");
  128.                 lcd.print(abs(i_tly));        
  129.               }
  130.             else
  131.               {
  132.                 lcd.print(abs(i_tly));
  133.               }
  134.         if(i_tly<0)
  135.           {lcd.write (2);}
  136.         else
  137.           {lcd.write (1);}  
  138.         break;
  139.         case 2:
  140.               lcd.setCursor(0,1);
  141.         if(i_tly<0)
  142.           {lcd.print("<");}
  143.         else
  144.           {lcd.print(">");}     
  145.         if(abs(i_tly)<10)
  146.               {
  147.                 lcd.print("0");
  148.                 lcd.print(abs(i_tly));        
  149.               }
  150.             else
  151.               {
  152.                 lcd.print(abs(i_tly));
  153.               }
  154.         if(i_tly<0)
  155.           {lcd.print("<");}
  156.         else
  157.           {lcd.print(">");}  
  158.         break;
  159.    }        
  160. }

  161. static void gpsdump(TinyGPS &gps)
  162. {
  163.   float flat, flon;
  164.   unsigned long age, date, time, chars = 0;
  165.   
  166.   //print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  167.   //print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  168.   gps.f_get_position(&flat, &flon, &age);

  169.   lcd_ref(8,0,2);     
  170.   lcd.setCursor(8, 0);
  171.   lcd.print ("*");   
  172.   //print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 3);
  173.   
  174.   lcd_ref(5,0,3);
  175.   lcd.setCursor(5, 0);
  176.   print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 2);
  177.   
  178.   lcd_ref(5,1,4);
  179.   lcd.setCursor(5, 1);
  180.   print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 3, 0);

  181.   lcd_ref(10,0,9);
  182.   lcd.setCursor(10, 0);  
  183.   lcd.print ("N");  
  184.   print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 6, 4);

  185.   lcd_ref(19,0,4);
  186.   lcd.setCursor(19, 0);   
  187.   print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 4, 0);
  188.   lcd.print ("M");



  189.   lcd_ref(9,1,9);
  190.   lcd.setCursor(9, 1);       
  191.   lcd.print ("E");
  192.   print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 7, 45);

  193.   lcd_ref(19,1,3);
  194.   lcd.setCursor(19, 1);
  195.   print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 3, 0);
  196.   lcd.print ("KM");

  197.   //print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  198.   //print_date(gps);
  199. }

  200. void lcd_ref(int x,int y,int z)
  201. {
  202.   lcd.setCursor(x, y);
  203.   for (int k=0;k<z;k++)
  204.   {
  205.     lcd.print (" ");   
  206.   }
  207. }

  208. static void print_int(unsigned long val, unsigned long invalid, int len)
  209. {
  210.   char sz[32];
  211.   if (val == invalid)
  212.     strcpy(sz, "*******");
  213.   else
  214.     sprintf(sz, "%ld", val);
  215.   sz[len] = 0;
  216.   for (int i=strlen(sz); i<len; ++i)
  217.     sz[i] = ' ';
  218.   if (len > 0)
  219.     sz[len-1] = ' ';
  220.   lcd.print(sz);
  221.   feedgps();
  222. }

  223. static void print_float(float val, float invalid, int len, int prec)
  224. {
  225.   char sz[32];
  226.   if (val == invalid)
  227.   {
  228.     strcpy(sz, "*******");
  229.     sz[len] = 0;
  230.         if (len > 0)
  231.           sz[len-1] = ' ';
  232.     for (int i=7; i<len; ++i)
  233.         sz[i] = ' ';
  234.     lcd.print(sz);
  235.   }
  236.   else
  237.   {
  238.     int vi = abs((int)val);
  239.     int flen = prec + (val < 0.0 ? 2 : 1);
  240.     flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;   
  241.     for (int i=flen; i<len; ++i)
  242.       {lcd.print(" ");}
  243.     lcd.print(val, prec);
  244.   }
  245.   feedgps();
  246. }

  247. static void print_str(const char *str, int len)
  248. {
  249.   int slen = strlen(str);
  250.   for (int i=0; i<len; ++i)
  251.     lcd.print(i<slen ? str[i] : ' ');
  252.   feedgps();
  253. }

  254. static bool feedgps()
  255. {
  256.   while (nss.available())
  257.   {
  258.     if (gps.encode(nss.read()))
  259.       return true;
  260.   }
  261.   return false;
  262. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-9-6 10:50:04 | 显示全部楼层
貌似很亮骚,有使用视频么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-6 11:09:04 | 显示全部楼层
迷你强 发表于 2013-9-6 10:50
貌似很亮骚,有使用视频么?

欢迎领导参观指导,视频上面有啊
回复 支持 反对

使用道具 举报

发表于 2013-9-6 17:04:19 | 显示全部楼层
这个是想把信息投到挡风玻璃上么,参考一下战斗机的抬头显示吧
回复 支持 反对

使用道具 举报

发表于 2013-9-6 21:03:45 | 显示全部楼层
好厉害啊 啊啊啊啊啊啊啊
回复 支持 反对

使用道具 举报

发表于 2013-9-6 22:15:14 来自手机 | 显示全部楼层
历害历害,这程序太牛B了。我一个都看不懂
回复 支持 反对

使用道具 举报

发表于 2013-9-6 23:34:18 | 显示全部楼层
哈哈,超级赞!很有创意!想当年BBS才流行的时候,不就是文字符号的天下么!楼主加油!
回复 支持 反对

使用道具 举报

发表于 2013-9-7 09:10:33 | 显示全部楼层
强大而不失华丽!
回复 支持 反对

使用道具 举报

发表于 2014-5-28 09:55:45 | 显示全部楼层
太强了,太强了,这个真是太强了
回复 支持 反对

使用道具 举报

发表于 2014-12-17 14:50:52 | 显示全部楼层
亲有四元数的库么
回复 支持 反对

使用道具 举报

发表于 2014-12-17 16:16:19 | 显示全部楼层
鸿子子 发表于 2014-12-17 14:50
亲有四元数的库么

找X-IMU官网
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-16 20:14 , Processed in 0.099444 second(s), 29 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表