Module GPS L80 là module thu thập thông tin được gửi về từ các vệ tinh GPS . Các thông tin này bao gồm: thời gian thực, vị trí, tọa độ, vận tốc ...Kết hợp module này với một máy tính hoặc một board mạch Vi xử lý như Arduino là bạn đã có thể làm được một số ứng dụng như thiết bị theo dõi hành trình, thiết bị chống trộm, đồng hồ thời gian thực ...
ARDUINO |
LCD Keypad Shield |
5V |
5V |
Gnd |
Gnd |
Pin 4 |
D4 |
Pin 5 |
D5 |
Pin 6 |
D6 |
Pin 7 |
D7 |
Pin 8 |
RS |
Pin 9 |
EN |
A0 |
Nút bấm ADC |
Arduino và Module GPS L80
ARDUINO |
Module GPS L80 |
5V |
5V |
Gnd |
Gnd |
Pin 0 – Rx |
RxD |
Pin 1 - Tx |
TxD |
Code tham khảo trên mạch Arduino - Uno VN01:
Code này sẽ hiển thị các thông tin về thời gian, tọa độ, tốc độ nhận được từ module GPS lên màn hình LCD, các bạn dùng phím bấm "RIGHT" trên shield LCD để chuyển trang màn hình.
(Lưu ý: Anten GPS phải để ngoài trời hoặc gần cửa sổ thì mới có thể bắt được tín hiệu từ vệ tinh GPS )
// code tham khảo do MLAB xây dựng dành cho Arduino, LCD Keypad Shield, Module GPS L80 // website: http://mlab.vn/ // Nội dung: Hiển thị các thông tin về thời gian, tốc độ, tọa độ nhận được từ GPS L80 lên LCD. Sử dụng nút bấm Right để chuyển trang. // include the library code: #include <LiquidCrystal.h> #include "string.h" #include "stdlib.h" // Buttons #define btnRIGHT 0 #define btnUP 1 #define btnDOWN 2 #define btnLEFT 3 #define btnSELECT 4 #define btnNONE 5 // GPRMC #define GPRMC_MID 0 #define GPRMC_UTC 1 #define GPRMC_STS 2 #define GPRMC_LAT 3 #define GPRMC_LAT_NS 4 #define GPRMC_LON 5 #define GPRMC_LON_EW 6 #define GPRMC_SOG 7 #define GPRMC_COG 8 #define GPRMC_DAT 9 #define GPRMC_MAV 10 #define GPRMC_MAV_EW 11 #define GPRMC_MOD 12 typedef union { unsigned char array_time[7]; struct { unsigned char year; unsigned char month; unsigned char date; unsigned char hour; unsigned char minute; unsigned char sec; }time; }SysTime; typedef enum { DISPLAY_GPS = 0, DISPLAY_RTC, DISPLAY_SPEED_ORG, DISPLAY_MAX }DISPLAY_E; typedef struct{ bool State_gps; /*!< trang thai gps 1 = co tin hieu, 0 = mat tin hieu */ SysTime time_gps; /*!< time gps */ float Lat; /*!< vi do */ float Lng; /*!< kinh do */ float SpeedGPS; /*!< Toc do GPS */ float OrGPS; /*!< Huong GPS 360 do */ }GPS_T; /*!< cau truc du lieu hanh trinh */ // initialize the library with the numbers of the interface pins LiquidCrystal lcd(8, 9, 4, 5, 6, 7); static float gps_convert_lon_to_float(unsigned char *lon_str, unsigned char *WE); static float gps_convert_lat_to_float(unsigned char *lon_str, unsigned char *NS); static void NMEA_GPRMC_Decoder(GPS_T *gps_data, String data); static int GetMessageFeilds(unsigned char **message_feildls, unsigned char *msg, unsigned char separate_char, int max_feild_get); GPS_T g_gps_data = {false, {0,0,0,0,0,0,0}, 0, 0, 0, 0}; int read_LCD_buttons(){ // read the buttons int adc_key_in = analogRead(0); // read the value from the sensor // my buttons when read are centered at these valies: 0, 144, 329, 504, 741 // we add approx 50 to those values and check to see if we are close // We make this the 1st option for speed reasons since it will be the most likely result if (adc_key_in > 1000) return btnNONE; // For V1.1 us this threshold if (adc_key_in < 50) return btnRIGHT; if (adc_key_in < 250) return btnUP; if (adc_key_in < 450) return btnDOWN; if (adc_key_in < 650) return btnLEFT; if (adc_key_in < 850) return btnSELECT; return btnNONE; // when all others fail, return this. } void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); Serial.setTimeout(5); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } // prints title with ending line break Serial.println("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n"); // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("MLAB:Hello World!"); lcd.setCursor(0, 1); lcd.print("mlab.vn"); } int button_pressed, tmp_button, table_display = 0; void loop() { char print_lcd[16]; char float_str[10]; int index_gprmc = 0; // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): tmp_button = read_LCD_buttons(); if(button_pressed != tmp_button) { Serial.println("Key pressed"); button_pressed = tmp_button; if(button_pressed == btnRIGHT) { table_display++; if(table_display >= DISPLAY_MAX) { table_display = 0; } } if(button_pressed == btnLEFT) { if(table_display == 0) { table_display = DISPLAY_MAX - 1; } else { table_display--; } } } while (Serial.available() > 0) { String str = Serial.readStringUntil(0x0D); index_gprmc = str.indexOf("GPRMC"); if(index_gprmc != -1) // Just run gprmc { str = str.substring(index_gprmc); NMEA_GPRMC_Decoder(&g_gps_data, str); switch(table_display) { case DISPLAY_GPS: { if(g_gps_data.State_gps == true) { lcd.clear(); lcd.setCursor(0, 0); dtostrf(g_gps_data.Lat, 10, 6, float_str); sprintf(print_lcd, "lat: %s", float_str); lcd.print(print_lcd); lcd.setCursor(0, 1); dtostrf(g_gps_data.Lng, 10, 6, float_str); sprintf(print_lcd, "lng: %s", float_str); lcd.print(print_lcd); } else { lcd.clear(); lcd.setCursor(0, 0); lcd.print("GPS not fix"); } break; } case DISPLAY_RTC: { lcd.clear(); lcd.setCursor(0, 0); sprintf(print_lcd, "%04d/%02d/%02d" , 2000 + g_gps_data.time_gps.time.year \ , g_gps_data.time_gps.time.month \ , g_gps_data.time_gps.time.date); lcd.print(print_lcd); lcd.setCursor(0, 1); sprintf(print_lcd, "%02d:%02d:%02d", g_gps_data.time_gps.time.hour \ , g_gps_data.time_gps.time.minute \ , g_gps_data.time_gps.time.sec); lcd.print(print_lcd); break; } case DISPLAY_SPEED_ORG: { lcd.clear(); lcd.setCursor(0, 0); dtostrf(g_gps_data.SpeedGPS, 5, 2, float_str); sprintf(print_lcd, "SPEED : %s", float_str); lcd.print(print_lcd); lcd.setCursor(0, 1); dtostrf(g_gps_data.OrGPS, 5, 2, float_str); sprintf(print_lcd, "ORG : %s", float_str); lcd.print(print_lcd); break; } default: break; } } } } static int GetMessageFeilds(unsigned char **message_feildls, unsigned char *msg, unsigned char separate_char, int max_feild_get) { int count_feild = 0; *message_feildls = msg; message_feildls++; count_feild++; while(*msg !='\0') { if(*msg == separate_char) { *msg = '\0'; *message_feildls = msg + 1; message_feildls++; count_feild++; if(count_feild >= max_feild_get) return count_feild; } msg++; } return count_feild; } static float gps_convert_lon_to_float(unsigned char *lon_str, unsigned char *WE) { unsigned char hours[3+1]; unsigned char minutes[8+1]; float ret; memset(hours,0,sizeof(hours)); memset(minutes,0,sizeof(minutes)); strncpy( hours, lon_str, 3 ); strncpy( minutes, lon_str + 3 , strlen(lon_str) - 3 ); ret = atof(hours); ret += atof(minutes)/60; if(strcmp(WE, "W") == 0) { return -ret; } return ret; } static float gps_convert_lat_to_float(unsigned char *lat_str, unsigned char *NS) { unsigned char hours[2+1]; unsigned char minutes[8+1]; float ret; memset(hours,0,sizeof(hours)); memset(minutes,0,sizeof(minutes)); strncpy( hours, lat_str, 2 ); strncpy( minutes, lat_str + 2 , strlen(lat_str) - 2 ); ret = atof(hours); ret += atof(minutes)/60; if(strcmp(NS, "S") == 0) { return -ret; } return ret; } static void NMEA_GPRMC_Decoder(GPS_T *gps_data, String data) { //Get data unsigned char data_bytes[128]; unsigned long time; unsigned char hour, minute, second, date, month, year; char *message_field[13]; data.getBytes(data_bytes, 128); if(GetMessageFeilds(message_field, data_bytes, ',', 13) == 13) { if(strcmp(message_field[GPRMC_MID], "GPRMC") != 0) { return; } if( strcmp(message_field[GPRMC_STS],"A") == 0) { gps_data->State_gps = true; gps_data->SpeedGPS = atof(message_field[GPRMC_SOG]) * 1.852; gps_data->OrGPS = atof(message_field[GPRMC_COG]); gps_data->Lat = gps_convert_lat_to_float(message_field[GPRMC_LAT], message_field[GPRMC_LAT_NS]); gps_data->Lng = gps_convert_lon_to_float(message_field[GPRMC_LON], message_field[GPRMC_LON_EW]); } else if( strcmp(message_field[GPRMC_STS],"V") == 0) { gps_data->State_gps = false; gps_data->Lat = 0; gps_data->Lng = 0; gps_data->SpeedGPS = 0; } *(message_field[GPRMC_UTC] + 6) = '\0'; time = atof(message_field[GPRMC_UTC]); hour = (unsigned char)(time / 10000); minute = (unsigned char)((time % 10000) / 100); second = (unsigned char)(((time % 10000) % 100)); time = atof(message_field[GPRMC_DAT]); date = (unsigned char)(time / 10000); month = (unsigned char)((time % 10000) / 100); year = (unsigned char)(((time % 10000) % 100)); gps_data->time_gps.time.year = year; gps_data->time_gps.time.month = month; gps_data->time_gps.time.date = date; gps_data->time_gps.time.hour = hour; gps_data->time_gps.time.minute = minute; gps_data->time_gps.time.sec = second; } } |
Video