Last recently, I put up a short post on how we can use Arduino to read data from a device. Cunningly, I made the process so simple (mainly for myself) that I neglected to actually use an Arduino.
So, in this post I will remedy that by providing an example on how to read data from a device using serial communication at the start, then move on to writing to the serial port.
In the last post, I gave an example of how you can connect a USB to TTL adapter to a device and read its data. This time round, we are going to use the UNO R3 to act as our USB to serial adapter. To do this, we are going to be using the following
- 1x breadboard
- 1x Arduino UNO R3
- 1x Neo-6M/GY-GPS6MV2 GPS Module
- 1x CH340 USB to TTL adapter
- Jumper wires
The proposition is quite simple; we want to send the output of the GPS module to the board over a serial port. Unfortunately, I have not found a way to simply connect it to the TX/RX pins on the board itself and have it output data. So, to accomplish this we need to create a second serial port to handle the incoming stream of information from the GPS module itself and we need to create that port in software.
To do this, we are going to have to use the Software Serial Library.:
1: #include "SoftwareSerial.h"
2: SoftwareSerial ss(8, 9);
The first line references the library we need to use in this program. If you get an error when compiling this code, you might want to check that you have this library installed from within the Library Manager.The second line is simply us creating a new software serial port called "ss", the numbers following represent the RX and TX pins on the board.
1: void setup() {
2: // put your setup code here, to run once:
3: Serial.begin(9600);
4: ss.begin(9600);
5: }
From reading up on using this library, it seemed that 9600 was the highest baud rate to go for and still have a stable connection. The GPS module can work up to 115200 baud, however when I configured the serial ports to use this speed, nothing happened.
1: void loop() {
2: // put your main code here, to run repeatedly:
3: if (ss.available())
4: Serial.write(ss.read());
5: if (Serial.available())
6: ss.write(Serial.read());
7: }
Think of the above as an exchange - the hardware serial port is empty until it reads the incoming message from the software serial port. Once it has that, then both ports will have the same message.
At the start of this article I mentioned that I used a CH340 USB to TTL adapter for debugging. This is because I had a fairly hard time getting the software serial port actually doing what I wanted it to do, quite a few of the articles I had read on the subject provided examples that simply did not work so I began to think my GPS module had become damaged.
So, to verify that the GPS module was working whilst the board was running the code, I connected it in series with the wires going from the GPS module to the board.
This let me run putty to make sure that I was getting something from the GPS module itself and make sure there was an incoming message for the board to do something with. It was actually quite helpful to do this while figuring out my problem.
The setup, minus the USB to TTL adapter, looks like this:
If you are trying this out for yourself, then hopefully you are seeing a nice barrage of NMEA sentences scrolling across your serial monitor.
However, if you are seeing nothing, then try swapping your RX/TX pins on the board itself. You might have gotten them mixed up - I certainly did a couple of times.
SoftwareSerial is not the only library available that can do the same thing. Another, very popular library you can install is AltSoftSerial. Syntactically, it is almost identical to SoftwareSerial and supports a wide arrange of MCU's and development boards. You can also use a mixture of different libraries to give yourself multiple serial ports to work with, should you need to, for example if you had a number of devices that provided data in the same way as the GPS module you will need to have more than one serial port configured to a set of pins. That way you will have an uninterrupted flow of data from each device on its own serial port.
From looking at the output, we can see that there are six distinct types of sentence being received, or at least the module is trying to populate the contents of six sentences with data from the GPS constellation, with that knowledge we might be able to do something useful with that data...
1: #include "SoftwareSerial.h"
2:
3: SoftwareSerial ss(8, 9);
4:
5: void setup() {
6: // put your setup code here, to run once:
7: Serial.begin(9600);
8: ss.begin(9600);
9: }
10:
11: void loop() {
12: // put your main code here, to run repeatedly:
13: if (ss.available())
14: Serial.write(ss.read());
15: if (Serial.available())
16: ss.write(Serial.read());
17: }