Здравствуйте! Хочу поделиться своими наработками. Я написал программу для управления освещением и вытяжкой в ванной, сделал сенсорное управление кранами на кухне и в ванной, а так же RGB светодиодной лентой для подсветки кухонного гарнитура. Я только начинаю изучать Arduino и программирование так что не судите строго. Может кому то пригодится или знающие люди подскажут может можно как-то оптимизировать код программы.
Логика работы сенсоров кранов: если поднести руки (или любой предмет) вода включится, после того как убрали руки вода выключится через 2 с. Если в зону действия сенсора на долго попал какой-то предмет, например поставили кастрюлю в раковину, вода выключится через 30 с. И включится только после того как предмет будет убран и сенсор будет активирован снова.
Логика управления освещением и вытяжкой: при открытии двери свет включается и начинается выдержка 40 с до выключения света. Если фиксируется движение, начало выдержки обновляется. При закрытии двери начинается выдержка 5 с, при которой не фиксируется движение. Я добавил эту выдержку потому, что иногда при выходе из ванной и закрытии двери срабатывает датчик движения и включается свет, когда в ванной никого нет. Когда защитная выдержка заканчивается, начинается фиксация движения. И если датчик движения сработал три раза до выключения света, свет останется включенным до открытия двери не зависимо будет ли дальнейшее движение или нет. После закрытия двери, если нет движения, свет выключится через 15 с.
Вытяжка включается/выключается шнурком с кнопкой. При выключении света, если вытяжка была включена, начинается отсчет выдержки (я сделал 10 мин) до ее выключения. Включение света во время 10ти минутной выдержки сбрасывает отсчет, он начнется заново после выключения света.
По началу я пробовал другой алгоритм работы освещения. Использовал два ИК сенсора и считал кол-во входящих/выходящих человек. Но так как сенсоры расположены на расстоянии 6 см (ширина дверной коробки) были ложные срабатывания. Может быть я еще не удачно выбрал высоту установки датчиков, все люди разного роста, еще датчик повторно срабатывал от заплетенных волос. А маленький ребенок вообще не мог выключить свет. Так что пришлось отказаться от такого управления светом.
Управление RGB лентой и её блоком питания я сделал с помощью переменного резистора. Программный код, с некоторыми переделками, я взял с сайта http://alexgyver.ru/arduino-algorithms/
Здравствуйте!
Я сделал сенсорное управление обычными смесителями на кухне и в ванной. Ручкой смесителя регулируется напор воды. Температура воды регулируется с помощью термостатического смесителя, его выход я подключил вместо горячей воды к смесителю на раковине.
Подача воды осуществляется с помощью клапана на подобии как в стиральной машине. Только я нашел на 12 В и с резьбой 1/2.
Включение клапана с помощью ИК сенсора.
Еще вопрос - на сколько громко срабатывают клапана и каково качество их изготовления?
Ну и фотки в студию! ))) В частности интересно было бы увидеть как вы примостили сенсоры вблизи крана ;)
Звук сработки клапанов такой же как на стиральной машине. Особо на него не обращаю внимания. Качество хорошее, работают уже около 3х месяцев. Термостатические смесители работают с 2015 года уже на второй квартире.
Фотки выложу позже. Сенсор я разместил в боковом сливном отверстии раковины. Но в новой квартире думаю перенести ИК диод и TSOP в корпус смесителя, чтобы не было срабатываний от противоположной стороны раковины. У меня стальная раковина и при настройке сенсора на сработку от рук в ценре раковины, и когда убираешь руки датчик начинает срабатывать отражаясь от противоположной стенки раковины. Поэтому пришлось уменьшить дальность до пропадания ложных срабатываний. Еще я заменил резистор для настройки дальности на многооборотный для большей точности.
1. В сливное отверстие вставлен обрезок маркера и загерметизирован. С одной стороны приклеен прозрачный пластик. Так что на сенсор влага не попадает. В работе около полугода.
2. Дверь обычная. На фото видна дверь шкафа купе в ванной. Свет выключается и при открытой двери, у меня через 40 сек, если PIR не срабатывает.
В будущем я буду монтировать ИК сенсор в смеситель. Сейчас пока все находится в режиме тестов.
У меня проем в 100 см пробивает без проблем, светодиод самособой выпаян и помещен напротив
в моем случае проем 120 см. грешу на датчики, в этот раз попались какие то странные - в неразобранном виде на максимуме регулятора срабатывают на препятствие только в пределах 10 см.
я думаю стоит воздержаться от покупок данного устройства вот у этого продавца:
действительно улучшают срабатывание ИК барьера. Стабильного срабатывания удалось достичь на 100 см. Далее уже требуется более точная настройка пары друг на друга. Точность срабатывания уменьшается по мере все более частого попадания солнечного света в помещение. Придется скорее всего переходить на лазер типа VL53L0XV2.
«Вы все ещё кипятите?» Безо всяких ИК барьеров ванная работает на ПИРах, туалет - ПИР и ИК дальномер (сверху вниз). Год работы без влезания в алгоритм по санузлу. Полет нормальный. Минимум вторжения в интерьер.
Мой вариант работы ИК датчиков в дверном проеме. Взял за основу один из кодов этой темы и переделал под прерывания дуни. На макете проверил все отрабатывает, в реальных условиях дверных не смотрел.
Так сам через пять минут выключится, если неподвижно медитировать. :)
А я наоборот люблю, с утра, не проснувшись, сидишь, а свет выключился. Если надо, шевельнулся и снова горит. Один датчик движения на потолке. А мучиться с этими барьерами и прочим, лишняя фигня, ИМХО
Я изменил программу. Теперь у меня светом в санузле управляют геркон и PIR. С помощью задержек я настроил программу так, что свет не выключится при закрытой двери даже если нет движения. Еще добавил сторожевой таймер.
boollamp; //переменная для хранения состояния освещения (вкл/выкл)
047
boolgerkon_flag; //вспомогательная переменная для хранения состояния сработки геркона
048
boolnoBody; //отсутствие людей в ванной
049
boolmotionClose; //переменная для индикации движения при закрытой двери
050
boolmotionOpen; //переменная для индикации движения при открытой двери
051
unsigned longlampOffTimeClose, lampOffTimeOpened, delayMotionOpened, delayMotionClosed, doorClosedNobody, lampOffTimeOpen; //переменные для хранения времени момента закрытия и открытия двери
052
//переменные для функции светодиодной индикации сработки датчика движения
Не открывается ссылка
А вы прям в али начните в поиске вбивать это название. Китайцы жгут.
Да уж, реально жгут - умный пирдатчик движения унитаза уф ... уточнение места
знаем где .com/item/PIR-16/32880924402.html
001
#define SENSOR1_PIN 2 //вход управления 1м электроклапаном
002
#define SENSOR2_PIN 3 //вход управления 2м электроклапаном
003
#define FLAP1_PIN 4 //выход управления 1м электроклапаном
004
#define FLAP2_PIN 5 //выход управления 2м электроклапаном
005
#define GERKON_PIN 6 //вход геркон
006
#define SENSOR_PIN 7 //вход датчик движения
007
#define LAMP_PIN 8 //выход управления освещением
008
#define R_PIN 9 //выход управления красным цветом
009
#define G_PIN 10 //выход управления зеленым цветом
010
#define B_PIN 11 //выход управления голубым цветом
011
#define RGB_POWER 12 //выход вкл/выкл БП для RGB
012
#define FAN_BUTTON_PIN 15 //вход управления вентилятором (кнопка)
013
#define FAN_PIN 16 //выход управления вентилятором
014
#define DEBOUNCE_DELAY 100 //время антидребезга кнопки вентилятора в мс
015
#define FAN_ON_TIME 10 //время работы вентилятора после выкл. света, мин
016
#define ON_FLAP1_ON 30 //время работы 1го клапана при активации сенсора, сек
017
#define ON_FLAP1_OFF 2 //время работы 1го клапана при деактивации сенсора, сек
018
#define ON_FLAP2_ON 30 //время работы 2го клапана при активации сенсора, сек
019
#define ON_FLAP2_OFF 2 //время работы 2го клапана при деактивации сенсора, сек
020
#define DEBOUNCE1_SENSOR 300 //задержка сработки для 1го электроклапана, мс
021
#define DEBOUNCE2_SENSOR 300 //задержка сработки для 2го электроклапана, мс
022
#define DELAY_LAMP_OFF_OPEN 40 //задержка выключения света после открытия двери, сек
023
#define DELAY_LAMP_OFF_CLOSE 15 //задержка выключения света после закрытия двери, сек
024
#define DELAY_DOOR_CLOSE 5 //задержка регистрации движения после закрытия двери, сек
025
#define DEBOUNCE_GERKON 80 //время антидребезга геркона в мс
026
#define INTERVAL 250 //интервал мигания светодиода индик. сработки датчика движения, мс
027
028
//переменные для управления кранами
029
unsigned
long
int
timeSensor1On, timeSensor1Off, timeSensor2On, timeSensor2Off;
030
bool
flap1On =
false
;
//переменная для хранения состояния 1го электроклапана
031
bool
flap2On =
false
;
//переменная для хранения состояния 2го электроклапана
032
bool
sensor1 = LOW;
//переменная для хранения состояния сенсора 1го электроклапана
033
bool
sensor2 = LOW;
//переменная для хранения состояния сенсора 2го электроклапана
034
bool
lastSensor1 = HIGH;
//переменная для хранения последнего состояния сенсора 1го электроклапана
035
bool
lastSensor2 = HIGH;
//переменная для хранения последнего состояния сенсора 2го электроклапана
036
//////////////////////////////////////////////////////////////////////////////////
037
038
//переменные для управления освещением
039
bool
lamp;
//переменная для хранения состояния освещения (вкл/выкл)
040
bool
gerkon_flag;
//вспомогательная переменная для хранения состояния сработки геркона
041
bool
sensor_flag;
//вспомогательная переменная для хранения состояния датчика движения
042
bool
motionClose;
//переменная для индикации движения при закрытой двери
043
bool
motionOpen;
//переменная для индикации движения при открытой двери
044
unsigned
long
doorClosedTime, doorOpenedTime, doorClosedDelay;
//переменные для хранения времени момента закрытия и открытия двери
045
//переменные для функции светодиодной индикации сработки датчика движения
046
unsigned
long
int
previousMillis = 0;
047
bool
ledMotionState;
048
byte
motionCount = 0;
049
////////////////////////////////////////////////////////////////////////////////////
050
051
//переменные для управления вентилятором
052
bool
fanState;
053
bool
fanButtonState;
054
bool
lastFanButtonState;
055
unsigned
long
int
lastDebounceTime = 0, fanButtonOffTime, workTime = (
long
)FAN_ON_TIME * 60 * 1000;
056
/////////////////////////////////////////////////////////////////////////////////////
057
058
//переменные для функции задержки (антидребезга) геркона
059
bool
_bounse3S = 1;
060
bool
_bounse3O = 1;
061
unsigned
long
_bounse3P = 0UL;
062
/////////////////////////////////////////////////////////////////////////////////////
063
064
//переменные для функций задержек (антидребезга) сенсоров электроклапанов
065
bool
_bounse1S = 1;
066
bool
_bounse1O = 1;
067
unsigned
long
_bounse1P = 0UL;
068
bool
_bounse2S = 1;
069
bool
_bounse2O = 1;
070
unsigned
long
_bounse2P = 0UL;
071
/////////////////////////////////////////////////////////////////////////////////////
072
073
//переменные для управления RGB
074
byte
bright = 100;
// яркость, от 0 до 100 (можно повесить на второй потенциометр при желании)
075
byte
R, G, B;
076
077
void
setup
() {
//конфигурация портов (вход или выход)
078
pinMode(SENSOR1_PIN, INPUT_PULLUP);
//подтягиваем вход к плюсу через внутренний резистор 20к
079
pinMode(FLAP1_PIN, OUTPUT);
080
pinMode(SENSOR2_PIN, INPUT_PULLUP);
081
pinMode(FLAP2_PIN, OUTPUT);
082
pinMode(GERKON_PIN, INPUT_PULLUP);
083
pinMode(LAMP_PIN, OUTPUT);
084
pinMode(SENSOR_PIN, INPUT);
085
pinMode(FAN_BUTTON_PIN, INPUT_PULLUP);
086
pinMode(FAN_PIN, OUTPUT);
087
pinMode(R_PIN, OUTPUT);
088
pinMode(G_PIN, OUTPUT);
089
pinMode(B_PIN, OUTPUT);
090
pinMode(RGB_POWER, OUTPUT);
091
pinMode(13, OUTPUT);
092
}
093
094
//управление светодиодной лентой RGB (взято с сайта <a href="http://alexgyver.ru/arduino-algorithms/" title="http://alexgyver.ru/arduino-algorithms/" rel="nofollow">http://alexgyver.ru/arduino-algorithms/</a>)
095
void
rgbLed () {
096
int
colorPot = analogRead(0);
// получаем значение с потенциометра (0 - 1023)
097
// разбиваем диапазон 0 - 1023 на участки, и играемся с цветом согласно текущему значению
098
if
(colorPot >= 10) {
//если значение больше 10, вкл. БП, иначе выкл.
099
digitalWrite(RGB_POWER, HIGH);
100
}
else
{
101
digitalWrite(RGB_POWER, LOW);
102
}
103
if
(colorPot <= 10) {
104
R = 0;
105
G = 0;
106
B = 0;
107
}
else
if
(colorPot > 10 && colorPot <= 20) {
108
byte
k = map(colorPot, 10, 20, 0, 255);
109
R = 255;
110
G = 255;
111
B = 255;
112
}
else
if
(colorPot > 20
/*&& colorPot <= 145*/
) {
113
byte
k = map(colorPot,
/*10, 145*/
20, 1023, 0, 255);
114
R = 255 - k;
115
G = 255 - k;
116
B = 255 - k;
117
}
/*else if (colorPot > 145 && colorPot <= 290) {
118
byte k = map(colorPot, 145, 290, 0, 255);
119
R = 0;
120
G = 0;
121
B = k;
122
} else if (colorPot > 290 && colorPot <= 435) {
123
byte k = map(colorPot, 290, 435, 0, 255);
124
R = 0;
125
G = k;
126
B = 255;
127
} else if (colorPot > 435 && colorPot <= 580) {
128
byte k = map(colorPot, 435, 580, 0, 255);
129
R = k;
130
G = 255;
131
B = 255;
132
} else if (colorPot > 581 && colorPot <= 725) {
133
byte k = map(colorPot, 581, 725, 0, 255);
134
R = 255 - k;
135
G = k;
136
B = 0;
137
} else if (colorPot > 725 && colorPot <= 870) {
138
byte k = map(colorPot, 725, 870, 0, 255);
139
R = 0;
140
G = 255 - k;
141
B = k;
142
} else if (colorPot > 870) {
143
byte k = map(colorPot, 870, 1023, 0, 255);
144
R = k;
145
G = 0;
146
B = 255 - k;
147
}*/
148
// подаём ШИМ на светодиод, учитывая яркость
149
analogWrite(R_PIN, (bright * R / 100));
150
analogWrite(G_PIN, (bright * G / 100));
151
analogWrite(B_PIN, (bright * B / 100));
152
}
153
154
//функция вкл/выкл вентилятора
155
//вентилятор вкл/выкл кнопкой при включенном свете. После выключения света,
156
//если вентилятор был включен, он выключится через время FAN_ON_TIME
157
void
fan(
bool
fanOff) {
158
bool
reading = !digitalRead(FAN_BUTTON_PIN);
159
if
(reading != lastFanButtonState) {
160
lastDebounceTime = millis() + DEBOUNCE_DELAY;
161
}
162
if
(lastDebounceTime <= millis()) {
163
if
(reading != fanButtonState) {
164
fanButtonState = reading;
165
if
(!fanButtonState) {
166
fanState = !fanState;
167
}
168
}
169
}
170
lastFanButtonState = reading;
171
172
if
(fanOff && fanState) {
//если свет выключился и вентилятор включен
173
fanButtonOffTime = millis() + workTime;
//записываем время выключения света (с опережением millis())
174
}
175
if
(fanButtonOffTime <= millis()) {
//если прошло время FAN_ON_TIME
176
fanState = LOW;
//выключить вентилятор
177
}
178
digitalWrite(FAN_PIN, fanState);
179
}
180
181
//функция антидребезга для геркона
182
//сформирована в программе FLProg
183
bool
bounseGerkon () {
184
bool
_bounceTmpD1 = digitalRead (GERKON_PIN);
185
if
(!_bounse3S)
186
{
187
if
(millis() >= (_bounse3P + DEBOUNCE_GERKON))
188
{
189
_bounse3O = _bounceTmpD1;
190
_bounse3S = 1;
191
}
192
}
193
else
194
{
195
if
( _bounceTmpD1 != _bounse3O )
196
{
197
_bounse3S = 0;
198
_bounse3P = millis();
199
}
200
}
201
return
_bounse3O;
202
}
203
204
//------------------------функция управления освещением, начало---------------------------
205
/* Логики работы: открыли дверь - включился свет, начался отсчет выдержки. По окончании
206
выдержки свет выключается, если при открытой двери есть движение, отсчет выдержки
207
обновляется. Если закрыть дверь при включенном свете - начинается отсчет второй вы-
208
держки, по истечении которой свет выключится. Если есть движение при закрытой двери
209
и включенном свете и при сработке датчика движени три раза в течении DELAY_LAMP_OFF_OPEN, свет не выключится
210
до следующего открывания двери не зависимо будет ещё срабатывать датчик движения или нет.
211
*/
212
void
lite() {
213
if
(bounseGerkon () && !gerkon_flag) {
//если геркон разомкнулся (дверь открылась) и до этого был замкнут
214
gerkon_flag = HIGH;
//изменение переменной (дверь была открыта)
215
lamp = HIGH;
//включить свет
216
motionClose = LOW;
//сброс индикатора движения
217
doorOpenedTime = millis() + (
long
)DELAY_LAMP_OFF_OPEN * 1000;
//начало отсчета до выключения света при открытой двери
218
}
219
if
(bounseGerkon () && gerkon_flag && digitalRead(SENSOR_PIN)) {
//если дверь открыта и есть движение
220
lamp = HIGH;
//включить свет
221
doorOpenedTime = millis() + (
long
)DELAY_LAMP_OFF_OPEN * 1000;
//обновление отсчета до выключения света при открытой двери
222
}
223
if
(bounseGerkon () && gerkon_flag && doorOpenedTime <= millis()) {
//если дверь открыта и прошло время выдержки
224
lamp = LOW;
//выключить свет
225
}
226
if
(!bounseGerkon () && gerkon_flag) {
//если геркон замкнулся (дверь закрылась) и до этого он был разомкнут
227
gerkon_flag = LOW;
//изменение переменной (дверь была закрыта)
228
doorClosedTime = millis() + (
long
)DELAY_LAMP_OFF_CLOSE * 1000;
//начало отсчета до выключения света при закрытой двери
229
doorClosedDelay = millis() + (
long
)DELAY_DOOR_CLOSE * 1000;
//начало задержки фиксации движения при закрытой двери
230
}
231
if
(!bounseGerkon () && !gerkon_flag) {
//если дверь закрыта
232
if
(doorClosedDelay <= millis()) {
//и если прошло время задержки до выключения света
233
if
(digitalRead(SENSOR_PIN) && !sensor_flag) {
//подсчет кол-ва сработок датчика движения при закрытой двери
234
sensor_flag = HIGH;
//для предотвращение ложного включения света до следующего
235
motionCount ++;
//открытия двери
236
motionClose = HIGH;
//
237
if
(!lamp) {
//если свет выключен
238
lamp = HIGH;
//включить свет
239
doorOpenedTime = millis() + (
long
)DELAY_LAMP_OFF_OPEN * 1000;
//на время DELAY_LAMP_OFF_OPEN
240
}
241
}
242
if
(!digitalRead(SENSOR_PIN) && sensor_flag) {
//если датчик движения деактивировался
243
sensor_flag = LOW;
//изменить переменную
244
}
245
if
(motionCount >= 3) {
246
motionCount = 3;
//ограничение кол-ва сработок датчика движения при закрытой двери до 3
247
}
248
}
249
}
250
//если дверь закрыта, прошло время до выключения света и счетчик сработок меньше трех
251
if
(!bounseGerkon () && !gerkon_flag && doorOpenedTime <= millis() && motionCount <= 2) {
252
lamp = LOW;
//выключить свет
253
}
254
//если дверь закрыта и движения не было и прошло время до выключения света при закрытой двери
255
if
(!bounseGerkon () && !gerkon_flag && !motionClose && doorClosedTime <= millis()) {
256
lamp = LOW;
//выключить свет
257
}
258
digitalWrite(LAMP_PIN, lamp);
//передать состояние переменной lamp на пин LAMP_PIN
259
260
if
(!lamp) {
//если свет выключен
261
motionCount = 0;
//обнулить счетчик сработок датчика движения
262
}
263
264
//индикация сработки датчика движения
265
//эту индикацию я сделал только для удобства мониторинга сработки датчика движения
266
if
(digitalRead(SENSOR_PIN)) {
//если сработал датчик движения
267
digitalWrite(13, HIGH);
//включить светодиод
268
}
else
{
269
if
(motionClose) {
//мигание при сработке при закрытой двери
270
if
(millis() - previousMillis >= INTERVAL) {
//
271
previousMillis = millis();
//
272
if
(ledMotionState == LOW) {
//
273
ledMotionState = HIGH;
//
274
}
else
{
//
275
ledMotionState = LOW;
//
276
}
//
277
digitalWrite(13, ledMotionState);
//
278
}
//
279
}
else
{
//при деактивации датчика движ., если не было сработки при закрытой двери,
280
digitalWrite(13, LOW);
//выключить светодиод
281
}
282
}
283
}
284
//------------------------функция управления освещением, конец---------------------------
285
286
//функция задержки сработки для 1го электроклапана
287
//сформирована в программе FLProg
288
bool
bounse1flap () {
289
bool
_bounceTmpD1 = (digitalRead (SENSOR1_PIN));
290
if
(!_bounse1S)
291
{
292
if
(millis() >= (_bounse1P + DEBOUNCE1_SENSOR))
293
{
294
_bounse1O = _bounceTmpD1;
295
_bounse1S = 1;
296
}
297
}
298
else
299
{
300
if
( _bounceTmpD1 != _bounse1O )
301
{
302
_bounse1S = 0;
303
_bounse1P = millis();
304
}
305
}
306
return
_bounse1O;
307
}
308
309
//функция задержки сработки для 2го электроклапана
310
//сформирована в программе FLProg
311
bool
bounse2flap () {
312
bool
_bounceTmpD1 = (digitalRead (SENSOR2_PIN));
313
if
(!_bounse2S)
314
{
315
if
(millis() >= (_bounse2P + DEBOUNCE2_SENSOR))
316
{
317
_bounse2O = _bounceTmpD1;
318
_bounse2S = 1;
319
}
320
}
321
else
322
{
323
if
( _bounceTmpD1 != _bounse2O )
324
{
325
_bounse2S = 0;
326
_bounse2P = millis();
327
}
328
}
329
return
_bounse2O;
330
}
331
332
//функция управления 1м краном
333
void
flap1() {
334
sensor1 = bounse1flap ();
//считывание состояние сенсора 1 с задержкой
335
if
(sensor1 == LOW && lastSensor1 == HIGH) {
//если активен и последнее сост. - неактивен, то ...
336
digitalWrite(FLAP1_PIN, HIGH);
//включаем 1й электроклапан
337
lastSensor1 = LOW;
//записываем последнее состояние сенсора 1
338
timeSensor1On = millis() + (ON_FLAP1_ON * 1000);
//записываем время сработки сенсора 1 +
339
}
//"опережаем время" на ON_FLAP1_ON для того,чтобы решить проблему
340
//с переполнением millis() т.е. "опережение времени" на ON_FLAP1_ON и ON_FLAP1_OFF
341
//(взято с сайта <a href="http://alexgyver.ru/arduino-algorithms/" title="http://alexgyver.ru/arduino-algorithms/" rel="nofollow">http://alexgyver.ru/arduino-algorithms/</a> от WakeUp4L1fe)
342
343
if
(sensor1 == HIGH && lastSensor1 == LOW) {
//если неактивен и последнее состояние сенсора 1 - активен
344
timeSensor1Off = millis() + (ON_FLAP1_OFF * 1000);
//записываем время деактивации сенсора 1 +
345
lastSensor1 = HIGH;
//"опережаем время" на ON_FLAP1_OFF
346
}
347
if
((timeSensor1On <= millis() && sensor1 == LOW) ||
//если после активации сенсора 1 прошло время ON_FLAP1_ON
348
(timeSensor1Off <= millis() && lastSensor1 == HIGH)) {
//или если после деактивации сенсора 1 прошло время ON_FLAP1_OFF
349
digitalWrite(FLAP1_PIN, LOW);
//то выключить кран
350
}
351
}
352
353
//функция управления 2м краном
354
void
flap2() {
355
sensor2 = bounse2flap ();
356
if
(sensor2 == LOW && lastSensor2 == HIGH) {
357
digitalWrite(FLAP2_PIN, HIGH);
358
lastSensor2 = LOW;
359
timeSensor2On = millis() + (ON_FLAP2_ON * 1000);
360
}
361
if
(sensor2 == HIGH && lastSensor2 == LOW) {
362
timeSensor2Off = millis() + (ON_FLAP2_OFF * 1000);
363
lastSensor2 = HIGH;
364
}
365
if
((timeSensor2On <= millis() && sensor2 == LOW) ||
366
(timeSensor2Off <= millis() && lastSensor2 == HIGH)) {
367
digitalWrite(FLAP2_PIN, LOW);
368
}
369
}
370
371
//основной цикл программы
372
void
loop
() {
373
lite();
374
fan(lamp);
375
flap1();
376
flap2();
377
rgbLed ();
378
}
Здравствуйте! Хочу поделиться своими наработками. Я написал программу для управления освещением и вытяжкой в ванной, сделал сенсорное управление кранами на кухне и в ванной, а так же RGB светодиодной лентой для подсветки кухонного гарнитура. Я только начинаю изучать Arduino и программирование так что не судите строго. Может кому то пригодится или знающие люди подскажут может можно как-то оптимизировать код программы.
Логика работы сенсоров кранов: если поднести руки (или любой предмет) вода включится, после того как убрали руки вода выключится через 2 с. Если в зону действия сенсора на долго попал какой-то предмет, например поставили кастрюлю в раковину, вода выключится через 30 с. И включится только после того как предмет будет убран и сенсор будет активирован снова.
Логика управления освещением и вытяжкой: при открытии двери свет включается и начинается выдержка 40 с до выключения света. Если фиксируется движение, начало выдержки обновляется. При закрытии двери начинается выдержка 5 с, при которой не фиксируется движение. Я добавил эту выдержку потому, что иногда при выходе из ванной и закрытии двери срабатывает датчик движения и включается свет, когда в ванной никого нет. Когда защитная выдержка заканчивается, начинается фиксация движения. И если датчик движения сработал три раза до выключения света, свет останется включенным до открытия двери не зависимо будет ли дальнейшее движение или нет. После закрытия двери, если нет движения, свет выключится через 15 с.
Вытяжка включается/выключается шнурком с кнопкой. При выключении света, если вытяжка была включена, начинается отсчет выдержки (я сделал 10 мин) до ее выключения. Включение света во время 10ти минутной выдержки сбрасывает отсчет, он начнется заново после выключения света.
По началу я пробовал другой алгоритм работы освещения. Использовал два ИК сенсора и считал кол-во входящих/выходящих человек. Но так как сенсоры расположены на расстоянии 6 см (ширина дверной коробки) были ложные срабатывания. Может быть я еще не удачно выбрал высоту установки датчиков, все люди разного роста, еще датчик повторно срабатывал от заплетенных волос. А маленький ребенок вообще не мог выключить свет. Так что пришлось отказаться от такого управления светом.
Управление RGB лентой и её блоком питания я сделал с помощью переменного резистора. Программный код, с некоторыми переделками, я взял с сайта http://alexgyver.ru/arduino-algorithms/
В своём проекте я использовал Arduino Nano.
... Но так как сенсоры расположены на расстоянии 6 см (ширина дверной коробки) были ложные срабатывания.
Приветствую!
Такая же ситуация была - удалось решить переходом на прерывания (см. выше мои сообщения). Сейчас расстояние между ИК датчиками порядка ~25 мм...
Вопрос к вам - что за краны и что за клапаны?
Буду благодарен за ссылку
Здравствуйте!
Я сделал сенсорное управление обычными смесителями на кухне и в ванной. Ручкой смесителя регулируется напор воды. Температура воды регулируется с помощью термостатического смесителя, его выход я подключил вместо горячей воды к смесителю на раковине.
Подача воды осуществляется с помощью клапана на подобии как в стиральной машине. Только я нашел на 12 В и с резьбой 1/2.
Включение клапана с помощью ИК сенсора.
Клапана такие:
https://s.click.aliexpress.com/e/cMCGLjj4
Термостатические смесители такие:
https://s.click.aliexpress.com/e/DJEFoYE
Сенсоры:
https://s.click.aliexpress.com/e/fRZL8dU
Спасибо! Возьму на заметку.
Еще вопрос - на сколько громко срабатывают клапана и каково качество их изготовления?
Ну и фотки в студию! ))) В частности интересно было бы увидеть как вы примостили сенсоры вблизи крана ;)
Спасибо! Возьму на заметку.
Еще вопрос - на сколько громко срабатывают клапана и каково качество их изготовления?
Ну и фотки в студию! ))) В частности интересно было бы увидеть как вы примостили сенсоры вблизи крана ;)
Звук сработки клапанов такой же как на стиральной машине. Особо на него не обращаю внимания. Качество хорошее, работают уже около 3х месяцев. Термостатические смесители работают с 2015 года уже на второй квартире.
Фотки выложу позже. Сенсор я разместил в боковом сливном отверстии раковины. Но в новой квартире думаю перенести ИК диод и TSOP в корпус смесителя, чтобы не было срабатываний от противоположной стороны раковины. У меня стальная раковина и при настройке сенсора на сработку от рук в ценре раковины, и когда убираешь руки датчик начинает срабатывать отражаясь от противоположной стенки раковины. Поэтому пришлось уменьшить дальность до пропадания ложных срабатываний. Еще я заменил резистор для настройки дальности на многооборотный для большей точности.
Обещанные фотографии:
Термостатический смеситель и клапан.
ИК сенсор с внутренней стороны раковины:
ИК сенсор с наружи:
Геркон в дверном косяке:
PIR и вентилятор. На время опытов смонтировал так. В дальнейшем думаю смонтировать PIR в такой же светильник в какие смонтированы лампы освещения.
Кузяво! )
У меня два вопроса:
1. ИК сенсор как то защищен от влаги? если нет - то как долго он уже в работе?
2. Про геркон. Как вы надрессировали домашних, чтобы они дверь постоянно закрывали? ))) Судя по фото она к тому еще и откатная?
По сравнению с готовыми решениями для смесителей с ИК (от ~8к руб) схема вполне годная, только мне кажется надо что-то с ИК датчиком придумать...
1. В сливное отверстие вставлен обрезок маркера и загерметизирован. С одной стороны приклеен прозрачный пластик. Так что на сенсор влага не попадает. В работе около полугода.
2. Дверь обычная. На фото видна дверь шкафа купе в ванной. Свет выключается и при открытой двери, у меня через 40 сек, если PIR не срабатывает.
В будущем я буду монтировать ИК сенсор в смеситель. Сейчас пока все находится в режиме тестов.
Понятно. Спасибо!
В будущем я буду монтировать ИК сенсор в смеситель
Интересно будет посмотреть что получилось. Удачи вам!
http://ru.aliexpress.com/item/1pcs-IR-Infrared-Obstacle-Avoidance-Sensor...
Излучающий светодиод выпаивается и ставится напротив в дверном проеме,надо 2 таких датчика
Доброго времени суток!
Подскажите, если кто владеет информацией, не смог сам найти, какова длина волны и мощность излучающего ИК светодиода на подобных датчиках?
В широком дверном проёме не добивает до приёмника ((
Хочу попробовать поставить помощнее ИК светодиод, типа такого:
https://ru.aliexpress.com/item/5-3/32953182050.html?spm=a2g0s.13010208.9...
http://ru.aliexpress.com/item/1pcs-IR-Infrared-Obstacle-Avoidance-Sensor...
Излучающий светодиод выпаивается и ставится напротив в дверном проеме,надо 2 таких датчика
Доброго времени суток!
Подскажите, если кто владеет информацией, не смог сам найти, какова длина волны и мощность излучающего ИК светодиода на подобных датчиках?
В широком дверном проёме не добивает до приёмника ((
Хочу попробовать поставить помощнее ИК светодиод, типа такого:
https://ru.aliexpress.com/item/5-3/32953182050.html?spm=a2g0s.13010208.9...
У меня проем в 100 см пробивает без проблем, светодиод самособой выпаян и помещен напротив
У меня проем в 100 см пробивает без проблем, светодиод самособой выпаян и помещен напротив
в моем случае проем 120 см. грешу на датчики, в этот раз попались какие то странные - в неразобранном виде на максимуме регулятора срабатывают на препятствие только в пределах 10 см.
я думаю стоит воздержаться от покупок данного устройства вот у этого продавца:
https://ru.aliexpress.com/item/Free-shipping-IR-Infrared-Obstacle-Avoida...
Всех приветствую! Докладаю.
Приобретенные ИК светодиоды повышенной мощности (3W 700mA 940nm 60degree) вот здесь:
https://www.aliexpress.com/store/product/5-PCS-3W-Infrared-IR-High-Power...
действительно улучшают срабатывание ИК барьера. Стабильного срабатывания удалось достичь на 100 см. Далее уже требуется более точная настройка пары друг на друга. Точность срабатывания уменьшается по мере все более частого попадания солнечного света в помещение. Придется скорее всего переходить на лазер типа VL53L0XV2.
«Вы все ещё кипятите?» Безо всяких ИК барьеров ванная работает на ПИРах, туалет - ПИР и ИК дальномер (сверху вниз). Год работы без влезания в алгоритм по санузлу. Полет нормальный. Минимум вторжения в интерьер.
Мой вариант работы ИК датчиков в дверном проеме. Взял за основу один из кодов этой темы и переделал под прерывания дуни. На макете проверил все отрабатывает, в реальных условиях дверных не смотрел.
01
// цель: считать количество людей в комнате
02
// материалы: датчик приближения ИК 2шт, блок реле, arduino pro mini
03
04
bool
IR1_state_old = 0;
// предыдущее значение первого датчика
05
bool
IR2_state_old = 0;
// предыдущее значение второго датчика
06
bool
IR1_state_new = 0;
// новое значение первого датчика
07
bool
IR2_state_new = 0;
// новое значение второго датчика
08
bool
flag = 0;
// флаг изменения состояния одного из датчиков
09
int
Human_Counter_New = 0;
// переменная для учета количества людей
10
int
LampRELE = 7;
// на этот вывод подключено реле на лампу
11
volatile unsigned
long
time_1;
// таймер 1 для учета зоны нечувтвительности
12
volatile unsigned
long
time_2;
// таймер 2 для учета зоны нечувтвительности
13
volatile
int
zad = 40;
// устранение дребезга, зона нечувствительности после последнего срабатывания
14
15
void
setup
() {
16
pinMode(LampRELE, OUTPUT);
17
attachInterrupt(0, IR1_state, CHANGE);
// вызов функции IR1_state при изменении пина D2
18
attachInterrupt(1, IR2_state, CHANGE);
// вызов функции IR2_state при изменении пина D3
19
Serial
.begin(9600);
// инициализация порта
20
Serial
.println(
"Порт готов"
);
// сообщение о готовности в порт
21
}
22
23
void
loop
() {
24
25
if
(flag) {
26
if
(Human_Counter_New < 0){Human_Counter_New = 0;}
27
Serial
.println(Human_Counter_New);
28
// Serial.print("IR1new=");Serial.print(IR1_state_new);Serial.print(" ");
29
// Serial.print("IR2new=");Serial.print(IR2_state_new);Serial.print(" ");
30
// Serial.print("IR1old=");Serial.print(IR1_state_old);Serial.print(" ");
31
// Serial.print("IR2old=");Serial.println(IR2_state_old);
32
IR1_state_old = IR1_state_new;
33
IR2_state_old = IR2_state_new;
34
flag = 0;
35
}
36
if
( Human_Counter_New > 0) {digitalWrite(LampRELE,HIGH);}
37
else
{digitalWrite(LampRELE,LOW); }
38
}
39
40
void
IR1_state() {
41
if
((millis()-time_1)>zad) {
42
IR1_state_new = !IR1_state_new;
43
if
(!IR1_state_old && !IR2_state_old && IR1_state_new && !IR2_state_new){Human_Counter_New++; }
44
else
{
45
if
(IR1_state_old && !IR2_state_old && !IR1_state_new && !IR2_state_new){Human_Counter_New--; }
46
}
47
flag = 1;
48
}
49
time_1 = millis();
50
}
51
52
53
void
IR2_state() {
54
if
((millis()-time_2)>zad) {
55
IR2_state_new = !IR2_state_new;
56
if
(!IR1_state_old && !IR2_state_old && IR1_state_new && !IR2_state_new){Human_Counter_New++; }
57
else
{
58
if
(IR1_state_old && !IR2_state_old && !IR1_state_new && !IR2_state_new){Human_Counter_New--; }
59
}
60
flag = 1;
61
}
62
time_2 = millis();
63
}
«Вы все ещё кипятите?»
мы кипятим, ага ) а ещё жжем )) а вы свет выключаете, если в ванной помедитировать? )))
Так сам через пять минут выключится, если неподвижно медитировать. :)
Так сам через пять минут выключится, если неподвижно медитировать. :)
)) вот именно поэтому то ИК барьеры и ставим (а кто-то и лазерные) ;)
Так сам через пять минут выключится, если неподвижно медитировать. :)
А я наоборот люблю, с утра, не проснувшись, сидишь, а свет выключился. Если надо, шевельнулся и снова горит. Один датчик движения на потолке. А мучиться с этими барьерами и прочим, лишняя фигня, ИМХО
Я изменил программу. Теперь у меня светом в санузле управляют геркон и PIR. С помощью задержек я настроил программу так, что свет не выключится при закрытой двери даже если нет движения. Еще добавил сторожевой таймер.
001
#include <MsTimer2.h>
002
#include <avr/wdt.h>
003
004
#define SENSOR1_PIN 2 //вход управления 1м электроклапаном
005
#define SENSOR2_PIN 3 //вход управления 2м электроклапаном
006
#define FLAP1_PIN 4 //выход управления 1м электроклапаном
007
#define FLAP2_PIN 5 //выход управления 2м электроклапаном
008
#define GERKON_PIN 6 //вход геркон
009
#define SENSOR_PIN 7 //вход датчик движения
010
#define LAMP_PIN 8 //выход управления освещением
011
#define R_PIN 9 //выход управления красным цветом
012
#define G_PIN 10 //выход управления зеленым цветом
013
#define B_PIN 11 //выход управления голубым цветом
014
#define RGB_POWER 12 //выход вкл/выкл БП для RGB
015
#define FAN_BUTTON_PIN 15 //вход управления вентилятором (кнопка)
016
#define FAN_PIN 16 //выход управления вентилятором
017
#define DEBOUNCE_DELAY 100 //время антидребезга кнопки вентилятора в мс
018
#define FAN_ON_TIME 600000 //время работы вентилятора после выкл. света, мс
019
#define ON_FLAP1_ON 30000 //время работы 1го клапана при активации сенсора, мс
020
#define ON_FLAP1_OFF 2000 //время работы 1го клапана при деактивации сенсора, мс
021
#define ON_FLAP2_ON 30000 //время работы 2го клапана при активации сенсора, мс
022
#define ON_FLAP2_OFF 2000 //время работы 2го клапана при деактивации сенсора, мс
023
#define DEBOUNCE1_SENSOR 300 //задержка сработки для 1го электроклапана, мс
024
#define DEBOUNCE2_SENSOR 300 //задержка сработки для 2го электроклапана, мс
025
#define DELAY_LAMP_OFF_OPEN 60000 //задержка выключения света при открытой двери, мс
026
#define DELAY_LAMP_OFF_OPENED 15000 //задержка выключения света после открытия двери, мс
027
#define DELAY_LAMP_OFF_CLOSE 10000 //задержка выключения света после закрытия двери, мс
028
#define DELAY_MOTION_OPENED 10000 //задержка регистрации движения после открытия двери, мс
029
#define DELAY_MOTION_CLOSED 5000 //задержка регистрации движения после закрытия двери, мс
030
#define DELAY_MOTION_NOBODY 25000 //время, после которого, свет не включится до след. открытия двери, мс
031
#define DEBOUNCE_GERKON 80 //время антидребезга геркона в мс
032
#define INTERVAL 250 //интервал мигания светодиода индик. сработки датчика движения, мс
033
034
035
//переменные для управления кранами
036
unsigned
long
int
timeSensor1On, timeSensor1Off, timeSensor2On, timeSensor2Off;
037
bool
flap1On =
false
;
//переменная для хранения состояния 1го электроклапана
038
bool
flap2On =
false
;
//переменная для хранения состояния 2го электроклапана
039
bool
sensor1 = LOW;
//переменная для хранения состояния сенсора 1го электроклапана
040
bool
sensor2 = LOW;
//переменная для хранения состояния сенсора 2го электроклапана
041
bool
lastSensor1 = LOW;
//переменная для хранения последнего состояния сенсора 1го электроклапана
042
bool
lastSensor2 = LOW;
//переменная для хранения последнего состояния сенсора 2го электроклапана
043
//////////////////////////////////////////////////////////////////////////////////
044
045
//переменные для управления освещением
046
bool
lamp;
//переменная для хранения состояния освещения (вкл/выкл)
047
bool
gerkon_flag;
//вспомогательная переменная для хранения состояния сработки геркона
048
bool
noBody;
//отсутствие людей в ванной
049
bool
motionClose;
//переменная для индикации движения при закрытой двери
050
bool
motionOpen;
//переменная для индикации движения при открытой двери
051
unsigned
long
lampOffTimeClose, lampOffTimeOpened, delayMotionOpened, delayMotionClosed, doorClosedNobody, lampOffTimeOpen;
//переменные для хранения времени момента закрытия и открытия двери
052
//переменные для функции светодиодной индикации сработки датчика движения
053
unsigned
long
int
previousMillis = 0;
054
bool
ledMotionState;
055
////////////////////////////////////////////////////////////////////////////////////
056
057
//переменные для управления вентилятором
058
bool
fanState;
059
bool
fanButtonState;
060
bool
lastFanButtonState;
061
unsigned
long
int
lastDebounceTime = 0, fanButtonOffTime;
062
/////////////////////////////////////////////////////////////////////////////////////
063
064
//переменные для функции задержки (антидребезга) геркона
065
bool
_bounse3S = 1;
066
bool
_bounse3O = 1;
067
unsigned
long
_bounse3P = 0UL;
068
/////////////////////////////////////////////////////////////////////////////////////
069
070
//переменные для функций задержек (антидребезга) сенсоров электроклапанов
071
bool
_bounse1S = 1;
072
bool
_bounse1O = 1;
073
unsigned
long
_bounse1P = 0UL;
074
bool
_bounse2S = 1;
075
bool
_bounse2O = 1;
076
unsigned
long
_bounse2P = 0UL;
077
/////////////////////////////////////////////////////////////////////////////////////
078
079
//переменные для управления RGB
080
byte
bright = 100;
// яркость, от 0 до 100 (можно повесить на второй потенциометр при желании)
081
byte
R, G, B;
082
083
void
setup
() {
//конфигурация портов (вход или выход)
084
pinMode(SENSOR1_PIN, INPUT_PULLUP);
//подтягиваем вход к плюсу через внутренний резистор 20к
085
pinMode(FLAP1_PIN, OUTPUT);
086
pinMode(SENSOR2_PIN, INPUT_PULLUP);
087
pinMode(FLAP2_PIN, OUTPUT);
088
pinMode(GERKON_PIN, INPUT_PULLUP);
089
pinMode(LAMP_PIN, OUTPUT);
090
pinMode(SENSOR_PIN, INPUT);
091
pinMode(FAN_BUTTON_PIN, INPUT_PULLUP);
092
pinMode(FAN_PIN, OUTPUT);
093
pinMode(R_PIN, OUTPUT);
094
pinMode(G_PIN, OUTPUT);
095
//pinMode(B_PIN, OUTPUT);
096
pinMode(RGB_POWER, OUTPUT);
097
pinMode(13, OUTPUT);
098
099
MsTimer2::
set
(2, timerInterrupt);
// период прерывания по таймеру 2 мс
100
MsTimer2::start();
// разрешаем прерывание по таймеру
101
102
// Serial.begin(9600); // инициализируем порт, скорость 9600
103
wdt_enable(WDTO_15MS);
// разрешаем сторожевой таймер, тайм-аутом 15 мс
104
}
105
106
//управление светодиодной лентой RGB (взято с сайта <a href="http://alexgyver.ru/arduino-algorithms/" title="http://alexgyver.ru/arduino-algorithms/" rel="nofollow">http://alexgyver.ru/arduino-algorithms/</a>)
107
void
rgbLed () {
108
int
colorPot = analogRead(0);
// получаем значение с потенциометра (0 - 1023)
109
// разбиваем диапазон 0 - 1023 на участки, и играемся с цветом согласно текущему значению
110
/*if (colorPot >= 10) { //если значение больше 10, вкл. БП, иначе выкл.
111
digitalWrite(RGB_POWER, HIGH);
112
} else {
113
digitalWrite(RGB_POWER, LOW);
114
}*/
115
if
(colorPot <= 10 || colorPot >= 1005) {
//если значение меньше 10 или больше 1005, выкл. БП, иначе вкл.
116
digitalWrite(RGB_POWER, LOW);
117
}
else
{
118
digitalWrite(RGB_POWER, HIGH);
119
}
120
if
(colorPot <= 10) {
121
R = 0;
122
G = 0;
123
B = 0;
124
}
else
if
(colorPot > 11 && colorPot <= 29) {
125
byte
k = map(colorPot, 10, 20, 0, 255);
126
R = 255;
127
G = 255;
128
B = 255;
129
}
else
if
(colorPot > 30
/*&& colorPot <= 145*/
) {
130
byte
k = map(colorPot,
/*10, 145*/
30, 1024, 0, 255);
131
R = 255 - k;
132
G = 255 - k;
133
B = 255 - k;
134
}
/*else if (colorPot > 145 && colorPot <= 290) {
135
byte k = map(colorPot, 145, 290, 0, 255);
136
R = 0;
137
G = 0;
138
B = k;
139
} else if (colorPot > 290 && colorPot <= 435) {
140
byte k = map(colorPot, 290, 435, 0, 255);
141
R = 0;
142
G = k;
143
B = 255;
144
} else if (colorPot > 435 && colorPot <= 580) {
145
byte k = map(colorPot, 435, 580, 0, 255);
146
R = k;
147
G = 255;
148
B = 255;
149
} else if (colorPot > 581 && colorPot <= 725) {
150
byte k = map(colorPot, 581, 725, 0, 255);
151
R = 255 - k;
152
G = k;
153
B = 0;
154
} else if (colorPot > 725 && colorPot <= 870) {
155
byte k = map(colorPot, 725, 870, 0, 255);
156
R = 0;
157
G = 255 - k;
158
B = k;
159
} else if (colorPot > 870) {
160
byte k = map(colorPot, 870, 1023, 0, 255);
161
R = k;
162
G = 0;
163
B = 255 - k;
164
}*/
165
// подаём ШИМ на светодиод, учитывая яркость
166
analogWrite(R_PIN, (bright * R / 100));
167
analogWrite(G_PIN, (bright * G / 100));
168
//analogWrite(B_PIN, (bright * B / 100));
169
}
170
171
//функция вкл/выкл вентилятора
172
//вентилятор вкл/выкл кнопкой при включенном свете. После выключения света,
173
//если вентилятор был включен, он выключится через время FAN_ON_TIME
174
//если свет включится и выключится еще раз при работающем вентиляторе,
175
//отсчет выдержки начнется с начала
176
void
fan(
bool
fanOff) {
177
bool
reading = !digitalRead(FAN_BUTTON_PIN);
178
if
(reading != lastFanButtonState) {
179
lastDebounceTime = millis() + DEBOUNCE_DELAY;
180
}
181
if
(lastDebounceTime <= millis()) {
182
if
(reading != fanButtonState) {
183
fanButtonState = reading;
184
if
(!fanButtonState) {
185
fanState = !fanState;
186
}
187
}
188
}
189
lastFanButtonState = reading;
190
191
if
(fanOff && fanState) {
//если свет выключился и вентилятор включен
192
fanButtonOffTime = millis() + FAN_ON_TIME;
//записываем время выключения света (с опережением millis())
193
}
194
if
(fanButtonOffTime <= millis()) {
//если прошло время FAN_ON_TIME
195
fanState = LOW;
//выключить вентилятор
196
}
197
digitalWrite(FAN_PIN, fanState);
198
}
199
200
//функция антидребезга для геркона
201
//сформирована в программе FLProg
202
bool
bounseGerkon () {
203
bool
_bounceTmpD1 = digitalRead (GERKON_PIN);
204
if
(!_bounse3S)
205
{
206
if
(millis() >= (_bounse3P + DEBOUNCE_GERKON))
207
{
208
_bounse3O = _bounceTmpD1;
209
_bounse3S = 1;
210
}
211
}
212
else
213
{
214
if
( _bounceTmpD1 != _bounse3O )
215
{
216
_bounse3S = 0;
217
_bounse3P = millis();
218
}
219
}
220
return
_bounse3O;
221
}
222
223
//------------------------функция управления освещением, начало---------------------------
224
/* Логики работы: открыли дверь - включился свет, начался отсчет выдержки 15 сек. По окончании
225
выдержки свет выключается, если при открытой двери есть движение (после задержки 10 сек),
226
начнется выдержка 1 мин. до выключения света.
227
Если закрыть дверь при включенном свете - начинается отсчет второй вы-
228
держки 10 сек, по истечении которой свет выключится. Если при закрытой двери есть движение
229
между интервалами DELAY_LAMP_OFF_CLOSE и DELAY_MOTION_NOBODY, свет не выключится
230
до следующего открывания двери не зависимо будет ещё срабатывать датчик движения или нет.
231
Если при закрытой двери не было движения в течении DELAY_MOTION_NOBODY, свет не
232
включится до следующего открывания двери.
233
*/
234
void
lite() {
235
if
(bounseGerkon () && !gerkon_flag) {
//если геркон разомкнулся (дверь открылась) и до этого был замкнут
236
gerkon_flag = HIGH;
//изменение переменной (дверь была открыта)
237
if
(!lamp) {
//если свет выключен
238
lamp = HIGH;
//включить свет
239
}
240
noBody = LOW;
//сброс флага отсутствие людей в ванной
241
motionClose = LOW;
//сброс индикатора движения
242
delayMotionOpened = millis() + DELAY_MOTION_OPENED;
//начало задержки фиксации движения
243
lampOffTimeOpened = millis() + DELAY_LAMP_OFF_OPENED;
//обновление отсчета до выключения света после открывания двери
244
}
245
if
(bounseGerkon () && gerkon_flag) {
//если дверь открыта
246
if
(delayMotionOpened <= millis()) {
//и если прошло время задержки фиксации движения
247
if
(digitalRead(SENSOR_PIN)) {
//и есть движение
248
lampOffTimeOpen = millis() + DELAY_LAMP_OFF_OPEN;
//обновление отсчета до выключения света при открытой двери
249
motionOpen = HIGH;
//флаг есть движение
250
if
(!lamp) {
//если свет выключен
251
lamp = HIGH;
//включить свет
252
}
253
}
254
}
255
}
256
//если дверь открыта и прошло время выдержки и не было движения
257
if
(bounseGerkon () && gerkon_flag && lampOffTimeOpened <= millis() && !motionOpen) {
258
lamp = LOW;
//выключить свет
259
}
260
//если дверь открыта и прошло время выдержки после движения
261
if
(bounseGerkon () && gerkon_flag && lampOffTimeOpen <= millis() && motionOpen) {
262
lamp = LOW;
//выключить свет
263
}
264
if
(!bounseGerkon () && gerkon_flag) {
//если геркон замкнулся (дверь закрылась) и до этого он был разомкнут
265
motionOpen = LOW;
266
gerkon_flag = LOW;
//изменение переменной (дверь была закрыта)
267
lampOffTimeClose = millis() + DELAY_LAMP_OFF_CLOSE;
//начало отсчета до выключения света при закрытой двери
268
delayMotionClosed = millis() + DELAY_MOTION_CLOSED;
//начало задержки фиксации движения
269
doorClosedNobody = millis() + DELAY_MOTION_NOBODY;
270
}
271
if
(!bounseGerkon () && !gerkon_flag) {
//если дверь закрыта
272
if
(delayMotionClosed <= millis()) {
//и если прошло время задержки фиксации движения при закрытой двери
273
if
(digitalRead(SENSOR_PIN) && !noBody) {
//если есть движение при закрытой двери
274
motionClose = HIGH;
//фиксация движения
275
if
(!lamp) {
//если свет выключен
276
lamp = HIGH;
//включить свет
277
}
278
}
279
}
280
}
281
//если дверь закрыта и движения не было и прошло время до выключения света при закрытой двери
282
if
(!bounseGerkon () && !gerkon_flag && !motionClose && lampOffTimeClose <= millis()) {
283
lamp = LOW;
//выключить свет
284
}
285
//если дверь закрыта, прошло время до выключения света и не было движения
286
if
(!bounseGerkon () && !gerkon_flag && !motionClose && doorClosedNobody <= millis()) {
287
noBody = HIGH;
//активировать флаг - никого нет
288
}
289
digitalWrite(LAMP_PIN, lamp);
//передать состояние переменной lamp на пин LAMP_PIN
290
291
//индикация сработки датчика движения
292
//эту индикацию я сделал только для удобства мониторинга сработки датчика движения
293
if
(digitalRead(SENSOR_PIN)) {
//если сработал датчик движения
294
digitalWrite(13, HIGH);
//включить светодиод
295
}
else
{
296
/*if (motionClose) { //мигание при сработке при закрытой двери
297
if (millis() - previousMillis >= INTERVAL) { //
298
previousMillis = millis(); //
299
if (ledMotionState == LOW) { //
300
ledMotionState = HIGH; //
301
} else { //
302
ledMotionState = LOW; //
303
} //
304
digitalWrite(13, ledMotionState); //
305
} //
306
} else {*/
//при деактивации датчика движ., если не было сработки при закрытой двери,
307
digitalWrite(13, LOW);
//выключить светодиод
308
}
309
//}
310
}
311
//------------------------функция управления освещением, конец---------------------------
312
313
//функция задержки сработки для 1го электроклапана
314
//сформирована в программе FLProg
315
bool
bounse1flap () {
316
bool
_bounceTmpD1 = (digitalRead (SENSOR1_PIN));
317
if
(!_bounse1S)
318
{
319
if
(millis() >= (_bounse1P + DEBOUNCE1_SENSOR))
320
{
321
_bounse1O = _bounceTmpD1;
322
_bounse1S = 1;
323
}
324
}
325
else
326
{
327
if
( _bounceTmpD1 != _bounse1O )
328
{
329
_bounse1S = 0;
330
_bounse1P = millis();
331
}
332
}
333
return
_bounse1O;
334
}
335
336
//функция задержки сработки для 2го электроклапана
337
//сформирована в программе FLProg
338
bool
bounse2flap () {
339
bool
_bounceTmpD1 = (digitalRead (SENSOR2_PIN));
340
if
(!_bounse2S)
341
{
342
if
(millis() >= (_bounse2P + DEBOUNCE2_SENSOR))
343
{
344
_bounse2O = _bounceTmpD1;
345
_bounse2S = 1;
346
}
347
}
348
else
349
{
350
if
( _bounceTmpD1 != _bounse2O )
351
{
352
_bounse2S = 0;
353
_bounse2P = millis();
354
}
355
}
356
return
_bounse2O;
357
}
358
359
//функция управления 1м краном
360
void
flap1() {
361
sensor1 = bounse1flap ();
//считывание состояние сенсора 1 с задержкой
362
if
(sensor1 == LOW && lastSensor1 == LOW) {
//если активен и последнее сост. - неактивен, то ...
363
digitalWrite(FLAP1_PIN, HIGH);
//включаем 1й электроклапан
364
lastSensor1 = HIGH;
//записываем последнее состояние сенсора 1
365
timeSensor1On = millis() + ON_FLAP1_ON;
//записываем время сработки сенсора 1 +
366
}
//"опережаем время" на ON_FLAP1_ON для того,чтобы решить проблему
367
//с переполнением millis() т.е. "опережение времени" на ON_FLAP1_ON и ON_FLAP1_OFF
368
//(взято с сайта <a href="http://alexgyver.ru/arduino-algorithms/" title="http://alexgyver.ru/arduino-algorithms/" rel="nofollow">http://alexgyver.ru/arduino-algorithms/</a> от WakeUp4L1fe)
369
370
if
(sensor1 == HIGH && lastSensor1 == HIGH) {
//если неактивен и последнее состояние сенсора 1 - активен
371
timeSensor1Off = millis() + ON_FLAP1_OFF;
//записываем время деактивации сенсора 1 +
372
lastSensor1 = LOW;
//"опережаем время" на ON_FLAP1_OFF
373
}
374
if
((timeSensor1On <= millis() && sensor1 == LOW) ||
//если после активации сенсора 1 прошло время ON_FLAP1_ON
375
(timeSensor1Off <= millis() && lastSensor1 == LOW)) {
//или если после деактивации сенсора 1 прошло время ON_FLAP1_OFF
376
digitalWrite(FLAP1_PIN, LOW);
//то выключить кран
377
}
378
}
379
380
//функция управления 2м краном
381
void
flap2() {
382
sensor2 = bounse2flap ();
383
if
(sensor2 == LOW && lastSensor2 == LOW) {
384
digitalWrite(FLAP2_PIN, HIGH);
385
lastSensor2 = HIGH;
386
timeSensor2On = millis() + ON_FLAP2_ON;
387
}
388
if
(sensor2 == HIGH && lastSensor2 == HIGH) {
389
timeSensor2Off = millis() + ON_FLAP2_OFF;
390
lastSensor2 = LOW;
391
}
392
if
((timeSensor2On <= millis() && sensor2 == LOW) ||
393
(timeSensor2Off <= millis() && lastSensor2 == LOW)) {
394
digitalWrite(FLAP2_PIN, LOW);
395
}
396
}
397
398
//основной цикл программы
399
void
loop
() {
400
lite();
401
fan(lamp);
402
flap1();
403
flap2();
404
rgbLed ();
405
}
406
407
// ---------------------------------------------------обработчик прерывания, 2 мс
408
void
timerInterrupt() {
409
wdt_reset();
// сброс сторожевого таймера
410
}
Добрый день. Пытаюсь освоить тему.
IR1_state_new = !IR1_state_new;
if (!IR1_state_old && !IR2_state_old && IR1_state_new && !IR2_state_new){Human_Counter_New++; }
else{
if (IR1_state_old && !IR2_state_old && !IR1_state_new && !IR2_state_new){Human_Counter_New--; }
}
flag = 1;
Вот у нас человек входит, те срабатывает сначала IR1 и потом IR2. Объясните пожалуйста поэтапно как это будет по скетчу.
Это был вопрос по скетчу из сообщения #568 kinguf