Запись измерений в массив

Тема в разделе "Arduino & Shields", создана пользователем Vetrinus, 16 окт 2015.

  1. Vetrinus

    Vetrinus Гик

    Здравствуйте )
    Хочу записывать измерения с датчика HC-SR04 в массив, и после измерений, с этим массивом производить считывание переменных, и на основе этих переменных, принимать решение.
    Вот, что у меня есть сейчас:
    Код (C++):
    #include <Ultrasonic.h>
    float distance[5];
    Ultrasonic us_1 (8,9);
    void setup() {
      Serial.begin(9600);
      for (byte i=0; i<5; i++) {
      float distance=us_1.Ranging(CM);
      }
       for (byte i=0; i<5; i++) {
        Serial.print(distance[i]);
        Serial.print(" ");
        i++;
      }
    }
    void loop() {
    }
    Пока что у меня выводятся только нули. Что почитать, чтобы понять где косяк?
     
  2. AlexU

    AlexU Гуру

    https://yandex.ru/search/?lr=10758&text=c++ работа с массивами

    Вы в массив ничего не пишете. Первый цикл должен быть примерно таким:
    Код (C++):
    for (byte i=0; i<5; i++) {
      distance[i]=us_1.Ranging(CM);
    }
     
  3. AlexVS

    AlexVS Гик

    И учтите, что если вы оставите цикл работы с массивом в процедуре setup(), то он быть выполнен только 1 раз, после рестарта.
     
  4. Vetrinus

    Vetrinus Гик

    Да, это я знаю. Теперь другой вопрос. У меня возникла проблема с правильной реализацией чтения данных из массива и реагирования на них. Сейчас у меня это сделано таким образом:
    Код (C++):
    #include <Ultrasonic.h>
    float distance[5];
    Ultrasonic us_1 (8,9);
    void setup() {
      Serial.begin(9600);
      for (byte i=0; i<5; i++) {
      distance[i]=us_1.Ranging(CM);
    }
      pinMode(A3, OUTPUT);
    }
    void loop()
    {
      boolean control=true;
      for (byte i=0; i<5; i++) {
      distance[i]=us_1.Ranging(CM);
      delay(150);
    // Serial.println(distance[i]);
    } for (byte i=0; i<5; i++) {
        Serial.print(distance[i]);
        Serial.print(" ");
      for (byte i=0; i<5; i++) {
        if (distance[i]<15){
          control==false;
        }
      }
      if (control == true) {
        analogWrite(A3, 150);
      }
      else {
        digitalWrite(A3, LOW);
      }
    }
    }
     
    Но диод, напрямую подключенный к А3, почему-то не гаснет, когда я пододвигаю препятствие ближе 15 см. В чем проблема и как правильнее?
     
  5. AlexU

    AlexU Гуру

    Код (C++):
    for (byte i=0; i<5; i++) {
       if (distance[i]<15){
         control==false; // ОШИБКА!!!! Это не присвоение, а сравнение.
       }
    }
    PS: А Вы уверены, что Вам нужны массивы?
     
  6. Vetrinus

    Vetrinus Гик

    Мне нужно осваивать различные способы) В случае с 5 измерениями, не особо, но допустим если будет нужда увеличить количество измерений до n, то мне просто памяти не хватит писать в условиях if условия для всех n измерений)
     
  7. Megakoteyka

    Megakoteyka Оракул Модератор

    Что мешает в цикле опрашивать дальномер и сразу обрабатывать показания?
    Зачем хранить их в массиве?
     
  8. Vetrinus

    Vetrinus Гик

    Проблема в том, что иногда датчик выдает совершенно нереалистичные данные, и на их основе принимает решение. А потом, как только данные становятся реальными, вертает все обратно. Такие дергания мне не нужны совершенно. Поэтому я и хочу, чтобы решение принималось по массиву, причем, надо еще сделать, чтобы более новые измерения заменяли более старые значения без полного обновления массива. Надо еще помыслить над этим.
     
    Последнее редактирование: 17 окт 2015
  9. vvr

    vvr Инженерище

    зачем какие то массивы
    усредняем данные за какой то промежуток времени выкидывая макс скачки значений
     
  10. Vetrinus

    Vetrinus Гик

    Оп, уже интересно. А с помощью каких функций это делается?
     
  11. DrProg

    DrProg Вечный нерд

    Медиана. Расчитывайте ее один раз из, скажем 10 замеров.
     
    ИгорьК нравится это.
  12. Vetrinus

    Vetrinus Гик

    Вот, в общем, к чему я пришел
    Код (C++):
    #include <Ultrasonic.h>
    #define Deviation 3
    float distance[6];
    Ultrasonic us_1 (8, 9);
    void setup() {
      Serial.begin(9600);
      for (byte i = 0; i < 6; i++) {
        distance[i] = us_1.Ranging(CM);
      }
      pinMode(A3, OUTPUT);
    }
    void loop()
    {
      //boolean control=true;
      distance[0] = us_1.Ranging(CM);
      delay(150);
      byte previous = 4;
      byte current = 5;
      for (byte i = 1; i < 6; i++) {
        distance[current] = distance[previous];
        previous--;
        current--;
        for (byte i = 0; i < 5; i++) {
          Serial.print(distance[i]);
          Serial.print(" ");
        }
        Serial.println(" ");
      }
    }
     
    И теперь у меня есть два вопроса:
    Почему, когда я вывожу функцию передвижения значений в массиве отдельно, с помощью void
    Код (C++):
    distance[0]=us_1.Ranging(CM);
    delay(150);
    changeVal;
    for(byte i=0; i<5; i++) {
    Serial.print(distance[i]);
    Serial.print(" ");
    }
    Serial.println(" ");
    }
    void getAvegage() {

    }
    void changeVal() {
    byte previous=4;
    byte current=5;
    for (byte i=1; i<6; i++) {
    distance[current]=distance[previous];
    previous--;
    current--;
    }
    У перестает это адекватно работать?

    И второй, как мне реализовать отсев значений? К примеру, в новый массив - выборку, куда будут попадать только значения, отличающиеся от среднего значения(как его определять в начале работы? Что будет, если в это среднее значение попадет косячное измерение?) не более чем на 3(допустим) сантиметра.
     
  13. Vetrinus

    Vetrinus Гик

    Иными словами, относительно чего считать, прошел ли скачок измерения, или нет? Я очень смутно представляю, как сделать это надежным, кроме как при каждом перезапуске вручную подтверждать адекватность этого среднего значения
     
  14. DrProg

    DrProg Вечный нерд

    Вы читать умеете или только пишите как глухарь на току? Если лень спросить что такое медиана, погуглите ее в интернете и найдете ответ на вопрос как игнорировать "скачки измерения".
     
    ИгорьК нравится это.
  15. Vetrinus

    Vetrinus Гик

    Виноват, дурак, исправлюсь)))
    Вопрос века - можно ли медиану рассчитывать из ряда неупорядоченных значений? Вроде как дискретный ряд - это то, что нужно, но меня терзают смутные сомненья.
    А если нельзя, то нужна функция сортировки массива по возрастанию, которую я сделал вот так:
    Код (C++):
     void sort() {
          bool leave=false;
          float temp;
          while (!leave) {
            leave=true;
            for (byte counter=0; counter<9; counter++) {
              byte i=0;
              if (distance[i]>distance[i+1]) {
                temp=distance[i];
                distance[i]=distance[i+1];
                distance[i+1]=temp;
                i++;
                leave=false;
              }
            }
          }
    }
    Но которая, почему-то, не работает выдает нули. Как быть?
     
  16. DrProg

    DrProg Вечный нерд

    Медиану надо вычислять из упорядоченных значений, в этом и смысл. Сперва массив сортируют "по росту", потом берут среднее или одно из средних, если количество данных четное. Способов сортировки несколько, самый простой и понятный "пузырьком", то есть запускается цикл от 0 до кол-во элементов, внутри него еще один такой же цикл и сравнивается значение первого со вторым, если одно больше другого то меняются местами, если нет то нет. В итоге получается упорядоченные данные. Например:
    Код (C++):
    int massiv[10] // массив из 10 элементов

      int swap;
      for (byte i = 0; i <= 9; i++) {
        for (byte j = 0; j <= 9; j++) {
          if (massiv[i] < massiv[j]) {
            swap = massiv[i];
            massiv[i] = massiv[j];
            massiv[j] = swap;
          }
        }
     
     
    ИгорьК нравится это.
  17. Vetrinus

    Vetrinus Гик

    Сделал. Вот функция сортировки отдельно.

    Код (C++):
    bool leave=false;
          float temp;
          while (!leave) {
            leave=true;
            byte i=0;
            for (byte counter=0; counter<9; counter++) {
              if (distance[i]>distance[i+1]) {
                temp=distance[i];
                distance[i]=distance[i+1];
                distance[i+1]=temp;
                leave=false;
              }
             i++;
            }
          }
    Образец взят отсюда: http://cppstudio.com/post/457/

    Вроде все работает)

    Еще вопрос, почему, когда я пытаюсь запихнуть этот код в void(), это перестает работать?
    DrProg, спасибо, за инфу)
     
  18. DrProg

    DrProg Вечный нерд

    Скорее всего потому, что переменные не видны. Они должны быть глобальными или передаваться в качестве параметров.
     
    ИгорьК нравится это.
  19. Vetrinus

    Vetrinus Гик

    Блин. Вот, вывел переменные в глобальные.. Все равно не работает.. Что я забыл?
    Код (C++):
    #include <Ultrasonic.h>

    #define HIGH_LEVEL 15
    #define LOW_LEVEL 201
    #define Hole 9
    #define Osmos_OUT
    #define lenght 10 //Размер массива, можно изменять.

    float distance[lenght];
    float median_1;
    float median_2;
    byte update_step;
    byte sort_step;
    byte current = lenght-1;
    byte previous = current-1;
    byte sort_cycle_step;
    byte sort_parameter;

    Ultrasonic us_1 (8, 9);

    void setup() {
      Serial.begin(9600);
      for (byte i = 0; i < lenght; i++) {
        distance[i] = us_1.Ranging(CM);
      }
    }
    void update_() {
      byte current = lenght-1;
      byte previous = current-1;
      for (update_step = 1; update_step < lenght; update_step++) {
        distance[current] = distance[previous];
        previous--;
        current--;
      }
    }
    void loop()
    {
      distance[0] = us_1.Ranging(CM);
      delay(150);
      /*  Serial.println("Before update");
        for (byte i=0; i<lenght; i++) {
        Serial.print (distance[i]);
        Serial.print (" ");
      }
        Serial.println (" ");*/

      update_;
       bool leave=false;
          float temp;
          while (!leave) {
            leave=true;
            sort_parameter=0;
            for (byte counter=0; counter<lenght-1; counter++) {
              if (distance[sort_parameter]>distance[sort_parameter+1]) {
                temp=distance[sort_parameter];
                distance[sort_parameter]=distance[sort_parameter+1];
                distance[sort_parameter+1]=temp;
                leave=false;
              }
             sort_parameter++;
            }
          }
          float M1=(distance[4]+distance[5])/2;
        //  Serial.println(M1);
        Serial.println("After update");
      for (byte i=0; i<lenght; i++) {
        Serial.print (distance[i]);
        Serial.print (" ");
      }
        Serial.println (" ");
      }
     
     
  20. DrProg

    DrProg Вечный нерд

    Что именно не работает? Данные из массива в массив не копируются?
     
    ИгорьК нравится это.