Суммирование данных ацп. Гуру, помогайте!

Тема в разделе "Arduino & Shields", создана пользователем Jazzy, 2 апр 2017.

  1. Jazzy

    Jazzy Нерд

    Делаю устройство, измеряющее ускорение по одной из осей акселерометра и преобразующее его в числа от 0 до 200. Есть проблема, пока не додумался как решить полностью.

    Получаю данные с аналогового акселерометра.
    Данные изначально идут со значениями от ~400 до ~700.
    Чтобы получить данные об ускорении от 0 до 200, делаю "постоянное вычитание" из следующего значения АЦП предыдущее его значение.
    Даже работает!! =)

    А вот дальше задача усложняется!!
    НУЖНО эти значения в реальном времени суммировать по таймеру/счетчику. После привышения количества измерений(или времени) или после превышения критической суммы или по срабатыванию датчика, процесс должен "обнуляться", а значение суммы разбиваться от 0 до 200, видимо, используя "map".

    Получаем усредненные значения динамики акселерометра за промежуток времени кароче.
    Работать должно без delay, так как устройство вполне динамичное.


    За КРИВОЙ КОД сильно не пинайте!! Буду Очень признателен за помощь, может кто более изящное и простое решение подскажет!!!! Пиво какбэ и всё такое ; -)

    Может массив использовать или как-то еще...

    Использовал SoftwareSerial, чтобы "убрать" туда лишние значения, чтобы в Serial были числа от 0 до 200.
    Работает только так.
     

    Вложения:

    • 21.jpg
      21.jpg
      Размер файла:
      32,5 КБ
      Просмотров:
      540
    Последнее редактирование: 2 апр 2017
  2. Jazzy

    Jazzy Нерд

    #include <SoftwareSerial.h>

    unsigned long values;
    unsigned long values2;

    const int ledPin = 13;
    int axelZ = 1;
    int level = 0;

    SoftwareSerial Serial1 (20, 30);

    void setup() {
    Serial.begin(9600);
    Serial1.begin(9600);
    pinMode(axelZ, INPUT);
    pinMode(ledPin, OUTPUT);
    }

    void loop() {

    values = analogRead(axelZ);
    Serial1.println(values);
    values2 = analogRead(axelZ);
    Serial1.println(values2);

    int summa = ((values2) - (values));

    if(summa >= 0){
    level = summa;

    Serial.println(level);

    }
    }
    }
     
    Последнее редактирование: 3 апр 2017
  3. Tomasina

    Tomasina Сушитель лампочек Модератор

    Игорь, Ваш выход ;)
     
  4. Jazzy

    Jazzy Нерд

    Ну что, есть тут мускулистые мозги?
    Пиво теплеет..)
     
  5. serg_admin

    serg_admin Гик

    Ну примерно так таймер включается - пробуйте прикрутить
    Код (C++):

    ISR( TIMER1_COMPA_vect  )//каждую миллисекунду прибавлять 1 к milis
    {
    ...
    }

    TCCR1A = 0; // CTC mode - TOP значения таймера в регистресе OCR1A.
    TCCR1B = _BV(WGM12); // CTC mode.
    // Делитель частоты счетчика 8 (CS12:10 - 010).
    // При частоте 16 MHz - 0,5 мкС один такт.
    TCCR1B |= _BV(CS11);
    // Из расчета 0,5 мкС на такт, ставим длину таймера 25 мили секунд.
    // 40 раз в секунду. 50000 *0,5 = 25 000.
    OCR1A  = 50000;
    TIMSK1 = _BV(OCIE1A); // Включить прерывание TOP таймера.
    Там же можно и значение читать.

    Конкретнее параметры можно озвучить
     
    Jazzy нравится это.
  6. Jazzy

    Jazzy Нерд

    Первое СПАСИБО, serg_admin!!!!

    Пошел пробовать прикручивать)
     
  7. serg_admin

    serg_admin Гик

  8. Jazzy

    Jazzy Нерд

    Пока немного другим пошел путем. Подскажите, почему такие числа огромные получаются при вычитании значений старта и остановки таймера?
    Там максимум ~50мс временной интервал.

    Пытаюсь измерить время между, скажем, "нажатиями".

    Код (C++):

    int ledPin = 13;
    int buttonPin = 2;
     
    int buttonVal = 0;    
    int buttonState = 0;
    int bounceCheck = 0;

    unsigned long TimerStart;
    unsigned long TimerStop;

    void setup() {
      pinMode(buttonPin, INPUT);
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);
    }

    void loop(){
      buttonVal = digitalRead(buttonPin);     //read input value from button
      delayMicroseconds(250);                           //wait
      bounceCheck = digitalRead(buttonPin);   //check again
      if(buttonVal == bounceCheck){           //if val is the same then not a bounce
      if(buttonVal == HIGH && buttonState == 1) {   //check if the input is HIGH

      TimerStart = micros();

      digitalWrite(ledPin, LOW);         //turn LED OFF
      buttonState = 0;
    }

      if(buttonVal == LOW && buttonState == 0){

      TimerStop = micros();

      digitalWrite(ledPin, HIGH);       //turn LED ON
      buttonState = 1;

      Serial.println(TimerStart - TimerStop);

        }
      }
    }
     
    Последнее редактирование: 5 апр 2017
  9. rkit

    rkit Гуру

    Потому что вышли ниже нуля в беззнаковом числе.
     
    Jazzy нравится это.
  10. Jazzy

    Jazzy Нерд

    Благодарю за ответ, rkit!!
    Были в этом направлении догадки.. Пофиксил немного)

    Подскажите, как скорректировать данный код, чтобы при привышении заданного значения(например 2000) происходил сброс таймера?

    Код (C++):

    int buttonPin = 2;          
    int buttonVal = 0;              
    int buttonState = 0;      
    int bounceCheck = 0;
                     

    //int potPin = 0;            
    //int potVal = 0;          

    int ledPin = 13;          

    unsigned long Waiting = 1023;//величина выдержки

    unsigned long TimerStart;
    unsigned long TimerStop;
    void setup() {

      pinMode(buttonPin, INPUT);
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);      
    }

    void loop(){

      buttonVal = digitalRead(buttonPin);     //read input value from button
      delayMicroseconds(250);                           //wait
      bounceCheck = digitalRead(buttonPin);   //check again
      if(buttonVal == bounceCheck){           //if val is the same then not a bounce
      if (buttonVal == HIGH && buttonState == 1) {   //check if the input is HIGH

         TimerStart = micros();

          digitalWrite(ledPin, LOW);         //turn LED OFF
     
          buttonState = 0;
     
        }
        if(buttonVal == LOW && buttonState == 0){
     
          TimerStop = micros();
     
          digitalWrite(ledPin, HIGH);       //turn LED ON

          buttonState = 1;
     
     
          unsigned long M = ((TimerStop - TimerStart)/1000);
          Serial.println(M);

     

      }

      }

    }
     
     
    Последнее редактирование: 5 апр 2017
  11. Jazzy

    Jazzy Нерд

    Последний рывок! Поддержите)

    Как таймер сбросить-то после превышения заданного значения именно в этом коде?
     
  12. serg_admin

    serg_admin Гик

    Не совсем понял, что имеется ввиду.
    Может это:
    Код (C++):
    void loop(){
     if (((TimerStop - TimerStart)/1000) > 2000)
       TimerStart = micros();
     
    Jazzy нравится это.
  13. Jazzy

    Jazzy Нерд

    Вот так и пробую!!! Но в какую область не вставляю, не сбрасывается, либо "залипает" на 0 ...


    Наверное, нужны дополнительные условия к if, только вот какое???:

    void loop(){
    if((((TimerStop - TimerStart)/1000)>2000) && (дополнительное условие))
    TimerStart = micros();
     
    Последнее редактирование: 7 апр 2017
  14. serg_admin

    serg_admin Гик

    Покажи как вставляешь. Может где - нибудь ошибся.
     
  15. Jazzy

    Jazzy Нерд

    в void loop(){..

    пробовал вставлять после и перед :
    - buttonState = 0;
    - buttonState = 1;

    - сразу после void loop(){
    - где только не пробовал)

    Либо превышает значение, либо только 0


    Выкладывать "простыни" кода с примерами?
     
  16. serg_admin

    serg_admin Гик

    Ну выложи простыни. Почему нет? Или ссылку на файл.
    Просто должно работать, а если не видно код, то нельзя сказать почему не работает.
     
  17. Jazzy

    Jazzy Нерд

    Вот например:

    Код (C++):

    int buttonPin = 2;      
    int buttonVal = 0;          
    int buttonState = 0;  
    int bounceCheck = 0;
                 

    //int potPin = 0;        
    //int potVal = 0;      

    int ledPin = 13;        

    unsigned long Waiting = 2000;//величина выдержки

    unsigned long TimerStart;
    unsigned long TimerStop;
    void setup() {

      pinMode(buttonPin, INPUT);
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);    
    }

    void loop(){

      buttonVal = digitalRead(buttonPin);     //read input value from button
      delayMicroseconds(250);                           //wait
      bounceCheck = digitalRead(buttonPin);   //check again
      if(buttonVal == bounceCheck){           //if val is the same then not a bounce
      if (buttonVal == HIGH && buttonState == 1) {   //check if the input is HIGH

         TimerStart = micros();

          digitalWrite(ledPin, LOW);         //turn LED OFF

          buttonState = 0;

         if (((TimerStop - TimerStart)/1000) > 2000)
         TimerStart = micros();

        }
        if(buttonVal == LOW && buttonState == 0){
          TimerStop = micros();
          digitalWrite(ledPin, HIGH);       //turn LED ON

          buttonState = 1;
          unsigned long M = ((TimerStop - TimerStart)/1000);
          Serial.println(M);


      }

      }

    }
     
     
  18. serg_admin

    serg_admin Гик

    В твоем коде необходимо что бы выполнились условия
    Код (C++):
    if(buttonVal == bounceCheck){           //if val is the same then not a bounce
      if (buttonVal == HIGH && buttonState == 1) {
    Т.е. надо нажать кнопку. Но если нажать кнопку то таймер и так сбросится.
     
    Jazzy нравится это.
  19. Jazzy

    Jazzy Нерд

    Это да, таймер сбрасывается от нажатия. Но запускается до следующего нажатия.
    По сути происходит кратковременное нажатие - отжатие.)

    Как сделать, чтобы, если следующего нажатия не произошло, но таймер превысил значение 2000, чтобы он сбрасывался?

    Через "else if" как-то ?
     
    Последнее редактирование: 10 апр 2017
  20. serg_admin

    serg_admin Гик

    Код (C++):
    int buttonPin = 2;      
    int buttonVal = 0;          
    int buttonState = 0;  
    int bounceCheck = 0;
                 

    //int potPin = 0;        
    //int potVal = 0;      

    int ledPin = 13;      

    unsigned long Waiting = 2000;//величина выдержки

    unsigned long TimerStart;
    unsigned long TimerStop;
    void setup() {

      pinMode(buttonPin, INPUT);
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);  
    }

    void loop(){
         if (((TimerStop - TimerStart)/1000) > 2000)
         TimerStart = micros();
      buttonVal = digitalRead(buttonPin);     //read input value from button
      delayMicroseconds(250);                           //wait
      bounceCheck = digitalRead(buttonPin);   //check again
      if(buttonVal == bounceCheck){           //if val is the same then not a bounce
      if (buttonVal == HIGH && buttonState == 1) {   //check if the input is HIGH

         TimerStart = micros();

          digitalWrite(ledPin, LOW);         //turn LED OFF

          buttonState = 0;

       }
        if(buttonVal == LOW && buttonState == 0){
          TimerStop = micros();
          digitalWrite(ledPin, HIGH);       //turn LED ON

          buttonState = 1;
          unsigned long M = ((TimerStop - TimerStart)/1000);
          Serial.println(M);


      }

      }

    }
     
    Jazzy нравится это.