Go Down

Topic: Hardware Serial receiving 0 bytes, but RX LED blinking (Read 99 times) previous topic - next topic

mmdk95

I am having quite a strange issue. Hardware serial through USB works without any problems, however when I connect with the D0/RX port I don't receive any data.

My test setup
I have connected a NEO6M GPS module to my hardware RX port on an Arduino nano clone (WAVGAT nano).  The NEO6M GPS module is also connected to 5V Perhaps the problem is that it is a clone board. However, since the hardware serial does work through USB, I can't imagine that being the issue. (If it is, could you tell me why?)

here is an image of the clone board circuit if that helps


I have a Bluetooth module connected through Software Serial pins (8 and 9). The Bluetooth connection works fine without any issues.

The reason why I want to use hardware serial for the GPS module is that the reliability of software serial work

Test Code (Very straight forward)
Code: [Select]
#include "SoftwareSerial.h"

SoftwareSerial ss = SoftwareSerial(8, 9);

void setup() {
  ss.begin(4800);
  Serial.begin(9600);
}

void passThrough() {
  int16_t byte;
  while ((byte = Serial.read()) >= 0) {
    ss.write(byte);
  }
}

void sendByteCount() {
  uint8_t bytes = 0;
  while (Serial.read() >= 0) {
    bytes++;
  }
  ss.print(F("Received "));
  ss.print(bytes, 10);
  ss.println(F(" bytes"));
}

void loop() {

  // passThrough();
  // wait a bit for data to be received
  delay(100);
  sendByteCount();
}


Observations
 - I do receive data from the NEO6M module when using software serial.
 - I do receive data from hardware Serial when using a USB connection.
 - RX LED led is blinking when connected to RX, TX LED is blinking when connected to TX

What I have tried so far that hasn't worked
 - Tried different baud rates (2400, 4800, 9600 (the default))
 - Swapped RX, and TX wires to make sure that wasn't the issue.

I am quite good with software however, the hardware is still a challenge sometimes. So I genuinely hope someone can give me advice on what the problem could be because I have run out of ideas.

Paul_KD7HB

You wrote: "since the hardware serial does work through USB". Can you tell us why you think this is true?
Paul

mmdk95

Yes, thank you for your reply. 

Perhaps I am misunderstanding something, but I would think that the RX TX pins from the USB controller are connected to D0 and D1 pins. I don't know how else they could connect that hardware serial.

tomparkin

I suspect (although I don't 100% know, so take with a pinch of salt!) that you're going to struggle to use the hardware serial port to talk to the GPS module in the way that you want.  I had a quick look at the Nano schematics and although the ATMega328P's RX/TX pins are connected to the header D0/D1 pins as you say, they're also directly connected through to the USB/Serial chip.

Possibly there is a way to disable the USB/Serial chip or something, but otherwise I think you're out of luck.

On a more positive note: it's not impossible to interface with a NEO6M using software serial from an ATMega328P.  I have had good results using libraries from here: https://github.com/SlashDevin -- specifically the NeoGPS and NeoSWSerial libraries.

A very minimal example (coded for Uno, you might need to transpose the pin numbers for a Nano, but the point is they're just common-or-garden digital I/O pins):

Code: [Select]

#include "NeoSWSerial.h"
#include "NMEAGPS.h"

#define GPS_BAUD 9600
#define GPS_SERIAL_RX_PIN 3
#define GPS_SERIAL_TX_PIN 2

static NeoSWSerial gpsSerial(GPS_SERIAL_RX_PIN, GPS_SERIAL_TX_PIN);
static NMEAGPS gps;

void setup()
{
    Serial.begin(115200);
    gpsSerial.begin(GPS_BAUD);
}

void loop()
{
    while(gps.available(gpsSerial)) {
        gps_fix = gps.read();
        // TODO: print out GPS fix information, see the NEOGPS examples for guidance
    }
}



FWIW, I've used this in a project with a 5Hz GPS update rate (although restricted NMEA sentences) and the software serial implementation apparently keeps up, in that I get valid fix information back to my Arduino loop() function on a ~200ms interval.

While I'm here -- a couple of observations.

#1.  I don't know what NEO6M module you're using, but the one I have (GY-NEO6MV2) uses 3.3v logic for it's serial interface.  So I needed to add some circuitry to interface it with the ATMega328P's 5v levels.  A simple howto is here: https://www.xarg.org/2016/06/neo6mv2-gps-module-with-arduino/

#2. You appear to be mixing up data types when working with the serial API.

Code: [Select]
void passThrough() {
  uint16_t byte;
  while ((byte = Serial.read()) >= 0) {
    ss.write(byte);
  }
}

In this function you are taking the the output of Serial.read() (an int, which for ATMega boards is a signed 16 bit integer), and assigning it to an unsigned variable uint16_t.  Check the language standards for exactly what happens, but it probably isn't what you expect/want, and it certainly isn't ever going to be < 0, since unsigned variables can't represent negative numbers.  Hence the while loop there is going to be infinite, since the byte variable can only ever be >=0.
For the goal of "read from the serial port while data is available" you can try the Serial.available() method:
Code: [Select]

while (Serial.available()) {
   int c = Serial.read();
   // TODO: do something with c
}

mmdk95

Hey tomparkin, thank you for your reply.


A single software serial does indeed work without issues, but through my testing, I found that I get a lot of corrupt data when using two software serials. Especially when the Arduino is being busy doing a lot of other things as well. 

My code is using the UBX protocol currently to do less string parsing, but perhaps their software serial may be a good alternative to do some testing on. It is still strange that hardware Serial is not working though. Would still like to find a solution for that, but I have a backup plan now at least.

@observation #1: I have the module powered with 5V. I hadn't mentioned that, but it's a good observation.

@observation #2 good catch. It should be an int16_t instead. A mistake I'd probably have caught if I had any data coming though :P 

I'll edit my original post, to fix my code and mention the 5V thing.


tomparkin

Quote
A single software serial does indeed work without issues, but through my
 testing, I found that I get a lot of corrupt data when using two
software serials. Especially when the Arduino is being busy doing a lot
of other things as well.
Ah, OK -- that wasn't clear to me previously.  It may be worth posting your code using the two software serial interfaces.
I note also that the NeoGPS library code has a good comment about serial port choices in src/GPSport.h (possibly this is driving your attempt to use the hardware serial interface?) which is worth a read if you've not done so already.

Quote
It is still strange that hardware Serial is not working though.
Uncertain :-/

The reason I'm sceptical TBH is that TTL serial is driven by the sender, and is high when idle (ref: e.g https://electronics.stackexchange.com/questions/6889/how-does-ttl-serial-work).  A start/stop "low bit" is used to indicate the beginning and end of a data byte.

So as you can see, if the USB/serial chip AND the NEO6M both think they're "the sender" for the ATMega's RX pin, the USB/Serial will normally be driving the line to Vcc.  When the NEO6M tries to drive it low for the serial start bit, there's going to be a fight between the USB/Serial and the NEO6M over whether the line is high or low.  It's probably not going to result in happiness.

As I said before though, there may be a way to disable the USB/serial chip perhaps.


mmdk95


Quote
The reason I'm sceptical TBH is that TTL serial is driven by the sender, and is high when idle (ref: e.g https://electronics.stackexchange.com/questions/6889/how-does-ttl-serial-work).  A start/stop "low bit" is used to indicate the beginning and end of a data byte.
Oh I see. I have tested it with just external power through VIN thinking that it may interfere if USB is plugged in or something. But perhaps that is not enough to disable it? 

I will do some googling, at least I have some direction to search in now, so it's already progress :)

Go Up