digitalWrite Problem

I have a problem with digitalWrite.
I have a N-Channel MOSFET which switches the GPS modules power ON/OFF.
The MOSFET is connected, via a resistor, to D5.
I only switch the GPS ON when required.

My Setup:

void setup() {

  pinMode(5, OUTPUT); // GPS PIN
  digitalWrite(5, HIGH);// ENSURE GPS IS OFF

  // Open serial communications and wait for port to open:
  Serial.begin(9600);

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

  // Switch GPS ON
  //   digitalWrite(5, LOW);

}

I am entering a single character in the Serial Monitor and my Sketch actions this:
My Loop:

void loop(void) {

  if (Serial.available())
  {
    serialData = Serial.read();

    if (serialData == 'I')
    {
      getID();
      serialData = "";
    }
    else if (serialData == 'G')
    {
      // Switch GPS ON
      digitalWrite(5, LOW);
      delay(100);
      getGPS();
    }
  }
}

In my loop (above) the "digitalWrite(5, LOW);" function does not work (Switch D5 LOW).
However, if I comment the "digitalWrite(5, LOW);" out in loop and uncomment "digitalWrite(5, LOW);" in setup, the GPS switches and works correctly.

Please DON'T post snippets, if you want to simplify it, post a MCVE.

Switching off modules like that can cause weird problems because of phantom power. Especially because apparently (schematic would be useful) you use a N-channel on the high side. Be warned!

To the problem: why are you sure the problem is the digitalWrite()? Two options:

  • That if() is never executed
  • You disable the power somewhere else in your code. That's why to NOT post snippets.

My Complete code:

#include <SoftwareSerial.h>
#include "GPS_GGA.h"

///*********************************************
//      Required for GPS Operation
// *********************************************/
#define pinGPS_Power 5
GPS_GGA gps_gga = GPS_GGA(&Serial, pinGPS_Power);
unsigned long time_now;
double period = .05;
///********************************************************************************************/

SoftwareSerial mySerial(8, 9); // RX, TX

byte myByte;

String myID;
String myPAC;

char serialData;

void setup() {

  pinMode(5, OUTPUT); // GPS PIN
  digitalWrite(5, HIGH);// ENSURE GPS IS OFF

  // Open serial communications and wait for port to open:
  Serial.begin(9600);

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

  // Switch GPS ON
  //   digitalWrite(5, LOW);

}

void getID() {
  mySerial.print("AT$I=10");
  mySerial.print('\n');

  String s = mySerial.readStringUntil('\n'); // Until CR (Carriage Return)
  s.trim();
  int posOO;
  posOO = (s.indexOf("00"));

  if (posOO == 0) {
    s.replace("00", "");
    if (s.length() == 6)
    {
      //      Serial.print("ID: ");
      Serial.print(s);
      s = "";
      delay(100);
      getPAC();
    }
  }

}

void getPAC() {
  mySerial.print("AT$I=11");
  mySerial.print('\n');

  String s = mySerial.readStringUntil('\n'); // Until CR (Carriage Return)
  s.trim();

  if (s.length() == 16)
  {
    Serial.println(s);
    s = "";
  }
}



void loop(void) {

  if (Serial.available())
  {
    serialData = Serial.read();

    if (serialData == 'I')
    {
      getID();
      serialData = "";
    }
    else if (serialData == 'G')
    {
      // Switch GPS ON
      digitalWrite(5, LOW);
      delay(100);
      getGPS();
    }
  }
}

void getGPS() {

  Serial.println("Got GPS");

  String myGPS;
  //
  time_now = millis();
  while (millis() < time_now + period * 60000)
  {

    gps_gga.receiveGPS();
    if (gps_gga.newGPS == true)
    {
      //      Serial.println(gps_gga.receivedGPS);

      myGPS = (gps_gga.receivedGPS);

      int PosGPS;
      PosGPS = myGPS.indexOf("GPRMC");
      //      Serial.println(PosGPS);
      if (PosGPS == 0) {
        Serial.println("Got GPS");
        digitalWrite(5, HIGH); //Got GPS IS running - now switch GPS OFF.
      }

      gps_gga.newGPS = false;
    }
  }

  Serial.println("GPS Download Time-Out");
  delay(100);
  digitalWrite(5, HIGH); ////GPS is NOT running - now make sure GPS OFF.
}

So many questions!

  • Where can I find that GPS_GGA-library?
  • Why does it need the 'pinGPS_Power' as well?
  • How is everything connected?
  • Why is 'period' a double ???
  • Never check time like:
millis() < time_now + period * 60000
//but use
millis() - previousTime < periode
  • Why mess with String's?

GPS_GGA Library attached.
I include the files, ccp and h in my sketch.
I have removed "pinGPS_Power"
GPS is connected to Hardware Serial.
'period' is a double simply to allow for decimal - I have changed this to your recommendation "millis() - previousTime < period" so reverted back to int.

Thanks for your assistance

GPS_GGA.cpp (3.57 KB)

GPS_GGA.h (830 Bytes)

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

For how long do you require the GPS?
Do you understand GPS units work, just turning it ON and in seconds getting reliable readings is not really possible.
The units have to acquire a number of satellites to compute readings.

Thanks.. Tom... :slight_smile:

Hi,
I realise that it takes a while before the GPS will get a reliable fix.
However, the purpose of this sketch is not for the GPS to run in order to obtain a fix.
The purpose is just to see if the GPS module (Quectel L96) is communicating with the micro.
It is, in essence, a sketch to test the various modules attached to the micro (ATMEGA328PB).
The GPS is just one of 3 modules connected to the ATMEGA328PB.
D5 of the ATMEGA328PB acts as the "switch" to the GPS through a N-Channel MOSFET.
I have established that the MOSFET does switch when the "digitalWrite(5, LOW);" is called in setup.
But does not switch when called from loop.

It looks like you are trying to use the serial port to get commands and emit debug info. But you're also using it for the GPS. That's unlikely to work well :wink: