Как добавить еще одно условие в цикл?

Я использую mpu6050 для подсчета подергиваний. Алгоритм подсчитывает пик/подергивание всякий раз, когда оно превышает пороговое значение. Теперь я хочу добавить, что алгоритм подсчитывает подергивание только тогда, когда оно превышает пороговое значение, и все подергивания в течение 90 секунд считаются как одно движение подергивания. Пожалуйста, помогите мне с этим. Также попробуйте интегрировать это в мой код.

Вот код:

#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;          // значение регистра необработанных данных температуры
char buffer[7];      // временный строковый буфер; используется с функцией dtostrf()
#define OUTPUT_READABLE_ACCELGYRO

#define LED_PIN 13
bool blinkState = false;

void setup() {

    // подключаемся к шине I2C (библиотека I2Cdev не делает этого автоматически)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    Serial.begin(115200);

    // инициализируем устройство
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();
    mpu6050.initialize();  // инициализируем сенсорный модуль MPU6050

    // проверяем соединение
    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
    +
        // отображение значений ускорения/гироскопа x/y/z, разделенных табуляцией
        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

    // мигать светодиодом для индикации активности
    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);

        // кал дергаться
        if (totave[i]>threshhold && flag==0) 
        {
            twitch=twitch+1;
            flag=1;
        }
        else if (totave[i] > threshhold && flag==1 )
        {
            //ничего не делать
        }
        if (totave[i] <threshhold  && flag==1 )
        {flag=0;}

        Serial.println('\n');
        Serial.print("twitch=");
        Serial.println(twitch);
    }

    //время с плавающей запятой=acc/100;
    //Serial.println(тим);
    delay(1000);
    // пошаговое вычисление(всего);
}

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


1 ответ


Лучший ответ:

0

Это можно сделать с помощью функции millis(). Он возвращает количество миллисекунд с момента запуска и может использоваться как простые часы. Возьмите оператор if, в котором вы увеличиваете twitch:

if (totave[i]>threshhold && flag==0) 
{
  if(millis()-last_twitch_timestamp > 90000){
    twitch=twitch+1;
    flag=1;
    last_twitch_timestamp = millis();
  }
}

Это проверит, прошло ли не менее 90 секунд (90000 мс) с момента последнего зарегистрированного подергивания (разница во времени между текущим временем и отметкой времени последнего подергивания). Если да, он зарегистрирует еще одно подергивание и сбросит отметку времени на текущее время (возвращаемое значение millis()). Это деактивирует регистрацию подергиваний на 90 секунд после каждого подергивания.

Чтобы это работало, вам нужно определить переменную last_twitch_timestamp в глобальном масштабе:

unsigned long last_twitch_timestamp = 90000;

Я инициализирую временную метку на 90000, чтобы можно было зарегистрировать самое первое подергивание. Если вы инициализируете его нулем, вам нужно будет подождать 90 секунд, пока не будет зарегистрировано первое подергивание.


Кстати: следующие задержки не имеют никакого смысла. Вы можете удалить их:

xaccl[i]=float(ax);
delay(1);
yaccl[i]=float(ay);
delay(1);

zaccl[i]=float(az);
delay(1);

И вы действительно должны соблюдать правильный отступ для всех строк. В Arduino IDE есть функция автоформатирования, которая упрощает работу с вами.

,

Благодарю за ваш ответ. Да, он считает все те подергивания, которые происходят в течение 90 с, как одно, но после 90 с он распознает следующее подергивание примерно через 5 с задержки. таким образом, эта 5-секундная задержка в подсчете повлияет на наши данные. Пожалуйста, помогите мне с этим., @zuni

Кроме того, как мы можем добавить, что подергивание засчитывается как одно в течение 90 с, но в течение этих 90 с должно быть минимум 4 движения., @zuni

@zuni Что вы подразумеваете под 5-секундной задержкой? Вы имеете в виду, что следующее подергивание распознается только через 95 с, а не через 90 с?, @chrisl

да можно сказать не сразу после 90х., @zuni

В вашем коде общая задержка составляет около 1,5 с. Это сокращает время вашей реакции. Если вам нужно более быстрое время реакции, вы должны полностью отказаться от вызовов задержки, перейдя к неблокирующему коду, как в примере BlinkWithoutDelay, @chrisl

хорошо, что помогло. пожалуйста, помогите мне с этим **Более того, как мы можем добавить, что подергивание считается как одно в течение 90 секунд, но в течение этих 90 секунд должно быть минимум 4 движения.**, @zuni

подсчитайте другую переменную прямо перед оператором millis if. Затем вы можете проверить это внутри оператора if и сбросить его там до нуля., @chrisl

вы бы написали синтаксис для этого ??, @zuni