I am using mpu6050 for counting the twitch movement. The algorithm is counting the peak/twitch whenever it goes above the threshold value. Now, I want to add that the algorithm count twitch only when it goes above threshold value and all the twitch within 90s are counted as one twitch movement. Kindly help me with this. Also try to integrate this in my code.
Here is the code:
#include "I2Cdev.h"
#include "MPU6050.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 accelgyro;
int16_t ax, ay, az;
float threshhold=5000.0;
float conmove=4;
const int sampletime=90000;
float xval[100]={0};
float yval[100]={0};
float zval[100]={0};
float xavg;
float yavg;
float zavg;
int twitch,flag=0;
MPU6050 mpu6050;
int16_t tr; // raw temperature data register value
char buffer[7]; // temporary string buffer; used with dtostrf() function
#define OUTPUT_READABLE_ACCELGYRO
#define LED_PIN 13
bool blinkState = false;
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
Serial.begin(115200);
// initialize device
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
mpu6050.initialize(); // initialize MPU6050 sensor module
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
pinMode(LED_PIN, OUTPUT);
calibrate();
delay(5000);
}
void loop() {
accelgyro.getAcceleration(&ax, &ay, &az);
tr = mpu6050.getTemperature();
#ifdef OUTPUT_READABLE_ACCELGYRO
+
// display tab-separated accel/gyro x/y/z values
Serial.print("a/g:\t");
Serial.print(ax); Serial.print("\t");
Serial.print(ay); Serial.print("\t");
Serial.print(az);
#endif
#ifdef OUTPUT_BINARY_ACCELGYRO
Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
#endif
// blink LED to indicate activity
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
int acc=0;
float totvect[100]={0};
float totave[100]={0};
float xaccl[100]={0};
float yaccl[100]={0};
float zaccl[100]={0};
for (int i=0;i<100;i++)
{
xaccl[i]=float(ax);
delay(1);
yaccl[i]=float(ay);
delay(1);
zaccl[i]=float(az);
delay(1);
totvect[i] = sqrt(((xaccl[i]-xavg)* (xaccl[i]-xavg))+ ((yaccl[i] - yavg)*(yaccl[i] - yavg)) + ((zval[i] - zavg)*(zval[i] - zavg)));
totave[i] = (totvect[i] + totvect[i-1]) / 2 ;
//acc=acc+totave[i];
Serial.println(totave[i]);
Serial.print("T = "); Serial.print(dtostrf(tr/340.0+36.53, 5, 1, buffer)); Serial.println(" °C");
// delay(200);
//cal twitch
if (totave[i]>threshhold && flag==0)
{
twitch=twitch+1;
flag=1;
}
else if (totave[i] > threshhold && flag==1 )
{
//do nothing
}
if (totave[i] <threshhold && flag==1 )
{flag=0;}
Serial.println('\n');
Serial.print("twitch=");
Serial.println(twitch);
}
//float tim=acc/100;
//Serial.println(tim);
delay(1000);
// stepcal(totave);
}
void calibrate()
{
digitalWrite(13,HIGH);
accelgyro.getAcceleration(&ax, &ay, &az);
float sum=0;
float sum1=0;
float sum2=0;
for (int i=0;i<100;i++)
{
xval[i]=float(ax);
sum=xval[i]+sum;
}
delay(100);
xavg=sum/100.0;
Serial.println(xavg);
for (int j=0;j<100;j++)
{
yval[j]=float(ay);
sum1=yval[j]+sum1;
}
yavg=sum1/100.0;
Serial.println(yavg);
delay(100);
for (int i=0;i<100;i++)
{
zval[i]=float(az);
sum2=zval[i]+sum2;
}
zavg=sum2/100.0;
delay(100);
Serial.println(zavg);
digitalWrite(13,LOW);
}
1 Answer 1
You can do this with the millis()
function. It returns the number of milliseconds since startup and can be used as a simple clock. Take the if statement, where you increment twitch
:
if (totave[i]>threshhold && flag==0)
{
if(millis()-last_twitch_timestamp > 90000){
twitch=twitch+1;
flag=1;
last_twitch_timestamp = millis();
}
}
This will check, if at least 90 seconds (90000ms) have passed since the last registered twitch (time difference between the current time and the timestamp of the last twitch). If yes, it will register another twitch and reset the timestamp to the current time (return value of millis()
). This deactivates twitch registering for 90s after each twitch.
For this to work, you need to define the last_twitch_timestamp
variable at global scope:
unsigned long last_twitch_timestamp = 90000;
I initialize the timestamp to 90000, so that the very first twitch can be registered. If you initialize it to zero, you would need to wait 90s, until the first twitch can be registered.
Btw: The following delays don't make any sense. You can remove them:
xaccl[i]=float(ax);
delay(1);
yaccl[i]=float(ay);
delay(1);
zaccl[i]=float(az);
delay(1);
And you should really really keep all lines indented correctly. The Arduino IDE has an autoformat feature to make it simpler for you.
-
thank you for your response. Yes,it is counting all those twitch that occurs within 90s as one but after 90s it recognize next twitch for approx after 5s delay. so, this 5 second delay in the count would effect the our data. kindly help me with that.zuni– zuni2020年01月21日 13:57:16 +00:00Commented Jan 21, 2020 at 13:57
-
Moreover, how can we add that the twitch is counted as one within 90s but there should be minimum 4 movements within that 90s.zuni– zuni2020年01月21日 14:03:25 +00:00Commented Jan 21, 2020 at 14:03
-
@zuni What do you mean by 5s delay?. Do you mean, that the next twitch is only recognized after 95s, but not after 90s?chrisl– chrisl2020年01月21日 14:42:34 +00:00Commented Jan 21, 2020 at 14:42
-
yes you can say not immediately after 90s.zuni– zuni2020年01月21日 19:03:34 +00:00Commented Jan 21, 2020 at 19:03
-
You have a total of about 1.5s delay in your code. That reduces your reaction time. If you need faster reaction time, you should ditch the delay calls totally, going to non-blocking code like in the
BlinkWithoutDelay
examplechrisl– chrisl2020年01月21日 19:08:55 +00:00Commented Jan 21, 2020 at 19:08