A porting of a GPS decoding and presenting program within the mbos RTOS. It is not a definitive application but a study program to test NMEA full decoding library and a first approach to an RTOS. Many thanks to Andrew Levido for his support and his patience on teaching me the RTOS principles from the other side of the Earth. It uses NMEA library by Tim (xtimor@gmail.com) ported by Ken Todotani (http://mbed.org/users/todotani/) on public mbed library (http://mbed.org/users/todotani/programs/GPS_nmeaLib/5yo4h) also available, as original universal C library, on http://nmea.sourceforge.net

Dependencies:   mbos Watchdog TextLCD mbed ConfigFile

Committer:
guiott
Date:
Sun Jan 29 22:08:35 2012 +0000
Revision:
1:360c4a23cb1d
Parent:
0:d177c0087d1f
Child:
2:8917036cbf69

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
guiott 0:d177c0087d1f 1 /* ////////////////////////////////////////////////////////////////////////////
guiott 0:d177c0087d1f 2 ** File: LeonardoMbos.cpp
guiott 0:d177c0087d1f 3 */
guiott 0:d177c0087d1f 4 /* 12345678901234567890 */
guiott 0:d177c0087d1f 5 char Ver1[] = "Leonardo's GPS 0.1.0";
guiott 0:d177c0087d1f 6 char Ver2[] = " by Guiott 01-12";
guiott 0:d177c0087d1f 7 /**
guiott 0:d177c0087d1f 8 * \mainpage Leonardo.cpp
guiott 0:d177c0087d1f 9 * \author Guido Ottaviani-->guido@guiott.com<--
guiott 0:d177c0087d1f 10 * \version 0.1.0
guiott 0:d177c0087d1f 11 * \date 01/2012
guiott 0:d177c0087d1f 12 * \details This is a test program to study the capability of a GPS module to
guiott 0:d177c0087d1f 13 control navigation of a robot in an outdoor environment.
guiott 0:d177c0087d1f 14
guiott 0:d177c0087d1f 15 This version is developed within the mbos RTOS:
guiott 0:d177c0087d1f 16 http://mbed.org/users/AndrewL/libraries/mbos/lqn3ca
guiott 0:d177c0087d1f 17
guiott 0:d177c0087d1f 18 It uses NMEA library by Tim (xtimor@gmail.com)
guiott 0:d177c0087d1f 19 available on public mbed library or http://nmea.sourceforge.net
guiott 0:d177c0087d1f 20
guiott 0:d177c0087d1f 21 The original gmath.c has been modified to fix a bug in nmea_distance_ellipsoid() function
guiott 0:d177c0087d1f 22 according to bug report ID: 2945855
guiott 0:d177c0087d1f 23
guiott 0:d177c0087d1f 24 http://sourceforge.net/tracker/?func=detail&aid=2945855&group_id=192054&atid=939854
guiott 0:d177c0087d1f 25
guiott 0:d177c0087d1f 26 // while ((delta_lambda > 1e-12) && (remaining_steps > 0)) original by xtimor
guiott 0:d177c0087d1f 27 while (( remaining_steps == 20 ) || ((fabs(delta_lambda) > 1e-12) && (remaining_steps > 0)))
guiott 0:d177c0087d1f 28
guiott 0:d177c0087d1f 29 the original code always returns a zero distance if the arrival point longitude
guiott 0:d177c0087d1f 30 is equal or smaller than the starting point one.
guiott 0:d177c0087d1f 31
guiott 0:d177c0087d1f 32 The mbed module is interfaced with a Garmin GPS sensor (used in standard mode)
guiott 0:d177c0087d1f 33 with an external antenna, a 20x4 LCD text display and a 5 keys keypad.
guiott 0:d177c0087d1f 34 A curiosity:
guiott 0:d177c0087d1f 35 All the hardware components of the test set are mounted on the top of a wooden
guiott 0:d177c0087d1f 36 box, looking like a kind of a steampunk navigator. When my daughter looked at
guiott 0:d177c0087d1f 37 the box she said: "it looks alike the navigator of the da Vinci car".
guiott 0:d177c0087d1f 38 This is the reason why the name of this project is "Leonardo".
guiott 0:d177c0087d1f 39 **
guiott 0:d177c0087d1f 40 -------------------------------------------------------------------------------
guiott 0:d177c0087d1f 41 * \copyright 2012 Guido Ottaviani
guiott 0:d177c0087d1f 42 guido@guiott.com
guiott 0:d177c0087d1f 43
guiott 0:d177c0087d1f 44 LeonardoMbos is free software: you can redistribute it and/or modify
guiott 0:d177c0087d1f 45 it under the terms of the GNU General Public License as published by
guiott 0:d177c0087d1f 46 the Free Software Foundation, either version 3 of the License, or
guiott 0:d177c0087d1f 47 (at your option) any later version.
guiott 0:d177c0087d1f 48
guiott 1:360c4a23cb1d 49 LeonardoMbos is distributed in the hope that it will be useful,
guiott 0:d177c0087d1f 50 but WITHOUT ANY WARRANTY; without even the implied warranty of
guiott 0:d177c0087d1f 51 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
guiott 0:d177c0087d1f 52 GNU General Public License for more details.
guiott 0:d177c0087d1f 53
guiott 0:d177c0087d1f 54 You should have received a copy of the GNU General Public License
guiott 0:d177c0087d1f 55 along with LeonardoMbos.cpp. If not, see <http://www.gnu.org/licenses/>.
guiott 0:d177c0087d1f 56
guiott 0:d177c0087d1f 57 -------------------------------------------------------------------------------
guiott 0:d177c0087d1f 58 */
guiott 0:d177c0087d1f 59 #include "Common.h"
guiott 0:d177c0087d1f 60 #include "mbed.h"
guiott 0:d177c0087d1f 61 #include <string>
guiott 0:d177c0087d1f 62 #include "TextLCD.h"
guiott 0:d177c0087d1f 63 #include "nmea/nmea.h"
guiott 0:d177c0087d1f 64 #include "Init.h"
guiott 0:d177c0087d1f 65 #include "Prototype.h"
guiott 0:d177c0087d1f 66 #include "mbos.h"
guiott 0:d177c0087d1f 67 #include "Tasks.h"
guiott 0:d177c0087d1f 68 #include <Watchdog.h>
guiott 0:d177c0087d1f 69
guiott 0:d177c0087d1f 70 TextLCD lcd(p12, p11, p24, p23, p22, p21, TextLCD::LCD20x4); // rs, e, d4-d7
guiott 0:d177c0087d1f 71
guiott 0:d177c0087d1f 72 Watchdog wd;
guiott 0:d177c0087d1f 73
guiott 0:d177c0087d1f 74 // Set up RTOS;
guiott 0:d177c0087d1f 75 mbos os(NUM_TASKS, NUM_TIMERS, NUM_RESOURCES);
guiott 0:d177c0087d1f 76
guiott 0:d177c0087d1f 77 int main()
guiott 0:d177c0087d1f 78 {
guiott 0:d177c0087d1f 79 Initialize();
guiott 0:d177c0087d1f 80 if (wd.WatchdogCausedReset())
guiott 0:d177c0087d1f 81 {
guiott 0:d177c0087d1f 82 pc.printf("Watchdog caused reset**********************************\r\n");
guiott 0:d177c0087d1f 83 }
guiott 0:d177c0087d1f 84 wd.Configure(WDT_TIMER); // sets the timeout interval
guiott 0:d177c0087d1f 85
guiott 0:d177c0087d1f 86 os.Start(); // the RTOS starts now
guiott 0:d177c0087d1f 87 }
guiott 0:d177c0087d1f 88
guiott 0:d177c0087d1f 89 //functions =====================================================================
guiott 0:d177c0087d1f 90
guiott 0:d177c0087d1f 91 int CmpRead(void)
guiott 0:d177c0087d1f 92 {/**
guiott 0:d177c0087d1f 93 *\brief Magnetic Compass reading
guiott 0:d177c0087d1f 94 */
guiott 0:d177c0087d1f 95 int Cmp;
guiott 0:d177c0087d1f 96
guiott 0:d177c0087d1f 97 // To Be Done
guiott 0:d177c0087d1f 98 Cmp = 0; // ************debug
guiott 0:d177c0087d1f 99 return(Cmp);
guiott 0:d177c0087d1f 100 }
guiott 0:d177c0087d1f 101
guiott 0:d177c0087d1f 102 void mbosIdleTask(void)
guiott 0:d177c0087d1f 103 {/**
guiott 0:d177c0087d1f 104 *\brief TASK 0 watchdog kick
guiott 0:d177c0087d1f 105 */
guiott 0:d177c0087d1f 106 while(1)
guiott 0:d177c0087d1f 107 {
guiott 0:d177c0087d1f 108 wd.Service(); // kick the dog before the timeout
guiott 0:d177c0087d1f 109 }
guiott 0:d177c0087d1f 110 }
guiott 0:d177c0087d1f 111
guiott 0:d177c0087d1f 112 void TempTask(void)
guiott 0:d177c0087d1f 113 {/**
guiott 0:d177c0087d1f 114 *\brief TASK 8 used to temporary test some functions
guiott 0:d177c0087d1f 115 */
guiott 0:d177c0087d1f 116 static int TempAng;
guiott 0:d177c0087d1f 117 while (1)
guiott 0:d177c0087d1f 118 {
guiott 0:d177c0087d1f 119 os.WaitEvent(TEMP_EVT);
guiott 0:d177c0087d1f 120
guiott 0:d177c0087d1f 121 if((TempAng+=5) >=360)
guiott 0:d177c0087d1f 122 {
guiott 0:d177c0087d1f 123 TempAng=0;
guiott 0:d177c0087d1f 124 }
guiott 0:d177c0087d1f 125 Ang[Mag]=TempAng;
guiott 0:d177c0087d1f 126 Ang[Dir]=360-TempAng;
guiott 0:d177c0087d1f 127 Ang[Gps]=180-TempAng;
guiott 0:d177c0087d1f 128 printf("%i %i %i \n", Ang[0], Ang[1], Ang[2]);
guiott 0:d177c0087d1f 129 }
guiott 0:d177c0087d1f 130 }
guiott 0:d177c0087d1f 131
guiott 0:d177c0087d1f 132 void GpsStringParse(void)
guiott 0:d177c0087d1f 133 {/**
guiott 0:d177c0087d1f 134 *\brief parse the GPS string to extract info
guiott 0:d177c0087d1f 135 */
guiott 0:d177c0087d1f 136 gps.attach(NULL); // Suspend serial interrupt while buffer change
guiott 0:d177c0087d1f 137 size = writePointer;
guiott 0:d177c0087d1f 138 writePointer = 0;
guiott 0:d177c0087d1f 139 bufferSelect++; // Change buffer
guiott 0:d177c0087d1f 140 gps.attach( &GpsSerialIsr ); // Resume serial interrupt
guiott 0:d177c0087d1f 141 nmea_parse(&parser, msgBuff[(bufferSelect-1)&1], size, &info);
guiott 0:d177c0087d1f 142 Coordinates(); // transform nmea coordinates in decimal degrees
guiott 0:d177c0087d1f 143 }
guiott 0:d177c0087d1f 144
guiott 0:d177c0087d1f 145 void GpsDist(void)
guiott 0:d177c0087d1f 146 {/**
guiott 0:d177c0087d1f 147 *\brief compute the distance and direction (forward and reverse)
guiott 0:d177c0087d1f 148 from point A to point B on the ellipsoid
guiott 0:d177c0087d1f 149 */
guiott 0:d177c0087d1f 150
guiott 0:d177c0087d1f 151 nmea_info2pos(&info, &Pos[0]); // current position
guiott 0:d177c0087d1f 152 nmea_info2pos(&Dest, &Pos[1]); // destination
guiott 0:d177c0087d1f 153
guiott 0:d177c0087d1f 154 Path.Dist = nmea_distance_ellipsoid(&Pos[0], &Pos[1], &Path.Azimuth[1], &Path.Azimuth[0]);
guiott 0:d177c0087d1f 155
guiott 0:d177c0087d1f 156 if(Path.Azimuth[0] > NMEA_PI)
guiott 0:d177c0087d1f 157 {// reverse direction
guiott 0:d177c0087d1f 158 Path.Azimuth[0] = Path.Azimuth[0] - NMEA_PI;
guiott 0:d177c0087d1f 159 }
guiott 0:d177c0087d1f 160 else
guiott 0:d177c0087d1f 161 {
guiott 0:d177c0087d1f 162 Path.Azimuth[1] = Path.Azimuth[1] + NMEA_PI;
guiott 0:d177c0087d1f 163 }
guiott 0:d177c0087d1f 164
guiott 0:d177c0087d1f 165 for(int i=0; i < 2; i++)
guiott 0:d177c0087d1f 166 {
guiott 0:d177c0087d1f 167 Path.Azimuth[i]=(nmea_radian2degree(Path.Azimuth[i]));
guiott 0:d177c0087d1f 168 if(Path.Azimuth[i] > 360)
guiott 0:d177c0087d1f 169 {
guiott 0:d177c0087d1f 170 Path.Azimuth[i] = Path.Azimuth[i] - 360;
guiott 0:d177c0087d1f 171 }
guiott 0:d177c0087d1f 172 if(Path.Azimuth[i] < 0)
guiott 0:d177c0087d1f 173 {
guiott 0:d177c0087d1f 174 Path.Azimuth[i] = Path.Azimuth[i] + 360;
guiott 0:d177c0087d1f 175 }
guiott 0:d177c0087d1f 176 }
guiott 0:d177c0087d1f 177 }
guiott 0:d177c0087d1f 178
guiott 0:d177c0087d1f 179 void LcdLightDimTask(void)
guiott 0:d177c0087d1f 180 {/**
guiott 0:d177c0087d1f 181 *\brief TASK 7, control the LCD backlight intensity to smoothly
guiott 0:d177c0087d1f 182 switch it on or off
guiott 0:d177c0087d1f 183 */
guiott 0:d177c0087d1f 184 static float LightVal=1;
guiott 0:d177c0087d1f 185
guiott 0:d177c0087d1f 186 while(1)
guiott 0:d177c0087d1f 187 {
guiott 0:d177c0087d1f 188 os.WaitEvent(LCD_LIGHT_DIM_ON_EVT | LCD_LIGHT_DIM_OFF_EVT);
guiott 0:d177c0087d1f 189 if(os.GetEvent()==LCD_LIGHT_DIM_ON_EVT)
guiott 0:d177c0087d1f 190 {
guiott 0:d177c0087d1f 191 if(LightVal<1)
guiott 0:d177c0087d1f 192 {
guiott 0:d177c0087d1f 193 for (LightVal=0; LightVal<=1; LightVal+=0.01f)
guiott 0:d177c0087d1f 194 {
guiott 0:d177c0087d1f 195 LcdBklight=LightVal;
guiott 0:d177c0087d1f 196 wait_ms(10);
guiott 0:d177c0087d1f 197 }
guiott 0:d177c0087d1f 198 }
guiott 0:d177c0087d1f 199 // Set the timer for the power saving backlight switch off
guiott 0:d177c0087d1f 200 os.ClearTimer(LCD_LIGHT_DIM_OFF_TMR);
guiott 0:d177c0087d1f 201 os.SetTimer(LCD_LIGHT_DIM_OFF_TMR, LCD_LIGHT_DIM_TIMER, 0);
guiott 0:d177c0087d1f 202 }
guiott 0:d177c0087d1f 203 else if(os.GetEvent()==LCD_LIGHT_DIM_OFF_EVT)
guiott 0:d177c0087d1f 204 {// The dimming off is slower than lighting up
guiott 0:d177c0087d1f 205 for (LightVal=1; LightVal>=0; LightVal-=0.01f)
guiott 0:d177c0087d1f 206 {
guiott 0:d177c0087d1f 207 LcdBklight=LightVal;
guiott 0:d177c0087d1f 208 wait_ms(30);
guiott 0:d177c0087d1f 209 }
guiott 0:d177c0087d1f 210 }
guiott 0:d177c0087d1f 211 }
guiott 0:d177c0087d1f 212 }
guiott 0:d177c0087d1f 213
guiott 0:d177c0087d1f 214 void Coordinates(void)
guiott 0:d177c0087d1f 215 {/**
guiott 0:d177c0087d1f 216 *\brief transform nmea coordinates in decimal degrees
guiott 0:d177c0087d1f 217 */
guiott 0:d177c0087d1f 218 degrees = trunc(info.lat / 100.0);
guiott 0:d177c0087d1f 219 minutes = info.lat - (degrees * 100.0);
guiott 0:d177c0087d1f 220 latitude = degrees + minutes / 60.0;
guiott 0:d177c0087d1f 221 degrees = trunc(info.lon / 100.0);
guiott 0:d177c0087d1f 222 minutes = info.lon - (degrees * 100.0);
guiott 0:d177c0087d1f 223 longitude = degrees + minutes / 60.0;
guiott 0:d177c0087d1f 224 }
guiott 0:d177c0087d1f 225
guiott 0:d177c0087d1f 226 void Deg2DegMinSec(double DecDeg, DegMinSec *DecSec)
guiott 0:d177c0087d1f 227 {/**
guiott 0:d177c0087d1f 228 *\brief convert decimalDeg to Deg Min decimalSec
guiott 0:d177c0087d1f 229 */
guiott 0:d177c0087d1f 230 DecSec->Deg = trunc(DecDeg);
guiott 0:d177c0087d1f 231 double MinDec = (DecDeg - DecSec->Deg);
guiott 0:d177c0087d1f 232 DecSec->Min = trunc(MinDec * 60);
guiott 0:d177c0087d1f 233 DecSec->Sec = (MinDec * 3600) - (DecSec->Min * 60);
guiott 0:d177c0087d1f 234 }
guiott 0:d177c0087d1f 235
guiott 0:d177c0087d1f 236 void ShowPcTask(void)
guiott 0:d177c0087d1f 237 {/**
guiott 0:d177c0087d1f 238 *\brief TASK 6, if a PC is connected, debug information can be sent to the console
guiott 0:d177c0087d1f 239 */
guiott 0:d177c0087d1f 240 static int it = 0;
guiott 0:d177c0087d1f 241 int i;
guiott 0:d177c0087d1f 242 DegMinSec DecCoord;
guiott 0:d177c0087d1f 243
guiott 0:d177c0087d1f 244 os.SetTimer(SHOW_PC_TMR, 1000, 1000);
guiott 0:d177c0087d1f 245 while(1)
guiott 0:d177c0087d1f 246 {
guiott 0:d177c0087d1f 247 os.WaitEvent(SHOW_PC_EVT);
guiott 0:d177c0087d1f 248
guiott 0:d177c0087d1f 249 if(pc.readable())
guiott 0:d177c0087d1f 250 {// wait for an input
guiott 0:d177c0087d1f 251 PcMonitor = (pc.getc()-48); // digit a number to en/dis-able debug
guiott 0:d177c0087d1f 252 }
guiott 0:d177c0087d1f 253
guiott 0:d177c0087d1f 254 if( PcMonitor==1 || PcMonitor>5)
guiott 0:d177c0087d1f 255 {// Display Info parameters
guiott 0:d177c0087d1f 256 pc.printf(
guiott 0:d177c0087d1f 257 "%03d, Lat: %f, Lon: %f, Sig:%d, Fix:%d, Inuse:%d\r\n",
guiott 0:d177c0087d1f 258 it++, latitude, longitude, info.sig, info.fix, info.satinfo.inuse );
guiott 0:d177c0087d1f 259 for (i = 0; i < NMEA_MAXSAT; i++)
guiott 0:d177c0087d1f 260 {
guiott 0:d177c0087d1f 261 if (info.satinfo.sat[i].sig > 0)
guiott 0:d177c0087d1f 262 pc.printf(" sat_id:%02d, sig:%02d, Inuse:%d\r\n",
guiott 0:d177c0087d1f 263 info.satinfo.sat[i].id , info.satinfo.sat[i].sig,
guiott 0:d177c0087d1f 264 info.satinfo.sat[i].in_use);
guiott 0:d177c0087d1f 265 }
guiott 0:d177c0087d1f 266 pc.printf("\r\n");
guiott 0:d177c0087d1f 267 }
guiott 0:d177c0087d1f 268
guiott 0:d177c0087d1f 269 if( PcMonitor==2 || PcMonitor>5)
guiott 0:d177c0087d1f 270 {// Display Distance parameters
guiott 0:d177c0087d1f 271 Deg2DegMinSec(nmea_radian2degree(Pos[0].lat), &DecCoord);
guiott 0:d177c0087d1f 272 pc.printf("Lat1:%d %d\'%.3f\" ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
guiott 0:d177c0087d1f 273 Deg2DegMinSec(nmea_radian2degree(Pos[0].lon), &DecCoord);
guiott 0:d177c0087d1f 274 pc.printf("Lon1:%d %d\'%.3f\" ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
guiott 0:d177c0087d1f 275 Deg2DegMinSec(nmea_radian2degree(Pos[1].lat), &DecCoord);
guiott 0:d177c0087d1f 276 pc.printf("Lat2:%d %d\'%.3f\" ", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
guiott 0:d177c0087d1f 277 Deg2DegMinSec(nmea_radian2degree(Pos[1].lon), &DecCoord);
guiott 0:d177c0087d1f 278 pc.printf("Lon2:%d %d\'%.3f\" \n", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
guiott 0:d177c0087d1f 279 pc.printf("Dist:%f Azimuth Start:%f Azimuth Final:%f \n\n",
guiott 0:d177c0087d1f 280 Path.Dist, Path.Azimuth[0], Path.Azimuth[1]);
guiott 0:d177c0087d1f 281 }
guiott 0:d177c0087d1f 282 }
guiott 0:d177c0087d1f 283 }
guiott 0:d177c0087d1f 284
guiott 0:d177c0087d1f 285 void ShowLcdTask(void)
guiott 0:d177c0087d1f 286 {/**
guiott 0:d177c0087d1f 287 *\brief TASK 3, display desired data on LCD
guiott 0:d177c0087d1f 288 */
guiott 0:d177c0087d1f 289
guiott 0:d177c0087d1f 290 static int Previous=0;
guiott 0:d177c0087d1f 291
guiott 0:d177c0087d1f 292 os.SetTimer(SHOW_LCD_TMR, SHOW_LCD_TIMER, 0);
guiott 0:d177c0087d1f 293 while(1)
guiott 0:d177c0087d1f 294 {
guiott 0:d177c0087d1f 295 os.WaitEvent(SHOW_LCD_EVT);
guiott 0:d177c0087d1f 296
guiott 0:d177c0087d1f 297 if(Previous != Menu)
guiott 0:d177c0087d1f 298 {// clear the display when function changes
guiott 0:d177c0087d1f 299 lcd.cls();
guiott 0:d177c0087d1f 300 Previous=Menu;
guiott 0:d177c0087d1f 301 }
guiott 0:d177c0087d1f 302
guiott 0:d177c0087d1f 303 switch(Menu)
guiott 0:d177c0087d1f 304 {
guiott 0:d177c0087d1f 305 case 0:
guiott 0:d177c0087d1f 306 showSatLcd();
guiott 0:d177c0087d1f 307 Previous=0;
guiott 0:d177c0087d1f 308 break;
guiott 0:d177c0087d1f 309
guiott 0:d177c0087d1f 310 case 1:
guiott 0:d177c0087d1f 311 if(info.sig != 0)
guiott 0:d177c0087d1f 312 {
guiott 0:d177c0087d1f 313 showInfoLcd();
guiott 0:d177c0087d1f 314 }
guiott 0:d177c0087d1f 315 else
guiott 0:d177c0087d1f 316 {
guiott 0:d177c0087d1f 317 showSatLcd();
guiott 0:d177c0087d1f 318 }
guiott 0:d177c0087d1f 319 Previous=1;
guiott 0:d177c0087d1f 320 break;
guiott 0:d177c0087d1f 321
guiott 0:d177c0087d1f 322 case 2:
guiott 0:d177c0087d1f 323 showMenuLcd();
guiott 0:d177c0087d1f 324 Previous=2;
guiott 0:d177c0087d1f 325 break;
guiott 0:d177c0087d1f 326
guiott 0:d177c0087d1f 327 case 3:
guiott 0:d177c0087d1f 328 showMenuLcd1();
guiott 0:d177c0087d1f 329 Previous=3;
guiott 0:d177c0087d1f 330 break;
guiott 0:d177c0087d1f 331
guiott 0:d177c0087d1f 332 case 4:
guiott 1:360c4a23cb1d 333 ShowPathLcd();
guiott 0:d177c0087d1f 334 Previous=4;
guiott 0:d177c0087d1f 335 break;
guiott 0:d177c0087d1f 336
guiott 0:d177c0087d1f 337 default:
guiott 0:d177c0087d1f 338 showInfoLcd();
guiott 0:d177c0087d1f 339 break;
guiott 0:d177c0087d1f 340 }
guiott 0:d177c0087d1f 341 //restart timer for other options
guiott 0:d177c0087d1f 342 os.SetTimer(SHOW_LCD_TMR, SHOW_LCD_TIMER, 0);
guiott 0:d177c0087d1f 343 }
guiott 0:d177c0087d1f 344 }
guiott 0:d177c0087d1f 345
guiott 1:360c4a23cb1d 346 void ShowPathLcd(void)
guiott 1:360c4a23cb1d 347 {
guiott 1:360c4a23cb1d 348 static int ChooseDir=0;
guiott 1:360c4a23cb1d 349 DegMinSec DecCoord;
guiott 1:360c4a23cb1d 350
guiott 1:360c4a23cb1d 351 Ang[Gps]=info.direction;
guiott 1:360c4a23cb1d 352 Ang[Mag]=CmpRead()-info.declination; //Compass reading corrected by declination
guiott 1:360c4a23cb1d 353 Ang[Dir]=Path.Azimuth[0];
guiott 1:360c4a23cb1d 354
guiott 1:360c4a23cb1d 355 ChooseDir++;
guiott 1:360c4a23cb1d 356 if(ChooseDir<7)
guiott 1:360c4a23cb1d 357 {
guiott 1:360c4a23cb1d 358 showDirLcd(Mag);
guiott 1:360c4a23cb1d 359 }
guiott 1:360c4a23cb1d 360 else if(ChooseDir>=7 && ChooseDir<12)
guiott 1:360c4a23cb1d 361 {
guiott 1:360c4a23cb1d 362 showDirLcd(Gps);
guiott 1:360c4a23cb1d 363 }
guiott 1:360c4a23cb1d 364 else if(ChooseDir>=12)
guiott 1:360c4a23cb1d 365 {
guiott 1:360c4a23cb1d 366 ChooseDir=0;
guiott 1:360c4a23cb1d 367 }
guiott 1:360c4a23cb1d 368 showDirLcd(Dir);
guiott 1:360c4a23cb1d 369
guiott 1:360c4a23cb1d 370 Deg2DegMinSec(nmea_ndeg2degree(Dest.lat), &DecCoord);
guiott 1:360c4a23cb1d 371 lcd.locate(6,0);
guiott 1:360c4a23cb1d 372 lcd.printf("%d%d\'%.0f", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
guiott 1:360c4a23cb1d 373 lcd.printf("%c", Dest.lat >= 0 ? 'N': 'S');
guiott 1:360c4a23cb1d 374
guiott 1:360c4a23cb1d 375 Deg2DegMinSec(nmea_ndeg2degree(Dest.lon), &DecCoord);
guiott 1:360c4a23cb1d 376 lcd.locate(6,1);
guiott 1:360c4a23cb1d 377 lcd.printf("%d%d\'%.0f", DecCoord.Deg, DecCoord.Min, DecCoord.Sec);
guiott 1:360c4a23cb1d 378 lcd.printf("%c", Dest.lon >= 0 ? 'E': 'W');
guiott 1:360c4a23cb1d 379
guiott 1:360c4a23cb1d 380 lcd.locate(6,2);
guiott 1:360c4a23cb1d 381 lcd.printf(" dist m");
guiott 1:360c4a23cb1d 382 lcd.locate(6,3);
guiott 1:360c4a23cb1d 383 lcd.printf("%4.3f",Path.Dist);
guiott 1:360c4a23cb1d 384
guiott 1:360c4a23cb1d 385
guiott 1:360c4a23cb1d 386 }
guiott 1:360c4a23cb1d 387
guiott 0:d177c0087d1f 388 void showDirLcd(int Indx)
guiott 0:d177c0087d1f 389 {/**
guiott 0:d177c0087d1f 390 *\brief display a sort of compass on LCD
guiott 0:d177c0087d1f 391 */
guiott 0:d177c0087d1f 392 int Angle;
guiott 0:d177c0087d1f 393
guiott 0:d177c0087d1f 394 Angle=Ang[Indx]/18;
guiott 0:d177c0087d1f 395
guiott 0:d177c0087d1f 396 lcd.locate(CmpPos[Indx],0);
guiott 0:d177c0087d1f 397 lcd.printf(" %c ",0xA5);
guiott 0:d177c0087d1f 398 lcd.locate(CmpPos[Indx],1);
guiott 0:d177c0087d1f 399 lcd.printf("%c %c",0xA5, 0xA5);
guiott 0:d177c0087d1f 400 lcd.locate(CmpPos[Indx],2);
guiott 0:d177c0087d1f 401 lcd.printf("%c %c",0xA5, 0xA5);
guiott 0:d177c0087d1f 402 lcd.locate(CmpPos[Indx],3);
guiott 0:d177c0087d1f 403 lcd.printf(" %c ",0xA5);
guiott 0:d177c0087d1f 404
guiott 0:d177c0087d1f 405 lcd.locate(CmpPos[Indx]+1,1);
guiott 0:d177c0087d1f 406 lcd.printf(Lab[Indx]);
guiott 0:d177c0087d1f 407 lcd.locate(CmpPos[Indx]+1,2);
guiott 0:d177c0087d1f 408 lcd.printf("%03i",Ang[Indx]);
guiott 0:d177c0087d1f 409
guiott 0:d177c0087d1f 410 switch (Angle)
guiott 0:d177c0087d1f 411 {
guiott 0:d177c0087d1f 412 case 0:
guiott 0:d177c0087d1f 413 lcd.locate(CmpPos[Indx]+2,0);
guiott 0:d177c0087d1f 414 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 415 break;
guiott 0:d177c0087d1f 416 case 1:
guiott 0:d177c0087d1f 417 lcd.locate(CmpPos[Indx]+2,0);
guiott 0:d177c0087d1f 418 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 419 lcd.locate(CmpPos[Indx]+3,0);
guiott 0:d177c0087d1f 420 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 421 break;
guiott 0:d177c0087d1f 422 case 2:
guiott 0:d177c0087d1f 423 lcd.locate(CmpPos[Indx]+3,0);
guiott 0:d177c0087d1f 424 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 425 break;
guiott 0:d177c0087d1f 426 case 3:
guiott 0:d177c0087d1f 427 lcd.locate(CmpPos[Indx]+3,0);
guiott 0:d177c0087d1f 428 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 429 lcd.locate(CmpPos[Indx]+4,1);
guiott 0:d177c0087d1f 430 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 431 break;
guiott 0:d177c0087d1f 432 case 4:
guiott 0:d177c0087d1f 433 lcd.locate(CmpPos[Indx]+4,1);
guiott 0:d177c0087d1f 434 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 435 break;
guiott 0:d177c0087d1f 436 case 5:
guiott 0:d177c0087d1f 437 lcd.locate(CmpPos[Indx]+4,1);
guiott 0:d177c0087d1f 438 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 439 lcd.locate(CmpPos[Indx]+4,2);
guiott 0:d177c0087d1f 440 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 441 break;
guiott 0:d177c0087d1f 442 case 6:
guiott 0:d177c0087d1f 443 lcd.locate(CmpPos[Indx]+4,2);
guiott 0:d177c0087d1f 444 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 445 break;
guiott 0:d177c0087d1f 446 case 7:
guiott 0:d177c0087d1f 447 lcd.locate(CmpPos[Indx]+4,2);
guiott 0:d177c0087d1f 448 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 449 lcd.locate(CmpPos[Indx]+3,3);
guiott 0:d177c0087d1f 450 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 451 break;
guiott 0:d177c0087d1f 452 case 8:
guiott 0:d177c0087d1f 453 lcd.locate(CmpPos[Indx]+3,3);
guiott 0:d177c0087d1f 454 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 455 break;
guiott 0:d177c0087d1f 456 case 9:
guiott 0:d177c0087d1f 457 lcd.locate(CmpPos[Indx]+3,3);
guiott 0:d177c0087d1f 458 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 459 lcd.locate(CmpPos[Indx]+2,3);
guiott 0:d177c0087d1f 460 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 461 break;
guiott 0:d177c0087d1f 462 case 10:
guiott 0:d177c0087d1f 463 lcd.locate(CmpPos[Indx]+2,3);
guiott 0:d177c0087d1f 464 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 465 break;
guiott 0:d177c0087d1f 466 case 11:
guiott 0:d177c0087d1f 467 lcd.locate(CmpPos[Indx]+2,3);
guiott 0:d177c0087d1f 468 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 469 lcd.locate(CmpPos[Indx]+1,3);
guiott 0:d177c0087d1f 470 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 471 break;
guiott 0:d177c0087d1f 472 case 12:
guiott 0:d177c0087d1f 473 lcd.locate(CmpPos[Indx]+1,3);
guiott 0:d177c0087d1f 474 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 475 break;
guiott 0:d177c0087d1f 476 case 13:
guiott 0:d177c0087d1f 477 lcd.locate(CmpPos[Indx]+1,3);
guiott 0:d177c0087d1f 478 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 479 lcd.locate(CmpPos[Indx]+0,2);
guiott 0:d177c0087d1f 480 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 481 break;
guiott 0:d177c0087d1f 482 case 14:
guiott 0:d177c0087d1f 483 lcd.locate(CmpPos[Indx]+0,2);
guiott 0:d177c0087d1f 484 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 485 break;
guiott 0:d177c0087d1f 486 case 15:
guiott 0:d177c0087d1f 487 lcd.locate(CmpPos[Indx]+0,2);
guiott 0:d177c0087d1f 488 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 489 lcd.locate(CmpPos[Indx]+0,1);
guiott 0:d177c0087d1f 490 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 491 break;
guiott 0:d177c0087d1f 492 case 16:
guiott 0:d177c0087d1f 493 lcd.locate(CmpPos[Indx]+0,1);
guiott 0:d177c0087d1f 494 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 495 break;
guiott 0:d177c0087d1f 496 case 17:
guiott 0:d177c0087d1f 497 lcd.locate(CmpPos[Indx]+0,1);
guiott 0:d177c0087d1f 498 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 499 lcd.locate(CmpPos[Indx]+1,0);
guiott 0:d177c0087d1f 500 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 501 break;
guiott 0:d177c0087d1f 502 case 18:
guiott 0:d177c0087d1f 503 lcd.locate(CmpPos[Indx]+1,0);
guiott 0:d177c0087d1f 504 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 505 break;
guiott 0:d177c0087d1f 506 case 19:
guiott 0:d177c0087d1f 507 lcd.locate(CmpPos[Indx]+1,0);
guiott 0:d177c0087d1f 508 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 509 lcd.locate(CmpPos[Indx]+2,0);
guiott 0:d177c0087d1f 510 lcd.printf("%c",0xFF);
guiott 0:d177c0087d1f 511 break;
guiott 0:d177c0087d1f 512 }
guiott 0:d177c0087d1f 513 }
guiott 0:d177c0087d1f 514
guiott 0:d177c0087d1f 515 void showMenuLcd(void)
guiott 0:d177c0087d1f 516 {/**
guiott 0:d177c0087d1f 517 *\brief display a selection menu on LCD
guiott 0:d177c0087d1f 518 */
guiott 0:d177c0087d1f 519 lcd.locate(0,0);
guiott 0:d177c0087d1f 520 lcd.printf("1 - item 1");
guiott 0:d177c0087d1f 521 lcd.locate(0,1);
guiott 0:d177c0087d1f 522 lcd.printf("2 - item 2");
guiott 0:d177c0087d1f 523 lcd.locate(0,2);
guiott 0:d177c0087d1f 524 lcd.printf("3 - item 3");
guiott 0:d177c0087d1f 525 lcd.locate(0,3);
guiott 0:d177c0087d1f 526 lcd.printf("4 - item 4");
guiott 0:d177c0087d1f 527 }
guiott 0:d177c0087d1f 528
guiott 0:d177c0087d1f 529 void showMenuLcd1(void)
guiott 0:d177c0087d1f 530 {/**
guiott 0:d177c0087d1f 531 *\brief display a selection menu on LCD
guiott 0:d177c0087d1f 532 */
guiott 0:d177c0087d1f 533 lcd.locate(0,0);
guiott 0:d177c0087d1f 534 lcd.printf("5 - item 5");
guiott 0:d177c0087d1f 535 lcd.locate(0,1);
guiott 0:d177c0087d1f 536 lcd.printf("6 - item 6");
guiott 0:d177c0087d1f 537 lcd.locate(0,2);
guiott 0:d177c0087d1f 538 lcd.printf("7 - item 7");
guiott 0:d177c0087d1f 539 lcd.locate(0,3);
guiott 0:d177c0087d1f 540 lcd.printf("8 - item 8");
guiott 0:d177c0087d1f 541 }
guiott 0:d177c0087d1f 542
guiott 0:d177c0087d1f 543 void showSatLcd(void)
guiott 0:d177c0087d1f 544 {/**
guiott 0:d177c0087d1f 545 *\brief displays satellite informations
guiott 0:d177c0087d1f 546 */
guiott 0:d177c0087d1f 547 for (int i = 0; i < NMEA_MAXSAT; i++)
guiott 0:d177c0087d1f 548 {
guiott 0:d177c0087d1f 549 if(info.satinfo.sat[i].id < 20)
guiott 0:d177c0087d1f 550 {
guiott 0:d177c0087d1f 551 lcd.locate((info.satinfo.sat[i].id % 20) - 1,0);
guiott 0:d177c0087d1f 552 }
guiott 0:d177c0087d1f 553 else
guiott 0:d177c0087d1f 554 {
guiott 0:d177c0087d1f 555 lcd.locate((info.satinfo.sat[i].id % 20) - 1,1);
guiott 0:d177c0087d1f 556 }
guiott 0:d177c0087d1f 557
guiott 0:d177c0087d1f 558 if (info.satinfo.sat[i].sig > 0)
guiott 0:d177c0087d1f 559 {
guiott 0:d177c0087d1f 560 lcd.printf("%d",info.satinfo.sat[i].sig/10);
guiott 0:d177c0087d1f 561 }
guiott 0:d177c0087d1f 562 else
guiott 0:d177c0087d1f 563 {
guiott 0:d177c0087d1f 564 lcd.printf(" ");
guiott 0:d177c0087d1f 565 }
guiott 0:d177c0087d1f 566 }
guiott 0:d177c0087d1f 567 lcd.locate(0,2);
guiott 0:d177c0087d1f 568 lcd.printf("12345678901234567890");
guiott 0:d177c0087d1f 569 lcd.locate(0, 3);
guiott 0:d177c0087d1f 570 lcd.printf("P%2.1f H%2.1f V%2.1f %iD",
guiott 0:d177c0087d1f 571 info.PDOP, info.HDOP, info.VDOP,info.fix);
guiott 0:d177c0087d1f 572 }
guiott 0:d177c0087d1f 573
guiott 0:d177c0087d1f 574 void showInfoLcd(void)
guiott 0:d177c0087d1f 575 {/**
guiott 0:d177c0087d1f 576 *\brief Show nmea info on LCD
guiott 0:d177c0087d1f 577 */
guiott 0:d177c0087d1f 578
guiott 0:d177c0087d1f 579 // static int lastSat = 0;
guiott 0:d177c0087d1f 580 // int satInview = 0;
guiott 0:d177c0087d1f 581
guiott 0:d177c0087d1f 582 if(info.sig != 0)
guiott 0:d177c0087d1f 583 {
guiott 0:d177c0087d1f 584 lcd.locate(0, 0);
guiott 0:d177c0087d1f 585 lcd.printf("%2.5f%c %3.5f%c",
guiott 0:d177c0087d1f 586 latitude, info.lat >= 0 ? 'N': 'S',
guiott 0:d177c0087d1f 587 longitude, info.lon >= 0 ? 'E': 'W');
guiott 0:d177c0087d1f 588
guiott 0:d177c0087d1f 589 lcd.locate(0, 1);
guiott 0:d177c0087d1f 590 lcd.printf("H%.0f D%.0f_%.1f %iD", info.elv, info.direction, info.declination, info.fix);
guiott 0:d177c0087d1f 591
guiott 0:d177c0087d1f 592 lcd.locate(0, 2);
guiott 0:d177c0087d1f 593 lcd.printf("P%2.1f H%2.1f V%2.1f S%i/%i",
guiott 0:d177c0087d1f 594 info.PDOP, info.HDOP, info.VDOP, info.satinfo.inuse, info.satinfo.inview);
guiott 0:d177c0087d1f 595
guiott 0:d177c0087d1f 596 /* lcd.locate(0, 3);
guiott 0:d177c0087d1f 597 lcd.printf("%02d-%02d-%04d %02d:%02d:%02d ",
guiott 0:d177c0087d1f 598 info.utc.day, info.utc.mon + 1, info.utc.year + 1900,
guiott 0:d177c0087d1f 599 info.utc.hour, info.utc.min, info.utc.sec); // Display JST (UTC + 9)
guiott 0:d177c0087d1f 600 */
guiott 0:d177c0087d1f 601
guiott 0:d177c0087d1f 602 /*
guiott 0:d177c0087d1f 603 lcd.locate(0, 5);
guiott 0:d177c0087d1f 604 for (int i = 0; i < NMEA_MAXSAT; i++) {
guiott 0:d177c0087d1f 605 if (info.satinfo.sat[i].sig > 0) {
guiott 0:d177c0087d1f 606 satInview++;
guiott 0:d177c0087d1f 607 lcd.printf(" sat_id:%02d, sig:%02d, Inuse:%d \n",
guiott 0:d177c0087d1f 608 info.satinfo.sat[i].id , info.satinfo.sat[i].sig,
guiott 0:d177c0087d1f 609 info.satinfo.sat[i].in_use);
guiott 0:d177c0087d1f 610 }
guiott 0:d177c0087d1f 611 }
guiott 0:d177c0087d1f 612 for (int j = satInview; j <= lastSat; j++)
guiott 0:d177c0087d1f 613 lcd.printf(" \n"); // delete line
guiott 0:d177c0087d1f 614 lastSat = satInview;
guiott 0:d177c0087d1f 615 */
guiott 0:d177c0087d1f 616
guiott 0:d177c0087d1f 617 }
guiott 0:d177c0087d1f 618 else
guiott 0:d177c0087d1f 619 {
guiott 0:d177c0087d1f 620 lcd.cls();
guiott 0:d177c0087d1f 621 lcd.locate(0,0);
guiott 0:d177c0087d1f 622 lcd.printf("NO FIX");
guiott 0:d177c0087d1f 623 }
guiott 0:d177c0087d1f 624
guiott 0:d177c0087d1f 625 // Grab a snapshot of the current RTC time.
guiott 0:d177c0087d1f 626 time_t seconds = time(NULL);
guiott 0:d177c0087d1f 627 char buffer[32];
guiott 0:d177c0087d1f 628 if((info.sig != 0)&&(SetTimeOk!=0))
guiott 0:d177c0087d1f 629 {
guiott 0:d177c0087d1f 630 strftime(buffer, 32, "%x %X", localtime(&seconds));
guiott 0:d177c0087d1f 631 }
guiott 0:d177c0087d1f 632 else
guiott 0:d177c0087d1f 633 {// if GPS time not valid doesn't display seconds
guiott 0:d177c0087d1f 634 strftime(buffer, 32, "%x %H:%M", localtime(&seconds));
guiott 0:d177c0087d1f 635 SetTimeOk = 0; // RTC was not set to a valid time
guiott 0:d177c0087d1f 636 }
guiott 0:d177c0087d1f 637 lcd.locate(0,3);
guiott 0:d177c0087d1f 638 lcd.printf("%s", buffer);
guiott 0:d177c0087d1f 639 }
guiott 0:d177c0087d1f 640
guiott 0:d177c0087d1f 641 void SetTimeTask(void)
guiott 0:d177c0087d1f 642 {/**
guiott 0:d177c0087d1f 643 *\brief TASK 5, Set RTC system time if the GPS time is valid
guiott 0:d177c0087d1f 644 */
guiott 0:d177c0087d1f 645 struct tm t;
guiott 0:d177c0087d1f 646
guiott 0:d177c0087d1f 647 os.SetTimer(SET_TIME_TMR, 60000, 60000);
guiott 0:d177c0087d1f 648 while(1)
guiott 0:d177c0087d1f 649 {
guiott 0:d177c0087d1f 650 os.WaitEvent(SET_TIME_EVT);
guiott 0:d177c0087d1f 651
guiott 0:d177c0087d1f 652 if(info.sig != 0)
guiott 0:d177c0087d1f 653 {
guiott 0:d177c0087d1f 654 t.tm_mday=info.utc.day;
guiott 0:d177c0087d1f 655 t.tm_mon=info.utc.mon;
guiott 0:d177c0087d1f 656 t.tm_year=info.utc.year;
guiott 0:d177c0087d1f 657 t.tm_hour=info.utc.hour;
guiott 0:d177c0087d1f 658 t.tm_min=info.utc.min;
guiott 0:d177c0087d1f 659 t.tm_sec=info.utc.sec;
guiott 0:d177c0087d1f 660
guiott 0:d177c0087d1f 661 time_t seconds = mktime(&t);
guiott 0:d177c0087d1f 662 set_time(seconds);
guiott 0:d177c0087d1f 663
guiott 0:d177c0087d1f 664 SetTimeOk = 1; // RTC was set
guiott 0:d177c0087d1f 665 }
guiott 0:d177c0087d1f 666 }
guiott 0:d177c0087d1f 667 }
guiott 0:d177c0087d1f 668
guiott 0:d177c0087d1f 669 void LedBlinkTask(void)
guiott 0:d177c0087d1f 670 {/**
guiott 0:d177c0087d1f 671 *\brief TASK 4
guiott 0:d177c0087d1f 672 LED 1: Quick blink=NOT fix, Slow blink=fix OK
guiott 0:d177c0087d1f 673 LED 2: blinks proportionally to HDOP
guiott 0:d177c0087d1f 674 LED 3: blinks proportionally to VDOP
guiott 0:d177c0087d1f 675 */
guiott 0:d177c0087d1f 676
guiott 0:d177c0087d1f 677 static int LedCnt1=0;
guiott 0:d177c0087d1f 678 // static int LedCnt2=0;
guiott 0:d177c0087d1f 679 int OnH=0;
guiott 0:d177c0087d1f 680 int OnV=0;
guiott 0:d177c0087d1f 681
guiott 0:d177c0087d1f 682 #define MAX 20
guiott 0:d177c0087d1f 683
guiott 0:d177c0087d1f 684 os.SetTimer(LED_BLINK_TMR, 100, 100);
guiott 0:d177c0087d1f 685
guiott 0:d177c0087d1f 686 while(1)
guiott 0:d177c0087d1f 687 {
guiott 0:d177c0087d1f 688 os.WaitEvent(LED_BLINK_EVT);
guiott 0:d177c0087d1f 689
guiott 0:d177c0087d1f 690 if((info.HDOP>0)&&(info.HDOP<=2))
guiott 0:d177c0087d1f 691 {
guiott 0:d177c0087d1f 692 OnH=2;
guiott 0:d177c0087d1f 693 }
guiott 0:d177c0087d1f 694 else if((info.HDOP>2)&&(info.HDOP<=4))
guiott 0:d177c0087d1f 695 {
guiott 0:d177c0087d1f 696 OnH=4;
guiott 0:d177c0087d1f 697 }
guiott 0:d177c0087d1f 698 else if((info.HDOP>4)&&(info.HDOP<=6))
guiott 0:d177c0087d1f 699 {
guiott 0:d177c0087d1f 700 OnH=6;
guiott 0:d177c0087d1f 701 }
guiott 0:d177c0087d1f 702 else if((info.HDOP>6))
guiott 0:d177c0087d1f 703 {
guiott 0:d177c0087d1f 704 OnH=MAX/2;
guiott 0:d177c0087d1f 705 }
guiott 0:d177c0087d1f 706
guiott 0:d177c0087d1f 707 if((info.VDOP>0)&&(info.VDOP<=2))
guiott 0:d177c0087d1f 708 {
guiott 0:d177c0087d1f 709 OnV=2;
guiott 0:d177c0087d1f 710 }
guiott 0:d177c0087d1f 711 else if((info.VDOP>2)&&(info.VDOP<=4))
guiott 0:d177c0087d1f 712 {
guiott 0:d177c0087d1f 713 OnV=4;
guiott 0:d177c0087d1f 714 }
guiott 0:d177c0087d1f 715 else if((info.VDOP>4)&&(info.VDOP<=6))
guiott 0:d177c0087d1f 716 {
guiott 0:d177c0087d1f 717 OnV=6;
guiott 0:d177c0087d1f 718 }
guiott 0:d177c0087d1f 719 else if((info.VDOP>6))
guiott 0:d177c0087d1f 720 {
guiott 0:d177c0087d1f 721 OnV=MAX/2;
guiott 0:d177c0087d1f 722 }
guiott 0:d177c0087d1f 723
guiott 0:d177c0087d1f 724 if(info.sig == 0)
guiott 0:d177c0087d1f 725 {
guiott 0:d177c0087d1f 726 led1=!led1;
guiott 0:d177c0087d1f 727 led2=0;
guiott 0:d177c0087d1f 728 led3=0;
guiott 0:d177c0087d1f 729 }
guiott 0:d177c0087d1f 730 else
guiott 0:d177c0087d1f 731 {
guiott 0:d177c0087d1f 732 if(LedCnt1<=MAX/2)
guiott 0:d177c0087d1f 733 {
guiott 0:d177c0087d1f 734 LedCnt1++;
guiott 0:d177c0087d1f 735 led1=0;
guiott 0:d177c0087d1f 736 if(LedCnt1<OnH)
guiott 0:d177c0087d1f 737 {
guiott 0:d177c0087d1f 738 led2=!led2;
guiott 0:d177c0087d1f 739 }
guiott 0:d177c0087d1f 740 else
guiott 0:d177c0087d1f 741 {
guiott 0:d177c0087d1f 742 led2=0;
guiott 0:d177c0087d1f 743 }
guiott 0:d177c0087d1f 744
guiott 0:d177c0087d1f 745 if(LedCnt1<OnV)
guiott 0:d177c0087d1f 746 {
guiott 0:d177c0087d1f 747 led3=!led3;
guiott 0:d177c0087d1f 748 }
guiott 0:d177c0087d1f 749 else
guiott 0:d177c0087d1f 750 {
guiott 0:d177c0087d1f 751 led3=0;
guiott 0:d177c0087d1f 752 }
guiott 0:d177c0087d1f 753 }
guiott 0:d177c0087d1f 754 else if((LedCnt1>MAX/2)&&(LedCnt1<=MAX))
guiott 0:d177c0087d1f 755 {
guiott 0:d177c0087d1f 756 LedCnt1++;
guiott 0:d177c0087d1f 757 led1=1;
guiott 0:d177c0087d1f 758 led2=0;
guiott 0:d177c0087d1f 759 led3=0;
guiott 0:d177c0087d1f 760 }
guiott 0:d177c0087d1f 761 else if(LedCnt1>MAX)
guiott 0:d177c0087d1f 762 {
guiott 0:d177c0087d1f 763 LedCnt1=0;
guiott 0:d177c0087d1f 764 }
guiott 0:d177c0087d1f 765 }
guiott 0:d177c0087d1f 766 }
guiott 0:d177c0087d1f 767 }
guiott 0:d177c0087d1f 768
guiott 0:d177c0087d1f 769
guiott 0:d177c0087d1f 770 void KeypadTask(void)
guiott 0:d177c0087d1f 771 {/**
guiott 0:d177c0087d1f 772 *\brief TASK 2, Keypad management.
guiott 0:d177c0087d1f 773 It uses just one ADC port. Five keys switch a 5 resistor ladder
guiott 0:d177c0087d1f 774 obtaining a unique voltage for each key, with a priority that
guiott 0:d177c0087d1f 775 depends from the position of the resistor in the ladder.
guiott 0:d177c0087d1f 776 This function makes an average of 50 analog values (50ms) before
guiott 0:d177c0087d1f 777 confirming the output, to filter out some noise and debounce keys
guiott 0:d177c0087d1f 778 */
guiott 0:d177c0087d1f 779
guiott 0:d177c0087d1f 780 static float KeypadAcc; // accumulator to compute average
guiott 0:d177c0087d1f 781 static float KeypadPrev; // previous value to compute variation
guiott 0:d177c0087d1f 782 static int KeypadCount; // all samples number
guiott 0:d177c0087d1f 783 static int KeypadRealCount; // valid samples only
guiott 0:d177c0087d1f 784 float KeypadVal;
guiott 0:d177c0087d1f 785 static char KeyPrev='-';
guiott 0:d177c0087d1f 786
guiott 0:d177c0087d1f 787 os.SetTimer(KEYPAD_TMR, 1, 1);
guiott 0:d177c0087d1f 788 while(1)
guiott 0:d177c0087d1f 789 {
guiott 0:d177c0087d1f 790 os.WaitEvent(KEYPAD_EVT);
guiott 0:d177c0087d1f 791 float InValue = KeypadIn.read();
guiott 0:d177c0087d1f 792 if ((InValue > 0.3) && (abs(InValue - KeypadPrev) < 0.1))
guiott 0:d177c0087d1f 793 {// makes the average only of the values above a threshold
guiott 0:d177c0087d1f 794 // and within an almost stable range
guiott 0:d177c0087d1f 795 KeypadAcc+=InValue;
guiott 0:d177c0087d1f 796 KeypadRealCount++;
guiott 0:d177c0087d1f 797 }
guiott 0:d177c0087d1f 798
guiott 0:d177c0087d1f 799 KeypadCount++;
guiott 0:d177c0087d1f 800 KeypadPrev=InValue;
guiott 0:d177c0087d1f 801
guiott 0:d177c0087d1f 802 if (KeypadCount >=50)
guiott 0:d177c0087d1f 803 {
guiott 0:d177c0087d1f 804 if(KeypadRealCount > 25)
guiott 0:d177c0087d1f 805 {
guiott 0:d177c0087d1f 806 KeypadVal=KeypadAcc/KeypadRealCount;
guiott 0:d177c0087d1f 807 }
guiott 0:d177c0087d1f 808 else
guiott 0:d177c0087d1f 809 {// not enough values to average
guiott 0:d177c0087d1f 810
guiott 0:d177c0087d1f 811 KeypadVal=0;
guiott 0:d177c0087d1f 812 }
guiott 0:d177c0087d1f 813
guiott 0:d177c0087d1f 814 KeypadAcc=0;
guiott 0:d177c0087d1f 815 KeypadCount=0;
guiott 0:d177c0087d1f 816 KeypadRealCount=0;
guiott 0:d177c0087d1f 817
guiott 0:d177c0087d1f 818 if(KeypadVal <0.15)
guiott 0:d177c0087d1f 819 {
guiott 0:d177c0087d1f 820 Key='-';
guiott 0:d177c0087d1f 821 }
guiott 0:d177c0087d1f 822 else if(KeypadVal>=0.3 && KeypadVal<0.35)
guiott 0:d177c0087d1f 823 {
guiott 0:d177c0087d1f 824 Key='E';
guiott 0:d177c0087d1f 825 }
guiott 0:d177c0087d1f 826 else if(KeypadVal>=0.42 && KeypadVal<0.50)
guiott 0:d177c0087d1f 827 {
guiott 0:d177c0087d1f 828 Key='v';
guiott 0:d177c0087d1f 829 }
guiott 0:d177c0087d1f 830 else if(KeypadVal>=0.60 && KeypadVal<0.65)
guiott 0:d177c0087d1f 831 {
guiott 0:d177c0087d1f 832 Key='^';
guiott 0:d177c0087d1f 833 }
guiott 0:d177c0087d1f 834 else if(KeypadVal>=0.74 && KeypadVal<0.78)
guiott 0:d177c0087d1f 835 {
guiott 0:d177c0087d1f 836 Key='>';
guiott 0:d177c0087d1f 837 }
guiott 0:d177c0087d1f 838 else if(KeypadVal>=0.85)
guiott 0:d177c0087d1f 839 {
guiott 0:d177c0087d1f 840 Key='<';
guiott 0:d177c0087d1f 841 }
guiott 0:d177c0087d1f 842
guiott 0:d177c0087d1f 843 if (Key!='-' && Key!=KeyPrev)
guiott 0:d177c0087d1f 844 {// switch on the LCD backlight if key pressed
guiott 0:d177c0087d1f 845 os.SetEvent(LCD_LIGHT_DIM_ON_EVT, LCD_LIGHT_DIM_TASK);
guiott 0:d177c0087d1f 846 }
guiott 0:d177c0087d1f 847 KeyPrev=Key;
guiott 0:d177c0087d1f 848 switch (Key)
guiott 0:d177c0087d1f 849 {
guiott 0:d177c0087d1f 850 case '^':
guiott 0:d177c0087d1f 851 Menu=0;
guiott 0:d177c0087d1f 852 break;
guiott 0:d177c0087d1f 853
guiott 0:d177c0087d1f 854 case '>':
guiott 0:d177c0087d1f 855 Menu=1;
guiott 0:d177c0087d1f 856 break;
guiott 0:d177c0087d1f 857
guiott 0:d177c0087d1f 858 case 'v':
guiott 0:d177c0087d1f 859 Menu=2;
guiott 0:d177c0087d1f 860 break;
guiott 0:d177c0087d1f 861
guiott 0:d177c0087d1f 862 case '<':
guiott 0:d177c0087d1f 863 Menu=3;
guiott 0:d177c0087d1f 864 break;
guiott 0:d177c0087d1f 865
guiott 0:d177c0087d1f 866 case 'E':
guiott 0:d177c0087d1f 867 Menu=4;
guiott 0:d177c0087d1f 868 break;
guiott 0:d177c0087d1f 869 }
guiott 0:d177c0087d1f 870 }
guiott 0:d177c0087d1f 871 }
guiott 0:d177c0087d1f 872 }
guiott 0:d177c0087d1f 873
guiott 0:d177c0087d1f 874 void trace_h(const char *str, int str_size)
guiott 0:d177c0087d1f 875 {/**
guiott 0:d177c0087d1f 876 *\brief output on console what's received on GPS serial
guiott 0:d177c0087d1f 877 Callback function for NMEA parser buffer trace
guiott 0:d177c0087d1f 878 */
guiott 0:d177c0087d1f 879 if( PcMonitor==5 || PcMonitor>5)
guiott 0:d177c0087d1f 880 {
guiott 0:d177c0087d1f 881 for (int i = 0; i < str_size; i++)
guiott 0:d177c0087d1f 882 {
guiott 0:d177c0087d1f 883 pc.putc(*str++);
guiott 0:d177c0087d1f 884 }
guiott 0:d177c0087d1f 885 }
guiott 0:d177c0087d1f 886 }
guiott 0:d177c0087d1f 887
guiott 0:d177c0087d1f 888 void error_h(const char *str, int str_size)
guiott 0:d177c0087d1f 889 {/**
guiott 0:d177c0087d1f 890 *\brief Callback function for NMEA parser error
guiott 0:d177c0087d1f 891 */
guiott 0:d177c0087d1f 892 for (int i = 0; i < str_size; i++)
guiott 0:d177c0087d1f 893 {
guiott 0:d177c0087d1f 894 pc.putc(*str++);
guiott 0:d177c0087d1f 895 }
guiott 0:d177c0087d1f 896 }
guiott 0:d177c0087d1f 897
guiott 0:d177c0087d1f 898 void GpsSerialTask(void)
guiott 0:d177c0087d1f 899 {/**
guiott 0:d177c0087d1f 900 *\brief TASK 1, wait for the event then get the input char
guiott 0:d177c0087d1f 901 */
guiott 0:d177c0087d1f 902 while(1)
guiott 0:d177c0087d1f 903 {
guiott 0:d177c0087d1f 904 os.WaitEvent(GPS_SERIAL_IN_EVT);
guiott 0:d177c0087d1f 905 GpsStringParse();
guiott 0:d177c0087d1f 906
guiott 0:d177c0087d1f 907 Dest.lat= 4151.32496; // ***************debug
guiott 0:d177c0087d1f 908 Dest.lon= 1229.34; // *************debug
guiott 0:d177c0087d1f 909
guiott 0:d177c0087d1f 910 GpsDist();
guiott 0:d177c0087d1f 911 }
guiott 0:d177c0087d1f 912 }
guiott 0:d177c0087d1f 913
guiott 0:d177c0087d1f 914 void GpsSerialIsr(void)
guiott 0:d177c0087d1f 915 {/**
guiott 0:d177c0087d1f 916 *\brief Interrupt handler for serial Rx
guiott 0:d177c0087d1f 917 set the event for the serial task
guiott 0:d177c0087d1f 918 */
guiott 0:d177c0087d1f 919 char c = gps.getc();
guiott 0:d177c0087d1f 920 msgBuff[bufferSelect & 1][writePointer] = c;
guiott 0:d177c0087d1f 921 if (writePointer++ == BUFF_SIZE)
guiott 0:d177c0087d1f 922 {
guiott 0:d177c0087d1f 923 writePointer = 0;
guiott 0:d177c0087d1f 924 }
guiott 0:d177c0087d1f 925 if (writePointer > 200)
guiott 0:d177c0087d1f 926 {// GPS input buffer full, start computing coordinates
guiott 0:d177c0087d1f 927 os.SetEvent(GPS_SERIAL_IN_EVT, GPS_SERIAL_TASK);
guiott 0:d177c0087d1f 928 }
guiott 0:d177c0087d1f 929 }
guiott 0:d177c0087d1f 930
guiott 0:d177c0087d1f 931 double trunc(double v)
guiott 0:d177c0087d1f 932 {/**
guiott 0:d177c0087d1f 933 *\brief Return nearest integer vaule less than input
guiott 0:d177c0087d1f 934 *
guiott 0:d177c0087d1f 935 *\parameters double variable to get nearest ingeger
guiott 0:d177c0087d1f 936 *
guiott 0:d177c0087d1f 937 *\return double
guiott 0:d177c0087d1f 938 */
guiott 0:d177c0087d1f 939 if(v < 0.0)
guiott 0:d177c0087d1f 940 {
guiott 0:d177c0087d1f 941 v*= -1.0;
guiott 0:d177c0087d1f 942 v = floor(v);
guiott 0:d177c0087d1f 943 v*=-1.0;
guiott 0:d177c0087d1f 944 } else {
guiott 0:d177c0087d1f 945 v = floor(v);
guiott 0:d177c0087d1f 946 }
guiott 0:d177c0087d1f 947 return v;
guiott 0:d177c0087d1f 948 }