$USD
  • EUR€
  • £GBP
  • $USD
TUTORIALS Arduino

Using Processing to read GPS data and displaying a map

DFRobot Dec 24 2012 1078

Recently, I have studied something related to Processing and used it to communicate with my Arduino board and GPS shield. Although I didn't get a perfect result, the experience I obtained may do a little help for you. Firstly, I used the GPS Shield and a GPS antenna to read the latitude and longitude of my local position. Then I transmitted the GPS data from Arduino to Processing via serial communication. After reading the GPS data, Processing can call for a static Google map and display it as an image. I also set a slider to zoom or narrow the loaded map so that I can check the map at different zoom levels. Following , I will explain how implement these functions. Processing is an open source programming language and environment for people who want to create images, animations, and interactions. Initially developed to serve as a software sketchbook and to teach fundamentals of computer programming within a visual context, Processing also has evolved into a tool for generating finished professional work. Today, there are tens of thousands of students, artists, designers, researchers, and hobbyists who use Processing for learning, prototyping, and production. I had tried to use Processing combined with JavaScript language to display a dynamic Google Map after reading the latitude and longitude from the GPS shield, but I failed to realize this function. Because JavaScript language can't make the web page to read the information or data transmitted between Arduino and our computer.
 

How to display a static Google Map by using Processing

A.Static Maps API V2 Developer Guide B.Two ways to display Static Google Map 1.Google Mapper Library

Google Mapper is a lightweight library that enables you to download images of any size from Google Maps.It is not very hard to use . Before using it please add the googleMapper library into Processing’s library first.

  • getMap() - Extracts a map from GoogleMaps.
  • lat2y - Converts latitude to y (for the map that was extracted).
  • lon2x - Converts longitude to x (for the map that was extracted).
  • y2lat - Converts y coordinate (on the map that was extracted) to latitude.
  • x2lon - Converts x coordinate (on the map that was extracted) to longitude.

Source Code1:Display_Static_Map_Method1

import googlemapper.*; PImage map; GoogleMapper gMapper; public void setup() { size(1280,480); double maCenterLat =31.219293128780347; double mapCenterLon =121.55058860778809; int zoomLevel =15; String mapType = GoogleMapper.MAPTYPE_HYBRID; int mapWidth=1280; int mapHeight=480; gMapper = new GoogleMapper(maCenterLat, mapCenterLon, zoomLevel, mapType, mapWidth,mapHeight); map = gMapper.getMap(); } public void draw() { image(map,0,0); saveFrame("map.jpg"); //println(gMapper.y2lat(240));//outputs 40.7782667 // println(gMapper.x2lon(320));//outputs -73.9698797 // println(gMapper.lat2y(31.219293128780347)); //outputs 240.0 // println(gMapper.lon2x(121.55058860778809));//outputs 320.0 }2.Using Google Static Map API You should apply for an API key

 

Source Code2:Display_Static_Map_Method2

PImage google_maps; float bx; float by; int imagewidth=800; int imageheight=400; void setup() { size(1000, 400); bx = width/2.0; by = height/2.0; google_maps = loadImage ("http://maps.googleapis.com/maps/api/staticmap?center=" + "38.880371,121.529036"+ "&size=800x400&zoom=20&sensor=false", // url "png"); // format // image(google_maps, 0, 0); imageMode(CENTER); } void draw(){ image(google_maps, bx, by); }

Arduino Part:

Attention: 1.Please place your GPS antenna outdoor and wait for a few minutes when you first run the GPS shield. 2.I do not call for the latitude_direction function and longitude_direction function in loop().You may call for these two functions when necessary.

Source Code3: sketch_Arduino_Part_GPS

#if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #define WireSend(args) Wire.write(args) #define WireRead(args) Wire.read(args) #define printByte(args) Serial.write(args) #define printlnByte(args)  Serial.write(args),Serial.println() #else #include "WProgram.h" #define WireSend(args) Wire.send(args) #define WireRead(args) Wire.receive(args) #define printByte(args) Serial.print(args,BYTE) #define printlnByte(args)  Serial.println(args,BYTE) #endif #include#define BUFFER_LENGTH 10//Define the buffer length int GPSAddress = 0x42;//GPS I2C Address double Datatransfer(char *data_buf,char num)//Data type converter?convert char type to float {                                           //*data_buf:char data array ;num:float length  double temp=0.0;  unsigned char i,j;  if(data_buf[0]=='-')  //If the data is negative  {    i=1;    //change the character data in the array into integers and add them up    while(data_buf[i]!='.')      temp=temp*10+(data_buf[i++]-0x30);    for(j=0;j;j++) temp=temp*10+(data_buf[++i]-0x30); //transfer the integers into floats for(j=0;j<num;j++) temp=temp/10; temp=0-temp; } else //If the data is positive { i=0; while(data_buf[i]!='.') temp=temp*10+(data_buf[i++]-0x30); for(j=0;j<num;j++) temp=temp*10+(data_buf[++i]-0x30); for(j=0;j<num;j++) temp=temp/10 ; } return temp; } void rec_init()//initial GPS { Wire.beginTransmission(GPSAddress); WireSend(0xff); //the address where to send the data Wire.endTransmission(); Wire.beginTransmission(GPSAddress); Wire.requestFrom(GPSAddress,10); //read 10 bytes from the GPS shield } char ID() //the ID is used for receiving GPS statements { char i = 0; char value[7]={ '$','G','P','G','G','A',',' }; //contents of the GPS statements char buff[7]={ '0','0','0','0','0','0','0' }; while(1) { rec_init(); //Initialization for receiving data while(Wire.available()) { buff[i] = WireRead(); //receive serial data if(buff[i]==value[i]) //compare and determin whether it is the correct ID { i++; if(i==7) { Wire.endTransmission(); return 1; } } else i=0; } Wire.endTransmission(); //Finish receiving } } void rec_data(char *buff,char num1,char num2) //the subfunction for receiving data { //*buff?array for storing data?num1?the number of commas?num2?the length of the array char i=0,count=0; if(ID()) { while(1) { rec_init(); while(Wire.available()) { buff[i] = WireRead(); if(count!=num1) { if(buff[i]==',') count++; } else { i++; if(i==num2) { Wire.endTransmission(); return; } } } Wire.endTransmission(); } } } void latitude() //Obtain the Latitude { char lat[10]={ '0','0','0','0','0','0','0','0','0','0' }; rec_data(lat,1 ,10); Serial.println(Datatransfer(lat,5),5); //turn the Latitude into float and print it out } void lat_dir() //Obtain the Latitude direction { char dir[1]={'0'}; rec_data(dir,2,1); //printlnByte(dir[0]); } void longitude() //Obtain the Longitude { char lon[11]={ '0','0','0','0','0','0','0','0','0','0','0' }; rec_data(lon,3,11); Serial.println(Datatransfer(lon,5),5); //turn the Longitude into float and print it out Serial.print("*"); } void lon_dir() //Obtain the Longitude direction { char dir[1]={'0'}; rec_data(dir,4,1); //printlnByte(dir[0]); } void setup() { Wire.begin(); //IIC Initialization Serial.begin(9600); //Set the baud rate } void loop() { while(1) { latitude(); //call for the latitude function longitude(); //call for the longitude function delay(5000); delay(5000); } }

  • Main functions used in the program:
  • latitude() //Obtain the Latitude
  • lat_dir() //Obtain the Latitude direction
  • longitude() //Obtain the Longitude
  • lon_dir() //Obtain the Longitude direction
  • Serial.println()
  • Serial.print() //Send data to Processing via serial communication

Firstly you should run the Arduino Part then run the Processing part.You can check the serial monitor of the Arduino software to see what the information or data is sending from Arduino to Processing.

Processing Part:

Source Code4: sketch_Processing_Part_GPS

Zoom level=9import controlP5.*; import googlemapper.*; import processing.serial.*; ControlP5 cp5; int zoomSlider=7; Slider abc; PImage map; GoogleMapper gMapper; float mapCenterLat=30.22; float mapCenterLon=100.22; int zoomLevel =15; String mapType = GoogleMapper.MAPTYPE_HYBRID; int mapWidth=1280; int mapHeight=480; float lat, lon; Serial port; // The serial port object void setup() { size(1280, 480); noStroke(); cp5 = new ControlP5(this); // add a horizontal sliders, the value of this slider will be linked // to variable 'sliderValue' cp5.addSlider("zoomSlider") .setPosition(50, 100) .setSize(40,200) .setRange(3, 21) .setNumberOfTickMarks(7) ; port = new Serial(this, Serial.list()[0], 9600); // Request values right off the bat port.write(65); } long interval = millis(); void draw() { try{ if (millis() - interval > 5000) { interval = millis(); gMapper = new GoogleMapper(mapCenterLat, mapCenterLon, zoomLevel, mapType, mapWidth, mapHeight); map = gMapper.getMap(); image(map, 0, 0); // saveFrame("map.jpg"); //zoomLevel=sliderValue; } zoomLevel=zoomSlider; } catch(Exception e){ e.printStackTrace();} } // Called whenever there is something available to read void serialEvent(Serial port) { // Data from the Serial port is read in serialEvent() // using the readStringUntil() function with * as the end character. String input = port.readStringUntil('*'); if (input != null) { // The data is split into an array of Strings with a comma or asterisk as a delimiter // and converted into an array of integers. //int[] vals = int(splitTokens(input, " *")); float[] vals = float(splitTokens(input, " *")); // Print message received println( "Receiving:" + input); lat =vals[0]/100; lon =vals[1]/100; mapCenterLat=lat; mapCenterLon=lon; } }Libraries used in Processing(download from here Document-->processing library) <1> Import Library-->serial <2> Import Library-->googlemapper <3> Import Library-->ControlP5-->Used to set a slider to zoom the map Important functions used in the program: (1) serialEvent(Serial port) It is called when data is available. The serialEvent() can be set with bufferUntil() to only trigger after a specific character is read. (2) readStringUntil(read data until a special character appears) (3) splitTokens(value, delim) The splitTokens() function splits a String at one or many character delimiters or "tokens." The delim parameter specifies the character or characters to be used as a boundary.

 

Hardware list

 

Related links

  • http://www.processing.org/
  • http://www.processing.org/learning/
  • http://processing.org/reference/libraries/
  • http://www.processing.org/reference/
  • http://www.learningprocessing.com/
  • http://wiki.processing.org/w/How_to_Install_a_Contributed_Library
  • http://processing.org/reference/libraries/serial/
  • http://arduino.cc/en/Reference/Serial
  • http://learning.codasign.com/index.php?title=Beginning_Processing_and_Arduino
  • http://www.learningprocessing.com/examples/chapter-19/example-19-10/
  • http://www.dfrobot.com/wiki/index.php?title=DFRduino_GPS_Shield-LEA-5H_(SKU:TEL0044)
REVIEW