More on mySerial.available()

Kind of embarassing, but I can’t run the SoftwareSerial example!
The serial.available never works!
Any hints?

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3);

void setup()  
{
 Serial.begin(9600);
 Serial.println("Goodnight moon!");

 // set the data rate for the NewSoftSerial port
 mySerial.begin(9600);
 mySerial.print("Hello, world");
}

void loop()                     // run over and over again
{

 if (mySerial.available()) {
   // never here
   Serial.print((char)mySerial.read());
 } else {
  // always here
   mySerial.write("Go home");
   delay (5000);
 }
 if (Serial.available()) {
   // never here
   Serial.println("Stay at home");
   mySerial.print((char)Serial.read());
 }
}

What is sending data to the software serial port?

Well, it is just an example, so suposelly the sending data is the message that was writen, right? I mean, if I read the other forum messages correctly, the available() should return the number of bytes to read, and if i'm using a Serial.Write() or Serial.println(), I should have bytes to read. So, if there is a previous print message, the available() should be non zero.

So, I think I understand your point. I'm suposed to have an incoming message at digital port 3 so it can be active, right? Well, I added a resistor to it, so the voltage would be "1" and the port would be on, but the behavior is the same. No success.

Serial.available() has nothing to do with the state of the RX or TX pins. As serial data arrives it is put into the serial buffer. Serial.available() tells you how many bytes are waiting in the buffer. So there has to be at least one valid byte received before serial.available will return true. The forgoing applies to software serial as well as hardware serial. You need a source of serial data to test software serial. That could be another Arduino or a GPS or whatever. There might be a way to do a "loopback" test where the port talks to itself, but I don't know for sure.

edit: software serial can't send and receive at the same time so no loopback, I think.

Serial.available() means that someone has senbt data to the serial port and its available for reading. That is, you have opened the arduino serial console on your computer and have typed some input into the input box and hit send.

The purpose of SoftwareSerial is to create another serial port so you can communicate with two things - for example the Serial Monitor (using HardwareSerial) and another Arduino or a Bluetooth module (using SoftwareSerial).

...R

I understand all of that, and indeed I have an GPS for that purpose, however it never gets available.

Show your wiring and code. What is the model of GPS (link, please)?

There it is.
2 is rx,
3 is tx,
gnd is black
VCC is 5V

The GPS is u-Blox NEO-6M

tinyGPS

This is the library that I use to communicate with my GPS. Mine is a Neo6M as well. Download and install the library and run the simple_test example. Change the software serial pins to match yours, first.

Well, the code I posted was the simpler one, so it could make the doubt easier to clarify. My real code is (not working as well):

#include <SoftwareSerial.h>
#include <TinyGPS.h>

#define rxPin 10
#define txPin 11

TinyGPS gps;
SoftwareSerial mySerial(rxPin, txPin); // RX, TX

void gpsdump(TinyGPS &gps);
void printFloat(double f, int digits = 2);

void setup()  
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  while (!Serial) {
    Serial.println("Inicializando Serial");
  }
  Serial.println("Serial ok!");
  delay(1000);

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);

  while (!mySerial) {
    Serial.println("Inicializando mySerial");
  }
  Serial.println("mySerial ok!");
  
  delay(1000);
  Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); Serial.println(sizeof(TinyGPS));
  Serial.println();
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();
  
  if (!Serial) {
    Serial.println("Ok");
  } else {
    Serial.println("Erro chato");
  }
  
  // Every 5 seconds we print an update
  if (!mySerial) {
    char c = mySerial.read(); 
    // Serial.print(c);  // uncomment to see raw GPS data
    if (gps.encode(c)) {
      newdata = true;
      // break;  // uncomment to print new data immediately!
    } else {
      Serial.println("GPS Indisponivel");
    }
  } else {
    Serial.println("Serial Indisponivel");
  }
  
  delay (5000);
  
  if (newdata) {
    Serial.println("Acquired Data");
    Serial.println("-------------");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
  }
}

void gpsdump(TinyGPS &gps)
{
  long lat, lon;
  float flat, flon;
  unsigned long age, date, time, chars;
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned short sentences, failed;

  gps.get_position(&lat, &lon, &age);
  Serial.print("Lat/Long(10^-5 deg): "); Serial.print(lat); Serial.print(", "); Serial.print(lon); 
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");
  
  // On Arduino, GPS characters may be lost during lengthy Serial.print()
  // On Teensy, Serial prints to USB, which has large output buffering and
  //   runs very fast, so it's not necessary to worry about missing 4800
  //   baud GPS characters.

  gps.f_get_position(&flat, &flon, &age);
  Serial.print("Lat/Long(float): "); printFloat(flat, 5); Serial.print(", "); printFloat(flon, 5);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  gps.get_datetime(&date, &time, &age);
  Serial.print("Date(ddmmyy): "); Serial.print(date); Serial.print(" Time(hhmmsscc): ");
    Serial.print(time);
  Serial.print(" Fix age: "); Serial.print(age); Serial.println("ms.");

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  Serial.print("Date: "); Serial.print(static_cast<int>(month)); Serial.print("/"); 
    Serial.print(static_cast<int>(day)); Serial.print("/"); Serial.print(year);
  Serial.print("  Time: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); 
    Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second));
    Serial.print("."); Serial.print(static_cast<int>(hundredths));
  Serial.print("  Fix age: ");  Serial.print(age); Serial.println("ms.");

  Serial.print("Alt(cm): "); Serial.print(gps.altitude()); Serial.print(" Course(10^-2 deg): ");
    Serial.print(gps.course()); Serial.print(" Speed(10^-2 knots): "); Serial.println(gps.speed());
  Serial.print("Alt(float): "); printFloat(gps.f_altitude()); Serial.print(" Course(float): ");
    printFloat(gps.f_course()); Serial.println();
  Serial.print("Speed(knots): "); printFloat(gps.f_speed_knots()); Serial.print(" (mph): ");
    printFloat(gps.f_speed_mph());
  Serial.print(" (mps): "); printFloat(gps.f_speed_mps()); Serial.print(" (kmph): ");
    printFloat(gps.f_speed_kmph()); Serial.println();

  gps.stats(&chars, &sentences, &failed);
  Serial.print("Stats: characters: "); Serial.print(chars); Serial.print(" sentences: ");
    Serial.print(sentences); Serial.print(" failed checksum: "); Serial.println(failed);
}

void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0) {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print("."); 

  // Extract digits from the remainder one at a time
  while (digits-- > 0) {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint;
  }
}

And yes. The wiring was right. I changed it to 2 and 3 to the simpler code.

#define rxPin 10
#define txPin 11

I thought you were using pins 2 and 3?

There it is. 2 is rx, 3 is tx, gnd is black VCC is

2 and 3 is the simpler version. 10 and 11 is for the complete code.
No big deal. I started trying the complex code, and then when I couldn’t figure the error out, I changed to the simpler code and changed also the wiring.
Anyway, for the complete code, yes, I’m using 10 and 11. And none of the codes work.
I’m starting to wonder my GPS is broken.

By the way, making it clear: The 11 pin is tx at arduino, so it is connected to rx at the GPS. The 10 pin is rx at arduino, so it is connected to tx at the GPS.

Anyway, I when I began, they were inverted. No success.

Which Arduino are you using?

The code that you posted won’t compile for me. I just set up my GPS with a Uno, loaded the simple_test from the library that I linked, set the RX and TX pins to 10 and 11. The GPS started to communicate right away.

You are right Uno RX (10) > GPS TX and Uno TX (11) > GPS RX

Here is the code from the library. If you have the same version of the library, give it a try.

#include <SoftwareSerial.h>

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   9600-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/

TinyGPS gps;
SoftwareSerial ss(10, 11);
void setup()
{
  Serial.begin(115200);
  ss.begin(9600);
  
  Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
}

void loop()
{
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
  }
  
  gps.stats(&chars, &sentences, &failed);
  Serial.print(" CHARS=");
  Serial.print(chars);
  Serial.print(" SENTENCES=");
  Serial.print(sentences);
  Serial.print(" CSUM ERR=");
  Serial.println(failed);
  if (chars == 0)
    Serial.println("** No characters received from GPS: check wiring **");
}

Library v. 12. It's alive!!!! Man, it works! Thanks for your time!

Glad to help. We are here all week.