Subversion Repositories dashGPS

Rev

Rev 27 | 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 ();
95
 
6 mjames 96
}
97
 
9 mjames 98
char fontBuf[] = "01234567";
6 mjames 99
extern "C" void
26 mjames 100
cc_run (struct bmp280_dev *bmp, struct bmp280_dev *bmp2)
11 mjames 101
 
6 mjames 102
{
27 mjames 103
  bool stat = updateLocation (&loc, &uc1);
23 mjames 104
 
27 mjames 105
  // process button press : done by polling loop
28 mjames 106
  uint8_t const buttonLimit = 3;
107
  uint8_t newPush = HAL_GPIO_ReadPin ( encoder_push_GPIO_Port,
108
  encoder_push_Pin);
109
  if (newPush == buttonState)
23 mjames 110
    buttonCount = 0;
28 mjames 111
  else if (buttonCount < buttonLimit)
23 mjames 112
    buttonCount++;
15 mjames 113
 
28 mjames 114
  if (buttonCount == buttonLimit)
115
    {
116
      buttonState = newPush;
117
      buttonCount = 0;
15 mjames 118
 
28 mjames 119
      // if the button is held down , we set the average speed
120
      if (buttonState == GPIO_PIN_RESET)
121
        {
122
          speedAvgSum = 0.0;
123
          speedAvgTime = 0.0;
124
        }
125
    }
23 mjames 126
 
28 mjames 127
  if (rmc_flag)
128
    {
129
      // get the time from the RTC
130
      RTC_TimeTypeDef sTime;
131
      rmc_flag = 0;
132
      display1.clearDisplay ();
133
      dial.draw_scale (0, 360, 8, 1, 45);
9 mjames 134
 
28 mjames 135
      if (loc.good)
136
        {
27 mjames 137
 
28 mjames 138
          heading = loc.heading;
139
          // add in time * speed to give "distance"
140
          if (loc.valid == 'A')
141
            {
142
              sTime.Seconds = loc.tv.tm_sec;
143
              sTime.Minutes = loc.tv.tm_min;
144
              sTime.Hours = loc.tv.tm_hour;
145
              HAL_RTC_SetTime (&hrtc, &sTime, RTC_FORMAT_BIN);
27 mjames 146
 
28 mjames 147
              if (lastLocTime != 0)
148
                {
149
                  double delta = difftime (loc.utc, lastLocTime);
150
                  // believe the speed .
151
                  if (delta > 0 && delta < 2)
152
                    {
153
                      speedAvgSum += loc.speed * delta;
154
                      speedAvgTime += delta;
155
                      lastLocTime = loc.utc;
156
                    }
157
                  else
27 mjames 158
                    lastLocTime = loc.utc;
28 mjames 159
                }
160
              else
161
                {
162
                  lastLocTime = loc.utc;
163
                }
164
            }
165
        }
166
      else
167
        {
168
          HAL_RTC_GetTime (&hrtc, &sTime, RTC_FORMAT_BIN);
169
        }
27 mjames 170
 
28 mjames 171
      // slow down the output of ata
172
      if (speedAvgTime > 0)
24 mjames 173
        speedAvg = (speedAvgSum / speedAvgTime) * KNOTS_TO_MPH;
28 mjames 174
      else
25 mjames 175
        speedAvg = 0.0;
23 mjames 176
 
28 mjames 177
      // update the display once per second
178
      loc.time[0] = (sTime.Hours / 10) + '0';
179
      loc.time[1] = (sTime.Hours % 10) + '0';
180
      loc.time[2] = (sTime.Minutes / 10) + '0';
181
      loc.time[3] = (sTime.Minutes % 10) + '0';
182
      loc.time[4] = (sTime.Seconds / 10) + '0';
183
      loc.time[5] = (sTime.Seconds % 10) + '0';
184
      // print out the GMT time at the top of the screen
185
      display1.gotoxy (0, 0);
186
      display1.printString (small_font, &loc.time[0], 2, WHITE);
187
      display1.printString (small_font, ":", 1, WHITE);
188
      display1.printString (small_font, &loc.time[2], 2, WHITE);
9 mjames 189
 
28 mjames 190
      display1.printString (small_font, ":", 1, WHITE);
191
      display1.printString (small_font, &loc.time[4], 2, WHITE);
9 mjames 192
 
28 mjames 193
      int dial_ang = heading + 180;
194
      dial.draw_needle (dial_ang);
9 mjames 195
 
28 mjames 196
      display1.gotoxy (70, 25);
197
      if (loc.valid == 'A')
198
        {
199
          display1.fontDigits (large_font, 3, -1, heading);
200
        }
201
      else
24 mjames 202
        display1.printString (large_font, "GPS?", 4, WHITE);
9 mjames 203
 
28 mjames 204
      if (loc.valid == 'A')
24 mjames 205
        speedMPH = loc.speed * KNOTS_TO_MPH;
28 mjames 206
      else
24 mjames 207
        speedMPH = 0.0;
9 mjames 208
 
28 mjames 209
      display1.gotoxy (0, 8);
210
      display1.fontDigits (large_font, 4, 1, speedMPH * 10);
211
      display1.printString (small_font, "c", 2, WHITE);
212
      display1.gotoxy (0, 24);
213
      display1.fontDigits (large_font, 4, 1, speedAvg * 10);
214
      display1.printString (small_font, "av", 2, WHITE);
10 mjames 215
 
28 mjames 216
      float x, y, z;
217
      if (IMU.magneticFieldAvailable ())
218
        {
24 mjames 219
 
28 mjames 220
          IMU.readMagneticField (x, y, z);
221
        }
26 mjames 222
 
28 mjames 223
      if (IMU.accelerationAvailable ())
224
        {
225
          IMU.readAcceleration (x, y, z);
226
        }
26 mjames 227
 
28 mjames 228
      struct bmp280_uncomp_data ucomp_data, ucomp_data2;
26 mjames 229
 
28 mjames 230
      if (HAL_GetTick () - lastTick > 100)
231
        {
232
          lastTick = HAL_GetTick ();
233
          /* Reading the raw data from sensor */
234
          rslt = bmp280_get_uncomp_data (&ucomp_data, bmp);
10 mjames 235
 
28 mjames 236
          /* reading the raw data from the second sensor */
237
          rslt2 = bmp280_get_uncomp_data (&ucomp_data2, bmp2);
26 mjames 238
 
28 mjames 239
          if (rslt2 == BMP280_OK)
240
            {
241
              rslt2 = bmp280_get_comp_temp_32bit (&temp32_out,
242
                                                  ucomp_data2.uncomp_temp,
243
                                                  bmp2);
244
            }
10 mjames 245
 
28 mjames 246
          if (rslt == BMP280_OK)
247
            {
248
              /* Getting the 32 bit compensated temperature */
249
              rslt = bmp280_get_comp_temp_32bit (&temp32,
250
                                                 ucomp_data.uncomp_temp, bmp);
24 mjames 251
 
28 mjames 252
              rslt = bmp280_get_comp_pres_32bit (&pres32,
253
                                                 ucomp_data.uncomp_press, bmp);
26 mjames 254
 
15 mjames 255
#if defined USB_DEVICE
27 mjames 256
                /*
257
                 *  $--XDR,a,x.x,a,c--c, ..... *hh<CR><LF> \\
15 mjames 258
 
16 mjames 259
              Field Number:
27 mjames 260
                 1) Transducer Type
261
                 2) Measurement Data
262
                 3) Units of measurement
263
                 4) Name of transducer
264
                 x) More of the same
265
                 n) Checksum
16 mjames 266
 
27 mjames 267
                 Example:
268
                 $IIXDR,C,19.52,C,TempAir*19
269
                 $IIXDR,P,1.02481,B,Barometer*29
16 mjames 270
 
27 mjames 271
                 Currently, OpenCPN recognizes the following transducers:
16 mjames 272
 
27 mjames 273
                 Measured Value | Transducer Type | Measured Data   | Unit of measure | Transducer Name
274
                 ------------------------------------------------------------------------------------------------------
275
                 barometric     | "P" pressure    | 0.8..1.1 or 800..1100           | "B" bar         | "Barometer"
276
                 air temperature| "C" temperature |   2 decimals                    | "C" celsius     | "TempAir" or "ENV_OUTAIR_T"
277
                 pitch          | "A" angle       |-180..0 nose down 0..180 nose up | "D" degrees     | "PTCH" or "PITCH"
278
                 rolling        | "A" angle       |-180..0 L         0..180 R       | "D" degrees     | "ROLL"
279
                 water temp     | "C" temperature |   2 decimals                    | "C" celsius     | "ENV_WATER_T"
280
                 */
281
                // compile a logger message over USB
282
                char buffer[200];
283
                int cnt = small_sprintf(buffer,"$MJXDR,C,%ld.%02ld,C,AirTemp,P,%01ld.%05ld,B,AirPres",temp32/100,temp32%100,pres32/100000,pres32%100000);
284
                uint8_t sum=0;
285
                for(int i=1; i<cnt; i++)
286
                sum += buffer[i];
287
                cnt+= small_sprintf(buffer+cnt,"*%02X\n",sum);
13 mjames 288
 
27 mjames 289
                CDC_Transmit_FS(reinterpret_cast<uint8_t*>(&buffer[0]),cnt);
15 mjames 290
#endif
13 mjames 291
 
28 mjames 292
            }
293
        }
294
      display1.gotoxy (0, 40);
295
      display1.fontDigits (large_font, 4, 1, temp32_out / 10, WHITE);
296
      display1.printString (small_font, "°", 1, WHITE);
26 mjames 297
 
28 mjames 298
      display1.gotoxy (0, 56);
299
      display1.fontDigits (small_font, 3, 1, temp32 / 10, WHITE);
300
      display1.printString (small_font, "° ", 2, WHITE);
301
      display1.fontDigits (small_font, 4, -1, pres32 / 100, WHITE);
302
      display1.printString (small_font, "mb", 2, WHITE);
26 mjames 303
 
28 mjames 304
      display1.display ();
24 mjames 305
 
28 mjames 306
    }
26 mjames 307
 
28 mjames 308
  HAL_Delay (10);
309
}