Subversion Repositories dashGPS

Rev

Rev 30 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "main.h"
  2. #include "libNMEA/nmea.h"
  3. #include <cstring>
  4. #include "libOLED/stm32_halDisplay.H"
  5. #include "libOLED/fontclass.H"
  6. #include "libOLED/displayDial.H"
  7. #include "libLSM9DS1/LSM9DS1.h"
  8.  
  9. #include "libBMP280/bmp280.h"
  10.  
  11. #include "libSmallPrintf/small_printf.h"
  12.  
  13. #if defined USB_DEVICE
  14. #include "usbd_cdc_if.h"
  15. #endif
  16.  
  17. LSM9DS1Class IMU (&hi2c2);
  18.  
  19. namespace
  20. {
  21.   int const WIDTH = 128;
  22.   int const HEIGHT = 64;
  23.   int const DISPLAY_RAMWIDTH = 132;
  24.  
  25. }
  26.  
  27. float speedMPH = 0.0;
  28. float speedAvg = 0.0;
  29.  
  30. double speedAvgTime = 0;    // sum of all deltaTime;
  31. double speedAvgSum = 0.0;  // sum of deltaTime * speed for each second
  32. double lastLocTime = 0.0; // last time there was a location
  33.  
  34. uint32_t nextPosTime = 0;
  35.  
  36. // convert knots to MPH
  37. double const KNOTS_TO_MPH = 1.128;
  38. int heading = 0;
  39. Location loc;
  40.  
  41. uint32_t lastTick = 0;
  42. int32_t temp32 = 0;
  43. uint32_t pres32 = 0;
  44. int32_t rslt;
  45. int32_t rslt2; // result from read of second sensor
  46. // second sensor
  47. int32_t temp32_out = 0;
  48.  
  49. uint8_t displayBuffer[dataSize (WIDTH, HEIGHT)];
  50.  
  51. stm32_halDisplay_t display1 (WIDTH, HEIGHT, DISPLAY_RAMWIDTH, displayBuffer,
  52.                              &hspi1,
  53.  
  54.                              SPI_CD_GPIO_Port,
  55.                              SPI_CD_Pin,
  56.                              SPI_RESET_GPIO_Port,
  57.                              SPI_RESET_Pin,
  58.                              SPI_NSS1_GPIO_Port,
  59.                              SPI_NSS1_Pin);
  60.  
  61. displayDial_t dial (display1, 96, 32, 32, 180);
  62.  
  63. // debouncer for the button
  64. char buttonState;
  65. char buttonCount;
  66. char rmc_flag = 0;
  67.  
  68. extern "C" uint8_t
  69. rmc_callback (uint8_t *data, uint16_t length)
  70. {
  71.   rmc_flag = 1;
  72.   HAL_GPIO_TogglePin (Green_LED_GPIO_Port, Green_LED_Pin);
  73.  
  74.   return CDC_Transmit_FS (data, length);
  75. }
  76.  
  77. extern "C" void
  78. cc_init ()
  79. {
  80.   display1.reset ();
  81.  
  82.   display1.init ();
  83.   display1.clearDisplay ();
  84.  
  85.   dial.draw_scale (0, 360, 8, 1, 45);
  86.  
  87.   display1.display ();
  88.  
  89.   memset (loc.time, '-', 6);
  90.   // every time we receive GPRMC, forward the text line to the USB driver
  91.   setRmcCallback (&rmc_callback);
  92.  
  93.   // initialise IMU operations
  94.   IMU.begin ();
  95. }
  96.  
  97. char fontBuf[] = "01234567";
  98. extern "C" void
  99. cc_run (struct bmp280_dev *bmp, struct bmp280_dev *bmp2)
  100.  
  101. {
  102.   bool stat = updateLocation (&loc, &uc1);
  103.  
  104.   // process button press : done by polling loop
  105.   uint8_t const buttonLimit = 3;
  106.   uint8_t newPush = HAL_GPIO_ReadPin ( encoder_push_GPIO_Port,
  107.   encoder_push_Pin);
  108.   if (newPush == buttonState)
  109.     buttonCount = 0;
  110.   else if (buttonCount < buttonLimit)
  111.     buttonCount++;
  112.  
  113.   if (buttonCount == buttonLimit)
  114.     {
  115.       buttonState = newPush;
  116.       buttonCount = 0;
  117.  
  118.       // if the button is held down , we set the average speed
  119.       if (buttonState == GPIO_PIN_RESET)
  120.         {
  121.           speedAvgSum = 0.0;
  122.           speedAvgTime = 0.0;
  123.         }
  124.     }
  125.  
  126.   if (rmc_flag)
  127.     {
  128.       // get the time from the RTC
  129.       RTC_TimeTypeDef sTime;
  130.       rmc_flag = 0;
  131.       display1.clearDisplay ();
  132.       dial.draw_scale (0, 360, 8, 1, 45);
  133.  
  134.       if (loc.good)
  135.         {
  136.  
  137.           heading = loc.heading;
  138.           // add in time * speed to give "distance"
  139.           if (loc.valid == 'A')
  140.             {
  141.               sTime.Seconds = loc.tv.tm_sec;
  142.               sTime.Minutes = loc.tv.tm_min;
  143.               sTime.Hours = loc.tv.tm_hour;
  144.               HAL_RTC_SetTime (&hrtc, &sTime, RTC_FORMAT_BIN);
  145.  
  146.               if (lastLocTime != 0)
  147.                 {
  148.                   double delta = difftime (loc.utc, lastLocTime);
  149.                   // believe the speed .
  150.                   if (delta > 0 && delta < 2)
  151.                     {
  152.                       speedAvgSum += loc.speed * delta;
  153.                       speedAvgTime += delta;
  154.                       lastLocTime = loc.utc;
  155.                     }
  156.                   else
  157.                     lastLocTime = loc.utc;
  158.                 }
  159.               else
  160.                 {
  161.                   lastLocTime = loc.utc;
  162.                 }
  163.             }
  164.         }
  165.       else
  166.         {
  167.           HAL_RTC_GetTime (&hrtc, &sTime, RTC_FORMAT_BIN);
  168.         }
  169.  
  170.       // slow down the output of ata
  171.       if (speedAvgTime > 0)
  172.         speedAvg = (speedAvgSum / speedAvgTime) * KNOTS_TO_MPH;
  173.       else
  174.         speedAvg = 0.0;
  175.  
  176.       // update the display once per second
  177.       loc.time[0] = (sTime.Hours / 10) + '0';
  178.       loc.time[1] = (sTime.Hours % 10) + '0';
  179.       loc.time[2] = (sTime.Minutes / 10) + '0';
  180.       loc.time[3] = (sTime.Minutes % 10) + '0';
  181.       loc.time[4] = (sTime.Seconds / 10) + '0';
  182.       loc.time[5] = (sTime.Seconds % 10) + '0';
  183.       // print out the GMT time at the top of the screen
  184.       display1.gotoxy (0, 0);
  185.       display1.printString (small_font, &loc.time[0], 2, WHITE);
  186.       display1.printString (small_font, ":", 1, WHITE);
  187.       display1.printString (small_font, &loc.time[2], 2, WHITE);
  188.  
  189.       display1.printString (small_font, ":", 1, WHITE);
  190.       display1.printString (small_font, &loc.time[4], 2, WHITE);
  191.  
  192.       int dial_ang = heading + 180;
  193.       dial.draw_needle (dial_ang);
  194.  
  195.       display1.gotoxy (70, 25);
  196.       if (loc.valid == 'A')
  197.         {
  198.           if (heading < 100)
  199.             display1.moveby (2, 0);
  200.           if (heading < 10)
  201.             display1.moveby (2, 0);
  202.  
  203.           display1.fontDigits (large_font, 3, -1, heading);
  204.         }
  205.       else
  206.         display1.printString (large_font, "GPS?", 4, WHITE);
  207.  
  208.       if (loc.valid == 'A')
  209.         speedMPH = loc.speed * KNOTS_TO_MPH;
  210.       else
  211.         speedMPH = 0.0;
  212.  
  213.       display1.gotoxy (0, 8);
  214.       display1.fontDigits (large_font, 4, 1, speedMPH * 10);
  215.       display1.printString (small_font, "c", 2, WHITE);
  216.       display1.gotoxy (0, 24);
  217.       display1.fontDigits (large_font, 4, 1, speedAvg * 10);
  218.       display1.printString (small_font, "av", 2, WHITE);
  219.  
  220.       float x, y, z;
  221.       if (IMU.magneticFieldAvailable ())
  222.         {
  223.  
  224.           IMU.readMagneticField (x, y, z);
  225.         }
  226.  
  227.       if (IMU.accelerationAvailable ())
  228.         {
  229.           IMU.readAcceleration (x, y, z);
  230.         }
  231.  
  232.       struct bmp280_uncomp_data ucomp_data, ucomp_data2;
  233.  
  234.       if (HAL_GetTick () - lastTick > 200)
  235.         {
  236.           lastTick = HAL_GetTick ();
  237.           /* Reading the raw data from sensor */
  238.           rslt = bmp280_get_uncomp_data (&ucomp_data, bmp);
  239.  
  240.           /* Check to see if the second BMP is online */
  241.           if (pollBmp2State ())
  242.             {
  243.               /* reading the raw data from the second sensor */
  244.               rslt2 = bmp280_get_uncomp_data (&ucomp_data2, bmp2);
  245.  
  246.               if (rslt2 == BMP280_OK)
  247.                 {
  248.                   rslt2 = bmp280_get_comp_temp_32bit (&temp32_out,
  249.                                                       ucomp_data2.uncomp_temp,
  250.                                                       bmp2);
  251.                 }
  252.               // if it returns 128,0,0 for both temperature and pressure at the same time,  then this ends up as the value 524288 which is broken ..
  253.               if (rslt2 != BMP280_OK
  254.                   || (ucomp_data2.uncomp_temp == 524288
  255.                       && ucomp_data2.uncomp_press == 524288))
  256.                 {
  257.                   /// try to reset the device, its playing up
  258.                   resetBmp2 ();
  259.  
  260.                 }
  261.             }
  262.           if (rslt == BMP280_OK)
  263.             {
  264.               /* Getting the 32 bit compensated temperature */
  265.               rslt = bmp280_get_comp_temp_32bit (&temp32,
  266.                                                  ucomp_data.uncomp_temp, bmp);
  267.  
  268.               rslt = bmp280_get_comp_pres_32bit (&pres32,
  269.                                                  ucomp_data.uncomp_press, bmp);
  270.  
  271. #if defined USB_DEVICE
  272.                 /*
  273.                  *  $--XDR,a,x.x,a,c--c, ..... *hh<CR><LF> \\
  274.  
  275.               Field Number:
  276.                  1) Transducer Type
  277.                  2) Measurement Data
  278.                  3) Units of measurement
  279.                  4) Name of transducer
  280.                  x) More of the same
  281.                  n) Checksum
  282.  
  283.                  Example:
  284.                  $IIXDR,C,19.52,C,TempAir*19
  285.                  $IIXDR,P,1.02481,B,Barometer*29
  286.  
  287.                  Currently, OpenCPN recognizes the following transducers:
  288.  
  289.                  Measured Value | Transducer Type | Measured Data   | Unit of measure | Transducer Name
  290.                  ------------------------------------------------------------------------------------------------------
  291.                  barometric     | "P" pressure    | 0.8..1.1 or 800..1100           | "B" bar         | "Barometer"
  292.                  air temperature| "C" temperature |   2 decimals                    | "C" celsius     | "TempAir" or "ENV_OUTAIR_T"
  293.                  pitch          | "A" angle       |-180..0 nose down 0..180 nose up | "D" degrees     | "PTCH" or "PITCH"
  294.                  rolling        | "A" angle       |-180..0 L         0..180 R       | "D" degrees     | "ROLL"
  295.                  water temp     | "C" temperature |   2 decimals                    | "C" celsius     | "ENV_WATER_T"
  296.                  */
  297.                 // compile a logger message over USB
  298.                 char buffer[200];
  299.                 int cnt = small_sprintf(buffer,"$MJXDR,C,%ld.%02ld,C,AirTemp,P,%01ld.%05ld,B,AirPres",temp32/100,temp32%100,pres32/100000,pres32%100000);
  300.                 uint8_t sum=0;
  301.                 for(int i=1; i<cnt; i++)
  302.                 sum += buffer[i];
  303.                 cnt+= small_sprintf(buffer+cnt,"*%02X\n",sum);
  304.  
  305.                 CDC_Transmit_FS(reinterpret_cast<uint8_t*>(&buffer[0]),cnt);
  306. #endif
  307.  
  308.             }
  309.         }
  310.       display1.gotoxy (0, 40);
  311.       display1.fontDigits (large_font, 4, 1, temp32_out / 10, WHITE);
  312.       display1.printString (small_font, "°", 1, WHITE);
  313.  
  314.       display1.gotoxy (0, 56);
  315.       display1.fontDigits (small_font, 3, 1, temp32 / 10, WHITE);
  316.       display1.printString (small_font, "° ", 2, WHITE);
  317.       display1.fontDigits (small_font, 4, -1, pres32 / 100, WHITE);
  318.       display1.printString (small_font, "mb", 2, WHITE);
  319.  
  320.       display1.display ();
  321.  
  322.     }
  323.  
  324.   HAL_Delay (10);
  325. }
  326.