GPS спидометр/логгер

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

Всем привет. Копался в ящике стола и наткнулся на GPS модуль UBLOX M8N и решил сделать небольшой комбаин который будет уметь запоминать текущую точку и считать пройденое расстояние (пока в планах), так же в планах прикрутить к нему модуль SD карты что-бы писать не нее трек. Сейчас он показывает текущую скорость, высоту, координаты, время и дату по GPS. Состоит данный девайс из модуля Ublox m8n, OLED дисплей 0.96 дюйма SSD1306, arduino uno (на время разработки), потом будет Arduino nano.

Сейчас используются 4 "экрана" которые переключаются одной кнопкой циклически. Еще будет кнопка фиксации точки от которой считать расстояние.

Сейчас скетч занимает 15656 байт (48%) памяти устройства. Глобальные переменные используют 1663 байт (81%) динамической памяти, оставляя 385 байт для локальных переменных.

А еще не написан одометр и не добавлен SD модуль. Помогите оптимизировать пожалуйста.

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <OLED_I2C.h>
static const int RXPin = 9, TXPin = 8; //GPS Pins
static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
OLED  myOLED(SDA, SCL, 8);
extern uint8_t SmallFont[];
extern uint8_t BigNumbers[];
int regim = 1;
int flag = 0;
// For stats that happen every 5 seconds
unsigned long last = 0UL;

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);
  myOLED.begin();
  myOLED.setFont(SmallFont);
  myOLED.setFont(BigNumbers);

}

void loop()
{
  // Dispatch incoming characters
  while (ss.available() > 0)
    gps.encode(ss.read());
  myOLED.clrScr();
  if (digitalRead(7) == HIGH && flag == 0) //если кнопка нажата
    // и перемення flag равна 0 , то ...
  {
    regim++;
    flag = 1;

    //это нужно для того что бы с каждым нажатием кнопки
    //происходило только одно действие
    // плюс защита от "дребезга"  100%

    if (regim > 4) //ограничим количество режимов
    {
      regim = 1; //так как мы используем только одну кнопку,
      // то переключать режимы будем циклично
    }

  }

  if (digitalRead(7) == LOW && flag == 1) //если кнопка НЕ нажата
    //и переменная flag равна - 1 ,то ...
  {
    flag = 0; //обнуляем переменную "knopka"
  }

  if (regim == 1) //первый режим
  {
    myOLED.setFont(SmallFont);
    myOLED.print("( )", LEFT, 0);
    myOLED.print(String(gps.satellites.value()), 6, 0);
    myOLED.print("SPEED", CENTER, 0);
    myOLED.print("||||", RIGHT, 0);
    myOLED.print("REC", RIGHT, 57);
    //  myOLED.print(String(gps.hdop.hdop(), gps.hdop.isValid()), 30, 57);
    myOLED.print("ODO:56.2", LEFT, 57);
    //  myOLED.print(String(gps.satellites.value()), RIGHT, 57);
    myOLED.setFont(BigNumbers);
    //myOLED.print("23.8", CENTER, 20);
    myOLED.print(String(gps.speed.kmph(), gps.speed.isValid()), CENTER, 20);
  }
  if (regim == 2) //второй режим
  {
    myOLED.setFont(SmallFont);
    myOLED.print("( )", LEFT, 0);
    myOLED.print(String(gps.satellites.value()), 6, 0);
    myOLED.print("ODO", CENTER, 0);
    myOLED.print("||||", RIGHT, 0);
    myOLED.print("TIME:", 66, 57);
    myOLED.print(String(gps.time.hour()), 97, 57);
    myOLED.print(":", 110, 57);
    myOLED.print(String(gps.time.minute()), 116, 57);
    ;
    
    myOLED.print("SP:", LEFT, 57);
    //  myOLED.print(String(gps.satellites.value()), RIGHT, 57);
    myOLED.print(String(gps.speed.kmph(), gps.speed.isValid()), 18, 57);
    myOLED.setFont(BigNumbers);
    myOLED.print("56.2", CENTER, 20);
    //  myOLED.print(String(gps.speed.kmph(), gps.speed.isValid()), CENTER, 20);
  }

  if (regim == 3) //третий режим
  {

    myOLED.setFont(SmallFont);
    myOLED.print("( )", LEFT, 0);
    myOLED.print(String(gps.satellites.value()), 6, 0);
    myOLED.print("GPS", CENTER, 0);
    myOLED.print("||||", RIGHT, 0);
    myOLED.print("LATITUDE:", LEFT, 15);
    myOLED.print(String(gps.location.lat(), gps.location.isValid()), 54, 15);
    myOLED.print("LONGITUDE:", LEFT, 25);
    myOLED.print(String(gps.location.lng(), gps.location.isValid()), 60, 25);
    myOLED.print("HEIGHT:", LEFT, 35);
    myOLED.print(String(gps.altitude.meters(), gps.altitude.isValid()), 40, 35);
    myOLED.print("SAT:", LEFT, 45);
    myOLED.print(String(gps.satellites.value()), 30, 45);
    myOLED.print("HDOP:", LEFT, 55);
    myOLED.print(String(gps.hdop.hdop(), gps.hdop.isValid()), 30, 55);


    //здесь может быть любое ваше действие
  }

  if (regim == 4) //четвертый режим
  {
    myOLED.setFont(SmallFont);
    myOLED.print("( )", LEFT, 0);
    myOLED.print(String(gps.satellites.value()), 6, 0);
    myOLED.print("INFO", CENTER, 0);
    myOLED.print("||||", RIGHT, 0);
    myOLED.print("TIME:", LEFT, 15);
    myOLED.print(String(gps.time.hour()), 30, 15);
    myOLED.print(":", 43, 15);
    myOLED.print(String(gps.time.minute()), 48, 15);
    myOLED.print("DATE:", LEFT, 25);
    myOLED.print(String(gps.date.day()), 30, 25);
    myOLED.print(".", 43, 25);
    myOLED.print(String(gps.date.month()), 48, 25);
    myOLED.print(".", 58, 25);
    myOLED.print(String(gps.date.year()), 64, 25);
    myOLED.print("POINT: 29322", LEFT, 35);
  }
  myOLED.update();




  last = millis();
  Serial.println();
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Цель оптимизации? Каких показателей нужно достичь?

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

ЕвгенийП пишет:

Цель оптимизации? Каких показателей нужно достичь?

Динамической памяти освободить, еще будут перемнные а памяти ужа занято много

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Все строки - в макрос F() обернуть, тогда будут в PROGMEM, и RAM жрать не будут. Переменную regim - на один байт можно скостить, т.е. вместо int - int8_t. Переменная flag - также, прописать bool.

iwizard7
iwizard7 аватар
Offline
Зарегистрирован: 30.04.2013

DIYMan пишет:

Все строки - в макрос F() обернуть, тогда будут в PROGMEM, и RAM жрать не будут. Переменную regim - на один байт можно скостить, т.е. вместо int - int8_t. Переменная flag - также, прописать bool.

 

Спасибо, надо почитать про макрос

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

iwizard7 пишет:

Динамической памяти освободить, еще будут перемнные а памяти ужа занято много

Так я и спрашиваю "сколько освободить"? Какова цель?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Можно освободить 1 кбайт, если заменить библиотеку экрана на ту, что не использует экранный буфер.

renoshnik
Offline
Зарегистрирован: 11.04.2013
#include <TinyGPS++.h> == парси строки самостоятельно, без этого костыля.
#include <SoftwareSerial.h>  ==  зачем это ? используй дефолтный сериал !