Project tutorial

Simple Inclinometer with Arduino © CC BY-NC-ND

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

  • 5,429 views
  • 1 comment
  • 18 respects

Components and supplies

Apps and online services

About this project

This project is about a simple inclinometer featuring auto rotation of display.

This inclinometer can be rotated in any position keeping the digits readable even upside down!

It is controlled by an Arduino 101 driven by accelerometers to read the tilt angle of X-Y axes.

Additionally, there is a feature to show the ambient temperature in Celsius or in Fahrenheit degrees.

The assemble is very simple and I hope you have fun using it!

Video

1) Material List

Arduino 101:

This version of the Arduino is no longer produced despite having interesting features such as temperature sensor, 6-axis accelerometer, gyroscope, temperature sensor and bluetooth on board.

It is very useful for this project avoiding an external MPU.

Multi-Function Shield (MFD):

The MFD can simplify and speed up the prototype development.

Main features:

  • 4 digit 7-segment LED display module driven by two serial 74HC595's
  • 4 x surface mount LED's in a parallel configuration
  • 10K adjustable precision potentiometer
  • 3 x independent push buttons
  • Piezo buzzer
  • DS18B20 temperature sensor interface
  • LM35 temperature sensor interface
  • Infrared receiver interface
  • Serial interface header for convenient connection to serial modules such as Bluetooth, wireless interface, voice module, a voice recognition module, etc.

2) Assembly

The assembly is very simple and it is not necessary any schematics.

Just insert the multi-function shield into Arduino taking care with the pinouts to avoid any demage during insertion.

Note: This project can be updated to any Arduino model using an external MPU-6050 breakout.

3) Setup

There are 3 buttons to setup the inclinometer:

  • Left button: Select the working mode.

a) Auto axis - In this mode, the axis (X or Y) to measure the inclination degrees is selected automatically by the internal gyroscope.

b) X-Axis - Show only the angles of axis X.

c) Y-Axis - Show only the angles of axis Y.

d) Temperature - Show the ambient temperature in Celsius or Fahrenheit.

  • Center button: Set the zero degree reference of X and Y axis. When Temperature Mode is selected, this button set the temperature scale (ºC or ºF).

  • Right button: Reset the reference of axis to original angles.

Note:

The X-axis is indicated in the display by the char "=" and the Y-axis by the char "| |".

The range of angles for tilt reading is -90° to + 90°.

4) Transfer Function

The main functions of code are:

  • Reading of accelerometers inclination angles.
  • Calculation of the transfer function of upside down effect for the 7-seg LED display.

With the angles is possible to detect the spacial position of the device to decide what routine will be released:

  • Front View - Inclinometer Stand Up
  • Front View - Inclinometer Upside Down

The transfer function for the display of 7-seg (A to F) works as follows:

A to D, B to E, C to F, D to A, E to B, F to C, G to G

To complete the upside down effect is necessary to invert the sequence of characters on the display:

From: 1, 2, 3, 4

To: 4, 3, 2, 1

Code

Inclinometer_with_Multi-Shield_and_Arduino_101_V1_2.inoArduino
Code for Arduino 101
/*
 * 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;
  }

}

Comments

Similar projects you might like

Simple UNO calculator

Project tutorial by Joprp05

  • 6,352 views
  • 0 comments
  • 6 respects

(Updated) Digital Clock w/ Mirrored Display for UNO-R3 & 101

Project tutorial by LAGSILVA

  • 993 views
  • 0 comments
  • 3 respects

Simple Arduino Uno - ESP 8266 Integration

Project tutorial by circuito.io team

  • 93,134 views
  • 23 comments
  • 75 respects

Simple wall clock using Adafruit 1/4 60 Ring Neopixel

Project tutorial by antiElectron

  • 6,691 views
  • 0 comments
  • 34 respects

A Simple Interactive Project with Processing on SBC

Project tutorial by Haoming Weng

  • 1,207 views
  • 0 comments
  • 5 respects
Add projectSign up / Login