Multidimensional Box

In this page you will find the description of how to implement a GPS sensor with arduino and how to integrate both components in the multidimensional box.

If you need additional specific information about this topic or if you want to look it personally please write an email

A GPS module is nothing more than a sensor requiring 5V wich transmit a specific protocol called NMEA on serial port. This is the reason why when you buy a GPS sensor you will need, mainly, to connect 4 basic connectors:

- 5V
- Ground
- TX
- RX

Follwoing is a possible connection schema:
Implemented in the multidimensional box

MultiBox Multidimensional opened

The NMEA protocol and the GPS source code

If you want very quickly to start reading values from the serial port, here attached you will find a simple source able to read NMEA data from the serial port and output those string in the debug console
Note that the following source code uses the SoftwareSerial library to connect two pins of Arduino as Serial TX/RX port



    // GPS pin connection
    #define rxGPS 3
    #define txGPS 5
    SoftwareSerial serialGPS = SoftwareSerial(rxGPS, txGPS); 
    String stringGPS = "";
    
    void setup() {
        pinMode(rxGPS, INPUT);
        pinMode(txGPS, OUTPUT);
        Serial.begin(9600);
    
        // GPS Setup
        serialGPS.begin(4800);
        digitalWrite(txGPS,HIGH);  //init the device
    
        // Cut first gibberish
        while(serialGPS.available())
        if (serialGPS.read() == '\r')
            break;
    }
    
    void loop()
    {
        String s = checkGPS();
        if(s && s.substring(0, 6) == "$GPGGA")      //search for a valid NMEA string
        {
        Serial.println(s);
        }
    }
    
    // Check GPS and returns string if full line recorded, else false
    String checkGPS()
    {
        if (serialGPS.available())
        {
        char c = serialGPS.read();
        if (c != '\n' && c != '\r')
        {
            stringGPS  = c;
        }
        else
        {
            if (stringGPS != "")
            {
            String tmp = stringGPS;
            stringGPS = "";
            return tmp;
            }
        }
        }
        return false;
    }
                

          

This is a very basic code and the NMEA string is found in a very basic way but is very useful for you in order to understand how it works.
As basic definition, NMEA is a combined electrical and data specification for communication between marine electronics such as echo sounder, sonars, anemometer, gyrocompass, autopilot, GPS receivers and many other types of instruments.
in few words a sequence of string identifing different information about geo coordinates and other geo references parameters like velocity, wether, time and so on.
An example of strings coming from a generic GPS device can be:

$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,19,13,28,070,17,26,23,252,,04,14,186,14*79
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43
$GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45

Now, based on this description we can, clearly, say that reading the NMEA protocol is not a joke. It could be very difficult for us to understand needed information just parsing these strings. Fortunatelly thanks to the Arduino community is very easy to find something interesting. Internet makes available for us thousand of libraries useful for our scope. The most interesting one is TinyGPS.
It is a very useful library that you can use (for free). In order to have more detailed instructions, you can refere to the linked web site, However, in any case, you need simply to send to the Tiny object all strings received from the GPS device (byte after byte). The Tiny library will automatically inform you when a valid NMEA string has been received. Once received you can simply invoke its methods and functions to work with GPS values returned by the device.

Start including it and creating the object.

                #include "TinyGPS.h"
                
                //create the GPS object
                TinyGPS gps;
          

Now continuosly read data from the serial port connected to the GPS module and pass those bytes to the GPS object


                if (Serial1.available()) {
                    char c = Serial1.read();
                    Serial.print(c);  // uncomment to see raw GPS data
                    if (gps.encode(c)) {
                        newdata = true;
                    }
                }
                if (newdata == true){ ....
          

If the block received is valid you need to estabilish if it is a block with a valid fix (GPS signal) or not.


                // retrieves +/- lat/long in 100000ths of a degree
                gps.get_position(&lat, &lon, &fix_age);
    
                if (fix_age == TinyGPS::GPS_INVALID_AGE){
                    SignalPresence = false;
                    
                    Serial.println("Data in but no fix detected");
                }
                else if (fix_age > 5000){
                    SignalPresence = false;
                    
                    Serial.println("Warning: possible old data. Wait for new data!");
                }
                else {
                    Serial.println("Data is current."); ...
          

Once data is correct you can play with the TinyGPS functions and have fun.


                // time in hhmmsscc, date in ddmmyy
				gps.crack_datetime(&year, &month, &day, &hour, &minutes, &second, &hundredths, &fix_age);

				// returns speed in 100ths of a knot
				speed = gps.f_speed_kmph();

				// course in 100ths of a degree
				course = gps.course();

				alt = gps.f_altitude();

				//Delete the old string from the display
				DrawStatus(DISPLAY_GPS, stringGPS, BLACK);

				//write the new string
				Serial.print(F("Write string"));
				Serial.println(stringGPS);
          

Using this library you can now read data from a GPS device and use them for your needs. In case of the multidimentional box I simply used those information to display static data on the OLED module.
In the picture you can see on the right you will note that the data displayed in the oled Arduino module are exactly the static data retrieved from the GPS in the source code showed before.

The OLED Display

What I used to build the multidimensional Box is a small OLED display o,96 inch with a resolution of 128x64 pixel. The version used is black and white but is very useful because of its dimension 2.7 x 2.8 cm It uses the protocol SPI very interesting. Due to its dimention its is very useful to be used to build smartwatch but more in general to build weareble objects (so perfect for BLE and for lithium batteries) The driver used is the SSD1306 and the voltage needed vary from 3,6V to 6V. Also this object s very easy to drive and it requires only to connect two cables (excluding + and ground) The Serial Peripheral Interface bus (SPI) is a synchronous serial communication interface specification used for short distance communication, primarily in embedded systems. The interface was developed by Motorola in the late 1980s and has become a de facto standard. Typical applications include Secure Digital cards and liquid crystal displays. SPI devices communicate in full duplex mode using a master-slave architecture with a single master. The master device originates the frame for reading and writing. Multiple slave devices are supported through selection with individual slave select (SS) lines. Sometimes SPI is called a four-wire serial bus, contrasting with three-, two-, and one-wire serial buses. The SPI may be accurately described as a synchronous serial interface.
Following the connection schema used for this exercise:

OLED connection schema

GND -> GND
Vcc -> 3.3V
Vcc -> 3.3V
MOSI -> 11
CLK -> 12
DC -> 9
CS -> 8

As first step you need to download the Adafruit Library: 'Adafruit_SSD1306'. You can get the latest version from GitHub or from our Download Area.
Rename and install the libraries under the Arduino libraries folder (if you do not know how to do it, please, see my tutorial). In the following code you will see how to write some chars on your OLED using the library you have downloaded just now:


    #include   
    #include   
    #include   
    #include   
        
    //pin connected
        
    #define OLED_MOSI   11  
    #define OLED_CLK   12  
    #define OLED_DC    9  
    #define OLED_CS    8  
    #define OLED_RESET 10  
        
    Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);  
        
    //Check if the display is the right one 
    #if (SSD1306_LCDHEIGHT != 64)  
    #error("wrong display used");  
    #endif  
        
    void setup()   {  
        Serial.begin(9600);  
        
        // 3.3V volt 
        display.begin(SSD1306_SWITCHCAPVCC);  
        
        // delete the screen  
        display.clearDisplay();  
        
        // set WHITE as default  
        display.setTextColor(WHITE);  
        
        // set dimension 
        display.setTextSize(1);  
        
        // set the cursor 
        display.setCursor(32,32);  
        
        // print a message
        display.print("Salve mondo");  
        
        // display the string  
        display.display();  
    }  
            
As you can see in this easy example you can print text in any oled display with simple instructions thanks to the Adafruit Library. The same library can be used also to print graphic.
The following code, for example is used in my multidimensional box in order to display a a small circle, in the top right corner, to evidence the presence of a GPS signal.


                        display.drawCircle(display.width() - 6, 5, 5, WHITE);
                        display.drawCircle(display.width() - 6, 5, 4, BLACK);
                        display.drawCircle(display.width() - 6, 5, 3, WHITE);
                        display.drawCircle(display.width() - 6, 5, 2, WHITE);
                        display.drawCircle(display.width() - 6, 5, 1, WHITE);
            

Using all these functions, I built a set of functions able to write GPS positions, Accellerometer values and the sonic distance measured using a sensor.
It is time now to show you how I used the Curie IMU accellerometer and how I build the Sonic sensor interface.

Leave a Comment