LAGSILVA
Published © CC BY-NC-ND

Simple Inclinometer with Arduino

This project is about a simple inclinometer using Arduino 101 including temperature feature and auto rotation of display (upside down view).

BeginnerShowcase (no instructions)30 minutes16,970

Things used in this project

Hardware components

Arduino 101
Arduino 101
×1
Multi Function Shield
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Inclinometer_with_Multi-Shield_and_Arduino_101_V1_2.ino

Arduino
/*
 * Project:   Inclinometer with Arduino 101 and Multi-Function Shield
   Author:    LAGSILVA
   Hardware:  Arduino 101 / Multi-Function Shield
   Revision:  V1.2 (Including Temperature)
   Date:      02.Sep.2018
   License:   CC BY-NC-ND 4.0
             (Attribution-NonCommercial-NoDerivatives 4.0 International)
*/

#define SDA_PORT PORTD
#define SDA_PIN 5
#define SCL_PORT PORTD
#define SCL_PIN 6

#include <CurieTimerOne.h>
#include <CurieIMU.h>

// Module connection pins (Digital Pins)
#define LATCH_PIN 4                             // Arduino 101 conection on Pin #4  = Latch of Display Module
#define CLK_PIN 7                               // Arduino 101 conection on Pin #7  = Clock of Display Module
#define DATA_PIN 8                              // Arduino 101 conection on Pin #8  = Data of Display Module

#define BTN_1_PIN A1
#define BTN_2_PIN A2
#define BTN_3_PIN A3

//    Front:       Upside Down:
//      A               D
//     ----            ----
//  F |    | B      C |    | E
//     -G -            -G -
//  E |    | C      B |    | F
//     ----            ----
//      D               A
//

// Chars Code {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, = , ||, , C, F}

byte N[] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6, 0x28, 0x12, 0xC6, 0x9C, 0x8E};

int delayRefresh;
byte view;
unsigned long ti;
float AcX, AcY, AcZ, gX, gY, gZ;
int uniAngle, dezAngle;
int axis, angle, angleX, angleRefX, angleY, angleRefY, temp;
boolean axisX, axisY, tempStatus, tCelsius;


void setup() {

  pinMode(LATCH_PIN, OUTPUT);
  pinMode(CLK_PIN, OUTPUT);
  pinMode(DATA_PIN, OUTPUT);

  pinMode(BTN_1_PIN, INPUT);
  pinMode(BTN_2_PIN, INPUT);
  pinMode(BTN_3_PIN, INPUT);

  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);

  CurieTimerOne.start(180000, kbdRead);

  CurieIMU.begin();

  // Set the accelerometer range to 2G
  CurieIMU.setAccelerometerRange(2);

  // Set gyro range to 250/second
  CurieIMU.setGyroRange(250);

  view = 0;              // Front View (regular view as default)
  axisX = true;
  axisY = false;
  angleRefX = 0;
  angleRefY = 0;
  axis = 0;
  tempStatus = false;
  tCelsius = true;

}


void loop() {

  delayRefresh = 70;

  CurieIMU.readAccelerometerScaled(AcX, AcY, AcZ);            // Read Accelerometers (G = m/s/s)
  CurieIMU.readGyroScaled(gX, gY, gZ);                        // Read Gyro (/s)
  temp = (CurieIMU.readTemperature() / 512) + 13;             // Read the temperature in Celsius degrees (C)

  if (AcX < 0) {
    view = 0;                                                 // Front View (regular view)
  }

  if (AcX > 0) {
    view = 1;                                                 // Front View (Upside Down)
  }

  angleX = atan(AcX / AcZ) * 180 / PI - angleRefX;
  angleY = atan(AcY / AcZ) * 180 / PI - angleRefY;

  if ((abs(gY) > 5) && (abs(gX) < 2) && (axis == 0)) {
    axisX = true;
    axisY = false;
  }

  if ((abs(gX) > 5) && (abs(gY) < 2) && (axis == 0)) {
    axisX = false;
    axisY = true;
  }

  if (axisX) {
    angle = angleX;
  }

  if (axisY) {
    angle = angleY;
  }

  uniAngle = abs(int(angle)) % 10;
  dezAngle = abs(int(angle)) / 10;


  // Display the Angle (-XX) or Temperature (C / F)

  if (tempStatus == false) {

    ti = millis();                                                            // Initial time for blinking dot

    while ((millis() - ti) < delayRefresh) {                                  // Timer in miliseconds to refresh the display


      if (view == 0) {                                                        // Front View mode (1)
        if (angle < 0) {
          displayChars(2, view, 0);                                           // Display Minus Signal "-" at Digi 0
        }
        displayChars(N[abs(dezAngle)], view, 1);                              // Display Digit 1
        displayChars(N[abs(uniAngle)], view, 2);                              // Display Digit 2
        if (axisY) {
          displayChars(N[10], view, 3);                                       // Display Degree Symbol "||" for Y-axis
        }
        if (axisX) {
          displayChars(N[11], view, 3);                                       // Display Degree Symbol "=" for X-axis
        }
      }

      if (view == 1) {                                                        // Front Upside Down mode (2)
        if (angle < 0) {
          displayChars(2, view, 3);                                           // Display Minus Signal "-" at Digit 3
        }
        displayChars(N[dezAngle], view, 2);                                   // Display Digit 2
        displayChars(N[uniAngle], view, 1);                                   // Display Digit 1
        if (axisY) {
          displayChars(N[10], view, 0);                                       // Display Symbol "||" for Y-axis
        }
        if (axisX) {
          displayChars(N[11], view, 0);                                       // Display Symbol "=" for X-axis
        }
      }
    }
  }

  if (tempStatus == true) {

    if (!tCelsius) {                                                          // Temperature conversion - Celsius to Fahrenheit
      temp = temp * 9 / 5 + 32;
    }

    ti = millis();                                                            // Initial time for blinking dot

    while ((millis() - ti) < delayRefresh) {                                  // Timer in miliseconds to refresh the display

      if (view == 0) {                                                        // Front View mode (1)
        displayChars(N[temp / 10], view, 0);                                  // Display Digit 0
        displayChars(N[temp % 10], view, 1);                                  // Display Digit 1
        displayChars(N[12], view, 2);                                         // Display Digit 2 - Symbol ""
        if (tCelsius) {
          displayChars(N[13], view, 3);                                       // Display Degree Symbol "C"
        }
        else {
          displayChars(N[14], view, 3);                                       // Display Degree Symbol "F"
        }
      }

      if (view == 1) {                                                        // Front View mode (1)
        displayChars(N[temp / 10], view, 3);                                  // Display Digit 0
        displayChars(N[temp % 10], view, 2);                                  // Display Digit 1
        displayChars(N[12], view, 1);                                         // Display Digit 2 - Symbol ""
        if (tCelsius) {
          displayChars(N[13], view, 0);                                       // Display Degree Symbol "C"
        }
        else {
          displayChars(N[14], view, 0);                                       // Display Degree Symbol "F"
        }
      }

    }

    displayChars(0, 1, 0);                                                    // Clear Digit 0
    displayChars(0, 1, 1);                                                    // Clear Digit 1
    displayChars(0, 1, 2);                                                    // Clear Digit 2
    displayChars(0, 1, 3);                                                    // Clear Digit 3

  }

}


void displayChars(byte num, byte statusM, byte disp) {                        // Chars Display Routine

  if (statusM == 1) {                                                         // Front Upside Down
    num = ((num >> 2) << 5) | ((num >> 5 ) << 2) | (num & 2);
  }

  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLK_PIN, LSBFIRST, ~num);                                // Display number
  shiftOut(DATA_PIN, CLK_PIN, LSBFIRST, 128 >> disp);                         // Set Digit (0-1-2-3)
  digitalWrite(LATCH_PIN, HIGH);

}


void kbdRead() {                                                              // Push Buttons Reading

  if (!digitalRead(BTN_1_PIN)) {                                              // Set mode

    axis = (axis + 1) % 4;

    if (axis == 0) {                                                          // Set mode "auto view" (X & Y axis)
      tempStatus = false;
    }

    if (axis == 1) {                                                          // Set mode X-axis only
      axisX = true;
      axisY = false;
    }

    if (axis == 2) {                                                          // Set mode Y-axis only
      axisX = false;
      axisY = true;
    }

    if (axis == 3) {                                                          // Set Temperature mode
      tempStatus = true;
    }

  }

  if (!digitalRead(BTN_2_PIN) && !tempStatus) {                               // Set reference for X & Y axis
    angleRefX = angleX;
    angleRefY = angleY;
  }

  if (!digitalRead(BTN_2_PIN) && tempStatus) {                                // Set temperature scale (C or F) in temperature mode
    tCelsius = !tCelsius;
  }

  if (!digitalRead(BTN_3_PIN) && !tempStatus) {                               // Reset X & Y axis to original values/reference
    angleRefX = 0;
    angleRefY = 0;
  }

}

Credits

LAGSILVA

LAGSILVA

7 projects • 340 followers
Mechanical Engineer in automotive industry since 1989. Coding and Arduino are my hobbies.

Comments