2023-05-21

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

Blog Archive

Contributors

CatWalker

CatWalker
CatWalker at 29