Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Walter Heger
Published © GPL3+

Inclinometer with Sony Spresense

Measure angle of your tool

BeginnerFull instructions provided8 hours161
Inclinometer with Sony Spresense

Things used in this project

Hardware components

Spresense boards (main & extension)
Sony Spresense boards (main & extension)
×1
6 DOF Sensor - MPU6050
DFRobot 6 DOF Sensor - MPU6050
×1
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
×1
Button
×1
Resistor 220 ohm
Resistor 220 ohm
×1
Magnet
×2

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Schematics

Code

main.ino

Arduino
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET     -1    // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_WIDTH   128   // OLED display width, in pixels
#define SCREEN_HEIGHT  64    // OLED display height, in pixels
#define SCREEN_ADDRESS 0x3C  // 0x3D for 128x64, 0x3C for 128x32
#define BUTTON_PIN     27    // input for button

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void initializeDisplay();
void loopDisplay();
void printAngle();

void initializeGyros();
void loopGyros();
const int MPU_addr=0x68;
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
int minVal=265;
int maxVal=402;
double x;
double y;
double z;

void initializeButton();
void loopButton();
double offset = 0;

const int numReadings  = 20;
double readings [numReadings];
int readIndex  = 0;
double smooth();

void setup(){
  Serial.begin(9600);

  initializeButton();
  initializeDisplay();
  initializeGyros();
}

void loop(){
  loopButton();
  loopGyros();
  loopDisplay();
  printAngle();
  delay(10);
}

// >>>>>>>>>>>> Display >>>>>>>>>>>>>>>

void initializeDisplay() {
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  } else {
    Serial.println(F("OLED display found"));
  }

  display.clearDisplay();

  display.setTextSize(4);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Hello, world!");
  display.display(); 
}

void loopDisplay() {
}

// <<<<<<<<<<<< Display <<<<<<<<<<<<<<<
// >>>>>>>>>>>> Gyros   >>>>>>>>>>>>>>>

void initializeGyros() {
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
}

void loopGyros() {
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);
  AcX=Wire.read()<<8|Wire.read();
  AcY=Wire.read()<<8|Wire.read();
  AcZ=Wire.read()<<8|Wire.read();
  int xAng = map(AcX,minVal,maxVal,-90,90);
  int yAng = map(AcY,minVal,maxVal,-90,90);
  int zAng = map(AcZ,minVal,maxVal,-90,90);
   
  x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
  y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
  z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);
   
  Serial.print(x);
  Serial.print(",");
  Serial.print(y);
  Serial.print(",");
  Serial.println(z);

  readings[readIndex] = z;
  readIndex++;
  if (readIndex == numReadings) { readIndex = 0; }
}

// <<<<<<<<<<<< Gyros <<<<<<<<<<<<<<<
// >>>>>>>>>>>> Button >>>>>>>>>>>>>>>

void initializeButton() {
  pinMode(BUTTON_PIN, INPUT);
}

void loopButton() {
  bool clicked = digitalRead(BUTTON_PIN);
  if (clicked) {
    offset = smooth();
  }
}

// <<<<<<<<<<<< Button <<<<<<<<<<<<<<<

void printAngle() {
  double real = abs(smooth() - offset);
  if (real > 180) { real = real - 180; }
  display.clearDisplay();
  // display.getInterface().flipHorizontal();
  display.setTextSize(1);
  display.setCursor(29, 0);
  display.println(F("Inclinometer"));
  display.setTextSize(1);
  display.setCursor(0, 16);
  display.println(real);
  display.setCursor(0, 32);
  display.println(z);
  display.setCursor(0, 48);
  display.println(offset);
  display.display(); 
}

double smooth() {
  double average;
  for (int i = 0; i < numReadings; i++) {
    average += readings[i];
  }
  average = average / numReadings;
  return average;
}

Credits

Walter Heger

Walter Heger

4 projects • 83 followers

Comments