glennedi
Published © LGPL

ADXL345 accelerometer "screen orientation"

Can you keep it upright?

IntermediateFull instructions provided1,001
ADXL345 accelerometer "screen orientation"

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
SparkFun Triple Axis Accelerometer Breakout - ADXL345
SparkFun Triple Axis Accelerometer Breakout - ADXL345
×1
MAXX7219 Display unit
Generic single 8*8 LED display using the MAXX7219 chip
×1
4K7 resistor
×2
Stripboard 37*24 holes
×1
0.1 inch connector socket 15 way
For Nano
×2
0.1 inch connector socket 8 way
For ADXL345 (I suggest a right angle version)
×1
0.1 inch connector plug 5 way
For display connection
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Circuit board for Nano, accelerometer & display

Code

Screen rotation code

C/C++
/*
 * December 2021
 * 
 * Use adxl345 to rotate display through portrait and landscape modes depending on sensor orientation.
 * 
 * Sketch is based on Example -> Adafruit ADXL345 -> sensortest.ino
 * 
 * Orientation code source:
 * Datasheet AN3461 - 6 Selecting portrait and landscape modes 
 * https://www.nxp.com/docs/en/application-note/AN3461.pdf 
 * (checked Dec 2021)
 * 
 */

// Circuit:
//
// ADXL345 pinout
// Gnd to Gnd
// Vcc to +5v
// SDA to Nano pin A5
// SCL to Nano pin A4
//
// Resistors 
// 4K7 pullup resistor one end to Vcc the other to Nano pin A4
// 4K7 pullup resistor one end to Vcc the other to Nano pin A5
//
// MAXX7219 pinout
// Vcc to +5v
// Gnd to Gnd
// Din to Nano pin 10
// CS to Nano pin 11
// CLK to Nano pin 13


// Additional libraries used
// Adafruit Unified Sensor
// Adafruit ADXL345 
// These can be installed via Sketch -> Include Libraries -> Manage Libraries...  (you will need to be online)
// Installing Adafruit ADXL345 first will prompt for Adafruit Unified Sensor to be installed - you need both

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

#include <LedControl.h>
/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin xx is connected to the DataIn 
 pin xx is connected to the CLK 
 pin xx is connected to LOAD 
 We have only a single MAX72XX.
 */
// Matrix
#define PIN_DATAIN 11
#define PIN_CLK 13
#define PIN_LOAD 10 

LedControl lc = LedControl(PIN_DATAIN, PIN_CLK, PIN_LOAD, 1);

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

#define zero_x 1.569
 
#define zero_y 1.569
 
#define zero_z 1.569

void setup(void) 
{
#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif
  Serial.begin(9600);
  Serial.println("Accelerometer Test"); Serial.println("");
  
  /* Initialise the sensor */
  if(!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while(1);
  }

  /* Set the range to whatever is appropriate for your project */
  //accel.setRange(ADXL345_RANGE_16_G);
  // accel.setRange(ADXL345_RANGE_8_G);
  // accel.setRange(ADXL345_RANGE_4_G);
   accel.setRange(ADXL345_RANGE_2_G);

  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);
  
}

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  accel.getEvent(&event);


  
float xv;
float yv;
float zv;

xv=(event.acceleration.x-zero_x);
yv=(event.acceleration.y-zero_y);
zv=(event.acceleration.z-zero_z);


/*
 * The orientation code
 * 
 (|G pz | < 0.5g) AND (G px > 0.5g) AND (|G py | < 0.4g): Change orientation to Top
 (|G pz | < 0.5g) AND (G px < -0.5g) AND (|G py | < 0.4g): Change orientation to Bottom
 (|G pz | < 0.5g) AND (G py > 0.5g) AND (|G px | < 0.4g): Change orientation to Right
 (|G pz | < 0.5g) AND (G py < -0.5g) AND (|G px | < 0.4g): Change orientation to Left.
|x| means the absoulute value of x
ADXL345 sensor gives results in ms^2 but thr formula above requires result in g force so you need to convert the g values
0.4g=3.9ms^2
0.5g=4.9ms^2
Conversion source online conversion calculator: https://www.convertunits.com/from/g-unit/to/m/(s%5e2) 

*/


if ((abs(zv)  < 4.9) && (xv > 4.9)  && (abs(yv)  < 3.9)) {rotate_display('t');} //Change orientation to Top
if ((abs(zv)  < 4.9) && (xv < -4.9) && (abs(yv)  < 3.9)) {rotate_display('b');} //Change orientation to Bottom
if ((abs(zv)  < 4.9) && (yv > 4.9)  && (abs(xv)  < 3.9)) {rotate_display('r');} //Change orientation to Right
if ((abs(zv)  < 4.9) && (yv < -4.9) && (abs(xv)  < 3.9)) {rotate_display('l');} //Change orientation to Left.


delay(1000);
  
}// Loop end

// My functions
void rotate_display(char my_direction)
{
  lc.clearDisplay(0);
switch(my_direction){
  case 't':lc.setLed(0,7,4,true);lc.setLed(0,6,3,true);lc.setLed(0,6,5,true);break;//
  case 'b':lc.setLed(0,0,4,true);lc.setLed(0,1,3,true);lc.setLed(0,1,5,true);break;//
  case 'r':lc.setLed(0,4,7,true);lc.setLed(0,3,6,true);lc.setLed(0,5,6,true);break;///
  case 'l':lc.setLed(0,4,0,true);lc.setLed(0,3,1,true);lc.setLed(0,5,1,true);break;//
  }
      
  }

Credits

glennedi

glennedi

5 projects • 23 followers

Comments