BN-880 GPS\Compass Module - The Compass
Let's tackle the compass module of the BN-880 Gps/Compass Module.
The Code:
#include <Arduino.h>
#include <Wire.h>
#include "HMC5883L_Simple.h"
#include <U8g2lib.h>
#include <SPI.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
// Create a compass
HMC5883L_Simple Compass;
// The TinyGPS++ object
TinyGPSPlus gps;
U8G2_ST7920_128X64_1_SW_SPI u8g2(U8G2_R0, 13, 11, 10, 8);
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 9600;
char zs[32] = "";
int x = 0;
int y = 0;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
void setup()
{
Serial.begin(115200);
ss.begin(GPSBaud);
Wire.begin();
u8g2.begin();
u8g2.clearBuffer();
// Magnetic Declination is the correction applied according to your present location
// in order to get True North from Magnetic North, it varies from place to place.
//
// The declination for your area can be obtained from http://www.magnetic-declination.com/
// Take the "Magnetic Declination" line that it gives you in the information,
//
// Examples:
// Christchurch, 23° 35' EAST
// Wellington , 22° 14' EAST
// Dunedin , 25° 8' EAST
// Auckland , 19° 30' EAST
//
Compass.SetDeclination(1, 40, 'E');
// The device can operate in SINGLE (default) or CONTINUOUS mode
// SINGLE simply means that it takes a reading when you request one
// CONTINUOUS means that it is always taking readings
// for most purposes, SINGLE is what you want.
Compass.SetSamplingMode(COMPASS_CONTINUOUS);
// The scale can be adjusted to one of several levels, you can probably leave it at the default.
// Essentially this controls how sensitive the device is.
// Options are 088, 130 (default), 190, 250, 400, 470, 560, 810
// Specify the option as COMPASS_SCALE_xxx
// Lower values are more sensitive, higher values are less sensitive.
// The default is probably just fine, it works for me. If it seems very noisy
// (jumping around), incrase the scale to a higher one.
Compass.SetScale(COMPASS_SCALE_400);
// The compass has 3 axes, but two of them must be close to parallel to the earth's surface to read it,
// (we do not compensate for tilt, that's a complicated thing) - just like a real compass has a floating
// needle you can imagine the digital compass does too.
//
// To allow you to mount the compass in different ways you can specify the orientation:
// COMPASS_HORIZONTAL_X_NORTH (default), the compass is oriented horizontally, top-side up. when pointing North the X silkscreen arrow will point North
// COMPASS_HORIZONTAL_Y_NORTH, top-side up, Y is the needle,when pointing North the Y silkscreen arrow will point North
// COMPASS_VERTICAL_X_EAST, vertically mounted (tall) looking at the top side, when facing North the X silkscreen arrow will point East
// COMPASS_VERTICAL_Y_WEST, vertically mounted (wide) looking at the top side, when facing North the Y silkscreen arrow will point West
Compass.SetOrientation(COMPASS_HORIZONTAL_X_NORTH);
}
// Our main program loop.
void loop()
{
u8g2.firstPage();
float heading = Compass.GetHeadingDegrees();
do {
u8g2.setFont(u8g2_font_squeezed_r6_tr);
printInt(5, 15, gps.satellites.value(), gps.satellites.isValid(), 5);
printFloat(5, 25, gps.location.lat(), gps.location.isValid(), 10, 7);
printFloat(5, 35, gps.location.lng(), gps.location.isValid(), 10, 7);
printFloat(5, 45, heading, 1, 6, 3);
printDateTime(5,55, gps.date, gps.time);
} while ( u8g2.nextPage() );
smartDelay(500);
Serial.print("Heading: \t");
Serial.println( heading );
delay(1000);
}
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void printInt(int x, int y, unsigned long val, bool valid, int len)
{
char sz[32] = "*****************";
if (valid)
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
u8g2.drawStr(x, y, "Sats: ");
u8g2.drawStr(x+17, y, sz);
smartDelay(0);
}
static void printFloat(int x, int y, float val, bool valid, int len, int prec)
{
if (!valid)
{
while (len-- > 1)
u8g2.drawStr(x, y, '*');
u8g2.drawStr(x, y, ' ');
}
else
{
dtostrf(val, len, prec, zs);
u8g2.drawStr(x, y, zs);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i=flen; i<len; ++i)
u8g2.drawStr(x, y, ' ');
}
smartDelay(0);
}
static void printDateTime(int x, int y, TinyGPSDate &d, TinyGPSTime &t)
{
if (!d.isValid())
{
u8g2.drawStr(x, y, "Time: ********** ");
}
else
{
char sz[32];
sprintf(sz, "GMT Time: %02d/%02d/%02d : %02d:%02d:%02d", d.month(), d.day(), d.year(), t.hour(), t.minute(), t.second());
u8g2.drawStr(x, y, sz);
}
smartDelay(0);
}
じゃまた
0 comments:
Post a Comment