Components and supplies
Arduino Nano R3
Project description
Code
Car-HUD Arduino sketch
arduino
1/* 2 This sketch acts as car windscreen HUD (head up display), by Marco Zonca, 10/2020 3 Arduino Nano as CPU, GPS BT-220 nmea every 1 sec, 3 x buttons, 3 x seven segment displays common cathode, 4 3 x 14511 BCD latch decoder, MPU EEPROM memory (1 byte) and many resistors; 5 6 WARNING: 7 ======= 8 Before updating software let disconnect RX pin on Arduino (TX from GPS) by the way of the JUMPER 9*/ 10 11#include <Wire.h> 12#include <EEPROM.h> 13 14String inputString = ""; 15String nm_time = "00:00:00"; 16String nm_validity = "V"; 17String nm_latitude = "dd°mm.mmmm'N"; 18String nm_longitude = "ddd°mm.mmmm'E"; 19String nm_knots = "0.0kn"; 20float nmf_knots = 0.0; 21float nmf_kmh = 0.0; 22int nmi_kmh = 0; 23String nm_truecourse = "360"; 24float nmf_truecourse = 360; 25String nm_date = "dd/mm/yyyy"; 26int nmi_truecourse = 0; 27byte kCent = 0; 28byte kDeci = 0; 29byte kUnit = 0; 30byte tCent = 0; 31byte tDeci = 0; 32byte tUnit = 0; 33byte brightness = 120; 34byte latch_off = HIGH; 35byte latch_on = LOW; 36int n=0; 37unsigned long lastmemcheck = 0; 38unsigned long memcheck = 60000; // check to save "brightness" value in EEPROM every 60 seconds 39 40bool stringComplete = false; 41bool isKMH=true; 42bool ret = false; 43 44const int disp001 = 2; // units display latch 45const int disp010 = 8; // tens display latch 46const int disp100 = 12; // undreds display latch 47 48const int disp001dim = 9; // units display dimmer/off pin 49const int disp010dim = 10; // tens display dimmer/off pin 50const int disp100dim = 11; // undreds display dimmer/off pin 51 52const int button_kt = 14; // kmh/truecourse button 53const int button_more = 15; // brightness + button 54const int button_less = 16; // brightness - button 55 56const int degreesLED = 3; // degrees LED 57 58const int bit_3 = 7; // bit 3 59const int bit_2 = 6; // bit 2 60const int bit_1 = 5; // bit 1 61const int bit_0 = 4; // bit 0 62 63const int dly = 10; // delay latch m/sec 64const byte off = 0; // the same as brightness=0 65const int addr = 0; // EEPROM address for brightness value 66 67const byte numbers[10] [4] = {{0,0,0,0},{1,0,0,0},{0,1,0,0},{1,1,0,0},{0,0,1,0}, 68 {1,0,1,0},{0,1,1,0},{1,1,1,0},{0,0,0,1},{1,0,0,1}}; // bits 0,1,2,3 69 70void setup() { 71 Serial.begin(9600); 72 Wire.begin(); 73 inputString.reserve(200); 74 brightness = EEPROM.read(addr); 75 if (brightness > 250 || brightness < 10) { brightness=120; } // avoid crazy values from 1st EEPROM read 76 pinMode(disp001, OUTPUT); 77 pinMode(disp010, OUTPUT); 78 pinMode(disp100, OUTPUT); 79 pinMode(degreesLED, OUTPUT); 80 pinMode(button_kt, INPUT_PULLUP); 81 pinMode(button_less, INPUT_PULLUP); 82 pinMode(button_more, INPUT_PULLUP); 83 pinMode(bit_3, OUTPUT); 84 pinMode(bit_2, OUTPUT); 85 pinMode(bit_1, OUTPUT); 86 pinMode(bit_0, OUTPUT); 87 88 analogWrite(disp001dim, off); // off and zero displays 89 analogWrite(disp010dim, off); 90 analogWrite(disp100dim, off); 91 analogWrite(degreesLED, off); 92 93 setBusNr(0); 94 digitalWrite(disp001, latch_on); 95 digitalWrite(disp010, latch_on); 96 digitalWrite(disp100, latch_on); 97 delay(dly); 98 digitalWrite(disp001, latch_off); 99 digitalWrite(disp010, latch_off); 100 digitalWrite(disp100, latch_off); 101 102 analogWrite(disp001dim, brightness); // on display 103 analogWrite(disp010dim, brightness); 104 analogWrite(disp100dim, brightness); 105} // setup() 106 107void loop() { 108 // GPS NMEA ------------------ 109 if (stringComplete == true) { // received nmea sentence by serial port RX 110 ret = nmeaExtractData(); 111 inputString = ""; 112 stringComplete = false; 113 if (ret == true) { 114 kCent=nmi_kmh/100; 115 n=nmi_kmh-(kCent*100); 116 kDeci=n/10; 117 n=nmi_kmh-(kCent*100)-(kDeci*10); 118 kUnit=n; 119 tCent=nmi_truecourse/100; 120 n=nmi_truecourse-(tCent*100); 121 tDeci=n/10; 122 n=nmi_truecourse-(tCent*100)-(tDeci*10); 123 tUnit=n; 124 display(); 125 } 126 } 127 if (millis() > (lastmemcheck+memcheck)) { // put in memory brightness value (if modified) 128 EEPROM.update(addr,brightness); 129 lastmemcheck=millis(); 130 } 131 checkButtons(); 132} 133 134void display() { 135 if (isKMH == true) { // speed in km/h (isKMH=true) 136 analogWrite(degreesLED, off); 137 setBusNr(kUnit); 138 digitalWrite(disp001, latch_on); 139 delay(dly); 140 digitalWrite(disp001, latch_off); 141 if (kDeci > 0 || kCent > 0) { // set tens off if tens=0 (and also undreds=0) 142 setBusNr(kDeci); 143 digitalWrite(disp010, latch_on); 144 delay(dly); 145 digitalWrite(disp010, latch_off); 146 analogWrite(disp010dim, brightness); 147 } else { 148 analogWrite(disp010dim, off); 149 } 150 if (kCent > 0) { // set undreds off if=0 151 setBusNr(kCent); 152 digitalWrite(disp100, latch_on); 153 delay(dly); 154 digitalWrite(disp100, latch_off); 155 analogWrite(disp100dim, brightness); 156 } else { 157 analogWrite(disp100dim, off); 158 } 159 } else { // true bearing in degrees (isKMH=false) 160 analogWrite(degreesLED, brightness); 161 setBusNr(tUnit); 162 digitalWrite(disp001, latch_on); 163 delay(dly); 164 digitalWrite(disp001, latch_off); 165 if (tDeci > 0 || tCent > 0) { // set tens off if tens=0 (and also undreds=0) 166 setBusNr(tDeci); 167 digitalWrite(disp010, latch_on); 168 delay(dly); 169 digitalWrite(disp010, latch_off); 170 analogWrite(disp010dim, brightness); 171 } else { 172 analogWrite(disp010dim, off); 173 } 174 if (tCent > 0) { // set undreds off if=0 175 setBusNr(tCent); 176 digitalWrite(disp100, latch_on); 177 delay(dly); 178 digitalWrite(disp100, latch_off); 179 analogWrite(disp100dim, brightness); 180 } else { 181 analogWrite(disp100dim, off); 182 } 183 } 184} // display() 185 186void checkButtons(){ 187 if (digitalRead(button_kt) == LOW) { 188 if (isKMH == true) { 189 isKMH=false; 190 } else { 191 isKMH=true; 192 } 193 delay(250); 194 } 195 if (digitalRead(button_more) == LOW) { 196 if (brightness <= 240) { 197 brightness=brightness+10; 198 } 199 analogWrite(disp001dim, brightness); 200 analogWrite(disp010dim, brightness); 201 analogWrite(disp100dim, brightness); 202 delay(100); 203 } 204 if (digitalRead(button_less) == LOW) { 205 if (brightness >= 20) { 206 brightness=brightness-10; 207 } 208 analogWrite(disp001dim, brightness); 209 analogWrite(disp010dim, brightness); 210 analogWrite(disp100dim, brightness); 211 delay(100); 212 } 213} // checkButtons() 214 215void setBusNr(int number) { // sets 4 bits bus 216 for (byte b=0; b<=3; b++) { 217 if (numbers[number][b]==0) { 218 if (b==0) {digitalWrite(bit_0, LOW);} 219 if (b==1) {digitalWrite(bit_1, LOW);} 220 if (b==2) {digitalWrite(bit_2, LOW);} 221 if (b==3) {digitalWrite(bit_3, LOW);} 222 } else { 223 if (b==0) {digitalWrite(bit_0, HIGH);} 224 if (b==1) {digitalWrite(bit_1, HIGH);} 225 if (b==2) {digitalWrite(bit_2, HIGH);} 226 if (b==3) {digitalWrite(bit_3, HIGH);} 227 } 228 } 229} // setBusNr() 230 231// extract data from nmea inputString 232bool nmeaExtractData() { 233 int d=0; 234 int s=0; 235 int y=0; 236 int z=0; 237 float t=0; 238 bool ret = false; //true if nmea sentence = $GNRMC and valid CHKSUM 239 if ((inputString.substring(0,6) == "$GNRMC") && (inputString.substring(inputString.length()-4,inputString.length()-2) == nmea0183_checksum(inputString))) { 240 y=0; 241 for (s = 1; s < 11; s ++) { 242 y=inputString.indexOf(",",y); 243 switch (s) { 244 case 1: //-----------------------time 245 z=inputString.indexOf(",",y+1); 246 if (z>(y+1)) { 247 nm_time=inputString.substring(y+1,y+2+1)+":"+inputString.substring(y+1+2,y+4+1)+":"+inputString.substring(y+1+4,y+6+1); 248 } 249 y=z; 250 break; 251 case 2: //-----------------------validity 252 z=inputString.indexOf(",",y+1); 253 if (z>(y+1)) { 254 nm_validity=inputString.substring(y+1,y+1+1); 255 } 256 y=z; 257 break; 258 case 3: //-----------------------latitude 259 z=inputString.indexOf(",",y+1); 260 if (z>(y+1)) { 261 nm_latitude=inputString.substring(y+1,y+2+1)+"°"+inputString.substring(y+1+2,y+10+1)+"'"; 262 } 263 y=z; 264 break; 265 case 4: //-----------------------north/south 266 z=inputString.indexOf(",",y+1); 267 if (z>(y+1)) { 268 nm_latitude=nm_latitude + inputString.substring(y+1,y+1+1); 269 } 270 y=z; 271 break; 272 case 5: //-----------------------longitude 273 z=inputString.indexOf(",",y+1); 274 if (z>(y+1)) { 275 nm_longitude=inputString.substring(y+1,y+3+1)+"°"+inputString.substring(y+1+3,y+11+1)+"'"; 276 } 277 y=z; 278 break; 279 case 6: //-----------------------east/west 280 z=inputString.indexOf(",",y+1); 281 if (z>(y+1)) { 282 nm_longitude=nm_longitude + inputString.substring(y+1,y+1+1); 283 } 284 y=z; 285 break; 286 case 7: //-----------------------speed knots 287 z=inputString.indexOf(",",y+1); 288 if (z>(y+1)) { 289 nmf_knots=inputString.substring(y+1,z).toFloat(); 290 t=roundOneDec(nmf_knots); 291 nm_knots=String(t,1)+"kn"; 292 nmf_kmh=roundTwoDec(nmf_knots * 1.852); 293 nmi_kmh=roundZeroDec(nmf_knots * 1.852); 294 } 295 y=z; 296 break; 297 case 8: //-----------------------true course 298 z=inputString.indexOf(",",y+1); 299 if (z>(y+1)) { 300 nmf_truecourse=inputString.substring(y+1,z).toFloat(); 301 t=roundZeroDec(nmf_truecourse); 302 nmi_truecourse=t; 303 d=t; 304 nm_truecourse=d; 305 } 306 y=z; 307 break; 308 case 9: //-----------------------date 309 z=inputString.indexOf(",",y+1); 310 if (z>(y+1)) { 311 nm_date=inputString.substring(y+1,y+2+1)+"/"+inputString.substring(y+1+2,y+4+1)+"/20"+inputString.substring(y+1+4,y+6+1); 312 } 313 y=z; 314 break; 315 case 10: 316 // statements n.u. 317 break; 318 default: 319 // statements n.u. 320 break; 321 } 322 } 323 ret=true; 324 } 325 return ret; 326} // nmeaExtractData() 327 328/* 329 SerialEvent occurs whenever a new data comes in the hardware serial RX. This 330 routine is run between each time loop() runs, so using delay inside loop can 331 delay response. Multiple bytes of data may be available. 332*/ 333void serialEvent() { 334 while (Serial.available()) { 335 char inChar = (char)Serial.read(); 336 inputString += inChar; 337 // if the incoming character is a newline, set a flag so the main loop can 338 // do something about it 339 if (inChar == '\ 340') { 341 stringComplete = true; 342 } 343 } 344} // serialEvent() 345 346//calculate checksum of nmea sentence 347String nmea0183_checksum(String nmea_data) { 348 int crc = 0; 349 String chSumString = ""; 350 int i; 351 // ignore the first $ sign, checksum in sentence 352 for (i = 1; i < (nmea_data.length()-5); i ++) { // remove the - 5 if no "*" + cksum + cr + lf are present 353 crc ^= nmea_data[i]; 354 } 355 chSumString = String(crc,HEX); 356 if (chSumString.length()==1) { 357 chSumString="0"+chSumString.substring(0,1); 358 } 359 chSumString.toUpperCase(); 360 return chSumString; 361} // nmea0183_checksum(String nmea_data) 362 363// round zero decimals 364float roundZeroDec(float f) { 365 float y, d; 366 y = f*1; 367 d = y - (int)y; 368 y = (float)(int)(f*1)/1; 369 if (d >= 0.5) { 370 y += 1; 371 } else { 372 if (d < -0.5) { 373 y -= 1; 374 } 375 } 376 return y; 377} 378 379// round one decimal 380float roundOneDec(float f) { 381 float y, d; 382 y = f*10; 383 d = y - (int)y; 384 y = (float)(int)(f*10)/10; 385 if (d >= 0.5) { 386 y += 0.1; 387 } else { 388 if (d < -0.5) { 389 y -= 0.1; 390 } 391 } 392 return y; 393} 394 395// round two decimals 396float roundTwoDec(float f) { 397 float y, d; 398 y = f*100; 399 d = y - (int)y; 400 y = (float)(int)(f*100)/100; 401 if (d >= 0.5) { 402 y += 0.01; 403 } else { 404 if (d < -0.5) { 405 y -= 0.01; 406 } 407 } 408 return y; 409} 410
Car-HUD Arduino sketch
arduino
1/* 2 This sketch acts as car windscreen HUD (head up display), by Marco Zonca, 10/2020 3 Arduino Nano as CPU, GPS BT-220 nmea every 1 sec, 3 x buttons, 3 x seven segment displays common cathode, 4 3 x 14511 BCD latch decoder, MPU EEPROM memory (1 byte) and many resistors; 5 6 WARNING: 7 ======= 8 Before updating software let disconnect RX pin on Arduino (TX from GPS) by the way of the JUMPER 9*/ 10 11#include <Wire.h> 12#include <EEPROM.h> 13 14String inputString = ""; 15String nm_time = "00:00:00"; 16String nm_validity = "V"; 17String nm_latitude = "dd°mm.mmmm'N"; 18String nm_longitude = "ddd°mm.mmmm'E"; 19String nm_knots = "0.0kn"; 20float nmf_knots = 0.0; 21float nmf_kmh = 0.0; 22int nmi_kmh = 0; 23String nm_truecourse = "360"; 24float nmf_truecourse = 360; 25String nm_date = "dd/mm/yyyy"; 26int nmi_truecourse = 0; 27byte kCent = 0; 28byte kDeci = 0; 29byte kUnit = 0; 30byte tCent = 0; 31byte tDeci = 0; 32byte tUnit = 0; 33byte brightness = 120; 34byte latch_off = HIGH; 35byte latch_on = LOW; 36int n=0; 37unsigned long lastmemcheck = 0; 38unsigned long memcheck = 60000; // check to save "brightness" value in EEPROM every 60 seconds 39 40bool stringComplete = false; 41bool isKMH=true; 42bool ret = false; 43 44const int disp001 = 2; // units display latch 45const int disp010 = 8; // tens display latch 46const int disp100 = 12; // undreds display latch 47 48const int disp001dim = 9; // units display dimmer/off pin 49const int disp010dim = 10; // tens display dimmer/off pin 50const int disp100dim = 11; // undreds display dimmer/off pin 51 52const int button_kt = 14; // kmh/truecourse button 53const int button_more = 15; // brightness + button 54const int button_less = 16; // brightness - button 55 56const int degreesLED = 3; // degrees LED 57 58const int bit_3 = 7; // bit 3 59const int bit_2 = 6; // bit 2 60const int bit_1 = 5; // bit 1 61const int bit_0 = 4; // bit 0 62 63const int dly = 10; // delay latch m/sec 64const byte off = 0; // the same as brightness=0 65const int addr = 0; // EEPROM address for brightness value 66 67const byte numbers[10] [4] = {{0,0,0,0},{1,0,0,0},{0,1,0,0},{1,1,0,0},{0,0,1,0}, 68 {1,0,1,0},{0,1,1,0},{1,1,1,0},{0,0,0,1},{1,0,0,1}}; // bits 0,1,2,3 69 70void setup() { 71 Serial.begin(9600); 72 Wire.begin(); 73 inputString.reserve(200); 74 brightness = EEPROM.read(addr); 75 if (brightness > 250 || brightness < 10) { brightness=120; } // avoid crazy values from 1st EEPROM read 76 pinMode(disp001, OUTPUT); 77 pinMode(disp010, OUTPUT); 78 pinMode(disp100, OUTPUT); 79 pinMode(degreesLED, OUTPUT); 80 pinMode(button_kt, INPUT_PULLUP); 81 pinMode(button_less, INPUT_PULLUP); 82 pinMode(button_more, INPUT_PULLUP); 83 pinMode(bit_3, OUTPUT); 84 pinMode(bit_2, OUTPUT); 85 pinMode(bit_1, OUTPUT); 86 pinMode(bit_0, OUTPUT); 87 88 analogWrite(disp001dim, off); // off and zero displays 89 analogWrite(disp010dim, off); 90 analogWrite(disp100dim, off); 91 analogWrite(degreesLED, off); 92 93 setBusNr(0); 94 digitalWrite(disp001, latch_on); 95 digitalWrite(disp010, latch_on); 96 digitalWrite(disp100, latch_on); 97 delay(dly); 98 digitalWrite(disp001, latch_off); 99 digitalWrite(disp010, latch_off); 100 digitalWrite(disp100, latch_off); 101 102 analogWrite(disp001dim, brightness); // on display 103 analogWrite(disp010dim, brightness); 104 analogWrite(disp100dim, brightness); 105} // setup() 106 107void loop() { 108 // GPS NMEA ------------------ 109 if (stringComplete == true) { // received nmea sentence by serial port RX 110 ret = nmeaExtractData(); 111 inputString = ""; 112 stringComplete = false; 113 if (ret == true) { 114 kCent=nmi_kmh/100; 115 n=nmi_kmh-(kCent*100); 116 kDeci=n/10; 117 n=nmi_kmh-(kCent*100)-(kDeci*10); 118 kUnit=n; 119 tCent=nmi_truecourse/100; 120 n=nmi_truecourse-(tCent*100); 121 tDeci=n/10; 122 n=nmi_truecourse-(tCent*100)-(tDeci*10); 123 tUnit=n; 124 display(); 125 } 126 } 127 if (millis() > (lastmemcheck+memcheck)) { // put in memory brightness value (if modified) 128 EEPROM.update(addr,brightness); 129 lastmemcheck=millis(); 130 } 131 checkButtons(); 132} 133 134void display() { 135 if (isKMH == true) { // speed in km/h (isKMH=true) 136 analogWrite(degreesLED, off); 137 setBusNr(kUnit); 138 digitalWrite(disp001, latch_on); 139 delay(dly); 140 digitalWrite(disp001, latch_off); 141 if (kDeci > 0 || kCent > 0) { // set tens off if tens=0 (and also undreds=0) 142 setBusNr(kDeci); 143 digitalWrite(disp010, latch_on); 144 delay(dly); 145 digitalWrite(disp010, latch_off); 146 analogWrite(disp010dim, brightness); 147 } else { 148 analogWrite(disp010dim, off); 149 } 150 if (kCent > 0) { // set undreds off if=0 151 setBusNr(kCent); 152 digitalWrite(disp100, latch_on); 153 delay(dly); 154 digitalWrite(disp100, latch_off); 155 analogWrite(disp100dim, brightness); 156 } else { 157 analogWrite(disp100dim, off); 158 } 159 } else { // true bearing in degrees (isKMH=false) 160 analogWrite(degreesLED, brightness); 161 setBusNr(tUnit); 162 digitalWrite(disp001, latch_on); 163 delay(dly); 164 digitalWrite(disp001, latch_off); 165 if (tDeci > 0 || tCent > 0) { // set tens off if tens=0 (and also undreds=0) 166 setBusNr(tDeci); 167 digitalWrite(disp010, latch_on); 168 delay(dly); 169 digitalWrite(disp010, latch_off); 170 analogWrite(disp010dim, brightness); 171 } else { 172 analogWrite(disp010dim, off); 173 } 174 if (tCent > 0) { // set undreds off if=0 175 setBusNr(tCent); 176 digitalWrite(disp100, latch_on); 177 delay(dly); 178 digitalWrite(disp100, latch_off); 179 analogWrite(disp100dim, brightness); 180 } else { 181 analogWrite(disp100dim, off); 182 } 183 } 184} // display() 185 186void checkButtons(){ 187 if (digitalRead(button_kt) == LOW) { 188 if (isKMH == true) { 189 isKMH=false; 190 } else { 191 isKMH=true; 192 } 193 delay(250); 194 } 195 if (digitalRead(button_more) == LOW) { 196 if (brightness <= 240) { 197 brightness=brightness+10; 198 } 199 analogWrite(disp001dim, brightness); 200 analogWrite(disp010dim, brightness); 201 analogWrite(disp100dim, brightness); 202 delay(100); 203 } 204 if (digitalRead(button_less) == LOW) { 205 if (brightness >= 20) { 206 brightness=brightness-10; 207 } 208 analogWrite(disp001dim, brightness); 209 analogWrite(disp010dim, brightness); 210 analogWrite(disp100dim, brightness); 211 delay(100); 212 } 213} // checkButtons() 214 215void setBusNr(int number) { // sets 4 bits bus 216 for (byte b=0; b<=3; b++) { 217 if (numbers[number][b]==0) { 218 if (b==0) {digitalWrite(bit_0, LOW);} 219 if (b==1) {digitalWrite(bit_1, LOW);} 220 if (b==2) {digitalWrite(bit_2, LOW);} 221 if (b==3) {digitalWrite(bit_3, LOW);} 222 } else { 223 if (b==0) {digitalWrite(bit_0, HIGH);} 224 if (b==1) {digitalWrite(bit_1, HIGH);} 225 if (b==2) {digitalWrite(bit_2, HIGH);} 226 if (b==3) {digitalWrite(bit_3, HIGH);} 227 } 228 } 229} // setBusNr() 230 231// extract data from nmea inputString 232bool nmeaExtractData() { 233 int d=0; 234 int s=0; 235 int y=0; 236 int z=0; 237 float t=0; 238 bool ret = false; //true if nmea sentence = $GNRMC and valid CHKSUM 239 if ((inputString.substring(0,6) == "$GNRMC") && (inputString.substring(inputString.length()-4,inputString.length()-2) == nmea0183_checksum(inputString))) { 240 y=0; 241 for (s = 1; s < 11; s ++) { 242 y=inputString.indexOf(",",y); 243 switch (s) { 244 case 1: //-----------------------time 245 z=inputString.indexOf(",",y+1); 246 if (z>(y+1)) { 247 nm_time=inputString.substring(y+1,y+2+1)+":"+inputString.substring(y+1+2,y+4+1)+":"+inputString.substring(y+1+4,y+6+1); 248 } 249 y=z; 250 break; 251 case 2: //-----------------------validity 252 z=inputString.indexOf(",",y+1); 253 if (z>(y+1)) { 254 nm_validity=inputString.substring(y+1,y+1+1); 255 } 256 y=z; 257 break; 258 case 3: //-----------------------latitude 259 z=inputString.indexOf(",",y+1); 260 if (z>(y+1)) { 261 nm_latitude=inputString.substring(y+1,y+2+1)+"°"+inputString.substring(y+1+2,y+10+1)+"'"; 262 } 263 y=z; 264 break; 265 case 4: //-----------------------north/south 266 z=inputString.indexOf(",",y+1); 267 if (z>(y+1)) { 268 nm_latitude=nm_latitude + inputString.substring(y+1,y+1+1); 269 } 270 y=z; 271 break; 272 case 5: //-----------------------longitude 273 z=inputString.indexOf(",",y+1); 274 if (z>(y+1)) { 275 nm_longitude=inputString.substring(y+1,y+3+1)+"°"+inputString.substring(y+1+3,y+11+1)+"'"; 276 } 277 y=z; 278 break; 279 case 6: //-----------------------east/west 280 z=inputString.indexOf(",",y+1); 281 if (z>(y+1)) { 282 nm_longitude=nm_longitude + inputString.substring(y+1,y+1+1); 283 } 284 y=z; 285 break; 286 case 7: //-----------------------speed knots 287 z=inputString.indexOf(",",y+1); 288 if (z>(y+1)) { 289 nmf_knots=inputString.substring(y+1,z).toFloat(); 290 t=roundOneDec(nmf_knots); 291 nm_knots=String(t,1)+"kn"; 292 nmf_kmh=roundTwoDec(nmf_knots * 1.852); 293 nmi_kmh=roundZeroDec(nmf_knots * 1.852); 294 } 295 y=z; 296 break; 297 case 8: //-----------------------true course 298 z=inputString.indexOf(",",y+1); 299 if (z>(y+1)) { 300 nmf_truecourse=inputString.substring(y+1,z).toFloat(); 301 t=roundZeroDec(nmf_truecourse); 302 nmi_truecourse=t; 303 d=t; 304 nm_truecourse=d; 305 } 306 y=z; 307 break; 308 case 9: //-----------------------date 309 z=inputString.indexOf(",",y+1); 310 if (z>(y+1)) { 311 nm_date=inputString.substring(y+1,y+2+1)+"/"+inputString.substring(y+1+2,y+4+1)+"/20"+inputString.substring(y+1+4,y+6+1); 312 } 313 y=z; 314 break; 315 case 10: 316 // statements n.u. 317 break; 318 default: 319 // statements n.u. 320 break; 321 } 322 } 323 ret=true; 324 } 325 return ret; 326} // nmeaExtractData() 327 328/* 329 SerialEvent occurs whenever a new data comes in the hardware serial RX. This 330 routine is run between each time loop() runs, so using delay inside loop can 331 delay response. Multiple bytes of data may be available. 332*/ 333void serialEvent() { 334 while (Serial.available()) { 335 char inChar = (char)Serial.read(); 336 inputString += inChar; 337 // if the incoming character is a newline, set a flag so the main loop can 338 // do something about it 339 if (inChar == '\n') { 340 stringComplete = true; 341 } 342 } 343} // serialEvent() 344 345//calculate checksum of nmea sentence 346String nmea0183_checksum(String nmea_data) { 347 int crc = 0; 348 String chSumString = ""; 349 int i; 350 // ignore the first $ sign, checksum in sentence 351 for (i = 1; i < (nmea_data.length()-5); i ++) { // remove the - 5 if no "*" + cksum + cr + lf are present 352 crc ^= nmea_data[i]; 353 } 354 chSumString = String(crc,HEX); 355 if (chSumString.length()==1) { 356 chSumString="0"+chSumString.substring(0,1); 357 } 358 chSumString.toUpperCase(); 359 return chSumString; 360} // nmea0183_checksum(String nmea_data) 361 362// round zero decimals 363float roundZeroDec(float f) { 364 float y, d; 365 y = f*1; 366 d = y - (int)y; 367 y = (float)(int)(f*1)/1; 368 if (d >= 0.5) { 369 y += 1; 370 } else { 371 if (d < -0.5) { 372 y -= 1; 373 } 374 } 375 return y; 376} 377 378// round one decimal 379float roundOneDec(float f) { 380 float y, d; 381 y = f*10; 382 d = y - (int)y; 383 y = (float)(int)(f*10)/10; 384 if (d >= 0.5) { 385 y += 0.1; 386 } else { 387 if (d < -0.5) { 388 y -= 0.1; 389 } 390 } 391 return y; 392} 393 394// round two decimals 395float roundTwoDec(float f) { 396 float y, d; 397 y = f*100; 398 d = y - (int)y; 399 y = (float)(int)(f*100)/100; 400 if (d >= 0.5) { 401 y += 0.01; 402 } else { 403 if (d < -0.5) { 404 y -= 0.01; 405 } 406 } 407 return y; 408} 409
Downloadable files
Sketch version 2 (read instructions first)
Sketch version 2 (read instructions first)
Sketch version 2.2 (read instructions first)
Sketch version 2.2 (read instructions first)
PCB #1 (components face)
PCB #1 (components face)
PCB #2 overview
PCB #2 overview
3D Plastic container picture
3D Plastic container picture
Fritzing picture
Fritzing picture
PCB #1 overview
PCB #1 overview
PCB #1 (bottom side)
PCB #1 (bottom side)
PCB #1 (top side)
PCB #1 (top side)
PCB #2 (bottom side)
PCB #2 (bottom side)
PCB #2 (components face)
PCB #2 (components face)
PCB #2 (top side)
PCB #2 (top side)
Fritzing schematic diagram
Fritzing schematic diagram
PCB #2 (components face)
PCB #2 (components face)
PCB #2 (top side)
PCB #2 (top side)
PCB #1 overview
PCB #1 overview
Sketch version 2 (read instructions first)
Sketch version 2 (read instructions first)
PCB #2 (bottom side)
PCB #2 (bottom side)
PCB #2 overview
PCB #2 overview
PCB #1 (bottom side)
PCB #1 (bottom side)
PCB #1 (top side)
PCB #1 (top side)
Sketch version 2.2 (read instructions first)
Sketch version 2.2 (read instructions first)
PCB #1 (components face)
PCB #1 (components face)
Fritzing picture
Fritzing picture
3D Plastic container picture
3D Plastic container picture
Comments
Only logged in users can leave comments
marcozonca
0 Followers
•0 Projects
0