Prędkościomierze służą do pomiaru prędkości poruszającego się pojazdu. Wcześniej budowaliśmy kłady na bazie modułu NEO6M GPS. Dziś wykorzystamy moduł NEO-6M do pomiaru prędkości poruszającego się pojazdu. Prędkościomierze oparte GPS z zasady są dokładniejsze niż standardowe prędkościomierze. Wszystko przez fakt, że mogą w sposób ciągły lokalizować pojazd i obliczać jego prędkość. Technologia pozycjonowanie GNSS (GPS, GLONASS, GALILEO, BEIDU) jest szeroko stosowana w transporcie morskim czy lądowym jak i smartfonach które macie w kieszeni. Wszystko to sprowadza się do nawigacji jak i odbierania alertów o ruchu drogowym.
W tym projekcie zbudujemy prędkościomierz Arduino GPS z wykorzystaniem modułu NEO6M GPS z wyświetlaczem OLED.
Potrzebne komponenty:
Moduł GPS NEO6M
Sam moduł GPS NEO-6M jest stosunkowo popularnym odbiornikiem GPS wraz z ceramiczną anteną, dzięki w miarę kompaktowym gabarytom anteny zapewnia szybkie wyszukiwanie satelit. Ten odbiornik ma możliwość wykrywania lokalizacji i śledzenia do 22 satelitów oraz identyfikuje lokalizacje w dowolnym miejscu na świecie. Dzięki wbudowanemu wskaźnikowi sygnału możemy monitorować stan sieci modułu. Posiada baterię podtrzymującą dane, dzięki czemu moduł może zapisać dane w przypadku przypadkowego wyłączenia głównego zasilania.
Funkcje modułu:
- Napięcie pracy: 2,7-3,6V DC
- Prąd prądu: 67 mA
- Szybkość transmisji: 4800-230400 jednak domyślnie 9600
- Protokół komunikacyjny: NEMA
- Interfejs: UART
- Antena zewnętrzna
- Wbudowana pamięć EEPROM.
Wyświetlacz OLED I2C
Termin OLED oznacza „organiczną diodę emitującą światło”, wykorzystuje tę samą technologię, która jest stosowana w większości naszych telewizorów, ale ma mniej pikseli w porównaniu do nich. Łączenie tych fajnie wyglądających modułów wyświetlacza z Arduino to prawdziwa przyjemność, ponieważ dzięki temu nasze projekty będą wyglądać fajnie. Cały artykuł na temat wyświetlaczy OLED i ich typów omówiliśmy tutaj. Tutaj używamy monochromatycznego 4-pinowego wyświetlacza OLED SH1106 OLED o przekątnej 1,28”. Ten wyświetlacz może działać tylko w trybie I2C.
Specyfikacja techniczna wyświetlacza:
Układ sterownika: SH1106
Napięcie wejściowe: 3,3V – 5V DC
Rozdzielczość: 128×64
Interfejs: I2C
Pobór prądu: 8 mA
Kolor piksela: niebieski, biały,
Kąt widzenia: >160 stopni
Opis pinout:
- VCC: Zasilanie wejściowe 3,3–5V DC
- GND: Złącze GND (masowe)
- SCL: Pin zegara interfejsu I2C
- SDA: Pin danych szeregowych interfejsu I2C
Schemat połączeń:
Kod programu
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);
//---------------------------------------------------------------------------
#include
#define rxPin 4
#define txPin 3
SoftwareSerial neogps(rxPin,txPin);
#include <TinyGPS++.h> //1.0.3 tej wersji użyłem
TinyGPSPlus gps;
//—————————————————————————
int x_max = 128; //OLED szerokość
int y_max = 62; //OLED wysokość
int x_center = x_max/2;
int y_center = y_max/2+10;
int arc = y_max/2;
int angle = 0;
//—————————————————————————
int needle_pos = 0;
u8g_uint_t xx = 0;
//—————————————————————————
//ikona satelity
#define sat_logo_width 20
#define sat_logo_height 20
const unsigned char sat_logo[] = {
0x00, 0x01, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x06, 0x00, 0x60, 0x30, 0x00,
0x60, 0x78, 0x00, 0xc0, 0xfc, 0x00, 0x00, 0xfe, 0x01, 0x00, 0xff, 0x01,
0x80, 0xff, 0x00, 0xc0, 0x7f, 0x06, 0xc0, 0x3f, 0x06, 0x80, 0x1f, 0x0c,
0x80, 0x4f, 0x06, 0x19, 0xc6, 0x03, 0x1b, 0x80, 0x01, 0x73, 0x00, 0x00,
0x66, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x70, 0x00, 0x00
};
//—————————————————————————
//zmienne programu
double lat;
double lng;
String hour, minute;
int second;
int num_sat, speed;
String heading;
/************************************************** *********************************************
* funkcja prędkościomierz GPS
* wszystko co na wyświetlaczu
************************************************** *****************************************/
void gauge(uint8_t angle) {
u8g.setFont(u8g_font_chikita);
//—————————————————————————
// granica miernika
u8g.drawCircle(x_center,y_center,arc+6, U8G_DRAW_UPPER_RIGHT);
u8g.drawCircle(x_center,y_center,arc+4, U8G_DRAW_UPPER_RIGHT);
u8g.drawCircle(x_center,y_center,arc+6, U8G_DRAW_UPPER_LEFT);
u8g.drawCircle(x_center,y_center,arc+4, U8G_DRAW_UPPER_LEFT);
//—————————————————————————
// pokaż wartość zmierzoną wskaźnik wychyłowy
u8g.drawStr(20, 42, „0”);
u8g.drawStr(18, 29, „25”);
u8g.drawStr(28, 14, „50”);
u8g.drawStr(60, 14, „100”);
u8g.drawStr(91, 14, „150”);
u8g.drawStr(101, 29, „175”);
u8g.drawStr(105, 42, „200”);
//—————————————————————————
// tekst środek
//nie chciało mi się włączyć o polskie znaki 😉
u8 g.setPrintPos(45,25);
u8g.print(„Predkosc”);
u8g.setPrintPos(54,32);
u8g.print(„km/h”);
//—————————————————————————
// narysuj wskaźnik igłowy od środka wskaźnika
float x1=sin(2*angle*2*3.14/360);
float y1=cos(2*angle*2*3.14/360);
u8g.drawLine(x_center, y_center, x_center+arc*x1, y_center-arc*y1);
u8g.drawDisc(x_center, y_center, 5, U8G_DRAW_UPPER_LEFT);
u8g.drawDisc(x_center, y_center, 5, U8G_DRAW_UPPER_RIGHT);
//—————————————————————————
//góra po lewej: narysuj logo satelity
u8g.drawXBM(0, 0, sat_logo_width, sat_logo_height, sat_logo);
u8g.setPrintPos(18, 5);
u8g.print(num_sat, 5);
//—————————————————————————
// góra prawa strona wyświetl kierunek
u8g.setPrintPos(110, 5);
u8g.print(heading);
//—————————————————————————
//lewy dół wyświetl szerokość i długość geograficzną
u8g.setPrintPos(0, 55);
u8g.print(lat, 4);
u8g.setPrintPos(0, 62);
u8g.print(lng, 4);
//—————————————————————————
//prawy dół wyświetl czas z GNSS
u8g.setFont(u8g_font_freedoomr10r);
u8g.setPrintPos(90, 65);
u8g.print(hour);
if(second%2 == 0)
{u8g.drawStr(104, 65, „:”);}
else
{u8g.drawStr(104, 65, ” „);}
u8g.setPrintPos(111, 65);
u8g.print(minute);
u8g.setFont(u8g_font_profont22);
u8g.setPrintPos(54,60);
if (speed<10){ u8g.print(„0”); } if (speed>99) {
u8g.setPrintPos(47,60);
}
u8g.print(speed);
//—————————————————————————
}
int i = 200;
void setup(void) {
Serial.begin(9600);
neogps.begin(9600);
u8g.setFont(u8g_font_chikita);
u8g.setColorIndex(1);
}
void loop(void){
Read_GPS();
needle_pos = map(speed,0,200,0,90);
xx = needle_pos;
if (xx<45)
{xx=xx+135;}
else
{xx=xx-45;}
{
u8g.firstPage();
do {
gauge(xx);
}
while( u8g.nextPage() );
}
//———————————————————-
}
void Read_GPS(){
boolean newData = false;
for (unsigned long start = millis(); millis() – start < 1000;)
{
while (neogps.available())
{
if (gps.encode(neogps.read()))
{
newData = true;
break;
}
}
}
//——————————————————————
//newData zostały pobrane
if(newData == true){
newData = false;
Get_GPS();
}
else {
}
}
void Get_GPS(){
num_sat = gps.satellites.value();
if (gps.location.isValid() == 1) {
speed = gps.speed.kmph();
//Serial.print(„Speed: „);Serial.println(gps_speed);
lat = gps.location.lat();
//Serial.print(„lat: „);Serial.println(lat);
lng = gps.location.lng();
//Serial.print(„lng: „);Serial.println(lng);
heading = gps.cardinal(gps.course.value());
//Serial.print(„heading: „);Serial.println(heading);
}
if (gps.time.isValid()){
hour = String(gps.time.hour()+1); //+1 czas zimowy w Polsce
hour = (hour.length() == 1) ? „0”+hour : hour;
minute = String(gps.time.minute());
minute= (minute.length() == 1) ? „0”+minute : minute;
second = gps.time.second();
}
}
Lub do pobrania plik ino