## Quick look at the NanoVNA

For a while now there is a very inexpensive Vector Network Analyzer (VNA) called NanoVNA available from various sources. At a price point of less than 50 USD it is very affordable for hobbyists. But is it any good?

The Nano VNA covers the frequency range from 50 kHz – 900 MHz, has a small inbuilt TFT touchscreen display and is battery operated. A USB port allows to connect a computer for an enhanced measurement experience using free VNA software of the web.

This is not an in-depth review, actually quite the opposite. I just wanted to share some first-glance pictures. I used a homebrew VHF preamplifier for my initial experiments with the NanoVNA. The first picture shows the (admittedly small) display displaying the frequency response of the VHF preamplifier:

The VHF preamplifer was built quick and dirty, centered around a MiniCircuits filter and MMIC. I included a bias-T in the circuit to be able to power the preamplifier through the coax cable of a soon to be receiver antenna. Here’s a picture:

The small size of the display is pretty annoying. Luckily, there’s a free software available online. As you can see by the screenshot below, it offers fantastic measurement and display options:

For a real review I will have to experiment more with the NanoVNA. But I must say that that first impression, especially considering the price-point makes it a quite interesting tool for the hobbyist.

## Arduino |Automatically Save Variables to EEPROM on Power-Down

A recurring challenge for Arduino projects is that variables are volatile and will be lost completely unless previously stored to some sort of non-volatile storage such as de inbuilt EEPROM. This article shows a minimalistic approach to detect sudden loss of power and automatically store a variable to an EEPROM adress.

First I should mention that this approach of course also works for other type of storage devices, such an external SD-Card. The simple solution I used in this 12V application is a 2-stage voltage regulator set-up and a power-sense input tied to an interrupt. The first stage gets the input voltage down to 9V. A voltage devider on the 9V rail supplies a steady high signal to PIN 3 of the Arduino Nano as long as a power source is connected to the circuit. As soon as this sense-input falls low, an Interrupt Service Routine (ISR) is triggered that stores the variable to a pre-defined adress of the EEPROM. The second stage consists out of two 7805 type voltage regulators. One for the Arduino Nano and one for all periphial devices such as the LC-Display. The Arduinos 5 Volt supply voltage is tied to a 1F supercapacitor. This guarantees that the Arduino has enough power available to safely detect the missing supply voltage on the 9V rail and store the example variable to the EEPROM.

The whole Setup looks something like this:

Crude test setup with 1F supercapacitor

 #include <EEPROM.h> // Some Variable int SomeVariable; // Pin to be used as power-down sense int PWR_DWN_PIN = 3; // The EEPROM address to be used int EE_ADDR = 10; void setup() {  // Retrieve last stored value of SomeVariable from EEPROM  EEPROM.get(EE_ADDR, SomeVariable);  // Set-up Interrupt Service Routine  attachInterrupt(digitalPinToInterrupt(PWR_DWN_PIN), PWR_DWN_ISR,FALLING); } void loop() {  // Do something cool  } // This Interrupt Service Routine will get called on power-down void PWR_DWN_ISR () {    // Push SomeVariable to the EEPROM    EEPROM.put(EE_ADDR, SomeVariable);     } 

This Setup works very well. How long the supercapacitor can power the Arduino and whether or not you even need a separate supply rail for periphials depends on the current demand of your circuit. So heres some math.

The charge of a capacitor is defined as follows:

$Q = It$

Q = charge of capacitor in Coulomb
I = Current in Amps
t = time in Seconds

So if we re-arrange the equation we could wrongly assume that if we divide Q by the current demand of our device, we will get the expected runtime in seconds. But we need to take into consideration that the Arduino does not work all the way down to 0 Volts. We need to define a lower voltage limit and divide the change of charge by the current draw of your device. But how do we get Q to begin with? The charge of a capacitor Q can also be expressed by the following Formula:

$Q = CV$

V = Voltage in Volts

So we can combine the two formulas in a way that we can calculate the time (t) if we know the capacitance of the supercapacitor, the expected current draw of the device and the maximum permissible change in voltage.

$t = \frac{\Delta VC}{I}$

So for my example I am allowing the 5 Volts to drop to 4 Volts, I am assuming 100 mA max. current and the supercap has a capacity of exactly 1F.

$t = \frac{(5V - 4V) 1}{0.1A} = 10 s$

10 seconds should be plenty of time to store a variable (or a few more) to the EEPROM. This approach works very well so far. A possible improvement, if needed, migth be to implement a change interrupt trigger instead of a falling edge trigger and re-initialize periphials on power-up if needed (e.g. LCD). This becomes necessary if power is reconnected during a time where the Arduino is still running but periphials where already shut-down. In that case they need a clean initialization before they will function properly.

## Diamex Prog-S2 | Arduino IDE

The Diamex Prog-S2 is an universal USB ISP programmer vor various microcontrollers including Atmel AVRs. This article shows how to integrate the programmer into the Arduino IDE

There are a few articles on the web that talk about the Diamex Prog-S2 and Arduino. But it seemed to me like they were either outdated or faulty.

To get the Arduino IDE to talk to the Arduino IDE, simply add the following lines to the programmers.txt file in the Arduino IDE program folder:

diamexavr.name=DIAMEX-AVR diamexavr.communication=serial diamexavr.protocol=stk500v2 diamexavr.program.tool=avrdude diamexavr.program.extra_params=-P{serial.port} -F

After restarting the Arduino IDE, the Prog-S2 should appear in the programmers list as “DIAMEX-AVR”.

The Diamex Prog-S2 appears in the programmer list after updating the programmers file.

Please don’t forget that you still need to select the proper COM-Port in order to use the Prog-S2 properly. Most importantly, you will have to use the “Upload using programmer” option to upload a Sketch to an Atmel AVR / Arduino chip using the Diamex Prog-S2.

## Automated Forward Gain Measurement

For a long time now I had a bunch of Mini Circuits portable test equipment bits and pieces sitting around. S signal generator, a switch matrix and power sensors. These devices aren’t made for manual operation as they feature no direct way of manipulating the instrument’s state without software. They’re made for automation. And as such i thought an automation example would be in order. Like in the last article, we’re going to have a look at a practical example again. So here are the parameters:

For my passive secondary surveillance receiver at 1090 MHz I am using a Mini Circuits VBFZ-1065 filter [1] and a ZKL-2 amplifier [2]. The filter’s datasheet lists a passband of 980 – 1150 MHz and a 20 dB bandwidth of 630 – 1800 MHz. But let’s see if we can verify the data using an automated test setup.

Measuring the forward gain is quite simple. Simply apply a signal of known amplitude and known frequency to the device under test, measure the output power and compare. Let’s say we apply a 1090 MHz signal with an amplitude of -30 dBm to an amplifier and measure 0 dBm out, we know the forward gain at this exact frequency is 30 dB. So a minimalistic automated setup could consist of just the signal generator as source and the power meter as sink. But we want more than that. Clearly both the generator and the power sensor have certain nonlinearities when it comes to sourcing and measuring a specific amplitude accurately. But these nonlinearities are deterministic and close to constant. Therefore, we can measure the nonlinearities and apply correction factors to our final measurement.

Test setup on the bench

To facilitate this calibration mode, I included the switch matrix. The matrix can switch the source and power sensor directly into each other via a straight through cable jumper or it can switch both to the device under test ports. The following closeup may help understand what I am talking about:

Closeup of the test setup

All we need now is MATLAB code. The code’s job in plain english is as follows: Switch the matrix to straight through connection, sweep the system, normalize to intended power level, store normalized values as calibration factors, display cal factors, switch to device under test, sweep system, normalize to calibration values, display sweep results relative to desired output power.

Now in MATLAB speak:

 % Connect to PWR Sensor pm1 = NET.addAssembly('C:\Users\Sebastian\Desktop\MC\mcl_pm64.dll') obja=mcl_pm64.usb_pm obja.Open_AnySensor

 % Connect to Switch switch1 = NET.addAssembly('C:\Users\Sebastian\Desktop\MC\mcl_RF_Switch_Controller64.dll') objc = mcl_RF_Switch_Controller64.USB_RF_SwitchBox objc.Connect % Connect to Sig Gen gen1 = NET.addAssembly('C:\Users\Sebastian\Desktop\MC\mcl_gen64.dll') objb = mcl_gen64.usb_gen objb.Connect % Switch to Cal Bridge % 0 = Straight Through, 3 = Through DUT % objc.Set_SwitchesPort(0) %% Sweep System % Drive Level in dBm Power = -30 % Start Frequency in MHz Fstart = 700 %Step Size in MHz StepSize = 2.5 %Step Count Steps = 400 %% Acquire Calibration Values % Switch to Through Connection objc.Set_SwitchesPort(0) % Enable RF objb.SetPowerON % Sweep for C = 1:Steps % Calculate Frequency F = Fstart + (StepSize*(C-1)); % Set Frequency and Power objb.SetFreqAndPower(F,Power,0) % Allow some settling time pause(0.25); % Read Power PWR=obja.ReadPower PWR=round(10*PWR)/10 % Write result into Array A(:,C) = PWR end objb.SetPowerOFF % Normalize for Count=1:length(A) A(:,Count)=A(:,Count)-Power; end CalValues = A power = A % Make Frequency Scale freq = linspace(Fstart,F,length(A)) % Plot figure; plot(freq,power) %% Acquire Real Values % Switch to Through Connection objc.Set_SwitchesPort(3) % Enable RF objb.SetPowerON % Sweep for C = 1:Steps % Calculate Frequency F = Fstart + (StepSize*(C-1)); % Set Frequency and Power objb.SetFreqAndPower(F,Power,0) % Allow some settling time pause(0.25); % Read Power PWR=obja.ReadPower PWR=round(10*PWR)/10 % Write result into Array Real(:,C) = PWR end objb.SetPowerOFF % Normalize for Count=1:length(Real) Real(:,Count)=Real(:,Count)-CalValues(:,Count)-Power; end power = Real % Make Frequency Scale freq = linspace(Fstart,F,length(Real)) % Plot figure(2); plot(freq,power) %% END 

% Disconenct all Devices obja.Disconnect objb.Disconnect objc.Disconnect 

The code was assembled using the various programming examples Mini Circuits offers for download on their website [3]. The overall process to interact with this type of portable test gear is to call a Dynamic Link Library (DLL) and call predefined functions from inside the DLL. The DLLs can be downloaded from the previous link location also.

The result for my setup with the VBFZ-1065+ and the ZKL-2 looks something like this:

Forward Gain Measurement

And the forward gain only looks as follows:

Forward gain of the filter and amplifier combo

[1] VBFZ-1065+, Mini Circuits: https://www.minicircuits.com/pdfs/VBFZ-1065+.pdf

[2] ZKL-2, Mini Circuits: http://www.minicircuits.com/pdfs/ZKL-2.pdf

## Thermal Design Basics | Practical Example

One of my portable police scanners has an external 6V jack. To use it in my car I used my standard linear voltage regulator board and a high quality ST L7806 voltage regulator to get the ~13.8V of the car down to 6V. Maximum observed current of the scanner was 0.25A. So the thermal design question of the day is: How hot will the linear regulator get and do I need a heatsink?

Universal Linear Regulator Board

So lets start with the obvious first question: How hot is too hot? The answer is of course to be found in the datasheet. The datasheet states an absolute maximum of 150 °C. Note that this is the maximum rating though. While you can safely run the device at 150 °C, you probably don’t want to. Remember that 100 °C is the boiling point of water. So 150 °C is pretty darn hot. But it’s within the parameters given to us.

ST L7800 Datasheet

So how do we calculate how hot the device gets? The key to that question is the dissipated power and a figure called the thermal resistance junction-ambient, symbolized as theta-ja (θja). It is also shown in the previous datasheet snapshot. This figure basically says how many degrees the device’s junction temperature rises ABOVE ambient temperature for a given amount of dissipated power. Ambient temperature, or “room temperature” is often assumed to be at 25 °C. And that’s what we’re gonna work with but when you do the math, please be practical. If you can reasonably expect the temperature to rise above 25 °C, then do the math accordingly.

So our formula for junction temperature is this:

Tjunction = Tambient + (θja * power)

Alright, let’s piece together what we have. Let’s start with the dissipated power. We put in 13.8 V at 0.25 A and get out 6V. That makes 1.95 Watts ([13.8V – 6V] * 0.25A) of power to turn into heat. To calculate the expected junction temperature we simply plug all the values into the formula and solve.

25 + (50 * 1.95) = 122.5 °C

That means we can expect the junction temperature of the device to reach 122.5 °C. This is within the given maximum ratings and thus the answer to the heatsink question is no, we do not need a heatsink.

But not the reality check, think along with me. Again remember that 100 °C is the boiling point of water. Do we really want a device 22.5 °C above that sitting around somewhere? And also we assumed ambient to be at 25 °C. Car ambient temperatures frequently rise well above that, especially when exposed to sunlight. On top of that, car voltages aren’t even close to stable and can exceed 14 volts easily. So the practical answer would be that we would elect to use a heatsink. And that’s exactly what I did.

How to size heatsinks is a more complicated story and will be part of a different article.

[1] L7800 Series Datasheet, ST: https://jaunty-electronics.com/blog/wp-content/uploads/2016/01/L7800.pdf

## AT&T go Phone Service for GSM Modules

When playing with GSM/GPRS modules for Arduino and other platforms, one is faced with the selection of a cell phone carrier that supports such devices. This article is going to show how to use AT&T’s go phone service for GSM modules.

For my SIM900 powered GPRS Shield V2.0 from seed [1] I needed to find a suitable cell phone provider. This proved to be more complex than I thought. I should point out that I am located in the USA. Cellular networks are different all over the world and what I write in this article may not be true for other countries.

For starters, it’s important to understand that some cellular providers do not support GSM at all. Verizon for instance is CDMA only. I learned this the hard way after purchasing a prepaid SIM card for Verizon. AT&T ended up being my go-to provider for my little gadgets. Their go phone SIM cards always did the trick for me. You can buy these online. My local At&T store actually kindly provided me with a hand full of inactive SIM cards free of charge. Those cards are useless until activated.

AT&T go SIM card

To activate a AT&T go SIM card, go visit the AT&T activation page.

To activate your At&T go SIM card simply enter the SIM card number and follow the prompts. One catch is that you need to have the IMEI number of your device. SIM800 or SIM900 powered modules have the IMEI printed directly on the GSM module. However, AT&T determines what plans they offer you based on the IMEI number. If you enter the actual IMEI of the GSM module, odds are you’re only going to get monthly data and text plans. Currently the cheapest is $45 / month for unlimited call and text plus 1 GB of data. This is good if you intend to use the GPRS functionality of the module. But if you only intend to use the text / call functionality sporadically, there’s more suitable plans available. The easiest pan to “unlock” these plans is to enter the IMEI of an old AT&T go phone. Don’t have one? Here’s one: IMEI: 865651028857609 After the activation is complete, the website will show you your new phone number. Now only add money to the account and your device is ready to be connected to the cellular network. That’s it, it’s that simple. WARNING: Many providers, such as AT&T, intend to shut down their 2G (GSM) and 2.5G (GPRS) networks in the very near future. AT&T announced this shutdown to be completed by the end of 2016. So if you’re developing a new product, this technology may not be the best to bet on. GSM enabled realtime GPS Tracker Links and Sources: [1] GPRS Shield V2.0, Seed: http://www.seeedstudio.com/depot/GPRS-Shield-V20-p-1379.html ## Realtime GPS Tracker w. SD Card Logger Part 2 | Google Maps Link This article shows how to build a realtime text message GPS tracker with integrated SD card logger. It allows coarse realtime tracking and more precise post analysis through the logged data. Not too long ago I wrote an article featuring a Realtime GPS Tracker w. SD Card Logger. That project sends raw NMEA [1] sentences via text message and logs them onto a SD card as well. This project is taking it a bit further. Not only is the logging frequency and text frequency independent now, but it also sends a clickable Google maps link via text message. The circuit is quite simple. It utilizes the seed SD card shield V4.0 and the GPRS Shield V2.0. The GPRS shield needs to be set to hardware serial via jumper. Pin 7 of the arduino needs to be connected to the TX line of the GPS module. In my case the GPS has a bitrate of 4800 bps. It’s a very common bitrate for navigation instruments as per NMEA 0183 standard. The code utilizes a library called TinyGPS++ [2]. It ingests GPS messages and parses them. It makes the Google Maps link assembly a whole lot easier. IT also allows for a custom logging format for the SD card file.  /* Realtime GSM GPS Tracker  Created: 01/22/2016 by Sebastian Westerhold KF5OBS This example code is in the public domain. SD Card uses SEED SD Card Shield v. 4.0 CS - pin 4 Connect GPS Module to PIN 7 on UNO Connect GPS Module to Serial 1 RX on Due */ #include #include // Soft Serial for UNO, comment out for Due #include SoftwareSerial Serial1(7, 8); // Include GPS Library #include "TinyGPS++.h" TinyGPSPlus gps; // Set up necessary variables const int chipSelect = 4; int counter = 100; char message[160]; char latitude[12]; char longitude[12]; // Setup routine void setup() { // Initiate Serial at 4800 baud Serial.begin(19200); // Wait for serial to become available while (!Serial) { } // Initiate serial for GPS module Serial1.begin(4800); // Iinitialize the SD card Serial.print("Initializing SD card..."); if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); return; } Serial.println("done."); // Set mode to text Serial.print("AT+CMGF=1\r"); // Give GSM module some start-up time delay(10000); } // Function to send text message void sendSMS(String message) { // AT command to initiate text message Serial.print("AT+CMGF=1\r"); delay(100); // AT command to set destination number Serial.println("AT + CMGS = \"+15015559350\""); delay(100); // Message body Serial.println(message); delay(100); // Termination character Serial.println((char)26); delay(100); // \n Serial.println(); } // Main routine void loop() { // If there's serial data int he buffer, add to dataString while(Serial1.available() >0) { // Feed it to the GPS engine gps.encode(Serial1.read()); } // If the location info is valid... if (gps.location.isValid()) { // Open file on SD Card File dataFile = SD.open("NMEA.txt", FILE_WRITE); // IF the file is opened successfully... if (dataFile) { // Assemble SC Card Line //** Assemble Date DD.MM.YYYY dataFile.print(gps.date.day()); dataFile.print("."); dataFile.print(gps.date.month()); dataFile.print("."); dataFile.print(gps.date.year()); dataFile.print(","); //** Assemble time HH:MM:SS dataFile.print(gps.time.hour()); dataFile.print(":"); dataFile.print(gps.time.minute()); dataFile.print(":"); dataFile.print(gps.time.second()); dataFile.print(","); dataFile.print(gps.location.lat()); dataFile.print(","); dataFile.print(gps.location.lng()); dataFile.print(","); dataFile.print(gps.speed.kmph()); dataFile.print(","); dataFile.print(gps.course.deg()); dataFile.print(","); dataFile.print(gps.altitude.meters()); dataFile.print(","); dataFile.print(gps.satellites.value()); dataFile.print(","); dataFile.print(gps.hdop.value()); dataFile.println(""); // Close the SD card file dataFile.close(); // wait for 10 seconds delay(10000); } // If there's any errors, so say via serial. else { Serial.println("error opening NMEA.txt"); } // Only send texts every 30 cycles (~ 10 Minutes) if (counter > 6*10) { // Assemble Text Message strcpy(message, "http://maps.google.com/"); strcat(message, "maps?z=12&t=m&q=loc:"); dtostrf(gps.location.lat(), 1, 6, latitude); strcat(message,latitude); strcat(message,"+"); dtostrf(gps.location.lng(), 1, 6, longitude); strcat(message,longitude); strcat(message,""); // Send via text sendSMS(message); counter=0; } }   counter++; }  You can download the code here: GSM_Track_SD_Card_UNO_GPS__ Please remember to change the target phone number! If everything is connected correctly and the GPS signal is valid, it’ll log a GPS position about every 10 seconds and send a position text about every 10 minutes. The text messages contain a clickable Google Maps link. Links and Sources: [1] NMEA 0183, Wikipedia: https://en.wikipedia.org/wiki/NMEA_0183 [2] TinyGPS++: http://arduiniana.org/libraries/tinygpsplus/ ## Realtime GPS Tracker w. SD Card Logger This article shows how to build a GPS tracker that sends NMEA GPS sentences to a remote device in realtime. At the same time it logs position information onto a SD card. A while ago I got a bunch of SIM900 GSM shields, the GPRS Shield V2.0 from seed [1]. Looking for project ideas I thought a realtime GPS tracker would be a great idea. It is a derrivative of my Simple Arduino SD-Card GPS/NMEA Datalogger. It is essentially the same circuit, except this time it adds GSM text messaging. I developed this project on the Arduino Due but converted it to the Uno platform as more of my readers are likely working with it. The only difference in code is that the Uno only has one UART while the Due has 4. But thanks to the software serial library it’s an easy conversion. Be certain to set the jumpers on the GPRS shield to hardware serial. The soft serial is used for the GPS receiver instead. GPS receivers spit out GPS information in a format called NMEA 0183, or NMEA for short. It is a standardized format for all kinds of navigation related instruments [2]. It’s primarily used in the marine world. Nearly any GPS module on the market can spit out NMEA sentences. The Arduino takes in NMEA sentences via Serial1, which is the software serial on the Uno or actual Serial 1 on a Due. Out of all the NMEA sentences the Arduino extracts the GPRMC sentence, a basic sentence sufficient for tracking purposes, and stores it on the SD card. It also takes the same sentence and sends it via text message. This happens about every 5 minutes. The code is quite simple:  /* Realtime GSM GPS Tracker  Created: 01/22/2016 by Sebastian Westerhold KF5OBS This example code is in the public domain. SD Card uses SEED SD Card Shield v. 4.0 CS - pin 4 Connect GPS Module to PIN 7 on UNO Connect GPS Module to Serial 1 RX on Due */ #include #include // Soft Serial for UNO // Comment out for Due #include SoftwareSerial Serial1(7, 8); // Set up necessary variables const int chipSelect = 4; char SerRead = 0; // Setup routine void setup() { // Initiate Serial at 19200 for GSM900 module Serial.begin(19200); // Wait until serial is ready while (!Serial) { } // Begin GPS Serial Serial1.begin(4800); // Initialize the SD card Serial.print("Initializing SD card..."); if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); return; } Serial.println("done."); // Set mode to text Serial.print("AT+CMGF=1\r"); delay(10000); } // function to send text message void sendSMS(String message) { // Initiate text message Serial.print("AT+CMGF=1\r"); delay(100); // Set target phone number Serial.println("AT + CMGS = \"+15015559350\""); delay(100); // send message Serial.println(message); delay(100); // send termination character Serial.println((char)26); delay(100); Serial.println(); } // Main routine void loop() { // our buffer for serial data String dataString = ""; // If there's serial data int he buffer, add to dataString while(Serial1.available() >0) { // read a line on the serial port dataString = Serial1.readStringUntil('\n'); } // If there's data in dataString, dump to SD card and send text message if (dataString.length() >0) { // Open file on SD Card File dataFile = SD.open("NMEA.txt", FILE_WRITE); // Dump data to file and serial port as well if (dataFile) { if (!dataString.indexOf("$GPRMC")) { dataFile.println(dataString); dataFile.close(); } } // send text message sendSMS(dataString); // Wait for about 5 minutes before next message delay(60000*5); 

 // If there's any errors, so say via serial. else { Serial.println("error opening NMEA.txt"); } } } 

If everything is connected correctly, you should receive text messages about every 5 minutes with the current \$GPRMC NMEA sentence.

The idea behind this is to take another Arduino to receive the NMEA sentence and blurt it out over its serial port to spoof a GPS receiver to a PC. That way any mapping software that accepts GPRMC sentences can be used without any modification.

[1] GPRS Shield V2.0, SEED: http://www.seeedstudio.com/wiki/GPRS_Shield_V2.0

[2] NMEA 0183, Wikipedia: https://en.wikipedia.org/wiki/NMEA_0183

## Simple Arduino SD-Card GPS/NMEA Datalogger

This article is going to show how to build a minimalistic GPS datalogger. The GPS logger is based on the Arduino platform and stores raw NMEA sentences from pretty much any GPS module to a SD card.

For a project I needed to log GPS information. I had various GPS modules and plenty of Arduinos laying around the lab. At first I intended for the Arduino to capture data from the GPS module, process it and then store it onto a SD card. However, I discarded that idea in favor of more flexibility and now use the arduino merely as pass-thru device for the raw GPS data.

Many GPS receivers spit out GPS information in a format called NMEA 0183, or NMEA for short. It is a standardized format for all kinds of navigation related instruments [1]. It’s primarily used in the marine world. Nearly any GPS module on the market can spit out NMEA sentences. As stated before, originally I wanted the Arduino to extract position, speed, heading and other values from said NMEA sentences and store the result on the SD card. But storage is junk cheap these days so I decided to dumb the entire NMEA sentences directly on the SD card.

Very simple Arduino SD-Card GPS NMEA Logger

The primary advantage of that idea is that any available bit of information is logged. Some information, like how many satellites are currently in view, may not be as interesting but again, storage is cheap. There’s various programs out there that can visualize NMEA data so logging the raw NMEA sentences also had compatibility advantages. NMEA 0183 is electrically a serial bus. Therefore, this project is basically a serial logger. It takes anything coming in on the Arduino’s hardware UART and dumps it unprocessed on the SD card. My GPS module uses a datarate of 4800 baud. If yours is different or you are logging data from a different device, keep in mind to adjust the code to the necessary data-rate.

The code is quite simple:

 * GPS NMEA SD Card Data Logger 

 This example shows how to log data from three analog sensors to an SD card using the SD library. The circuit: GPS Module TX conencted to the Arduino RX pin. SD card attached to SPI bus as follows: MOSI - pin 11 MISO - pin 12 CLK - pin 13 CS - pin 4 Created: 01/22/2016 by Sebastian Westerhold KF5OBS This example code is in the public domain. */ #include #include // Set up necessary variables const int chipSelect = 4; char SerRead = 0; // Setup routine void setup() { // Initiate Serial at 4800 baud Serial.begin(4800); while (!Serial) { } // Now initialize the SD card Serial.print("Initializing SD card..."); if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); return; } Serial.println("card initialized."); } // Main routine void loop() { // our buffer for serial data String dataString = ""; // If there's serial data int he buffer, add to dataString while(Serial.available() >0) { SerRead=Serial.read(); dataString += SerRead; } // If there's data in dataString, dump to SD card if (dataString.length() >0) { // Open file on SD Card File dataFile = SD.open("NMEA.txt", FILE_WRITE); // Dump data to file and serial port as well if (dataFile) { dataFile.print(dataString); dataFile.close(); Serial.print(dataString); } 

 // If there's any errors, so say via serial. else { Serial.println("error opening NMEA.txt"); } } }