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
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
#include "U8glib.h" U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); //--------------------------------------------------------------------------- #include <SoftwareSerial.h> #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 ;) u8g.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


