RGB диод. Эксперимент 1.
Цель: провести эксперимент с RGB диодом.
Описание работы светодиода
Трёхцветный светодиод или RGB-светодиод — это совмещённые в одном корпусе светодиоды красного, зелёного и синего цветов.
Светодиод имеет 4 ноги. 3 ноги — аноды, соответствующие отдельным цветам и одна — общий катод. Подавая сигнал на один из анодов, можно добиться свечения одним из цветов. Используя широтно-импульсную модуляцию (PWM-сигнал) для всех анодов одновременно, можно получить свечение произвольным цветом.
Красный | Зеленый | Синий | |
---|---|---|---|
Максимальное прямое напряжение (В) | 1.9 | 3.8 | 3.8 |
Сила тока (мА) | 20 | 20 | 20 |
Схема
Управлять работой светодиода будет микроконтроллер ATTiny13A, он будет выдавать 3 PWM сигнала разной скважности. Считывать он будет потенциометр, который будет задавать скважность. Т.к потенциометр один, то будет еще и кнопка, нажатие которой будет переключать канал, на который будет воздействовать потенциометр. Схема питается от источника питания 4.8 Вольт.
Вот как выглядит сама схема:
Подключение светодиода достаточно простое и так как схема упрощена, то используется один токоограничительный резистор 220 Ом, но это не совсем верно, лучше использовать три, на каждый канал диода. Т.к у меня в запасе был один резистор, то оставлю пока так. Но при повторении нужно быть внимательным.
Ножки МК 0, 3, 4 используются как каналы выводы, формирующие PWM сигнал для диода. Ножка 2 - АЦП для потенциометра и ножка 1 - цифровой вход для кнопки.
Требует внимания схема, которойобернута кнопка. Там можно увидеть RC цепь, это для того, чтоб аппаратно избежать дребезга контактов кнопки и не городить программные навароты "антидребезга". Вот выделенная схема для подавления дребезга:
Вот как это выглядит на макетной плате:
Программа
А теперь программа микроконтроллера.
#define F_CPU 9600000UL
#include <avr/io.h>
#include <util/delay.h>
#define _BV(bit) (1 << (bit))
unsigned char buttonPull = 0;
unsigned char tunningOutput = 0;
unsigned int border1 = 50;
unsigned int border2 = 50;
unsigned int border3 = 50;
unsigned int counter = 0;
unsigned int comparator = 0;
unsigned char out_result = 0;
unsigned char old_result = 0;
int main(void)
{
//настройка выходов
DDRB = _BV(DDB0) | _BV(DDB3) | _BV(DDB4) ;
//настройка АЦП для считывания значения напряжения на потенциометре
ACSR=0x80;
ADMUX = _BV(MUX0);
ADCSRA = _BV(ADEN) | _BV(ADPS0);
while (1)
{
//кнопка нажата и ранее не была нажата? да, устанавливаем признак
if ((PINB & _BV(PINB1)) && !buttonPull){
buttonPull = 1;
}
//кнопка была нажата, но теперь отпущена? да, переключаем канал, на который воздейсвует потенциометр
if (!(PINB & _BV(PINB1)) && buttonPull){
buttonPull = 0;
tunningOutput++;
tunningOutput = tunningOutput%3;
}
//считываем АЦП, включаем, дожидаемся флажка и записываем число, опорное напряжение - 4.8В
ADCSRA |= _BV(ADSC);
while ((ADCSRA & _BV(ADIF)) == 0);
comparator = ADCW;
//в зависимости от выбранного канала
switch(tunningOutput){
case 0:{
border1 = comparator / 11;
break;
}
case 1:{
border2 = comparator / 11;
break;
}
default:{
border3 = comparator / 11;
break;
}
}
_delay_us(1);
//PWM формируется программно, без таймеров
//полный период - это 25 квантов времени, в каждый квант сравнивается граница (от 0 до 100) и номер кванта.
//т.к квантов 25, а нужно 100, то для совпадения размерностей номер кванта умножается на 4
// если получившееся число меньше границы, то устанавливаем 1 на нужную ножку МК, иначе, устанавливаем 0
counter++;
counter=counter%25;
out_result = 0;
if ((counter*4)<border1){
out_result |= _BV(PORTB0);
}
if ((counter*4)<border2){
out_result |= _BV(PORTB3);
}
if ((counter*4)<border3){
out_result |= _BV(PORTB4);
}
if (old_result!=out_result) PORTB = out_result;
old_result = out_result;
}
}
Вот так и формируется сигнал с заданным PWM. Частота сигнала должн быть более 80 Гц, чтоб глаз не замечал мерцания.
Fuse bits = 0x6A 0xFD 0xFF
Вот как теперьдиод меняет цвета в зависимости от настроек каналов:
А это формируемый PWM сигнал от трех каналов: