Gadget, Strike and Dip

Strike and Dip Part IV

This post was originally published on September 22, 2017 at https://sparklechicken.net/channel/jakessbc

 

I know what you’re thinking. What happened to Part III? Well, Part III was a trash fire. So I scrapped most of the hardware design and the program and pretty much started from scratch. In the process, I swapped in a better display with integrated buttons, and an altimeter. The unit now gives strike, dip and altitude above sea level in meters. I’ve been doing some digging, and found a GPS unit that will be able to run concurrently with the other sensors and an SD card reader. By the time this bad boy is done, it will automagically give you strike, dip, dip direction, altitude, GPS coordinates, and a date stamp in a CSV file that you can load up into your GIS software.

Both the IMU and the altimeter run off of I²C, so they only need two pins on the Arduino to run both of them. The up and down buttons on the keypad turn the backlight on the display on and off.

This build requires:

Arduino Uno
ST7735 1.4″ TFT
9-DOF IMU L3GD20 + LSM303
MPL3115A2 Barometric Altimeter
Veleman 16×2 LCD Keypad Shield


#include <Adafruit_MPL3115A2.h>
#include <LiquidCrystal.h>
#include <Wire.h>

#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>
#include <Adafruit_L3GD20_U.h>
#include <Adafruit_9DOF.h>
#include <Adafruit_GFX.h>    // Core graphics library



/* Assign a unique ID to the sensors */
Adafruit_9DOF                dof   = Adafruit_9DOF();
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);
Adafruit_LSM303_Mag_Unified   mag   = Adafruit_LSM303_Mag_Unified(30302);
Adafruit_MPL3115A2 baro = Adafruit_MPL3115A2();
/* Update this with the correct SLP for accurate altitude measurements */
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
float p = 3.1415926;
float adjHeading = 0;
float adjStrike = 0;
/*set pins for Vubble Level */
int left = 13;
int level = 12;
int right = 11;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

/**************************************************************************/
/*!
    @brief  Initialises all the sensors used by this example
*/
/**************************************************************************/
void initSensors()
{
  if(!accel.begin())
  {
    /* There was a problem detecting the LSM303 ... check your connections */
    Serial.println(F("Ooops, no LSM303 detected ... Check your wiring!"));
    while(1);
  }
  if(!mag.begin())
  {
    /* There was a problem detecting the LSM303 ... check your connections */
    Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    while(1);
  }
  if (! baro.begin()) {
       Serial.println("Couldnt find sensor");
       return;
     }
}

/**************************************************************************/
/*!

*/
/**************************************************************************/
void setup(void)
{
  Serial.begin(115200);
  Serial.println(F("Adafruit 9 DOF Pitch/Roll/Heading Example")); Serial.println("");
  
  /* Initialise the sensors */
  initSensors();
  uint16_t time = millis();
  
  time = millis() - time;
  
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(0,0);
  lcd.print("Strike + Dip"); // print a simple message
  
}

/**************************************************************************/
/*!
    @brief  Constantly check the roll/pitch/heading/altitude/temperature
*/
/**************************************************************************/
void loop(void)
{
  sensors_event_t accel_event;
  sensors_event_t mag_event;
  sensors_vec_t   orientation;

  /* Calculate pitch and roll from the raw accelerometer data 
     and calculate heading from magnetometer*/
  accel.getEvent(&accel_event);
  mag.getEvent(&mag_event);
  if (dof.fusionGetOrientation(&accel_event, &mag_event, &orientation))
  {
    if (orientation.heading < 0)
    {
      adjHeading = 360 + orientation.heading;
    }
    else
    {
      adjHeading = orientation.heading;
    }
    
    
     float pascals = baro.getPressure();
  float altm = baro.getAltitude();
  float tempC = baro.getTemperature();
    /* 'orientation' should have valid .roll field 
       pitch will be represented by Vubble Level*/
    adjHeading = abs(360-adjHeading);
    lcd.setCursor(0,0);
    lcd.print("D:");
    lcd.print(abs(orientation.roll));
    lcd.print(" ");
    lcd.print("S:");
    lcd.print(adjHeading);
    lcd.setCursor(0,1);
    lcd.print("A:");
    lcd.print(altm);
    
    lcd_key = read_LCD_buttons();  // read the buttons
 
 switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnRIGHT:
     {
     break;
     }
   case btnLEFT:
     {
      lcd.print("Left");
     break;
     }
   case btnUP:
     {
     analogWrite(10, 100);
     break;
     }
   case btnDOWN:
     {
     analogWrite(10, 0);
     break;
     }
   case btnSELECT:
     {
     break;
     }
     case btnNONE:
     {
      lcd.print("       ");
     break;
     }
 }
  
}
}
int read_LCD_buttons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor
 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
 // we add approx 50 to those values and check to see if we are close
 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
 if (adc_key_in < 50)   return btnRIGHT; 
 if (adc_key_in < 195)  return btnUP;
 if (adc_key_in < 380)  return btnDOWN;
 if (adc_key_in < 555)  return btnLEFT;
 if (adc_key_in < 790)  return btnSELECT;  
 return btnNONE;  // when all others fail, return this...
}