This should be a quick fix (tilt return to neutral)


I’m measuring tilt using an accelerometer (MPU6050). 5 positions are possible (left, right, forward, backward and neutral). Each position returns a value. What I would like is whenever a value for any tilted position is reached once, the sensor has to be brought back to neutral position and again to tilt to get a second value returned. Should be easy enough, right? For some reason anything I try results in no tilt returns…

Any help is much appreciated!
Here is the code:

#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"

MPU6050 accelgyro;

int16_t ax, ay, az;

int getTilt()
  // read raw accel measurements from device
  accelgyro.getAcceleration(&ax, &ay, &az);
  if (ax < -7000) 
    return 4;
  if (ax > 7000) 
    return 3;
  if (az < -7000)
    return 2; 
  if (az > 7000)
    return 1;    
   return 0;

// Array Filter to cancel out sensor fluctuations
int getTiltAverage() {
  int arrayLength = 20;
  int tiltValues[arrayLength];
  int zeros = 0,ones = 0, twos = 0, threes = 0, fours = 0;
  for (int i=0; i < arrayLength; i++) { tiltValues[i] = getTilt(); delay(15); }
  for (int i=0; i < arrayLength; i++) {
    switch (tiltValues[i]) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
  //90% of getTilt() returns has to be identical to rule out any unwanted fluctuations from the sensor
  if ((ones/arrayLength) > 0.9) return 1;
  if ((twos/arrayLength) > 0.9) return 2;
  if ((threes/arrayLength) > 0.9) return 3;
  if ((fours/arrayLength) > 0.9) return 4;
  if ((zeros/arrayLength) > 0.9) return 0;
  return -1;

Why do you have two getTilt() functions?

  if ((ones/arrayLength) > 0.9) return 1;

You don’t appear to be requesting floating-point arithmetic, so the test for > 0.9 isn’t likely to work.

@Nick Gammon: Without the array filter, a small bump to the sensor already returned a treshold value. With this array, this problem was solved.

You have neglected to include the definitions of the global variables you use in your code. I will guess that your tilt sensor is returning float values.

If you want to smooth the returned values, you can just use an decaying average for each value you read from the sensor - that only needs one global/static variable for each value, and no re-reading.

The second part of your problem is that you want to wait until the input returns to center before you accept another input. To do that I'd define an enumerated type with values for each possible position, and a global/static variable holding the current reported position. Each time your function to read the state is called, you will read the device and recalculate the smoothed values, determine the instantaneous position (as an enumerated value) by comparing the smoothed values against your thresholds, and compare the instantaneous position against the reported position to decide whether to update the reported position. Finally, return the current reported position.

I'd implement that with one function to read the sensor and smooth the values, another function to do the threshold comparisons and return the position as an enumerated value, and finally the function which is called to update and return the currently reported position. All together you would be looking at about a dozen lines of code.

Why do you have two getTilt() functions?

That was a mistake while I copied the code, I edited my initial post with the correct code.

I've been searching for more clarity on global/static values, enumerated values and determining the instantanuous position for some time but I still have no idea hwo to do it. I don't even know where to start. Can anybody point me in the right direction or show me the way to some good examples from which I can get a better understanding and adapt it to my situation. I might be in above my head here... :~

Global variables are available to all functions (global scope and global lifetime).

Variables inside a function are only available to that function (local scope and local lifetime). Local lifetime means it is re-initialized every time through the function.

If a variable inside a function is declared static it now has global lifetime but still local scope.