Главная » Микроконтроллеры » Контроллер освещения на ATtiny13 с подсчетом входящих и выходящих людей

Контроллер освещения на ATtiny13 с подсчетом входящих и выходящих людей

Говорят, что «необходимость — мать изобретательности». Мой проект, конечно же, создавался не из нужды, а из-за удобства. Это датчик освещенности, который автоматически включает освещение в комнате когда кто-то входит в нее.

HILDA - электрическая дрель
Многофункциональный электрический инструмент способн...
Подробнее

Решение на самом деле очень простое, хотя требует некоторой работы в части подключения к электросети и монтажа датчиков. На самом деле, эта часть самая сложная, если вы хотите сделать это эстетично. И так как устройство было на стадии эксперимента, то вопрос эстетики стоял на втором плане.

Принцип действия

В основе проекта — микроконтроллер ATtiny13, несколько оптических компонентов и реле 12В/230В. Идея и принцип действия основан на инфракрасном обнаружении, входит ли кто-то в комнату или выходит из нее.

Система подсчитывает количество людей, входящих в комнату. Если в комнату войдут три человека, свет выключится после выхода из нее третьего, но с заданной задержкой. Лично я иногда выхожу из комнаты буквально на «секунду» и возвращаюсь, так что в моем случае этот функционал точно пригодится.

Когда инфракрасный свет, излучаемый ИК-светодиодами, постоянно попадает на фототранзисторы, микроконтроллер «знает», что в этом месте никого нет. Только в зависимости от того, с какой стороны кто-то идет, свет включается или выключается. Направление определяется порядком прерывания лучей. Принцип работы очень простой, поэтому перейдем к конкретике, а собственно к «железу».

Оборудование

Самым важным вопросом, помимо микроконтроллера, в этом проекте было — как построить схему, которая могла бы различать, стоит ли кто-то в данном месте (между ИК-светодиодом и датчиком) или нет.

В этом устройстве я использовал инфракрасный диапазон, к которому человеческий глаз нечувствителен. Благодаря этому, невидимым для людей способом, мы можем контролировать, пересекает ли кто-нибудь инфракрасные лучи.

Методом многих проб и ошибок я экспериментировал с соответствующими номиналами резисторов, последовательно включенных с фототранзисторами, чтобы они относительно точно реагировали на изменение состояния на входе микроконтроллера только в этом инфракрасном диапазоне.

Как видно из графика, характеристики фототранзистора не идеальны. Хотя он характеризуется наивысшей чувствительностью в диапазоне, для которого он предназначен. Он реагирует на все остальные, видимые частоты, которые я наблюдал во время тестов.

Именно поэтому так важен подбор резистора, подключенного последовательно с фототранзистором, благодаря которому он не реагирует на внешнее освещение.

Я использовал светодиоды и фототранзисторы одного производителя и с тем же рабочим диапазоном, чтобы получить максимальную чувствительность с минимальными усилиями. Конечно, ничто не мешает использовать другие светодиоды или фототранзисторы.

Принципиальная схема

 

На схеме, помимо микроконтроллера, также можно увидеть линейный стабилизатор 7805 (регулятор напряжения), на вход которого подается +12 В. Чтобы обеспечить хорошее и стабильное питание, я добавил в схему стабилизатора несколько электролитических конденсаторов. Как видите, нашлось место и для нескольких развязывающих конденсаторов по 100 нФ.

Почему схема питается от 12-вольтового адаптера если все равно переводим в +5 В? Напряжение +12В требуется для реле NT73-2CS12-24. Это реле управляется МОП-транзистором BS170.

В схему также добавлены сигнальный светодиод, микровыключатель, резистор 4k7 (подтягивающий сброс ATtina) и разъемы для подключения датчиков (фототранзисторов).

Возвращаясь к фототранзисторам, давайте теперь разберемся с ними в плане управления. На входы датчиков подается питание. Когда инфракрасное излучение попадает на фототранзистор, он усиливает этот световой сигнал, что вызывает падение напряжения на входе микроконтроллера и приводит к интерпретации сигнала как «0». Однако, когда инфракрасный луч прерывается, на входе устанавливается «1».

Очень «полезными» здесь являются триггеры Шмитта на входных выводах микроконтроллера, благодаря которым состояние входа остается стабильным, а переключает состояние с определенным гистерезисом.

Печатные платы

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

Плата микроконтроллера получилась неплохой. Заданные размеры должны были быть такими, чтобы он поместился в имеющийся у меня корпус.

Печатная плата доступна для скачивания внизу страницы.

Список компонентов:

  • Микроконтроллер ATtiny13A-PU
  • Реле NT73-2CS12-24
  • 2 светодиода L-53F3BT
  • 2 фототранзистора L-53P3BT
  • Резисторы 1x 4k7, 2x 20k, 2x 75R, 1x 1K, 1x 240R
  • Конденсаторы 1x 220 мкФ, 1x 100 мкФ, 3x 100 нФ
  • 5 2-полюсных разъема
  • 1 разъем для питания
  • Адаптер питания 12 В
  • Стабилизатор 7805
  • Транзистор BS170
  • Несколько проводов витой пары
  • Микровыключатель
  • Красный светодиод 3мм
  • Панелька DIP8

Программное обеспечение

Дизайн программы, можно сказать, классический. В исходной версии я хотел организовать работу на внешних прерываниях, которые «будили» бы систему в момент прерывания инфракрасных лучей.

Но по ходу работы передумал и написал программу по-другому, потому что здесь нет никаких требований по питанию, поэтому нет необходимости переводить систему в спящий режим.

Ниже приведен код программы с комментариями:

#define F_CPU 1000000L //определение тактовой частоты процессора
#include <stdio.h>  // подключение необходимых библиотек
#include <avr/io.h>  
#include <util/delay.h>  
  
  
#define PRZ (1<<PB0)  //переключить определение макроса  
#define PRZ_ON PORTB &=~PRZ  
#define PRZ_OFF PORTB |=PRZ  
  
#define LED (1<<PB1)  // Определение макроса светодиода
#define LED_ON PORTB |=LED  
#define LED_OFF PORTB &=~LED  
  
int przerwano_1(void);  // прототипы функций, код которых можно увидеть в конце
int przerwano_2(void);                  
int ustaw_przekaznik(int);                        
  
int N=1; // инициализация глобальной переменной, отвечающей за подсчет людей, которые входят
   // свет включается в начале, поэтому я предполагаю, что в комнате 1 человек 
    
int l;  // переменная, отвечающая за подсчет кратных 10 мс, чтобы свет не погас сразу после выхода 
int const CZAS_ZWLOKI = 10*100; // константа, отвечающая за установку времени задержки выключения света, например 30 секунд * 100; 
     
     
int main(void)  
{  
 DDRB|=(1<<PB0)|(1<<PB1); // Светодиодные и релейные выходы
 PORTB|=(1<<PB3)|(1<<PB4); // датчики  
 PORTB|=(1<<PB2);   // кнопка  
   
  
 LED_ON; _delay_ms(100); LED_OFF; _delay_ms(100); // мигание светодиода в качестве приветствия 🙂
 LED_ON; _delay_ms(100); LED_OFF;  
   
    while(1)  
    {  
  if (!(PINB & 0b100)) {  // когда кнопка нажата
   _delay_ms(50);   // ожидание 50 мс для избежания дребезга
   if (!(PINB & 0b100)) {  
    N= (N<=0) ? 1 : 0; // когда N<=0 то присвоить 0 для N  
   }  
   LED_ON;  
   _delay_ms(400); // ожидание 400 мс, чтобы случайно не вызвать несколько выключений одним касанием
   LED_OFF;  // кстати, он мигает светодиодом, сигнализируя о том, что он "схватился"
  }  
    
  if (przerwano_1() && !przerwano_2()) {  // когда кто-то выходит из комнаты  
   while (przerwano_1()) {     // когда прерывается 1 луч
    while (przerwano_2()) {    // затем, когда второй луч был прерван  
      if (!przerwano_1()) {  // и, наконец, когда 1 луч "вернулся в видимость"
        LED_ON;  
        if (N==1) {   // если последний человек выходит из комнаты 
          while (!przerwano_1()) { // если он вернется меньше чем через задержку, свет не погаснет
           l++;     // обратный отсчет кратный 10 мс  
           if (l >= CZAS_ZWLOKI) { // и если он придет позже, он погаснет
            N--;  
            break;  
           }  
           _delay_ms(10); // подожди 10 мс  
          }  
        } else {  
          N--;  //если в комнате остался хотя бы один человек, вычтите его 
        }  
        LED_OFF;  
        break;     // уменьшить N и прервать while (interrupted_2 ()) 
      }  
    }  
   }  
  }  
  else if (przerwano_2() && !przerwano_1()) { // похоже на выход из комнаты
   while (przerwano_2()) {     // луч 2 был прерван 
    while (przerwano_1()) {    // 1 луч был прерван
      if (!przerwano_2()){  // луч 2 "видимость восстановлена"
       N++;  
       break;     // увеличьте количество людей и остановитесь while(przerwano_1())  
      }         
    }  
   }  
  }  
  N=ustaw_przekaznik(N);  // настройка реле 
  l=0;     // установить счетную переменную 
    }  
}  
  
int ustaw_przekaznik(int k) { // функция, отвечающая за управление реле
 if (k<=0) {     // в случае ошибки и получения отрицательного количества людей в комнате
  k=0;     // код исправляет это и устанавливает N = 0, т.е. возвращает 
  PRZ_OFF;  
 } else {     // когда количество людей в комнате больше 0, включите свет
  PRZ_ON;  
 }  
 return k;     // вернуть количество человек в комнате в переменную N 
}  
  
int przerwano_1(void) {      
 return (PINB & 0b1000) ? 1 : 0; // если луч прерван, верните 1, иначе 0
}  
  
int przerwano_2(void) {      
 return (PINB & 0b10000) ? 1 : 0;  
}
Скачать файл проекта (140,5 KiB, скачано: 100)

 

Источник

Паяльный фен YIHUA 8858
Обновленная версия, мощность: 600 Вт, расход воздуха: 240 л/час...
Подробнее

Оставить комментарий

Ваш email нигде не будет показан. Обязательные для заполнения поля помечены *

*