Hi!
I have tried to figure this out myself but am a bit in above my head here.
What I already have is an arduino game of Simon Says (Simon. The memory game to test your concentration. Play my simon free online at www.freegames.ws) but instead of the 4 buttons I use tilt in 4 directions measured by an accelerometer (MPU6050). My problem is that when the sensor is tilted past the treshold it keeps returning values for that side or 'button'. What I want to achieve is that once the sensor is tilted and 1 value is returned, the sensor has to be returned into neutral position, before being able to return a second tilt value. For example: when the sequence is 'right-right-left' the movement of the sensor should be 'neutral-right-neutral-right-neutral-left-neutral'.
This is my code responsible for reading out and smoothing the sensor values:
#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:
zeros++;
break;
case 1:
ones++;
break;
case 2:
twos++;
break;
case 3:
threes++;
break;
case 4:
fours++;
break;
}
}
//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;
}
}
From the programming questions I received the following response but after looking into it, I am not able to implement this in my code:
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.
I really hope someone is willing to give me a hand here, so that I can get to the next step in my project. I would like to reward the helper while I am on a student budget but we will figure something out surely :).