Плавное изменение цвета RGB-светодиода

Автор: | 30.11.2017

Примечательный проект «светодиоды в снегу» — в капсулу от бахилл прячется от влаги платка с батарейкой CR2032, микроконтроллером, резисторами и RGB-светодиодом. Весь функционал — плавное изменение цвета. «Упаковываете» такую игрушку в снежок и страшно собой гордитесь. Я вот теперь задумался тоже подобное собрать. Пользователи уже посчитали, прикинули, что при потреблении 5 мАч, от одной новой батарейки будет гореть не меньше 40-45 часов, а если убрать горение красной доли диода, то вообще неделю. На сайте доступен PDF-документ, который можно распечатать и сразу перевести на текстолит.

На плату я установил конденсатор для более стабильного питания. В плане компонентов тут приходится обходиться малой кровью, так как пространство ограничено. Даже разъёма для программирования я не предусмотрел, подпаивался проводками к пинам (специально для этого каналы светодиода оказались на пинах для программирования, а RESET я вывел отдельной площадкой). Резисторы и конденсаторы на этой плате типоразмера 0805.

Пока платы травились, я занялся программой. В ATtiny45 аппаратный вывод ШИМ-сигнала поддерживается на ножках PB0, PB1 и ещё на нескольких. PB2 в этом списке не оказалось. Но плата уже нарисована и травится, поэтому я решил сделать программный ШИМ, применив второй таймер (Timer1).

Для того, чтобы сделать светилку более гибкой в настройке, я применил такой механизм. В чипе есть ПЗУ (EEPROM). В первой ячейке будем хранить число, которое задаёт режим работы. После каждого включения будем увеличивать это значение на 1 и сохранять его в ПЗУ. Так, дёргая батарейкой в разъёме, можно переключать режимы работы. Для того, чтобы не пропустить нужный, каждый режим я продублировал (фактически, следующий режим включится после двух передёргиваний батарейки). Fuse-биты я посчитал, 1МГц мне хватит для комфортного ШИМ и для низкого энергопотребления. Вообще говоря, фьюз-биты оказались стандартными для tiny45, так что их можно не менять. Я использовал Attiny45 просто потому что Attiny13 не было, а в целом они почти одинаковые…


Подробнее о проекте можно почитать на geektimes

А вот, на всякий случай, код этого проекта на Си
#include
#include
#include
#include

#define r_pwm(pwm) OCR0A = pwm
#define b_pwm(pwm) OCR0B = pwm
#define g_pwm(pwm) OCR1A = pwm

#define NUM_MODES 16

int main(void)
{
/* Init LED GPIO pins */
DDRB = 7; /* pins 0, 1, 2 */

/* Init PWM timers */
/* Timer0 is for R and G channels */
TCCR0A = (1<= NUM_MODES)
mode = 0;
eeprom_write_byte((uint8_t *) 1, mode);

uint8_t i;
while(1) {
switch(mode >> 1) {
case 0:
r_pwm(255);
break;
case 1:
g_pwm(255);
break;
case 2:
b_pwm(255);
break;
case 3:
r_pwm(255);
g_pwm(255);
break;
case 4:
g_pwm(255);
b_pwm(255);
break;
case 5:
r_pwm(255);
b_pwm(255);
break;
case 6:
r_pwm(255);
g_pwm(255);
b_pwm(255);
break;
case 7:
for (i=0; i < 255; i++) { r_pwm(255-i); g_pwm(i); _delay_ms(20); } for (i=0; i < 255; i++) { g_pwm(255-i); b_pwm(i); _delay_ms(20); } for (i=0; i < 255; i++) { b_pwm(255-i); r_pwm(i); _delay_ms(20); } } } return 0; } ISR(TIM1_OVF_vect) { if (OCR1A != 0) PORTB |= (1<<2); } ISR(TIM1_COMPA_vect) { PORTB &= ~(1<<2); }

Добавить комментарий

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