Уважаемые знатоки ардуино есть 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 продолжал работать. то есть зашел в помещение, включился свет и вентилятор, вышел свет сразу отключился а вентилятор еще пару минут работает, но в случае если допустим через минуту повторно зашел все заново включается и таймер вентилятор сбрасывается. Заранее спасибо всем кто откликнется. И еще раз оговорюсь я чайник в программировании.
Код (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 в начале программы.
ну вообще-то с нулем надо разбираться. можно конечно его замедианить, но хороший стук себя покажет, если ошибка - она обязательно вылезет, в самый неподходящий момент. Скорее всего нуль от конфликта библиотек, в том числе и со встроенными ардуиновскими библиотеками.
Ну, вообще, как вариант, можно просто игнорировать ноль. По поводу паузы: Код (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); } } }