#include #include "SparkFun_Ublox_Arduino_Library_Series_6_7.h" //for GPS #include //for screen #include //for screen #include "Adafruit_LEDBackpack.h" //for screen #include #include #include //for determining startup brightness #include #define DISPLAY_ADDRESS 0x70 //I2C address of screen #define GPS_WAIT_TIME 1100 #define GPS_UPDATE_FREQUENCY 10 //GPS update frequency per sec #define DEBOUNCE_DELAY 250 //time in ms #define MIDDLE_SCREEN_BRIGHTNESS 5 //#define PROFILE true //GPS SFE_UBLOX_GPS myGPS; //threading std::atomic speed(0); std::atomic_int gpsFixType(0); //screen Adafruit_AlphaNum4 disp = Adafruit_AlphaNum4(); unsigned long timeOfLastFix = 0UL; unsigned long timer = millis(); bool setInitBrightness = false; unsigned long brightnessTimer = millis(); //button volatile bool buttonPushed = false; volatile int ScreenBrightnessUser = 15; volatile int screenBrightnessCurrent = ScreenBrightnessUser; volatile unsigned long lastButtonPush = 0UL; volatile bool manualBrightness = false; //profiler int runCounter = 0; unsigned long profileTimer = millis(); void chageBrightness() { if (millis() - lastButtonPush > DEBOUNCE_DELAY) { buttonPushed = true; lastButtonPush = millis(); manualBrightness = true; } } void connectGPS() { //need to do this everytime the GPS turns back on do { //set gps to 115200 baudrate code comes from sparkfun examples // Serial.println("GNSS: trying 115200 baud"); Serial1.begin(115200); if (myGPS.begin(Serial1) == true) break; delay(100); //Serial.println("GNSS: trying 9600 baud"); Serial1.begin(9600); if (myGPS.begin(Serial1) == true) { //Serial.println("GNSS: connected at 9600 baud, switching to 115200"); myGPS.setSerialRate(115200); delay(100); } else { delay(2000); //Wait a bit before trying again to limit the Serial output } } while (1); myGPS.setAutoPVT(true); myGPS.setUART1Output(COM_TYPE_UBX); //Set the UART1 port to output UBX only (turn off NMEA noise) myGPS.setNavigationFrequency(GPS_UPDATE_FREQUENCY); //set frequency of updates to 10/sec //myGPS.setDynamicModel(DYN_MODEL_AUTOMOTIVE); //set dynamic model of GPS to automotive to more accutate results } bool setStartBrightness() { double az = 0; double el = 0; int hour = myGPS.getHour(); int min = myGPS.getMinute(); int sec = myGPS.getSecond(); int day = myGPS.getDay(); int month = myGPS.getMonth(); int year = myGPS.getYear(); setTime(hour, min, sec, day, month, year); time_t timeUtc = now(); double lat = myGPS.getLatitude(); lat = lat / 10000000; double lng = myGPS.getLongitude(); lng = lng / 10000000; calcHorizontalCoordinates(timeUtc, lat, lng, az, el); //el = el - 180; if (el > SUNRISESET_STD_ALTITUDE) { screenBrightnessCurrent = 15; } else if ((el < SUNRISESET_STD_ALTITUDE) && (el > CIVIL_DAWNDUSK_STD_ALTITUDE)) { screenBrightnessCurrent = MIDDLE_SCREEN_BRIGHTNESS; } else if (el < CIVIL_DAWNDUSK_STD_ALTITUDE) { screenBrightnessCurrent = 0; } ScreenBrightnessUser = screenBrightnessCurrent; disp.setBrightness(screenBrightnessCurrent); return true; } void setup() { //setup screen Wire.setSCL(17); Wire.setSDA(16); //Wire.setClock(100000); disp.begin(DISPLAY_ADDRESS); disp.setBrightness(ScreenBrightnessUser); //screen brightness pinMode(20, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(20), chageBrightness, FALLING); rp2040.wdt_begin(2000); //start hardware watchdog } void setup1() { //setup GPS Serial1.setRX(1); Serial1.setTX(0); connectGPS(); //setStartBrightness(); } void loop() { //set init brightness if ((!setInitBrightness && gpsFixType.load() > 0) || ((!manualBrightness && millis() > brightnessTimer + 6000) && gpsFixType.load() > 0)) { //fire every minute setStartBrightness(); setInitBrightness = true; brightnessTimer = millis(); } //change brightness if (buttonPushed == true) { if (ScreenBrightnessUser == 15) { ScreenBrightnessUser = MIDDLE_SCREEN_BRIGHTNESS; } else if (ScreenBrightnessUser == MIDDLE_SCREEN_BRIGHTNESS) { ScreenBrightnessUser = 0; } else { ScreenBrightnessUser = 15; } disp.setBrightness(ScreenBrightnessUser); screenBrightnessCurrent = ScreenBrightnessUser; buttonPushed = false; } disp.clear(); if (gpsFixType.load() > 0) { if (screenBrightnessCurrent != ScreenBrightnessUser) { disp.setBrightness(ScreenBrightnessUser); screenBrightnessCurrent = ScreenBrightnessUser; } timeOfLastFix = millis(); //reset no gps screen display int temp = speed.load() * 10; //int temp = rand(); if (temp < 10) { temp = 0; } // show 0 when stopped and not noise. int digit0 = temp / 1000; int digit1 = (temp / 100) - (digit0 * 10); int digit2 = (temp / 10) - (digit0 * 100) - (digit1 * 10); int digit3 = temp - (digit0 * 1000) - (digit1 * 100) - (digit2 * 10); if (speed > 100) { //dont show leading 0 if going under 100km/h disp.writeDigitAscii(0, 48 + digit0); } if (speed > 10) { //dont show 10s digit if less then 10km/h disp.writeDigitAscii(1, 48 + digit1); } disp.writeDigitAscii(2, 48 + digit2, true); disp.writeDigitAscii(3, 48 + digit3); } else { if (screenBrightnessCurrent != 0) { disp.setBrightness(0); screenBrightnessCurrent = 0; } unsigned long currentTime = millis(); unsigned long timeSinceLastFIx = timeOfLastFix - currentTime; int flashStage = timeSinceLastFIx % 3000; for (int x = 0; x < 4; x++) { if (flashStage < 1000) { //disp.writeDigitAscii(x, 95); disp.writeDigitAscii(x, 3U); //bottom } else if (flashStage < 2000 && flashStage > 1000) { disp.writeDigitRaw(x, 192u); //middle } else if (flashStage < 3000 && flashStage > 2000) { disp.writeDigitRaw(x, 1); //top } } } disp.writeDisplay(); rp2040.wdt_reset(); //rest watchdog timer #if PROFILE //profiling runCounter++; if(millis() > profileTimer + 1000){ Serial.println(runCounter); runCounter=0; profileTimer=millis(); } #endif } void loop1() { //myGPS.getPVT(GPS_WAIT_TIME); speed.store(myGPS.getGroundSpeed() * 0.0036); //get speed in mm/s and convert to Km/h gpsFixType.store(myGPS.getFixType(GPS_WAIT_TIME)); //getFixType() will return >1 for fix type and 0 for no fix. }