Basierend auf einem TTGO LoRa mit OLED 128×64 mit BN-880 GPS.
Anschluss
- Batterie/Lipo an den unteren Bat-Connector
- GPS an 5V/12(RX)/13(TX)/GND
Arduino mit der ESP32-Erweiterung, Board TTGO-LoRa-OLED.
Features
- 5 Hz GPS-Datenrate
- Die 5 höchsten Geschwindigkeiten, die höchste extra groß angezeigt
- Satellitenanzahl-Anzeige
Hier der Code:
//Libraries for OLED Display #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> const unsigned char ubxRate1Hz[] = { 0x06,0x08,0x06,0x00,0xE8,0x03,0x01,0x00,0x01,0x00 }; const unsigned char ubxRate5Hz[] = { 0x06,0x08,0x06,0x00,200,0x00,0x01,0x00,0x01,0x00 }; const unsigned char ubxRate10Hz[] = { 0x06,0x08,0x06,0x00,100,0x00,0x01,0x00,0x01,0x00 }; const unsigned char ubxRate16Hz[] = { 0x06,0x08,0x06,0x00,50,0x00,0x01,0x00,0x01,0x00 }; // Disable specific NMEA sentences const unsigned char ubxDisableGGA[] = { 0x06,0x01,0x08,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x01 }; const unsigned char ubxDisableGLL[] = { 0x06,0x01,0x08,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x01 }; const unsigned char ubxDisableGSA[] = { 0x06,0x01,0x08,0x00,0xF0,0x02,0x00,0x00,0x00,0x00,0x00,0x01 }; const unsigned char ubxDisableGSV[] = { 0x06,0x01,0x08,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x01 }; const unsigned char ubxDisableRMC[] = { 0x06,0x01,0x08,0x00,0xF0,0x04,0x00,0x00,0x00,0x00,0x00,0x01 }; const unsigned char ubxDisableVTG[] = { 0x06,0x01,0x08,0x00,0xF0,0x05,0x00,0x00,0x00,0x00,0x00,0x01 }; const unsigned char ubxDisableZDA[] = { 0x06,0x01,0x08,0x00,0xF0,0x08,0x00,0x00,0x00,0x00,0x00,0x01 }; #define Battadc 34 //OLED pins #define OLED_SDA 4 #define OLED_SCL 15 #define OLED_RST 16 #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define SDA 21 #define SCL 22 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST); bool enable_dbg; bool sig_valid, sig_rxok; float sig_speed, saved_spd; int sig_sats; float maxspeed[5]; // Cut out the wanted substring from a comma-separated string static String extract_val(char *buf, int len, int cpos) { String str=""; int i,cc=0,cs=0,ce=255; for (i=0;i0) sig_valid = true; Serial.println(s); sig_speed = s.toFloat(); saved_spd = sig_speed; } else if (buf[2]=='G' && buf[3]=='G' && buf[4]=='A') { display.print(buf); String s = extract_val(buf, pos, 7); Serial.println(s); sig_sats = s.toInt(); } } else if (c=='$') pos=0; else if (pos < sizeof(buf)) buf[pos++] = c; } //Warteschleife, die ankommende Daten vom GPS Modul verarbeitet und den Status des Tasters prüft static void smartdelay(unsigned long ms) { unsigned long start = millis(); do { while (Serial2.available()) { char c=Serial2.read(); parse_gps(c); if (enable_dbg) Serial.print(c); //display.print(c); } //display.display(); } while (millis() - start < ms); } static void sendUBX( const unsigned char *progmemBytes, size_t len ) { Serial2.write( 0xB5 ); // SYNC1 Serial2.write( 0x62 ); // SYNC2 uint8_t a = 0, b = 0; while (len-- > 0) { uint8_t c = ( *progmemBytes++ ); a += c; b += a; Serial2.write( c ); } Serial2.write( a ); // CHECKSUM A Serial2.write( b ); // CHECKSUM B delay(100); } static void updateRate() { sendUBX(ubxRate5Hz, 10); } void setup() { pinMode(0, INPUT_PULLUP); // button pinMode(SCL, INPUT_PULLUP); // I2C of GPS compass pinMode(SDA, INPUT_PULLUP); analogSetAttenuation(ADC_0db); // control sensitivity; ADC_11db, ADC_6db, ADC_2_5db, ADC_0db pinMode(Battadc, INPUT); adcAttachPin(Battadc); Serial.begin(115200); // debug Serial2.begin(9600,SERIAL_8N1,12,13); // GPS //reset OLED display via software pinMode(OLED_RST, OUTPUT); digitalWrite(OLED_RST, LOW); delay(20); digitalWrite(OLED_RST, HIGH); //initialize OLED Wire.begin(OLED_SDA, OLED_SCL); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32 //Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } display.setTextColor(WHITE); display.setTextSize(1); display.clearDisplay(); display.display(); delay(2000); sendUBX(ubxDisableGLL, 12); sendUBX(ubxDisableGSA, 12); sendUBX(ubxDisableGSV, 12); sendUBX(ubxDisableRMC, 12); sendUBX(ubxDisableZDA, 12); Serial2.print("$PUBX,41,1,0007,0003,19200,0*25\r\n"); Serial2.flush(); delay(100); Serial2.end(); Serial2.begin(19200,SERIAL_8N1,12,13); delay(1000); updateRate(); } void loop() { int i; bool spdwritten = false; char tmp[32]; float spd; smartdelay(0); display.clearDisplay(); // drawString(x,y,text);? or ACROBOTIC_SSD1306 with setTextXY/putString display.setCursor(0, 0); if (sig_valid) { spd = sig_speed; sig_speed = 0.0; // show maximum speed, with 5 places to see glitches display.println("Geschwindigkeit (max)"); for (i=0; i<5; i++) { if (spd > maxspeed[i] && !spdwritten) { maxspeed[i] = spd; spdwritten = true; break; } } for (i=0; i<5; i++) { if (i==0) display.setTextSize(2); sprintf(tmp, "%4.1f km/h", maxspeed[i]); display.println(tmp); if (i==0) display.setTextSize(1); } // show current speed sprintf(tmp,"S%4.1f Sats %3d", saved_spd, sig_sats); display.print(tmp); } else { display.println("No GPS fix."); if (sig_rxok) display.println("GPS RX ok"); sprintf(tmp," Sats %3d", sig_sats); display.print(tmp); } display.display(); int vbatt = analogRead(Battadc); if (digitalRead(0)==0) { // clear for (i=0;i<5; i++) maxspeed[i] = 0.0; display.clearDisplay(); } }