Subversion Repositories dashGPS

Rev

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

Rev Author Line No. Line
6 mjames 1
#include "main.h"
15 mjames 2
#include "libNMEA/nmea.h"
9 mjames 3
#include <cstring>
6 mjames 4
#include "libOLED/stm32_halDisplay.H"
7 mjames 5
#include "libOLED/fontclass.H"
8 mjames 6
#include "libOLED/displayDial.H"
26 mjames 7
#include "libLSM9DS1/LSM9DS1.h"
7 mjames 8
 
11 mjames 9
#include "libBMP280/bmp280.h"
10
 
13 mjames 11
#include "libSmallPrintf/small_printf.h"
15 mjames 12
 
13
#if defined USB_DEVICE
13 mjames 14
#include "usbd_cdc_if.h"
15 mjames 15
#endif
13 mjames 16
 
26 mjames 17
LSM9DS1Class IMU (&hi2c2);
18
 
6 mjames 19
namespace
20
{
21
  int const WIDTH = 128;
22
  int const HEIGHT = 64;
23
  int const DISPLAY_RAMWIDTH = 132;
24
 
25
}
26
 
10 mjames 27
float speedMPH = 0.0;
23 mjames 28
float speedAvg = 0.0;
15 mjames 29
 
23 mjames 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
15 mjames 33
 
24 mjames 34
uint32_t nextPosTime = 0;
35
 
23 mjames 36
// convert knots to MPH
37
double const KNOTS_TO_MPH = 1.128;
9 mjames 38
int heading = 0;
39
Location loc;
40
 
11 mjames 41
uint32_t lastTick = 0;
42
int32_t temp32 = 0;
43
uint32_t pres32 = 0;
44
int32_t rslt;
26 mjames 45
int32_t rslt2; // result from read of second sensor
46
// second sensor
47
int32_t temp32_out = 0;
11 mjames 48
 
6 mjames 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
 
9 mjames 61
displayDial_t dial (display1, 96, 32, 32, 180);
8 mjames 62
 
22 mjames 63
// debouncer for the button
64
char buttonState;
65
char buttonCount;
27 mjames 66
char rmc_flag = 0;
22 mjames 67
 
27 mjames 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
 
6 mjames 77
extern "C" void
78
cc_init ()
79
{
11 mjames 80
  display1.reset ();
81
 
9 mjames 82
  display1.init ();
6 mjames 83
  display1.clearDisplay ();
84
 
9 mjames 85
  dial.draw_scale (0, 360, 8, 1, 45);
6 mjames 86
 
87
  display1.display ();
9 mjames 88
 
10 mjames 89
  memset (loc.time, '-', 6);
26 mjames 90
  // every time we receive GPRMC, forward the text line to the USB driver
27 mjames 91
  setRmcCallback (&rmc_callback);
26 mjames 92
 
93
  // initialise IMU operations
94
  IMU.begin ();
6 mjames 95
}
96
 
9 mjames 97
char fontBuf[] = "01234567";
6 mjames 98
extern "C" void
26 mjames 99
cc_run (struct bmp280_dev *bmp, struct bmp280_dev *bmp2)
11 mjames 100
 
6 mjames 101
{
27 mjames 102
  bool stat = updateLocation (&loc, &uc1);
23 mjames 103
 
27 mjames 104
  // process button press : done by polling loop
28 mjames 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)
23 mjames 109
    buttonCount = 0;
28 mjames 110
  else if (buttonCount < buttonLimit)
23 mjames 111
    buttonCount++;
15 mjames 112
 
28 mjames 113
  if (buttonCount == buttonLimit)
114
    {
115
      buttonState = newPush;
116
      buttonCount = 0;
15 mjames 117
 
28 mjames 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
    }
23 mjames 125
 
28 mjames 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);
9 mjames 133
 
28 mjames 134
      if (loc.good)
135
        {
27 mjames 136
 
28 mjames 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);
27 mjames 145
 
28 mjames 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
27 mjames 157
                    lastLocTime = loc.utc;
28 mjames 158
                }
159
              else
160
                {
161
                  lastLocTime = loc.utc;
162
                }
163
            }
164
        }
165
      else
166
        {
167
          HAL_RTC_GetTime (&hrtc, &sTime, RTC_FORMAT_BIN);
168
        }
27 mjames 169
 
28 mjames 170
      // slow down the output of ata
171
      if (speedAvgTime > 0)
24 mjames 172
        speedAvg = (speedAvgSum / speedAvgTime) * KNOTS_TO_MPH;
28 mjames 173
      else
25 mjames 174
        speedAvg = 0.0;
23 mjames 175
 
28 mjames 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);
9 mjames 188
 
28 mjames 189
      display1.printString (small_font, ":", 1, WHITE);
190
      display1.printString (small_font, &loc.time[4], 2, WHITE);
9 mjames 191
 
28 mjames 192
      int dial_ang = heading + 180;
193
      dial.draw_needle (dial_ang);
9 mjames 194
 
28 mjames 195
      display1.gotoxy (70, 25);
196
      if (loc.valid == 'A')
197
        {
30 mjames 198
          if (heading < 100)
199
            display1.moveby (2, 0);
200
          if (heading < 10)
201
            display1.moveby (2, 0);
202
 
28 mjames 203
          display1.fontDigits (large_font, 3, -1, heading);
204
        }
205
      else
24 mjames 206
        display1.printString (large_font, "GPS?", 4, WHITE);
9 mjames 207
 
28 mjames 208
      if (loc.valid == 'A')
24 mjames 209
        speedMPH = loc.speed * KNOTS_TO_MPH;
28 mjames 210
      else
24 mjames 211
        speedMPH = 0.0;
9 mjames 212
 
28 mjames 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);
10 mjames 219
 
28 mjames 220
      float x, y, z;
221
      if (IMU.magneticFieldAvailable ())
222
        {
24 mjames 223
 
28 mjames 224
          IMU.readMagneticField (x, y, z);
225
        }
26 mjames 226
 
28 mjames 227
      if (IMU.accelerationAvailable ())
228
        {
229
          IMU.readAcceleration (x, y, z);
230
        }
26 mjames 231
 
28 mjames 232
      struct bmp280_uncomp_data ucomp_data, ucomp_data2;
26 mjames 233
 
30 mjames 234
      if (HAL_GetTick () - lastTick > 200)
28 mjames 235
        {
236
          lastTick = HAL_GetTick ();
237
          /* Reading the raw data from sensor */
238
          rslt = bmp280_get_uncomp_data (&ucomp_data, bmp);
10 mjames 239
 
31 mjames 240
          /* Check to see if the second BMP is online */
241
          if (pollBmp2State ())
28 mjames 242
            {
31 mjames 243
              /* reading the raw data from the second sensor */
244
              rslt2 = bmp280_get_uncomp_data (&ucomp_data2, bmp2);
10 mjames 245
 
31 mjames 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
                }
29 mjames 261
            }
28 mjames 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);
24 mjames 267
 
28 mjames 268
              rslt = bmp280_get_comp_pres_32bit (&pres32,
269
                                                 ucomp_data.uncomp_press, bmp);
26 mjames 270
 
15 mjames 271
#if defined USB_DEVICE
27 mjames 272
                /*
273
                 *  $--XDR,a,x.x,a,c--c, ..... *hh<CR><LF> \\
15 mjames 274
 
16 mjames 275
              Field Number:
27 mjames 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
16 mjames 282
 
27 mjames 283
                 Example:
284
                 $IIXDR,C,19.52,C,TempAir*19
285
                 $IIXDR,P,1.02481,B,Barometer*29
16 mjames 286
 
27 mjames 287
                 Currently, OpenCPN recognizes the following transducers:
16 mjames 288
 
27 mjames 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);
13 mjames 304
 
27 mjames 305
                CDC_Transmit_FS(reinterpret_cast<uint8_t*>(&buffer[0]),cnt);
15 mjames 306
#endif
13 mjames 307
 
28 mjames 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);
26 mjames 313
 
28 mjames 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);
26 mjames 319
 
28 mjames 320
      display1.display ();
24 mjames 321
 
28 mjames 322
    }
26 mjames 323
 
28 mjames 324
  HAL_Delay (10);
325
}