Project: Nano gps with epaper and radio transmitter

Hi.

I have startet working with the Arduino Nano to create one of my ideas for a low power GPS receiver with e-paper display. The unit will be put into a waterproof case and used when kayaking. I want to see my location, heading, speed and the time of the last data received. Later on I am planning to add a radio transmitter which will open several exciting oportunities.

I have managed to create the receiver and put the location info on screen, but as the Nano has limited space i need some help shaving off a few Kb to make room for the next step. I’m trying to build the code modular in case i will change one of the units later.

As for the e-paper I got it working but I’m not sure that I’m using the most efficient code. Also I’m not sure if I really need to include all the items from the library; GxEPD2. I feel the display is blinking and refreshing more than needed. Not sure if I need the “do, while” combination in this code?

For the GPS I’m sure my code can be improved and will appreciate any ideas. I haven’t managed to get the timestamp from the latest data. I tried taking code from the example, but I must be missing some understanding because I only got an error about to few arguments.

Drawing of the project attached. Code below.

Any ideas and improvements will be grately appreciated.

#include <GxEPD2.h>
#include <GxEPD2_3C.h>
#include <GxEPD2_BW.h>
#include <GxEPD2_EPD.h>
#include <GxEPD2_GFX.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <Fonts/FreeMonoBold9pt7b.h>

#define MAX_DISPAY_BUFFER_SIZE 800 // 
#define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8))

#define MAX_HEIGHT_3C(EPD) (EPD::HEIGHT <= (MAX_DISPAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8))
GxEPD2_3C<GxEPD2_213c, MAX_HEIGHT_3C(GxEPD2_213c)> display(GxEPD2_213c(/*CS=10*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7));


TinyGPS gps;
SoftwareSerial ss(2, 3);

float Glon;
float Glat;
int Gsat;
int x=0; //teksten starter til venstre
int y=15; // teksten starter øverst på skjermen
int z=20; // linjeavstand
float kmph;
float heading;

void setup() {
  Serial.begin(115200);
  ss.begin(9600);
  display.init(115200);

Serial.println("Starting");


}

void loop() {

NEO6MV2();
delay(1000);
Sensor(); // Run program to show sensor data on epaper display
delay(9000);
}

  

   void NEO6MV2()
   {
    
    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.println(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.println(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.println(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
    Serial.println(" ");
    Serial.println(gps.f_speed_kmph() ==TinyGPS::GPS_INVALID_F_SPEED ? 0 : gps.f_speed_kmph());
    Serial.println(gps.f_course());
 
    Glon=flon;
    Glat=flat;
    Gsat=gps.satellites();
    kmph=gps.f_speed_kmph();
    heading=gps.f_course();
  }
  
  gps.stats(&chars, &sentences, &failed);
  Serial.print(" CHARS=");
  Serial.println(chars);
  Serial.print(" SENTENCES=");
  Serial.println(sentences);
  Serial.print(" CSUM ERR=");
  Serial.println(failed);
  if (chars == 0)
    Serial.println("** No characters received from GPS: check wiring **"); 
    
    }

    void Sensor()
{
  display.setRotation(1);
  display.setFont(&FreeMonoBold9pt7b);
  display.setTextColor(GxEPD_BLACK);
  display.setFullWindow();
  display.fillScreen(GxEPD_WHITE);
  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE); // set the background to white (fill the buffer with value for white)
    display.setCursor(x, y); // set the postition to start printing text
    display.print(" LAT= ");
    display.print(Glat, 6);// print some text
    display.setCursor(0, y+z);
    display.print(" LON= ");
    display.print(Glon, 6);
    display.setCursor(0, y+2*z);
    display.print(" SAT= ");
    display.print(Gsat);
    display.setCursor(0, y+3*z);
    display.print(" Km/h= ");
    display.print(kmph);
    display.setCursor(0, y+4*z);
    display.print(" Heading=");
    display.print(heading);

  }
 while (display.nextPage()); 

   }

Best Regards
Knut-Magne

Is the issue too much code memory usage or data, varaiable memory usage too high? Of course, libraries can be consuming bytes too.

If your just starting the project, and already running out of program memory, then you probably need an Arduino with more memory.

The ePaper displays do take a lot of memory as I recall, I did a project using one, and it was obvious (to me) at the start that the project was going to need more program space than a ProMini\Nano could manage.

Railroader: Is the issue too much code memory usage or data, varaiable memory usage too high? Of course, libraries can be consuming bytes too.

The program memory takes up 70% of the capacity. Global variables uses 79% of dynamic memory. Do you have any ideas to reduce any of the two?

I hope that some of the epaper liblaries can be excluded, but I don't know how to find out which is actually needed for my program.

srnet: If your just starting the project, and already running out of program memory, then you probably need an Arduino with more memory.

The ePaper displays do take a lot of memory as I recall, I did a project using one, and it was obvious (to me) at the start that the project was going to need more program space than a ProMini\Nano could manage.

You might be right. I still hope the memory shortage is mostly due to poor programming skills, becaus that is something which can be improved :)

Is the difference between an epaper program and an Oled program that big? I was hoping to use the epaper due to the low power consumption and visibility in the sun. For my application i don't need frequent updates.. maybe once a minute, and I find it nice that the text stays on screen even if the arduino sleeps for a while.

Can save some dynamic memory by leaving all the quoted Serial.prints in PROGMEM, with the F-Macro.

Serial.print(" LAT="); becomes Serial.print(F(" LAT="));

Leo..

Wawa: Can save some dynamic memory by leaving all the quoted Serial.prints in PROGMEM, with the F-Macro.

Serial.print(" LAT="); becomes Serial.print(F(" LAT="));

Leo..

Thank you. I was not aware of that macro. I've just read a little bit about it and as far as i understand it can only be used for things that will not change. Does that mean I can us it for static text, but not for any variables?

All the libraries/resources needed to operate your display are probably killing your memory. Could you use a simpler display? Maybe an LCD?

Can you slim down your dependencies?

KnutMagne: Does that mean I can us it for static text, but not for any variables?

Yes. Static text in quotation marks only. Leo..

KnutMagne: Is the difference between an epaper program and an Oled program that big? I was hoping to use the epaper due to the low power consumption and visibility in the sun. For my application i don't need frequent updates.. maybe once a minute, and I find it nice that the text stays on screen even if the arduino sleeps for a while.

It can be.

Why dont you try and see ?

That you might not want to do frequent updates or want low power consumption, wont make the required libraries smaller.

If you think some of the libraries are 'not needed' then dont include them and see what happens .........