Everyone gets excited when they have the opportunity to learn how to drive their first car and sometimes the process towards receiving that drivers license can become a very tedious and time consuming one, especially when it comes to logging all of those practice driving hours! Well, fear not because an easier solution to driver logging is here!
The GPS Drivers Log, using the Adafruit Feather M0 Adalogger, is a tool for learning drivers that uses a GPS antenna to track everywhere you drive, including your coordinates, time elapsed while driving, and speed at which you were driving at certain points in time. This data is collected every 2 seconds and stored in an SD card located on the Adalogger. Once you're done logging your driving hours, you simply return home, plug the Ethernet board (WIZ750SR) into your network, and begin the downloading process. The WIZ750SR takes care of the tedious process of setting client/server credentials.
To start the device up, you first need to plug the 3.7 V LiPo battery to the Adafruit Feather Wing Adalogger.
Once you see the main menu appear on the LCD screen,
press the A button and a new screen will appear that will ask if you are ready to start logging.
When you are ready, press the B button and the device will start searching for a satellite link to connect to and start logging data.
When the red LED starts blinking slowly, that's when you know you have achieved a connection with the satellite. Once you have a connection, the main menu will display the quality of the connection (a higher value means better quality), the speed you are traveling (in mph), and the time of the log.
Once you are done practicing your driving, press the A or B button to go back to the main menu. Then, when you come back home, or are at the MVA host (innovators dream), use the Ethernet cable to establish a connection with a client to the WIZ750SR and press C to begin the transfer of data from the SD. At the same time as it's transferring data, it's saving the data on the client.
Once all the data is downloaded, the LCD displays the main menu once again and you can reuse it for another drive!
Now let us get into more details on how the device works.
SD configureThe Adafruit Feather Wing Adalogger features an SD card device to log information. The SD card can be accessed thru the standard Arduino SD library.
The function calls SD.begin with the SS pin set to 4 for the Adalogger board. On success it returns true, and you are ready to write to the board.
const int chipSelect = 4;
//Initialize SD card
bool InitSD()
{
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
return false;
}
return true;
}
In
order to write to the SD card we need to open a file, the parameters are the filename and the open mode. In our case we are opening the file for writing. We check that the file opens without error. Then, we use println to append a data line in the file. Finally, in order to make sure the buffer is flushed to the card we close the file.
// open the file.
File dataFile = SD.open(LOGFILENAME, FILE_WRITE);
// if the file is available, write to it:
if (dataFile)
{
//Add the data to the string buffer
dataString += "Time: ";
dataString += String(GPS.hour);
...
dataFile.println(dataString);
dataFile.close();
}
A
very nice introduction to the Adalogger can be found at the Adafruit web page here.
The Global Position System (GPS) uses a family of satellites to calculate the current position of the device by using the time of transmission, the strength of the transmission received, and the satellite location of a sequential pulse signal the family of satellites transmits. The device then calculates its 3D position with this data. We know it is actually way more complicated but I think this can suffice as a curiosity teaser. You can find out more at www.gps.gov.
OK. Now, we use the Adafruit ultimate GPS featherwing device to collect the GPS data. The featherwing is a family of expansion boards designed for the Feather family of boards. First, install the Arduino library through the library manager, search for the Adafruit GPS library, and select install.
Let us point out that the data communicated by the GPS system is a comma separated vector which set of values represents the date, time, latitude, longitude, speed, angle, altitude, etc. The vector can be parse by the library in order to get individual pieces of data from it.
The GPS library contains an Adafruit_GPS class that takes care of the board settings. Create an instance of the class in order to use the functions. The constructor takes the serial port the board is connected to as a parameter. In our case, this is Serial1.
// Serial port for the GPS module
#define GPSSerial Serial1
// Connect to the GPS on the hardware port
Adafruit_GPS GPS(&GPSSerial);
On the setup function we initialize the GPS extension board by GPS.begin with the serial speed (9600). The board communicates through the UART port of the Feather Adalogger. This will bring a serial communication challenge; we will address this on the next step.
The next commands sets the board to get the minimum recommended data on a fix link, the refreshing update rate and use of an external antenna.
void setup {
...
// 9600 NMEA is the default baud rate for Adafruit MTK GPS's
GPS.begin(9600);
// Turn on RMC (recommended minimum) and GGA (fix data) including altitude
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
GPS.sendCommand(PGCMD_ANTENNA);
...
}
Every cycle on the main loop we check the GPS buffer for new data. If there is a full GPS data record by checking the GPS.newNMEAreceived() function, then we parse the record in order for the GPS object to:
void ProcessGPS()
{
// read data from the GPS
char c = GPS.read();
// Sentence is received?
if (GPS.newNMEAreceived())
{
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // if sentence is not complete.
}
...
}
A software timer will process every two seconds new GPS data and save it to the SD card.
// check the timer, if over the threshold --> reset.
if (timer > millis()) timer = millis();
// every 2 seconds or so, print out the current stats
if (millis() - timer > 2000)
{
timer = millis(); // reset the timer
Add all the require data on string and save it to a logger file in the SD card (as shown in the previous section). The below code is just a small set of the data string.
dataString += " Altitude: ";
dataString += String(GPS.altitude);
dataString += String(", ");
dataString += " Satellites: ";
dataString += String((int)GPS.satellites);
Part of these codes have being taken from the GPS samples and the Adafruit tutorial for the GPS featherwing here.
UART Challenge AcceptedThe GPS FeatherWing board uses the Serial1 to communicate, we need another UART to communicate with the WIZ750SR device. The Adafruit Feather M0 Adalogger has one active serial port only, and we need to configure the board to activate another serial port.
Thanks to Lady Ada and her brilliant article, "Using ATSAMD21 SERCOM for more SPI, I2C and Serial ports", we were able to create Serial2 by changing the pin mode to the corresponding serial use. Following the instructions on the before mentioned article we got:
#include <Arduino.h> // required before wiring_private.h
#include "wiring_private.h" // require to activate second UART
Uart Serial2 (&sercom1, 11, 10, SERCOM_RX_PAD_0, UART_TX_PAD_2);
void SERCOM1_Handler()
{
Serial2.IrqHandler();
}
This
code activates pins 11 and 10 to be use as RX and TX pins, with SERCOM1 handling the timing.
Now we just need to activate the pins as peripheral and linked them to the correct mode.
void setup
{
//Initialize second UART matching the settings for the WIZ750SR
Serial2.begin(115200);
// Assign pins 10 & 11 SERCOM functionality
pinPeripheral(10, PIO_SERCOM);
pinPeripheral(11, PIO_SERCOM);
}
Alright, challenge complete. We were able to activate a new serial port to communicate with the WIZ7500SR.
Server-Client ConfigureThe WIZ7500SR configuration was a breeze once we figured out how powerful and out-of-the-box of a device it really is. At first glance we thought we needed to program the bootloader from scratch and program the chip, but once we figured out the default program takes care of all of that, and we only needed to set the operation mode and local ip address. The setting was really easy.
Here we have the settings we use. The operation mode is set to TCP servers, which means that once connected if there is a client on your same network, it will establish a communication link with it. Our server uses static IP set to 192.168.1.75 with open port 5000. Notice we also have TCP Keep-Alive enabled in order to avoid short outages of communication as possible.
Now to setup the client machine.
We are using a mini PC MSi Intel Celeron N3160 to run our Python client program. The machine is running Ubuntu 16.04 and we are using Python 2.7.
On our client code we need to create a network socket binding to our server address (192.168.1.75) with listening port (5000).
host = "192.168.1.75"
port = 5000
#initialize a socket
client_socket = socket.socket()
#Request a communication link with the server
client_socket.connect((host, port))
We send to the server a passcode to verify our identity.
#Passcode
message = "gpsData"
...
#Send passcode
client_socket.send(message.encode())
The
server at the Adafruit Adalogger board then verifies the passcode sent.
bool Connect2Client()
{
//return true;
if (Serial2.available())
{
String dataRead="";
while (Serial2.available())
{
char inByte = Serial2.read();
if (inByte != '\n' && inByte != '\r')
dataRead += inByte;
Serial.write(inByte);
delay(50);
}
Serial.print(String(dataRead.length()));
Serial.print(String(PASSCODE).length());
Serial.println(dataRead);
//Check for passcode. If correct return communicaton stablished.
if (dataRead.compareTo(String(PASSCODE)) == 0)
return true;
}
If they match the server starts streaming the GPS data.
bool SendFile()
{
File dataFile = SD.open(LOGFILENAME);
if (dataFile) {
while (dataFile.available()) {
//Send data thru UART 2 port
Serial2.write(dataFile.read());
}
dataFile.close();
Serial2.write("Bye");
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
return false;
}
return true;
}
Once the server finishes it sends the "Bye" code to indicate all data has being transmitted.
On the client side, data is received and securely saved on a Master GPS log file.
#Read data from server
data = client_socket.recv(1024).decode()
#Print debug information or data received.
print('Received from server: '+data)
#if file has not being initialize then open file.
if (initFile == False):
outFile = open(outfilename,'w')
initFile = True
#Write to file data raceived.
outFile.write(data)
UI DesignWe know user interface is not the most exciting thing to talk when you have so many devices working, but we thought it would be interesting to know how to interface with the FeatherWing OLED buttons.
First we declare two global variables that will hold the current menu selection (CurrMenSel) and a variable that will track any selection made by the buttons.
//Menu related variables.
int MenuSel = 0;
int CurrMenuSel = 0;
The main loop will run through the current selected menu options and check if any of the active buttons have being pressed. If a valid button was pressed the MenuSel variable changes to the next menu to be display (forward or backward) and/or task to be executed.
//Menu Selection.
if (CurrMenuSel == 0)
{
if (! digitalRead(BUTTON_A))
{
MenuSel = 1;
}
if (! digitalRead(BUTTON_C))
{
varConnected = false;
MenuSel = 3;
}
}
...
The program then checks to see if a menu selection has been press and executes the corresponding task, refreshing the current selected menu variable to the choice selected.
//Main task execute
if (CurrMenuSel != MenuSel)
{
if (MenuSel == 0)
{
DisplayMainMenu();
}
else if (MenuSel == 1)
{
DisplayConfirm();
}
else if (MenuSel == 2)
{
DisplayGPSLog();
}
else if (MenuSel == 3)
{
DisplayWizNet();
}
else if (MenuSel == 4)
{
DisplayDownloading();
}
//Try to clear the buffer from the buttons
CurrMenuSel = MenuSel;
}
Data Collection and BustedHere is a short sample of practice drive to the mall. Sorry, the coordinates have been mask in order to protect the innocent.
Notice that the time is being represented in GMT (Greenwich Mean Time) and it would require a conversion to the required timezone. Also, the speed is reported in knots, a conversion to mph was applied and is shown next to the knot speed.
Time 9 24 20 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 26.46794 23 Angle 296.02 Altitude 185.6 Satellites 5
Time 9 24 22 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 27.9409384 24.28 Angle 298.58 Altitude 185.4 Satellites 5
Time 9 24 24 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 28.884578 25.1 Angle 297.49 Altitude 185.5 Satellites 5
Time 9 24 26 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 27.9524462 24.29 Angle 297.74 Altitude 185.6 Satellites 5
Time 9 24 28 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 27.9409384 24.28 Angle 297.33 Altitude 185.6 Satellites 5
Time 9 24 30 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 25.6163628 22.26 Angle 297.32 Altitude 185.5 Satellites 5
Time 9 24 32 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 20.2997592 17.64 Angle 302.46 Altitude 185.5 Satellites 6
Time 9 24 34 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 13.1419076 11.42 Angle 300.65 Altitude 185.9 Satellites 6
Time 9 24 36 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 7.1233282 6.19 Angle 297.41 Altitude 186 Satellites 6
Time 9 24 38 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 0.2071404 0.18 Angle 293.72 Altitude 186.6 Satellites 6
Time 9 24 40 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 6.0070716 5.22 Angle 258.72 Altitude 187 Satellites 6
Time 9 24 42 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 12.485963 10.85 Angle 216.62 Altitude 186.9 Satellites 5
Time 9 24 44 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 20.7945946 18.07 Angle 204.79 Altitude 186.2 Satellites 6
Time 9 24 46 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 28.596883 24.85 Angle 200.5 Altitude 186.2 Satellites 6
Time 9 24 48 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 32.9468314 28.63 Angle 199.95 Altitude 186.3 Satellites 6
Time 9 24 50 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 35.444024 30.8 Angle 201.42 Altitude 186 Satellites 7
Time 9 24 52 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 36.2725856 31.52 Angle 201.19 Altitude 186 Satellites 7
Time 9 24 54 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 37.1932096 32.32 Angle 202.25 Altitude 186.3 Satellites 7
Time 9 24 56 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 37.3773344 32.48 Angle 202.4 Altitude 187 Satellites 7
Time 9 24 58 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 36.2150466 31.47 Angle 202.03 Altitude 188.6 Satellites 7
Time 9 25 0 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 34.7420482 30.19 Angle 202.61 Altitude 189.8 Satellites 7
Time 9 25 2 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 32.336918 28.1 Angle 202.48 Altitude 190.8 Satellites 7
Time 9 25 4 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 30.6797948 26.66 Angle 202.63 Altitude 191.6 Satellites 7
Time 9 25 6 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 29.9432956 26.02 Angle 201.31 Altitude 191.9 Satellites 7
Time 9 25 8 Date 28-6-2018 Fix 1 quality 1Location XXXXXN YYYYYW Speed (knots) 30.2309906 26.27 Angle 202.91 Altitude 192 Satellites 7
Finally, here is a graph of another practice drive in highway, notice in the samples how close to the speed limit. And busted.
We can see this device being extremely useful to the MVA for any and all learning drivers who are in the process of logging their required driving hours. By using this tool, learning drivers will not have to worry about carrying around or losing their small drivers log booklets. The MVA will be able to easily analyze the data and the data will also be more reliable because the device records the driving hours at the moment they are completed.
Thank you for reading thru the project. If you would like to know more about our activities, please visit our web page www.vistelilabs.com. We hope to meet you at the 2018 World Maker Faire, we will be there showcasing.
Comments