1

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

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.

8
  • 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 Jan 21 '20 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 Jan 21 '20 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 Jan 21 '20 at 14:42
  • yes you can say not immediately after 90s. – zuni Jan 21 '20 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 example – chrisl Jan 21 '20 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.