Wemos D1 mini (esp8266), GPS interfering with stepper.

I am using a Wemos D1 mini (esp8266) for a stepper remote control project that also uses GPS groundspeed for stepper motor speed regulation. The last step was adding the gps to the sketch.

Using the TinyGPSPlus library which calls for SoftwareSerial, I found I had my old problem back again where the stepper rpm would pulse at about 1Hz in sinc with the led on the GPS receiver. :cry:

So back to basics. I merged the basic TinyGPSPlus Device example with the AccelStepper constant speed example.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 13, TXPin = 15;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

#include <AccelStepper.h>

AccelStepper stepper(1, 4, 5); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5


void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
  Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();

  stepper.setMaxSpeed(1600);
   stepper.setSpeed(1000);  
}

void loop()
{
  
   stepper.runSpeed();
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

And sure enough, the pulsing rpm is still there.
I have tried reading the gps on the hardware serial port Rx pin of the Wemos D1 mini but I don't seem to be able to read the GPS on that port so I don't know if this problem is strictly related to the SoftwareSerial.

Does anyone know how to get the GPS working on the hardware serial Rx port, (arduino pin1)? I realise I will probably lose serial comms but I can live with that if need be.

Does anyone know how to get the GPS working on the hardware serial Rx port, (arduino pin1)?

It should be easy. Connect the GPS to pins 0 and 1 and Serial.begin() at the appropriate baud rate. As you say, you will lose the ability to use the serial interface for anything else.

How do you know that the GPS is not working on the Serial port ?

UKHeliBob:
It should be easy. Connect the GPS to pins 0 and 1 and Serial.begin() at the appropriate baud rate. As you say, you will lose the ability to use the serial interface for anything else.

How do you know that the GPS is not working on the Serial port ?

It always sounds easy. :frowning:

Thanks for your reply UKHeliBob.

I had the code working under software serial except for the interference with the stepper so I simply deleted the software serial and set the Wemos to read Serial instead. The effect should have been noticeable on the stepper motor.

I might try a simple test sketch to light a led if gps.encode == true.

I just tried this example where I commented out the software serial and set the gps code to read the primary serial port instead.

#include <TinyGPS++.h>
//#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 3, TXPin = 1; //Wemos hardware serial is Tx(1) Rx(3).
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
//SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(GPSBaud);
 // ss.begin(GPSBaud);
  pinMode(BUILTIN_LED, OUTPUT);

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
  Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (Serial.available() > 0)
    if (gps.encode(Serial.read()))
      digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED));

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

and got a flash from the led every 5 seconds which indicates "No GPS detected: check wiring".
A valid GPS stream should flash the led every second.

Unless I have an error in the above sketch which is entirely possible.

Unless I have an error in the above sketch which is entirely possible.

In your original post you said

I realise I will probably lose serial comms but I can live with that if need be.

but you are still using it in the latest sketch.

UKHeliBob:
In your original post you saidbut you are still using it in the latest sketch.

Are you referring to the Serial.print? OK. I thought they would not effect it because the gps only uses the Rx pin. But I am probably wrong.

Revised code. Same result.

#include <TinyGPS++.h>
//#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 3, TXPin = 1;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
//SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(GPSBaud);
 // ss.begin(GPSBaud);
  pinMode(BUILTIN_LED, OUTPUT);

  //Serial.println(F("DeviceExample.ino"));
 // Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
 // Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
 // Serial.println(F("by Mikal Hart"));
 // Serial.println();
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (Serial.available() > 0)
    if (gps.encode(Serial.read()))
      //digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED));

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    //Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{ /*
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
  */
}

Are you referring to the Serial.print?

Yes

Did anyone spot the deliberate mistake in the last sketch? :wink:

#include <TinyGPS++.h>
//#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 3, TXPin = 1;
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
//SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(GPSBaud);
 // ss.begin(GPSBaud);
  pinMode(BUILTIN_LED, OUTPUT);

  //Serial.println(F("DeviceExample.ino"));
 // Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
 // Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
 // Serial.println(F("by Mikal Hart"));
 // Serial.println();
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (Serial.available() > 0)
    if (gps.encode(Serial.read()))
      digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED));

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    //Serial.println(F("No GPS detected: check wiring."));
    digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED));

    while(true);
  }
}

void displayInfo()
{ /*
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
  */
}

This sketch indicates no serial stream from gps.

Your sketch gives the GPS 5 seconds to respond then goes into an infinite loop doing nothing. Is that what you meant to do ?

Out of desperation I tried connecting the GPS Tx to the wemos D1 mini Rx(IO3) without the logic level converter and now everything works. :slight_smile:

But according to what I have read, all inputs on the D1 mini are NOT 5v tolerant so I am wary of continuing with this set up.

It seems strange that while using software.serial and IO13 for the gps serial via the logic level converter I got valid data but by simply swapping IO13 to IO3 I could not get any data through unless I remove the logic level converter.

Can anyone confirm whether IO3 is/is not 5v tolerant?

1 Like