Vitezometru OLED / Speedometer GPS
Codul de mai jos este un vitezometru pentru masina. Are o corectie pentru 5km/h, avertizari optice si acustice pentru depasiri de viteza. Deasemenea pentru a evita fluctuatiile numarului de sateliti disponibili are integrate unele protectii pentru a nu deruta in cazul lipsei numarului minim de sateliti disponibili.
Totusi in dreapta ecranului afiseaza in continuare viteza GPS
In partea stanga jos indica numarul de sateliti disponibili.
Are integrate atentionari sonore: lipsa GPS, conectare, si "overspeed"
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
TinyGPSPlus gps;
SoftwareSerial ss(4, 3); // RX, TX
const int led1 = 6; // 55 km/h
const int led2 = 7; // 95 km/h
const int led3 = 8; // 135 km/h
const int buzzerPin = 9;
bool gpsSignal = false;
bool over170 = false;
bool gpsFixBeeped = false;
unsigned long lastGpsAnim = 0;
unsigned long gpsAnimStep = 0;
unsigned long lastNoFixBeep = 0;
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(buzzerPin, OUTPUT);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(buzzerPin, LOW);
Serial.begin(9600);
ss.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
beepStart(); // Beep la pornire
}
void loop() {
while (ss.available() > 0) {
gps.encode(ss.read());
}
int sateliti = gps.satellites.value();
double vitezaReala = gps.speed.kmph();
if (gps.location.isValid() && gps.speed.isValid() && sateliti >= 5) {
gpsSignal = true;
if (!gpsFixBeeped) {
beepFix();
gpsFixBeeped = true;
}
double speedKmh = vitezaReala + 5.0; // adaugă 5 km/h la viteza GPS
display.clearDisplay();
// afișare număr sateliți în stânga jos
display.setTextSize(1);
display.setCursor(0, SCREEN_HEIGHT - 8);
display.print(sateliti);
display.print(" SAT");
// afișare viteza reala GPS în dreapta sus, font mic
display.setTextSize(1);
display.setCursor(SCREEN_WIDTH - 30, 0);
if (gps.speed.isValid()) {
display.print((int)vitezaReala);
} else {
display.print("--");
}
if (speedKmh < 10) {
speedKmh = 0;
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(buzzerPin, LOW);
display.setTextSize(3);
display.setCursor(10, 0);
display.print(" 0");
display.setTextSize(1);
display.setCursor(100, 22);
display.print("km/h");
display.display();
} else {
display.setTextSize(3);
display.setCursor(10, 0);
int viteza = (int)speedKmh;
if (viteza < 10) display.print(" ");
else if (viteza < 100) display.print(" ");
display.print(viteza);
display.setTextSize(1);
display.setCursor(100, 22);
display.print("km/h");
controlLeds(viteza);
controlBuzzer(viteza);
display.display();
}
} else {
if (gpsSignal) {
gpsSignal = false;
gpsFixBeeped = false;
digitalWrite(buzzerPin, LOW);
}
display.clearDisplay();
display.setTextSize(2);
display.setCursor(10, 10);
if (millis() - lastGpsAnim > 500) {
gpsAnimStep = (gpsAnimStep + 1) % 4;
lastGpsAnim = millis();
}
String gpsText = "GPS";
for (int i = 0; i < gpsAnimStep; i++) gpsText += ".";
display.print(gpsText);
display.display();
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
if (millis() - lastNoFixBeep > 10000) {
beepNoFix();
lastNoFixBeep = millis();
}
}
}
void controlLeds(int viteza) {
if (viteza > 148) {
blinkAllLeds();
} else if (viteza > 136) {
blinkLed(led2);
digitalWrite(led3, HIGH);
digitalWrite(led1, HIGH);
} else if (viteza > 96) {
blinkLed(led1);
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW);
} else {
digitalWrite(led1, viteza > 55);
digitalWrite(led2, viteza > 95);
digitalWrite(led3, viteza > 135);
}
}
void controlBuzzer(int viteza) {
static unsigned long lastBeepTime = 0;
static bool over170 = false;
if (viteza > 170) {
if (!over170) {
digitalWrite(buzzerPin, HIGH);
over170 = true;
}
return;
} else {
if (over170) {
digitalWrite(buzzerPin, LOW);
over170 = false;
}
}
if (viteza > 150 && viteza <= 170) {
if (millis() - lastBeepTime >= 1000) {
digitalWrite(buzzerPin, HIGH);
delay(100);
digitalWrite(buzzerPin, LOW);
lastBeepTime = millis();
}
}
}
void blinkLed(int pin) {
static unsigned long lastBlink = 0;
static bool state = false;
if (millis() - lastBlink > 500) {
state = !state;
digitalWrite(pin, state);
lastBlink = millis();
}
}
void blinkAllLeds() {
static unsigned long lastBlink = 0;
static bool state = false;
if (millis() - lastBlink > 300) {
state = !state;
digitalWrite(led1, state);
digitalWrite(led2, state);
digitalWrite(led3, state);
lastBlink = millis();
}
}
void beepStart() {
digitalWrite(buzzerPin, HIGH);
delay(100);
digitalWrite(buzzerPin, LOW);
}
void beepFix() {
for (int i = 0; i < 3; i++) {
digitalWrite(buzzerPin, HIGH);
delay(100);
digitalWrite(buzzerPin, LOW);
delay(100);
}
}
void beepNoFix() {
for (int i = 0; i < 2; i++) {
digitalWrite(buzzerPin, HIGH);
delay(100);
digitalWrite(buzzerPin, LOW);
delay(100);
}
}
Comentarii
Trimiteți un comentariu