Автоматическая кухонная подсветка по ультразвуковому датчику
- Войдите на сайт для отправки комментариев
Привет. Проект для управления светодиодной подсветкой.
При приближении человека на 1,2 метра плавно включается светодиодная лента на 12 Вольт. Если человек продолжает присутствовать в "поле зрения" датчика - лента светится. При покидании зоны через 30 секунд лента плавно гаснет. При поднесении руки к датчику на растояние менее 5 см - начинает увеличиваться яркость ленты и при достижении максимума сбрасывается на ноль.
Использованные компоненты: Arduino Pro mini, ультразвуковой дальномер HC-SR04, фоторезистор 1-20КОм, Мосфет с материнской платы, резистор 330 Ом.
Подключение: Датчик на пины 2,3,4,5. 2+, 3Trig, 4 Echo, 5-. Фоторезистор на + питания и A3. Резистор 330 Ом на А3 и минус. Мосфет затвор на 9, сток исток на минус и минус светодиодной ленты. Светодиодная лента вторым концом на +12В. Питание ардуино 12В на пин RAW.
#include "GyverFilters.h"
GMedian testFilter;
#include <EEPROM.h>
#define trigPin 3 //Триггер
#define echoPin 4 //Эхо
#define Ledpin 9 //Светодиодная лента через транзистор годятся только 9 или 10 пины для ШИМ 32 кГц!!!! Иначе медленный ШИМ убъет глаза!!
#define MinesPin 5 //- датчика
#define PlusPin 2 //+ Датчика
#define MinesPin 5 //- датчика
#define delay_Led 30000 //Задержка выключения света в мс
#define distOn 120//дистанция включения
#define distSet 5//дистанция срабатывания
#define analogSens 140// фотодатчик 0..1023. Не включаем подсветку днем
byte LightLed = EEPROM.read(0);//Яркость ленты 0..255. При первом включении яркость максимальная 255
unsigned long next_time;//Переменная задержки выключения
byte flag = LOW;// Флаг однократного плавного затухания
void setup() {
TCCR1A = 0b00000001; // 8bit
TCCR1B = 0b00000001; // x1 phase correct//разгоняем ШИМ на 9,10 пинах до 31,4 кГц
analogReference(INTERNAL);//устанавливаем максимальное измеряемое напряжение аналогового входа 1,1В.
pinMode(trigPin, OUTPUT); //пин триггера в режиме выхода
pinMode(echoPin, INPUT); //пин эхо в режиме входа
pinMode(MinesPin, OUTPUT); digitalWrite(5, LOW); //питание датчика
pinMode(PlusPin, OUTPUT); digitalWrite(2, HIGH);//питание датчика
pinMode(9, OUTPUT);// светодиод
}
void loop() {
if (testFilter.filtered(measure()) < distOn) {//Обнаружение
if (analogRead(A3) < analogSens) { //Проверяем яркость вокруг после обнаружения
for (byte i = 0; i < LightLed; i++) {
analogWrite(Ledpin, i);
delay(10);
if (i < 20) delay (30);
if (i < 5) delay (50);
}
flag = HIGH;
presence:
if (testFilter.filtered(measure()) < distOn) {// Светим пока присутствуем
next_time = millis() + delay_Led;
if (testFilter.filtered(measure()) < distSet) {//Управление ШИМ
LightLed++;
analogWrite(Ledpin, LightLed);
if (LightLed == 255); delay (20000); //Остановка на макс яркости
if (LightLed == 1); delay (5000); //Остановка на мин яркости
goto presence;
} else goto presence;
} else goto Off;
} else goto Off;
} else goto Off;
Off:
if (next_time > millis())goto presence;
for (int i = LightLed * flag; i != 0; i--) {
analogWrite(Ledpin, i);
delay(20);
if (i < 20) delay (30);
if (i < 5) delay (50);
}
if (flag) EEPROM.update(0, LightLed);
flag = LOW; analogWrite(Ledpin, 0);
}
long measure() { //блок, измеряющий расстояние
delay(50);//рекомендуемая задержка измерений
digitalWrite(trigPin, LOW); delayMicroseconds(5);
digitalWrite(trigPin, HIGH); delayMicroseconds(15);
digitalWrite(trigPin, LOW);
return (pulseIn(echoPin, HIGH) / 66); //получаем расстояние с датчика
}
Библиотека цифровой фильтрации тут https://github.com/AlexGyver/GyverLibs



Немного подправил код.
Теперь 5-8 см увеличивают яркость, менее 5см уменьшает яркость. Также добавил защиту от переполнения millis.
#include "GyverFilters.h" GMedian testFilter; #include <EEPROM.h> #define trigPin 3 //Триггер #define echoPin 4 //Эхо #define Ledpin 9 //Светодиодная лента через транзистор годятся только 9 или 10 пины для ШИМ 32 кГц!!!! Иначе медленный ШИМ убъет глаза!! #define MinesPin 5 //- датчика #define PlusPin 2 //+ Датчика #define delay_Led 30000 //Задержка выключения света в мс #define distOn 120//дистанция включения #define distSet 5//дистанция срабатывания #define analogSens 140// фотодатчик 0..1023. Не включаем подсветку днем byte LightLed = EEPROM.read(0);//Яркость ленты 0..255. При первом включении яркость максимальная 255 unsigned long next_time;//Переменная задержки выключения byte flag = LOW;// Флаг однократного плавного затухания void setup() { TCCR1A = 0b00000001; // 8bit TCCR1B = 0b00000001; // x1 phase correct//разгоняем ШИМ на 9,10 пинах до 31,4 кГц analogReference(INTERNAL);//устанавливаем максимальное измеряемое напряжение аналогового входа 1,1В. pinMode(trigPin, OUTPUT); //пин триггера в режиме выхода pinMode(echoPin, INPUT); //пин эхо в режиме входа pinMode(MinesPin, OUTPUT); digitalWrite(5, LOW); //питание датчика pinMode(PlusPin, OUTPUT); digitalWrite(2, HIGH);//питание датчика pinMode(9, OUTPUT);// светодиод } void loop() { if (testFilter.filtered(measure()) < distOn) {//Обнаружение if (analogRead(A3) < analogSens) { //Проверяем яркость вокруг после обнаружения for (byte i = 0; i < LightLed; i++) { analogWrite(Ledpin, i); delay(10); if (i < 20) delay (30); } flag = HIGH; presence: if (testFilter.filtered(measure()) < distOn) {// Светим пока присутствуем next_time = millis() + delay_Led; long data = testFilter.filtered(measure()); if (data < 8 && data > 4) { //Управление ШИМ LightLed++; if (LightLed == 255) { LightLed = 254; } analogWrite(Ledpin, LightLed); goto presence; } if (data < 5) {//Управление ШИМ LightLed--; if (LightLed == 0) { LightLed = 1; } analogWrite(Ledpin, LightLed); goto presence; } else goto presence; } else goto Off; } else goto Off; } else goto Off; Off: if (next_time - millis() > delay_Led) {next_time = millis();} //Защита от переполнения millis() if (next_time > millis())goto presence; for (int i = LightLed * flag; i != 0; i--) { analogWrite(Ledpin, i); delay(20); if (i < 20) delay (30); } if (flag) EEPROM.update(0, LightLed); flag = LOW; analogWrite(Ledpin, 0); } long measure() { //блок, измеряющий расстояние delay(50);//рекомендуемая задержка измерений digitalWrite(trigPin, LOW); delayMicroseconds(5); digitalWrite(trigPin, HIGH); delayMicroseconds(15); digitalWrite(trigPin, LOW); return (pulseIn(echoPin, HIGH) / 66); //получаем расстояние с датчика }добавил защиту от переполнения millis.
Нахуа? Она прекрасно защищена грамотным программированием. А если ее надо защищать принудительно, то чота не в порядке в консерватории, например, программирование вапще не преподавают.
Дык, школа-ж!
Дык, школа-ж!
Он неоспоримый бог микроконтроллеров. Принимайте "Бомбит" и больше НЕБОМБИТ))) Лучше б goto покритиковали. Гайвер себе такого не позволяет.
Ну а по серйозному, какая разница кто библиотеку фильтра собрал. Фильтрует себе тихонько и кушать не просит. Проект рабочий.
С тех пор, как Гиверу показали грубую ошибку в этой библиотеке (см. #52) он попытался её исправить (см. ту же функцию здесь). Но, исправил неправильно. Так что ... «фильтрует, не сомневайтесь» :=)
Лучше б goto покритиковали. Гайвер себе такого не позволяет.
Да без проблем - вместо goto нужный блок кода выносится в отдельную процедуру, которая и вызывается при необходимости. Не верите? Спросите у Гайвера ))
Я в их религиях не силен ))
помогите пожалуйста разобраться со скетчем
,библиотеку по ссылке скачал положил в библиотеки,не компилируется,пишет ошибку
invalid use of template-name 'GMedian' without an argument list
Скетч - подключить библиотеку - добавить zip библиотеку.
спасибо p-a-h-a,попробывал этот вариант,теперь кампилятор ругается на это
может библиотека обновленная?
столько всего кампилировалось,а это ни какую,что вообще происходит
столько всего кампилировалось,а это ни какую,что вообще происходит
Попробуй компилировать, может удачнее будет.
вы какую версию GyverFilters использовали:
1.6
1.7
1.8
2.0
??
так вот и так и так пробовал.
столько всего кампилировалось,а это ни какую,что вообще происходит
Попробуй компилировать, может удачнее будет.
может кому пригодится:
GyverFilters V 1.3
файлы с расширением "h";"ccp"
положить туда где лежит файл скетча.
Скетч - подключить библиотеку - добавить zip библиотеку.
p-a-h-a вы можете поправить код,под новую библиотеку фильтров или помочь разобраться с этим?
ещё подсветка выключается и обратно включается,хотя и находишся в поле зрения дальномера 30 см (уставка 80 см)
задержка выключения 3 сек(3000)
ещё бы,индикацию ввести при регулировке яркости (на цыфровые пины)когда прибавляешь и убавляешь,и ночной режим,допустим в % от максимальной яркости,
может кому пригодится:
GyverFilters V 1.3
Интересно, кому может пригодится неработающий код? GyverFilters же цену на прошлогодний овёс выдаёт, это давно известно.
Да выкиньте вы этот фильтр, скользящее среднее вставьте вместо него да и все. А еще лучше на прерываниях сделать измерение с фильтром. Что было под рукой то и взял. Кому не нравится, тот сам делает устройство своим кодом. На коленке за пол часа набросал код да и все. Хоть кто то бы альтернативу предложил. Что ж все такие недоброжелательные профессионалы, диванные критики тут?
1.вариант подсветки супер,по памяти влезет в атмегу 8,клаас.
2.я вообще код не могу писать,тем более какие то фильтры вставлять)))
3.поэтому и задаю вопросы,вот так,можете попинать малехо))
проект классный ,забрасывать ненужно,на критиков обращать внимание не надо,пусть лают.
... Что было под рукой то и взял. ...
... На коленке за пол часа набросал код да и все....
Гайвер-стиль - "тяп-ляп - в продакшн?"
Что ж тогда удивлятся на реакцию сообщества?
Три светодиода добавились. На 10,11,12 пины. Два показывают в какую сторону яркость изменяется, третий (10) изменяет свою яркость в зависимости от расстояния. Гайвер фильтр заменен функцией скользящего среднего.
//----------Используемые библиотеки--------------------- #include <EEPROM.h> // Стандартная библиотека, не требует установки. //--------- Пины подключения периферии------------------ //Сигнальные светодиоды: #define ledDistance 10 // Светодиод указывает дистанцию до объекта. Ярче - ближе. #define ledLightUp 11 // Светодиод указывает, что яркость увеличивается #define ledLightDown 12// Светодиод указывает, что яркость уменьшается #define ledPin 9 //Светодиодная лента через транзистор годятся только 9 или 10 пины для ШИМ 32 кГц!!!! Иначе медленный ШИМ убъет глаза!! //Датчик расстояния #define trigPin 3 //Триггер #define echoPin 4 //Эхо #define MinesPin 5 //- датчика #define PlusPin 2 //+ Датчика //Датчик освещенности (фоторезистор) #define lightPin A3 //----------------Настройки поведения------------------- #define NUM_AVER 10 // Количество измерений для расчета среднего значения расстояния. Больше - медленнее реакция #define delay_Led 60000 //Задержка выключения света в мс после последнего обнаружения человека #define distOn 100 //дистанция в см, на которой при обнаружении объекта включется свет #define distLightUp 12//дистанция в см, при которой начинается увеличение яркости #define distLightDown 5 // дистанция в см, при которой начинается уменьшение яркости #define analogSens 110// Фотодатчик 0..1023. Не включаем подсветку днем. #define delayMeasurement 20 // Задержка перед каждым измерением дистанции. Рекомендована 50. Влияет на скорость реакции, особенно при изменении яркости. //-------------------Переменные------------------------- uint8_t LightLed = EEPROM.read(0);//Яркость ленты. Читаем из энергонезависимой памяти 0..255. uint32_t timePowerrOff;// Переменная содержит время, когда нужно выключить свет boolean ledOffFlag = true;// Флаг однократного плавного затухания boolean eepromNeedUpdate = false; // Флаг что яркость поменялась и ее нужно запомнить при следующем выключении света void setup() { Serial.begin(115200); TCCR1A = 0b00000001; // 8bit TCCR1B = 0b00000001; // x1 phase correct//разгоняем ШИМ на 9,10 пинах до 31,4 кГц analogReference(INTERNAL);//устанавливаем максимальное измеряемое напряжение аналогового входа 1,1В. pinMode(trigPin, OUTPUT); //пин триггера в режиме выхода pinMode(echoPin, INPUT); //пин эхо в режиме входа pinMode(MinesPin, OUTPUT); digitalWrite(MinesPin , LOW); //питание датчика pinMode(PlusPin, OUTPUT); digitalWrite(PlusPin , HIGH);//питание датчика pinMode(ledPin, OUTPUT);// светодиодная лента pinMode(ledLightUp, OUTPUT); pinMode(ledLightDown, OUTPUT); } void setLedOn() { if (ledOffFlag) { // Если свет был выключен то плавно зажигаем его for (int i = 0; i <= LightLed; ++i) { analogWrite(ledPin, i); delay(30); if (i < 20) delay (40); } } timePowerrOff = delay_Led + millis(); digitalWrite (ledLightUp, false);// Гасим светодиод настройки яркости digitalWrite (ledLightDown, false);// Гасим светодиод настройки яркости ledOffFlag = false; // Опустили флаг. Свет включен. } void setLedDistance(uint32_t distance) {// меняем яркость индикаторного светодиода в соответствии с дистанцией if (distance > distLightUp) { //Если мы не в режиме настроек яркости то отобразим дистанцию. distance = constrain(distance, 0, distOn); distance = map(distance, 0, distOn, 100, 0); analogWrite(ledDistance, distance); } } void setLedLightDown() {// Настройка уменьшения яркости analogWrite(ledDistance, 0); // Гасим светодиод настройки яркости if (LightLed == 1) digitalWrite (ledLightDown, LOW); else digitalWrite (ledLightDown, HIGH);// Включаем светодиод настройки яркости if (LightLed > 1) { LightLed--; analogWrite(ledPin, LightLed); } eepromNeedUpdate = true; // Поднимаем флаг что нужно сохранить настройки яркости в энергонезависимую память } void setLedLightUp() {// Настройка увеличения яркости analogWrite(ledDistance, 0);// Гасим светодиод настройки яркости if (LightLed == 255) digitalWrite (ledLightUp, LOW); else digitalWrite (ledLightUp, HIGH);// Включаем светодиод настройки яркости if (LightLed < 255) { LightLed++; analogWrite(ledPin, LightLed); } eepromNeedUpdate = true; // Поднимаем флаг что нужно сохранить настройки яркости в энергонезависимую память } void powerrOff() {//Плавное выключение for (int i = LightLed; i != 0; --i) { analogWrite(ledPin, i - 1); delay(30); if (i < 20) delay (40); } ledOffFlag = true; // Подняли флаг что свет выключен if (eepromNeedUpdate) { // В случае изменения, сохраняем текущие настройки яркости в энергонезависимую память. EEPROM.update(0, LightLed); eepromNeedUpdate = false; } } void loop() { uint32_t distance = middleArifm(measure()); //Показания датчика расстояния uint16_t light = analogRead(lightPin); //Показания датчика света setLedDistance(distance);// Обновить яркость светодиода, показывающего дистанцию if (light < analogSens || timePowerrOff > millis()) { // Если недостаточно света или сейчас включен свет if (distance < distOn) //И если в поле зрения датчика кто-то есть setLedOn();// Включить свет if (distance < distLightUp && distance > distLightDown)// Если дистанция небольшая то увеличиваем яркость setLedLightUp(); if (distance <= distLightDown) // Если дистанция совсем маленькая то уменьшаем яркость setLedLightDown(); } if (timePowerrOff < millis() && !ledOffFlag) // Если долго никого не было и свет еще не выключали то гасим свет powerrOff(); if (ledOffFlag) 2 + 2 != 4; } uint32_t measure() { //блок, измеряющий расстояние delay(delayMeasurement);//Задержка перед измерением дистанции digitalWrite(trigPin, LOW); delayMicroseconds(5); digitalWrite(trigPin, HIGH); delayMicroseconds(15); digitalWrite(trigPin, LOW); return (pulseIn(echoPin, HIGH) / 66); //получаем расстояние с датчика } uint32_t middleArifm(uint32_t newVal) { // принимает новое значение uint32_t average; // перем. среднего static uint32_t valArray[NUM_AVER]; // массив static byte idx = 0; // индекс static boolean firstRun = true; valArray[idx] = newVal; // пишем каждый раз в новую ячейку if (++idx >= NUM_AVER) idx = 0; // перезаписывая самое старое значение average = 0; // обнуляем среднее for (int i = 0; i < NUM_AVER; i++) { if (firstRun) valArray[i] = distOn + 1; // при первом включении устанавливаем дистанцию чтоб не менялась яркость average += valArray[i]; // суммируем } average /= NUM_AVER; // делим firstRun = false; return average; // возвращаем }Во красавчик p-a-h-a .
А есть схема всего? Куда и чего цеплять?
А есть схема всего? Куда и чего цеплять?