Код для включения света по датчику приближения

Можно так:
#define if2(lo,val,hi) if ((lo) < val && val < (hi))
Можно и через inline, но тогда менее универсально.

ааааа
ну-ну :slight_smile:

С ходу не знаю, но думаю, что если покопать в сторону языков для аналитических вычислений, то что-нибудь найдётся.

я спицально для такого написал себе шаблонную функцию

bool Between(const T &AValue, const T AMin, const T AMax);
2 лайка

@TAPAH, в строках с 11 по 19 Вы по сути вычисляете среднее арифметическое. Для борьбы с внезапными выбросами это никудышнее решение. Гораздо лучше вычислять медиану.

Скорректировал. Но выход всё равно живет своей жизнью, включается и выключается с каким-то интервалом. При этом показания датчика не попадают в условия “if”:


const int relPin1 = 2; // Назначаю переменную на второй DI\DO
unsigned long int timing1; // Переменная для хранения точки отсчета
int Sensor1 = 0; // Добавляю переменную для датчика 1
int timer1; // Переменная для таймера

void setup() {
Serial.begin(9600);
pinMode(relPin1, OUTPUT); // Назначаю второй DI\DO выходом
}

void loop() {
Sensor1 = Sensor1 + analogRead(A1); // Т.к. показания датчика приблиения скачут, суммирую его показания, чтобы уменьшить ошибки
delay(500);
Sensor1 = Sensor1 + analogRead(A1);
delay(500);
Sensor1 = Sensor1 + analogRead(A1);
delay(500);
Sensor1 = Sensor1 + analogRead(A1);
delay(500);
Sensor1 = Sensor1 + analogRead(A1);
delay(500);
Serial.println(Sensor1);

if (Sensor1 > 2600 && Sensor1 < 4000) { 
    timing1 = millis(); // Присваиваю переменной "Таймер" значение времени на пройденного с момента запуска контроллера.
}
timer1 = millis() - timing1;
if (timer1 < 10000) {
        digitalWrite(relPin1, HIGH); // Включить выход 1 на 5 секунд
    }
else {
  digitalWrite(relPin1, LOW);
}
Sensor1 = 0;
Serial.println(Sensor1);
delay(500);

Датчик очень редко, но еще и какие-то мега высокие значения выдает ни с того ни с сего.

Я еще только начинающий в написание кода. Изучу вопрос и попробую через медиану, спасибо!

int тут - таймер бомбы замедленного действия.

Понял, спасибо! А long хватит?

Поменял на long, но выход всё равно живет своей жизнью.

нет. Тип переменной должен совпадать с типом счетчика миллис на вашем контроллере

Изменил переменную на unsigned long, но вот в чем проблема: через небольшой интервал времени millis() обнуляется. Т.е. не через 50 суток, а через несколько секунд или несколько десятков секунд.
Это приводит к тому, что такой код не работает:

timer1 = millis() - timing1;
if (timer1 < 10000) 

Поэтому, несмотря на то, что датчик не срабатывал, значение таймера всё равно попадает под интервал меньше 10сек.
Подскажите, пожалуйста, в чем может быть дело?

Миллис может обнулиться только на ресете.

1 лайк

Загрузил сейчас такой код:


const int relPin1 = 2; // Назначаю переменную на второй DI\DO
unsigned long timing1; // Переменная для хранения точки отсчета
long Sensor1 = 0; // Добавляю переменную для датчика 1
unsigned long timer1; // Переменная для таймера

void setup() {
Serial.begin(9600);
pinMode(relPin1, OUTPUT); // Назначаю второй DI\DO выходом
}

void loop() {
Sensor1 = Sensor1 + analogRead(A1); // Т.к. показания датчика приблиения скачут, суммирую его показания, чтобы уменьшить ошибки
delay(500);
Sensor1 = Sensor1 + analogRead(A1);
delay(500);
Sensor1 = Sensor1 + analogRead(A1);
delay(500);
Sensor1 = Sensor1 + analogRead(A1);
delay(500);
Sensor1 = Sensor1 + analogRead(A1);
delay(500);
Serial.println("Значение датчика: ");
Serial.println(Sensor1);

if (Sensor1 > 2600 && Sensor1 < 4000) { 
    timing1 = millis(); // Присваиваю переменной "Таймер" значение времени на пройденного с момента запуска контроллера.
}
delay(500);
Serial.println("время фикс: ");
Serial.println(timing1);
Serial.println("Время контроллера: ");
Serial.println(millis());
delay(500);
timer1 = millis() - timing1;
Serial.println("Разница времени: ");
Serial.println(timer1);
if (timer1 < 10000) {
        digitalWrite(relPin1, HIGH); // Включить выход 1 на 5 секунд
        Serial.println("Включить свет");
        
    }
else {
  digitalWrite(relPin1, LOW);
  Serial.println("Отдых");
}

Sensor1 = 0;
Serial.println(Sensor1);
delay(500);
}

Вот что на мониторе порта выводит:
12:48:48.815 → Значение датчика:
12:48:48.862 → 416
12:48:49.092 → время фикс:
12:48:49.092 → 0
12:48:49.092 → Время контроллера:
12:48:49.138 → 6393
12:48:49.604 → Разница времени:
12:48:49.650 → 6897
12:48:49.650 → Включить свет
12:48:49.650 → 0
12:48:51.781 → Значение датчика:
12:48:51.781 → 410
12:48:52.293 → время фикс:
12:48:52.293 → 0
12:48:52.293 → Время контроллера:
12:48:52.339 → 2488
12:48:52.803 → Разница времени:
12:48:52.803 → 2992
12:48:52.803 → Включить свет
12:48:52.849 → 0
12:48:55.224 → Значение датчика:
12:48:55.224 → 297
12:48:55.737 → время фикс:
12:48:55.737 → 0
12:48:55.737 → Время контроллера:
12:48:55.737 → 5921
12:48:57.684 → Значение датчика:
12:48:57.732 → 360
12:48:57.829 → время фикс:
12:48:57.829 → 0
12:48:57.829 → Время контроллера:
12:48:57.829 → 1420
12:48:58.172 → Разница времени:
12:48:58.218 → 1813

Время контроллера почему-то не постоянно растет, а то больше, то меньше.

Как-то вы интересно с миллисом работаете. Чем классика не устраивает?

if(millis() - timer1 >= 10000)
{
  timer1 = millis();

}
1 лайк

Запомните: всегда (от слова ВСЕГДА) в отладочных версиях (а там, где это ничему не мешает, то и окончательных) вставляйте в setup вывод чего-нибудь в Serial. Чего угодно - названия программы, версии, да хоть слова “кака” - чего-нибудь.

Тогда Вы сразу увидите, если контроллер перезагружается и не будете гадать почему millis обнулился.

1 лайк

У тебя что-то с питанием, видимо, не так (или контакт плохой, или коротит что-то, или ампер не хватает etc).
Не должно так быть, миллис всегда растёт (до переполнения).

Точно, спасибо!
Подключал сразу три датчика - не хватала сил все запитать через USB порт.
Теперь всё работает)

Спасибо! Помогло, увидел перезагрузку.