Прошу помощи по коду

Тема в разделе "Arduino & Shields", создана пользователем AngelLeo, 28 сен 2016.

  1. AngelLeo

    AngelLeo Нуб

    Уважаемые знатоки ардуино есть 2 вопроса. Заранее оговорюсь я чайник в работе с ардуино, от свистка уже избавился но все еще многое не понимаю. Нужна помощь в коде с сонаром HC-SR04 и реле
    Код (C++):
    float dist_cm = ultrasonic.Ranging(CM); // Считываем дистанцию
    Serial.println(dist_cm); // Выводим в порт
    delay(10); // Делам задержку

    if (dist_cm < 20){
    digitalWrite(Relay1, LOW); // Включаем свет
    digitalWrite(Relay2, LOW); // Включаем вентилятор
    }

    if (dist_cm > 21){
    digitalWrite(Relay1, HIGH); // Выключаем свет
    digitalWrite(Relay2, HIGH);    // включаем/выключаем LED
    }
    }
    1 проблема: в том, что датчик показал себя не ахти часто бывают ложные значения к примеру
    все измеряется и тут случайно проскакивает 0
    195.00
    195.00
    0.00
    196.00
    197.00
    196.00
    происходит срабатывание реле.
    Как сделать для включения не 1 значение if (dist_cm < 20){ а хотя бы 3-5 последовательных значения, то есть если 3 или 5 раз подряд придет значение меньше 20 то включить в противном случае продолжить считывание.
    2 проблема: как на 2 реле вывести задержку минуты в 2 при выключении но так что бы сам цыкл loop продолжал работать.
    то есть зашел в помещение, включился свет и вентилятор, вышел свет сразу отключился а вентилятор еще пару минут работает, но в случае если допустим через минуту повторно зашел все заново включается и таймер вентилятор сбрасывается.
    Заранее спасибо всем кто откликнется.
    И еще раз оговорюсь я чайник в программировании.
     
    Последнее редактирование: 28 сен 2016
  2. Vetrinus

    Vetrinus Гик

    Код (C++):
    #include <Ultrasonic.h>
    #define array_size 20
    float distance[array_size]; //Объявляем массив для хранения замеров

    Ultrasonic us_1 (2, 3);

    void setup() {
      for (byte i = 0; i < 20; i++) {
        distance[i] = us_1.Ranging(CM); // заполняем его
      }
    }
    void loop() {
      distance[0] = us_1.Ranging(CM); // обновляем 0 индекс массива
      delay(150);
      byte previous = array_size - 2;
      byte current =  array_size - 1;
      for (byte i = 1; i < array_size; i++) { //Сдвигаем все значения массива на единицу
        distance[current] = distance[previous];
        previous--;
        current--;
      }
      bool leave = false;
      float temp;
      while (!leave) { //циклом сортируем массив, гуглить "сортировка пузырьком"
        leave = true;
        byte i = 0;
        for (byte counter = 0; counter < array_size-1; counter++) {
          if (distance[i] > distance[i + 1]) {
            temp = distance[i];
            distance[i] = distance[i + 1];
            distance[i + 1] = temp;
            leave = false;
          }
          i++;
        }
      }
      float Median = (distance[9] + distance[10]) / 2; //Рассчитываем медиану
    }

     
    Вот вам мой кейс, как я эту проблему решал.
    Решение о включении реле вычисляется по медиане из 20 замеров. Если недостаточно, то увеличьте значение array_size в начале программы.
     
    Tomasina нравится это.
  3. Onkel

    Onkel Гуру

    ну вообще-то с нулем надо разбираться. можно конечно его замедианить, но хороший стук себя покажет, если ошибка - она обязательно вылезет, в самый неподходящий момент. Скорее всего нуль от конфликта библиотек, в том числе и со встроенными ардуиновскими библиотеками.
     
  4. Vetrinus

    Vetrinus Гик

    Ну, вообще, как вариант, можно просто игнорировать ноль.
    По поводу паузы:
    Код (C++):
    #include <Ultrasonic.h>
    #define array_size 20
    #define two_min 120000
    float distance[array_size]; //Объявляем массив для хранения замеров
    unsigned long moment;

    Ultrasonic us_1 (2, 3);

    void setup() {
      for (byte i = 0; i < 20; i++) {
        distance[i] = us_1.Ranging(CM); // заполняем его
      }
    }

    void loop() {
      distance[0] = us_1.Ranging(CM); // обновляем 0 индекс массива
      delay(150);
      byte previous = array_size - 2;
      byte current =  array_size - 1;
      for (byte i = 1; i < array_size; i++) { //Сдвигаем все значения массива на единицу
        distance[current] = distance[previous];
        previous--;
        current--;
      }
      bool leave = false;
      float temp;
      while (!leave) { //циклом сортируем массив, гуглить "сортировка пузырьком"
        leave = true;
        byte i = 0;
        for (byte counter = 0; counter < array_size - 1; counter++) {
          if (distance[i] > distance[i + 1]) {
            temp = distance[i];
            distance[i] = distance[i + 1];
            distance[i + 1] = temp;
            leave = false;
          }
          i++;
        }
      }
      float Median = (distance[9] + distance[10]) / 2; //Рассчитываем медиану,
    //но не забудьте, при изменении размера пересчитать, какие именно индексы массива будут по середине.
      if (Median < 20) {
        digitalWrite(Relay1, LOW); // Включаем свет
        digitalWrite(Relay2, LOW); // Включаем вентилятор
        moment = millis();
        //У вас активный уровень - низкий?
      }

      if (Median > 21) {
        digitalWrite(Relay1, HIGH); // Выключаем свет
        if(millis()-moment > two_min){
          digitalWrite(Relay2, HIGH);
        }
      }
    }