Hello,
I'm currently developing a GPS Tracker based on ATMega328, a GPS Module u-blox NEO-6M-V2 and a LCD screen.
My project has a button to select the information I show on the display. The GPS send the data every 30sec using SoftwareSerial.
I use interrupt to manage button push (using variable "selectedMode" that i increment on each push).
The interrupt is also triggered when the GPS sends information.
The problem : sometimes the variable "selectedMode" goes to 0 so my display goes to the 1st page event if I don't push the button.
May it be the serial communication from the GPS that overflow and erase my variable ?
I don't see any reason ?
Here is my code (I removed some parts for brevity) :
#define F_CPU 16000000
#include <Ports.cpp>
#include <TinyGPS++.cpp>
#include <SoftwareSerial.cpp>
#include <LiquidCrystal.cpp>
#define MODE_OFF 4
// Set pins.
#define BUTTON_PIN 2 // The number of the push-button pin.
#define LCD_LIGHT_PIN A4 // The number of the pin where anode of the display backlight is.
#define LCD_LIGHT_ON_TIME 10000 // How long (in milliseconds) should lcd light stay on?
volatile int val; // variable for reading the pin status
volatile int val2; // variable for reading the delayed status
static const int RXPin = 12, TXPin = 0;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial gpsSerial(RXPin, TXPin);
byte interruptPin = 0;
unsigned int currentLcdLightOnTime = 0;
volatile byte selectedMode = 0;
volatile byte oldMode = -1;
const int sentenceSize = 64;
char gpsSentence[sentenceSize];
// Initialize the LiquidCrystal library with the numbers of the interface pins.
// LiquidCrystal(rs, e, d4, d5, d6, d7)
LiquidCrystal lcd(8, 9, 5, 6, 7, 3);
ISR(WDT_vect) {
Sleepy::watchdogEvent();
}
void modeSelectorInterrupt() {
val = digitalRead(BUTTON_PIN); // read input value and store it in val
delay(10); // 10 milliseconds is a good amount of time for debouncing
val2 = digitalRead(BUTTON_PIN); // read the input again to check for bounces
if (val == val2)
{
if (val == HIGH) {
++selectedMode;
if (selectedMode == MODE_OFF + 1)
{
selectedMode = 0;
}
}
}
}
// code removed
void readGps()
{
static int i = 0;
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (gpsSerial.available())
{
char ch = gpsSerial.read();
gps.encode(ch);
if (ch != '\n' && ch != '\r' && i < sentenceSize)
{
gpsSentence[i] = ch;
++i;
}
else
{
gpsSentence[i] = '\0';
i = 0;
//Serial.println(gpsSentence);
}
}
}
}
void getInfos()
{
readGps();
lcd.clear();
lcd.print(selectedMode);
lcd.print("-");
lcd.print(gpsSerial.overflow());
lcd.print("-");
switch (selectedMode) {
case 0:
LcdOn();
displayPosition();
break;
case 1:
LcdOn();
displayDateTime();
break;
case 2:
LcdOn();
displaySats();
break;
case 3:
LcdOn();
displaySpeed();
break;
case MODE_OFF:
LcdOff();
break;
}
}
void setup() {
gpsSerial.begin(9600);
// Set the lcd number of columns and rows.
lcd.begin(16, 2);
attachInterrupt(interruptPin, modeSelectorInterrupt, RISING);
// Set the push-button pin as an input.
pinMode(BUTTON_PIN, INPUT);
// Set the lcd display backlight anode pin as an output.
pinMode(LCD_LIGHT_PIN, OUTPUT);
// Set the lcd display backlight anode pin to high - lcd light on.
digitalWrite(LCD_LIGHT_PIN, HIGH);
getInfos();
}
void loop() {
getInfos();
//delay(1000);
//Sleepy::loseSomeTime(60000);
Sleepy::powerDown();
}
Please help