DIY Arduino Inclinometer

 

inclinometer bannerHave you ever been off-roading and been on some crazy angle and wondered if you were about to roll??? Or are you just looking for bragging rights? I may have the solution for you!

I decided I wanted to check on my angles when 4wding and started looking at inclinometers but quickly worked out that you could buy either a cheap mechanical one or a really expensive one for lots of $$$$.”

You can download a phone app but most of them need the phone to be mounted level in a visible location which isn’t the easiest to do.

I decided to make my own Arduino version. I looked around online and came across some good examples but none that suited what I wanted. I have limited knowledge of programming so spent a good few days learning until I was able to get things like the OLED screen to even display some text.  Fast forward a few weeks and I had a working prototype which I tested in my vehicle for about a month.

Because I’m using an accelerometer as the sensor, it is affected by gravity and movement, so getting it to smoothly display the readings rather then jumping all over the place was difficult. When you are measuring angles in degrees, imagine how many degree changes there are just driving on a road. With the surface, the vehicle suspension etc. To make it read as smooth, a filter was applied to the sensor to try and counteract some of the movement.

Ok, I know what you are thinking… hurry up and just list the instructions so I can build one. Fair enough… here you go, enjoy I have now made this project Open Source!!!!


PARTS LIST

  • 0.96 Inch White SPI OLED Display Module 12864 LED For Arduino $9
  • GY-291 ADXL345 Digital 3-axis Acceleration of Gravity Tilt Module $3
  • ATmega328P Nano V3 Controller Board Compatible Arduino $5
  • LM2596 DC-DC Verstellbar Step-Down-Schaltregler Power Supply Module $2.50
  • 3.5-5.5V Standard Passive Buzzer Module For Arduino $5
  • MOGAMI 2844 Screened 4 Wire Ultra-flexible 32 AWG Signal Cable $10 per 30cm (can use any other wire you desire however this cable is so thin and malleable)

Total = $34.50 WOAH…

The cheapest place to buy all the electronics from other than the cable was Banggood


ARDUINO SOFTWARE

https://www.arduino.cc/en/main/software

(Download the ARDUINO 1.8.2 software for your computer, eg, windows, Mac etc.

ARDUINO LIBARIES

https://www.dropbox.com/s/f4ps4smmq29ohhz/Inclinometer%20libaries.zip?dl=0

These need to be added to the Arduino library before you can upload the code. Once these are added to the library close the program and re-open it for the libraries to be included.

ARDUINO CODE

https://www.dropbox.com/s/fh06dt3abtsnt3w/Inclinometer_pajero_sport.ino?dl=0

(Download the inclinometer code here, or, if you are having issues the raw code is at the bottom of this page).

 


ASSEMBLY INSTRUCTIONS

OLED

OLED pins          to          Arduino pins

  • OLED SDA                       D4
  • OLED SCL                       D3
  • OLED DC                         D5
  • OLED RESET                  D6
  • OLED VCC                       3v3 (I use the shield of the cable for power)

 

GY-291 ADXL345 (be careful when soldering as it only takes a little bit of heat to affect the calibration of the sensor)

Sensor               to            Arduino Pins

  • GND                                GND
  • VCC                                 3v3
  • CS                                    3v3
  • SDA                                 A4
  • SCL                                 A5

BUZZER

Buzzer              to            Arduino Pins

  • –                                        GND
  • S or +                               D8

LM2596 DC-DC

(This item is not needed if you are powering the Arduino from a USB 5v source)

  • Input – Vehicle 12v power +/-

LM2596               to          Arduino Pins

  • Out +                        VIN
  • Out –                         GND

To make it easy here is a drawing of my wiring.

Diagram1


SETTING YOUR OWN ANGLES

In the code there are 12 lines of code where you will need to set your own max / warning Pitch & Roll angles. Each of these lines have the following or similar at the end of their line to make it easy for you to locate and change

//CHANGE 40 TO YOUR DESIRED PITCH ANGLE//

For example you would change this


display.println(“Max 45”);display.setCursor(55,0);display.println(“Warn @ 38”); //CHANGE 45/38 TO YOUR DESIRED ROLL ANGLE//


to


display.println(“Max 40“);display.setCursor(55,0);display.println(“Warn @ 35“); //CHANGE 45/38 TO YOUR DESIRED ROLL ANGLE//


This will now give you a max angle of 40 and warn at 35 deg.

Now that you have it all wired up and you changed the angles to suit, you will need to flash the Arduino with the code that you downloaded and edited. Don’t forget to add the libraries otherwise the code will not work.  If you need help adding the libraries then click here.

Once the code is uploaded you should have a fully working inclinometer for your 4×4.

All you have to do is build it into your dash and mount the accelerometer level. Once it is mounted level there is no need to calibrate it, as it works on gravity.


Waiver of Liability

By downloading and using this inclinometer you release The Pajero Sport from all liability relating to injuries or damage that may occur if you rely on the inclinometer during any activity, etc. By downloading this code you agree to hold The Pajero Sport entirely free from any liability, including financial responsibility for injuries or damage incurred, regardless of whether injuries or damage are caused by negligence.

In other words… Use this at your own risk


 

Feel free to follow me on here and Instagram. If you make one please let me know or tag me on instagram (@the_pajero_sport). I would love to see your photos using the inclinometer.

 


Here is the (Inclinometer_pajero_sport.ino) Raw Code in case the download link does not work for some reason.


#include <Adafruit_SSD1306.h>

//If using software SPI (the default case):
#define OLED_MOSI 4
#define OLED_CLK 3
#define OLED_DC 5
#define OLED_CS 12
#define OLED_RESET 6

Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

#if (SSD1306_LCDHEIGHT != 64)
#define SSD1306_LCDHEIGHT 64
#error(“Height incorrect, please fix Adafruit_SSD1306.h!”);
#endif

//Arduino 1.0+ Only!
//Arduino 1.0+ Only!

#include <Wire.h>
//#include <ADXL345.h>

#include <SparkFun_ADXL345.h>

//#include <LCD.h>
//#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27 // <<—– Add your address here. Find it from I2C Scanner
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
//LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

ADXL345 adxl; //variable adxl is an instance of the ADXL345 library

int x,y,z;
float xg,yg,zg;
float soh;
float toh;
float tilt;
float climb;
float angle;
float angle1;
String dir;
String dir1;

uint8_t degree[8] = {140,146,146,140,128,128,128,128};

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
const float alpha = .5;

double fXg = 0;
double fYg = 0;
double fZg = 0;

void setup(){

adxl.setRangeSetting(16);

// Digital Pins for buzzer
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);

Serial.begin(9600);

// by default, we’ll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306_SWITCHCAPVCC);
// init done

// lcd.begin (16,2);
// lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
// lcd.setBacklight(HIGH);
// lcd.createChar(0, degree);
// lcd.home ();
// lcd.print(“Angle Meter”);
Serial.begin(9600);
adxl.powerOn();
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
// adxl.printAllRegister();
}

void loop(){
// Clear the buffer.
display.clearDisplay();

// text display tests
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(10,0);
display.println(“Max 45”);display.setCursor(55,0);display.println(“Warn @ 38”); //CHANGE 45/38 TO YOUR DESIRED ROLL ANGLE//
// text display tests
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(10,13);display.print(angle, 0);display.print(“\t”);display.setCursor(65,13);display.print(“Roll”);
// text display tests
display.setTextSize(2);
display.setTextColor(WHITE);
if ((angle> 38) && (angle< 90));display.setCursor(47,13);display.println(dir); //CHANGE 38 TO YOUR DESIRED ROLL ANGLE//

// text display tests
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(55,0);
if ((angle> 38) && (angle< 90)) display.println(” !WARNING! “); //CHANGE 38 TO YOUR DESIRED ROLL ANGLE//
if ((angle< -38) && (angle> -90)) display.println(” !WARNING! “); //CHANGE 38 TO YOUR DESIRED ROLL ANGLE//
if ((angle> 38) && (angle< 90)) tone(8,15); //CHANGE 38 TO YOUR DESIRED ROLL ANGLE//
if ((angle> 0) && (angle< 38)) noTone(8); //CHANGE 38 TO YOUR DESIRED ROLL ANGLE//
// text display tests
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(10,35);
display.println(“Max 45”);display.setCursor(55,35);display.println(“Warn @ 40”); //CHANGE 45/40 TO YOUR DESIRED PITCH ANGLE//

// text display tests
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(10,50);display.print(angle1, 0);display.print(“\t”);display.setCursor(65,50);display.print(“Pitch”);
// text display tests
display.setTextSize(2);
display.setTextColor(WHITE);
if ((angle> 38) && (angle< 90));display.setCursor(47,50);display.println(dir1); //CHANGE 38 TO YOUR DESIRED PITCH ANGLE//

// text display tests
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(55,35);
if ((angle1> 40) && (angle1< 90)) display.println(” !WARNING! “); //CHANGE 40 TO YOUR DESIRED PITCH ANGLE//
if ((angle1< -40) && (angle1> -90)) display.println(” !WARNING! “); //CHANGE 40 TO YOUR DESIRED PITCH ANGLE//
if ((angle1> 40) && (angle1< 90)) tone(9,15); //CHANGE 40 TO YOUR DESIRED PITCH ANGLE//
if ((angle1> 0) && (angle1< 40)) noTone(9); //CHANGE 40 TO YOUR DESIRED PITCH ANGLE//
display.setTextColor(BLACK, WHITE); // ‘inverted’ text
//display.println(3.141592);

display.setTextSize(2);
display.setTextColor(WHITE);
//display.print(“0x”);
//display.println(0xDEADBEEF, HEX);
display.display();
//delay(2000);
//display.clearDisplay();

//#define ADXL345_RANGE_2G

//adxl.setRange(ADXL345_RANGE_2G);

//Boring accelerometer stuff
double pitch, roll, Xg, Yg, Zg;
adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z

//Low Pass Filter
fXg = x * alpha + (fXg * (1.0 – alpha));
fYg = y * alpha + (fYg * (1.0 – alpha));
fZg = z * alpha + (fZg * (1.0 – alpha));

//Roll & Pitch Equations
roll = (atan2(-fYg, fZg)*180.0)/M_PI;
pitch = (atan2(fXg, sqrt(fYg*fYg + fZg*fZg))*180.0)/M_PI;

Serial.print(pitch);
Serial.print(“:”);
Serial.println(roll);
//xg = x*0.0039;
// yg = y*0.0039;
//zg = z*0.0039;
// Output x,y,z values – Commented out
//Serial.print(“X Value: “); Serial.print(xg);
//Serial.print(“, Y Value: “); Serial.print(yg);
//Serial.print(“, Z Value: “); Serial.println(zg);

soh = roll;//yg/zg;
tilt = roll;
if (abs(tilt) > 90) {
// lcd.setCursor (0,1);
// lcd.print(” “);
// lcd.setCursor (0,1);
// lcd.print(“Tilt:Range Error”);
}
else {
if (tilt < 0) {
dir = ((char)27);
angle = abs(tilt);
} else {
dir = ((char)26);
angle = tilt;
}

toh = pitch;//xg/zg;
climb = pitch;//atan(toh)*57.296;
if (abs(climb) > 90) {
// lcd.setCursor (0,1);
// lcd.print(” “);
// lcd.setCursor (0,1);
// lcd.print(“Tilt:Range Error”);
}
else {
dir1 = ((char)24);
if (climb < 0) {
angle1 = abs(climb);
} else {
dir1 = ((char)25);
angle1 = climb;
}
//Serial.print(“Tilt Angle is: “); Serial.print(tilt); Serial.println(” degrees.”);
delay(150);

}} }


 

 

11 thoughts on “DIY Arduino Inclinometer

  1. Thanks for sharing your project!

    I have installed Arduino IDE 1.8.2 but I am having issues with the library files. After downloading and installing the library files I receive compile errors.

    Adafruit_SSD1306.h:49:26: fatal error: Adafruit_GFX.h: No such file or directory
    #include

    So I downloaded the Adafruit-GFX library and copied the Adafruit_GFX.h file into the library file. Then I received the next error message when verifying the sketch.

    Adafruit_GFX.h:10:21: fatal error: gfxfont.h: No such file or directory
    #include “gfxfont.h”

    So I copied over the gfxfont.h file into the library file. Now I’m receiving the following error message.

    Wire.h:25:21: fatal error: variant.h: No such file or directory
    #include “variant.h”

    I do not know where to find the “variant.h” file. Could you help point me in the right direction?

    Thanks!!

    Like

    1. Hi Chris.
      Did you download and include the library? and have you tried just flashing the INO to the Arduino to see if that works? It looks like it has library issues and cant find some of the files..

      Like

  2. Yes, I downloaded the included library and installed it in the Arduino library. I’m just wondering if all of the necessary library files are contained in the dropbox library.

    Like

  3. Hi, Thank you for the code, work great, with little tweak i have made it work with oled and adxl345 both on I2C on arduino Nano.

    Like

      1. Hi, almost done, will share picture and the shematic as soon as i come back from work and install it in 10 days.

        Like

      2. Hi, it is installed on a Ford Escape 2010 AWD and work well, thank you, can’t find a way to send you directly a pic 😦

        Like

Leave a comment