Subversion Repositories dashGPS

Rev

Rev 29 | Go to most recent revision | 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
 
28 mjames 240
          /* reading the raw data from the second sensor */
241
          rslt2 = bmp280_get_uncomp_data (&ucomp_data2, bmp2);
26 mjames 242
 
28 mjames 243
          if (rslt2 == BMP280_OK)
244
            {
245
              rslt2 = bmp280_get_comp_temp_32bit (&temp32_out,
246
                                                  ucomp_data2.uncomp_temp,
247
                                                  bmp2);
248
            }
30 mjames 249
          // 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 ..
250
          if (rslt2 != BMP280_OK
251
              || (ucomp_data2.uncomp_temp == 524288
252
                  && ucomp_data2.uncomp_press == 524288))
29 mjames 253
            {
254
              /// try to reset the device, its playing up
255
              resetBmp2 ();
10 mjames 256
 
29 mjames 257
            }
258
 
28 mjames 259
          if (rslt == BMP280_OK)
260
            {
261
              /* Getting the 32 bit compensated temperature */
262
              rslt = bmp280_get_comp_temp_32bit (&temp32,
263
                                                 ucomp_data.uncomp_temp, bmp);
24 mjames 264
 
28 mjames 265
              rslt = bmp280_get_comp_pres_32bit (&pres32,
266
                                                 ucomp_data.uncomp_press, bmp);
26 mjames 267
 
15 mjames 268
#if defined USB_DEVICE
27 mjames 269
                /*
270
                 *  $--XDR,a,x.x,a,c--c, ..... *hh<CR><LF> \\
15 mjames 271
 
16 mjames 272
              Field Number:
27 mjames 273
                 1) Transducer Type
274
                 2) Measurement Data
275
                 3) Units of measurement
276
                 4) Name of transducer
277
                 x) More of the same
278
                 n) Checksum
16 mjames 279
 
27 mjames 280
                 Example:
281
                 $IIXDR,C,19.52,C,TempAir*19
282
                 $IIXDR,P,1.02481,B,Barometer*29
16 mjames 283
 
27 mjames 284
                 Currently, OpenCPN recognizes the following transducers:
16 mjames 285
 
27 mjames 286
                 Measured Value | Transducer Type | Measured Data   | Unit of measure | Transducer Name
287
                 ------------------------------------------------------------------------------------------------------
288
                 barometric     | "P" pressure    | 0.8..1.1 or 800..1100           | "B" bar         | "Barometer"
289
                 air temperature| "C" temperature |   2 decimals                    | "C" celsius     | "TempAir" or "ENV_OUTAIR_T"
290
                 pitch          | "A" angle       |-180..0 nose down 0..180 nose up | "D" degrees     | "PTCH" or "PITCH"
291
                 rolling        | "A" angle       |-180..0 L         0..180 R       | "D" degrees     | "ROLL"
292
                 water temp     | "C" temperature |   2 decimals                    | "C" celsius     | "ENV_WATER_T"
293
                 */
294
                // compile a logger message over USB
295
                char buffer[200];
296
                int cnt = small_sprintf(buffer,"$MJXDR,C,%ld.%02ld,C,AirTemp,P,%01ld.%05ld,B,AirPres",temp32/100,temp32%100,pres32/100000,pres32%100000);
297
                uint8_t sum=0;
298
                for(int i=1; i<cnt; i++)
299
                sum += buffer[i];
300
                cnt+= small_sprintf(buffer+cnt,"*%02X\n",sum);
13 mjames 301
 
27 mjames 302
                CDC_Transmit_FS(reinterpret_cast<uint8_t*>(&buffer[0]),cnt);
15 mjames 303
#endif
13 mjames 304
 
28 mjames 305
            }
306
        }
307
      display1.gotoxy (0, 40);
308
      display1.fontDigits (large_font, 4, 1, temp32_out / 10, WHITE);
309
      display1.printString (small_font, "°", 1, WHITE);
26 mjames 310
 
28 mjames 311
      display1.gotoxy (0, 56);
312
      display1.fontDigits (small_font, 3, 1, temp32 / 10, WHITE);
313
      display1.printString (small_font, "° ", 2, WHITE);
314
      display1.fontDigits (small_font, 4, -1, pres32 / 100, WHITE);
315
      display1.printString (small_font, "mb", 2, WHITE);
26 mjames 316
 
28 mjames 317
      display1.display ();
24 mjames 318
 
28 mjames 319
    }
26 mjames 320
 
28 mjames 321
  HAL_Delay (10);
322
}