I just got my new Arduino Mega to take advantage of the extra capabilities. I have upgraded to Arduino IDE 0015 and the IDE is set up correctly for the MEGA board.
I am building a GPS/compass unit using the GPS shield from Adafruit, a HMC6352 digital compass module and a 4x20 LCD with the LCD117 interface board from moderndevice.com
My code is working great on the Diecimila - compass works great, GPS is fine and the LCD displayss the correct output.
BUT - if I upload the sketch to the MEGA (upload is fine) and then try the MEGA (using the exact same pins on the GPS shield) then it doesn't work!!!
With the MEGA my sketch runs the "void setup()" function and then seems to die - it doesn't appear to enter the "void loop()".
Am I doing something wrong? Is this a known problem?
Here's my sketch - still a work in progress - if it'll help:
#include <SoftwareSerial.h>
#include <NewSoftSerial.h>
#include <Stdio.h>
#include <Wire.h>
// LCD variables
#define LcdRxPin 13 // LcdRxPin is immaterial - not used - just make this an unused Arduino pin number
#define LcdTxPin 3
SoftwareSerial LcdSerial = SoftwareSerial(LcdRxPin, LcdTxPin);
// end LCD variables
// GPS variables
NewSoftSerial GpsSerial = NewSoftSerial(0, 1);
#define GpsPwrPin 2
#define GPSRATE 4800
// GPS parser for 406a
#define BUFFSIZ 90 // plenty big
char buffer[BUFFSIZ];
char *parseptr;
char buffidx;
uint8_t hour, minute, second, year, month, date;
uint32_t latitude, longitude;
uint8_t groundspeed, trackangle;
char latdir, longdir;
char status;
// end GPS variables
// compass variables
int compassAddress = 0x42 >> 1;
int compassHeading;
int compassSWpin=4;
int compassWpin=5;
int compassNWpin=6;
int compassNpin=7;
int compassNEpin=8;
int compassEpin=9;
int compassSEpin=10;
int compassSpin=11;
// end compass variables
// initialise LCD
void initLcd(){
pinMode(LcdTxPin, OUTPUT);
LcdSerial.begin(9600); // 9600 baud is chip comm speed
LcdSerial.print("?G420");
delay(100); // pause to allow LCD EEPROM to program
LcdSerial.print("?Bff"); // set backlight to 40 hex
delay(100); // pause to allow LCD EEPROM to program
LcdSerial.print("?s6"); // set tabs to six spaces
delay(1000); // pause to allow LCD EEPROM to program
/* LcdSerial.print("?D0040E150404000000"); // N arrow
delay(200);
LcdSerial.print("?D10F03050910000000"); // NE arrow
delay(200);
LcdSerial.print("?D20004021F02040000"); // E arrow
delay(200);
LcdSerial.print("?D3000000100905030F"); // SE arrow
delay(200);
LcdSerial.print("?D40000000404150E04"); // S arrow
delay(200);
LcdSerial.print("?D5000000011214181E"); // SW arrow
delay(200);
LcdSerial.print("?D60004081F08040000"); // W arrow
delay(200);
LcdSerial.print("?D71E18141201000000"); // NW arrow
delay(200);
*/
LcdSerial.print("?c0"); // turn cursor off
delay(200);
LcdSerial.print("?f"); // clear the LCD
delay(1000);
LcdSerial.print("?x00?y0");
delay(100);
LcdSerial.print(" LCD Ready...");
delay(500);
}
// initialise GPS
void initGps(){
if (GpsPwrPin) {
pinMode(GpsPwrPin, OUTPUT);
}
pinMode(13, OUTPUT);
GpsSerial.begin(GPSRATE);
digitalWrite(GpsPwrPin, LOW); // pull low to turn on!
LcdSerial.print("?x00?y1");
delay(100);
LcdSerial.print(" GPS Ready...");
delay(500);
}
void initCompass(){
// this for debugging the data
//Serial.begin(9600);
// set up
CLKPR = (1<<CLKPCE);
CLKPR = 0;
// initialize the HMC6352
Wire.begin(); // join i2c bus (compassAddress optional for master)
//
pinMode(compassSWpin, OUTPUT);
pinMode(compassWpin, OUTPUT);
pinMode(compassNWpin, OUTPUT);
pinMode(compassNpin, OUTPUT);
pinMode(compassNEpin, OUTPUT);
pinMode(compassEpin, OUTPUT);
pinMode(compassSEpin, OUTPUT);
pinMode(compassSpin, OUTPUT);
LcdSerial.print("?x00?y2");
delay(100);
LcdSerial.print(" Compass Ready...");
delay(500);
}
// setup
void setup(){
initLcd();
delay(1000);
initGps();
delay(1000);
initCompass();
delay(2000);
}
// main
void loop()
{
uint32_t tmp;
readline();
// check if $GPRMC (global positioning fixed data)
if (strncmp(buffer, "$GPRMC",6) == 0) {
// hhmmss time data
parseptr = buffer+7;
tmp = parsedecimal(parseptr);
hour = tmp / 10000;
minute = (tmp / 100) % 100;
second = tmp % 100;
parseptr = strchr(parseptr, ',') + 1;
status = parseptr[0];
parseptr += 2;
// grab latitude & long data
// latitude
latitude = parsedecimal(parseptr);
if (latitude != 0) {
latitude *= 10000;
parseptr = strchr(parseptr, '.')+1;
latitude += parsedecimal(parseptr);
}
parseptr = strchr(parseptr, ',') + 1;
// read latitude N/S data
if (parseptr[0] != ',') {
latdir = parseptr[0];
}
// longitude
parseptr = strchr(parseptr, ',')+1;
longitude = parsedecimal(parseptr);
if (longitude != 0) {
longitude *= 10000;
parseptr = strchr(parseptr, '.')+1;
longitude += parsedecimal(parseptr);
}
parseptr = strchr(parseptr, ',')+1;
// read longitude E/W data
if (parseptr[0] != ',') {
longdir = parseptr[0];
}
// groundspeed
parseptr = strchr(parseptr, ',')+1;
groundspeed = parsedecimal(parseptr);
// track angle
parseptr = strchr(parseptr, ',')+1;
trackangle = parsedecimal(parseptr);
// date
parseptr = strchr(parseptr, ',')+1;
tmp = parsedecimal(parseptr);
date = tmp / 10000;
month = (tmp / 100) % 100;
year = tmp % 100;
LcdSerial.print("?f");
LcdSerial.print("?x00?y0");
char datetime[17];
sprintf(datetime,"%02d/%02d/%02d %02d:%02d:%02d",date,month,year,hour,minute,second);
LcdSerial.print(datetime);
LcdSerial.print("?x00?y1");
//char latitude[13];
//sprintf(latitude,"%s %02do%02d'%2d.$2d\"",latdir,
LcdSerial.print(latdir);
LcdSerial.print(' ');
LcdSerial.print(latitude/1000000, DEC);
LcdSerial.print("o");
LcdSerial.print((latitude/10000)%100, DEC);
LcdSerial.print('\'');
LcdSerial.print((latitude%10000)*6/1000, DEC);
LcdSerial.print('.');
LcdSerial.print(((latitude%10000)*6/10)%100, DEC);
LcdSerial.print('"');
LcdSerial.print("?x00?y2");
LcdSerial.print(longdir);
LcdSerial.print(' ');
LcdSerial.print(longitude/1000000, DEC);
LcdSerial.print("o");
LcdSerial.print((longitude/10000)%100, DEC);
LcdSerial.print('\'');
LcdSerial.print((longitude%10000)*6/1000, DEC);
LcdSerial.print('.');
LcdSerial.print(((longitude%10000)*6/10)%100, DEC);
LcdSerial.print('"');
Wire.beginTransmission(compassAddress);
Wire.send('A');
Wire.endTransmission();
delay(10);
Wire.requestFrom(compassAddress, 2);
if(2 <= Wire.available()) // if two bytes were received
{
compassHeading = Wire.receive(); // receive high byte (overwrites previous compassHeading)
compassHeading = compassHeading << 8; // shift high byte to be high 8 bits
compassHeading += Wire.receive(); // receive low byte as lower 8 bits
compassHeading /= 10;
lightNorth(compassHeading);
//Serial.println(compassHeading); // print the compassHeading
}
}
}
uint32_t parsedecimal(char *str) {
uint32_t d = 0;
while (str[0] != 0) {
if ((str[0] > '9') || (str[0] < '0'))
return d;
d *= 10;
d += str[0] - '0';
str++;
}
return d;
}
void readline(void) {
char c;
buffidx = 0; // start at begninning
while (1) {
c=GpsSerial.read();
if (c == -1)
continue;
//Serial.print(c);
if (c == '\n')
continue;
if ((buffidx == BUFFSIZ-1) || (c == '\r')) {
buffer[buffidx] = 0;
return;
}
buffer[buffidx++]= c;
}
}
void lightNorth(int compassHeading){
digitalWrite(compassSWpin, LOW);
digitalWrite(compassWpin, LOW);
digitalWrite(compassNWpin, LOW);
digitalWrite(compassNpin, LOW);
digitalWrite(compassNEpin, LOW);
digitalWrite(compassEpin, LOW);
digitalWrite(compassSEpin, LOW);
digitalWrite(compassSpin, LOW);
if ((compassHeading>=338 && compassHeading<=360) || (compassHeading>=0 && compassHeading<23))
digitalWrite(compassNpin, HIGH);
else if (compassHeading>=23 && compassHeading<68)
digitalWrite(compassNEpin, HIGH);
else if (compassHeading>=68 && compassHeading<113)
digitalWrite(compassEpin, HIGH);
else if (compassHeading>=113 && compassHeading<158)
digitalWrite(compassSEpin, HIGH);
else if (compassHeading>=158 && compassHeading<203)
digitalWrite(compassSpin, HIGH);
else if (compassHeading>=203 && compassHeading<248)
digitalWrite(compassSWpin, HIGH);
else if (compassHeading>=248 && compassHeading<293)
digitalWrite(compassWpin, HIGH);
else if (compassHeading>=293 && compassHeading<338)
digitalWrite(compassNWpin, HIGH);
}