Arduino LED мига плавно. Контрол на яркостта на LED чрез потенциометър

10.09.2021

Как се раждат програмите

Това ще бъде малко необичайна статия, в нея ще се опитам не просто да покажа готов код, който прави нещо, но ще покажа как се ражда едно устройство и фърмуера за него. Ще разгледаме логиката на програмата и как да изградим тази логика.

Днес ще решим следния проблем: има 2 светодиода, те трябва да бъдат свързани към Arduino и трябва да се реализира възможност за регулиране на яркостта на тяхното осветление.

Да започваме!

На първо място, трябва да помислим как ще изглежда нашето устройство и какво ще ни трябва, за да го внедрим. Трябва ни нещо, за да регулираме яркостта на светодиодите и да видим в какъв режим работят светодиодите в момента щит, който обсъдихме в последната статия, е страхотен.

Сега просто трябва да свържем светодиодите, така наречената Bradboard е страхотна за това, това е пластмасово нещо (не знам как друго да го нарека), в което можете да свържете проводници от Arduino и други без запояване електронни компоненти, което е много удобно, когато не знаете как точно ще изглежда готово устройствоили веригата е необходима само за няколко стартирания. Китайците занитват огромен брой от техните разновидности, аз лично използвам този:

За да се разбере по-лесно как работи вътре, ще приложа диаграма на вътрешните връзки:

Свързване на светодиоди къмАрдуино

Мнозина сега ще кажат: какво е толкова трудно да свържете светодиод, това е крушка! И те ще грешат, светодиодът далеч не е обикновена крушка, а полупроводниково осветително устройство. Което не се захранва от напрежение като обикновена крушка, а от ток и ако токът надвиши допустимите стойности, светодиодът ще започне да се влошава, яркостта му ще намалее, което ще се забележи след известно време, в зависимост от мощността на токът се пробива или дори изгаря незабавно.

Как да избегнем повреда на светодиода поради висок ток? Всичко е много просто: трябва да използвате резистор за ограничаване на тока, който трябва да се изчисли за всеки светодиод в зависимост от неговите характеристики. Изчисляването на резистори за светодиод е тема за отделна статия и днес няма да се задълбочаваме в тази тема, тъй като най-вероятно не знаете характеристиките на светодиода, който сте намерили някъде. В този случай използвам малко правило: ако светодиодът не свети ярко, тогава го захранвам през резистор със съпротивление от 220 до 400 ома, в зависимост от това кой резистор е бил под ръка. Основното нещо, което трябва да запомните е, че повече е по-добре, отколкото по-малко. С повече съпротивление, отколкото изисква светодиодът, той просто ще свети по-слабо от нормалното.

Сега трябва да решим как да регулираме яркостта на светодиода, за това можете да използвате променливи резистори, които по принцип ще премахнат интерактивната настройка и поради тази причина няма да използваме този методв тази статия. Ще използваме ШИМ, внедрен на платката Arduino.

Какво е PWM

PWM ( широчинно-импулсна модулация) е промяна в работния цикъл на сигнала за определен период от време. Шим сигналът има следната форма в сравнение с постоянен сигнал:

На тази снимка 100% от работния цикъл е липсата на ШИМ като такъв, сигналът върви без промени, сякаш изходът е просто свързан към 5 волта.

0% работен цикъл е липсата на сигнал, сякаш проводникът не е свързан никъде.

Останалите режими на работа са бързо превключване на режимите на работа, което кара светодиода да мига с висока скорост, незабележима за човешкото око (100 пъти в секунда), което го кара да гори с недостатъчна яркост. Arduino, в зависимост от версията на използвания чип, има различни количества PWM изходи, на платката са маркирани със знака ~ от предишната статия знаем, че това са 6 изхода 3, 5, 6, 9, 10 и 11, ще използваме пинове 10 и 11.

Нека най-накрая свържем светодиодите към платката. Поставяме нашия LCD щит на Arduino и сглобяваме следната схема, за която имаме нужда от мозъчна платка, 2 светодиода, 2 резистора от 250 ома и 3-4 мъжки-мъжки проводника. Диаграмата ще изглежда така:

И не забравяйте, че светодиодът има полярност, дългият или крив крак на светодиода (както е на диаграмата) е плюс, който е свързан чрез резистор.

Тук вероятно ще завърша първата част на статията, във втората част ще работим върху разработването на логиката на работа и писането на програмен код. всичко добро!

Потенциометърът е променлив резистор, който променя съпротивлението си, когато завъртите копчето.

Какво е необходимо за проекта:

  • Arduino UNO или друг аналог
  • Развойна дъска
  • Потенциометър
  • LED
  • Резистор 220 ома

Схема на свързване на макет.

За да регулираме яркостта на светодиода, ние го свързваме към конектор, който поддържа PWM, в нашия случай това е цифров щифт 3. Свързваме VCC и GND конекторите на потенциометъра към захранващите и заземяващите шини на макетната платка. Конектор A0 към аналогов щифт A0.

След успешно сглобяване на веригата, изтеглете тази скица:

#define LED 3 #define POT A0 void setup() ( pinMode(LED, OUTPUT); // настройка на щифта за изходен режим pinMode(POT, INPUT); // настройка на щифта за входен режим ) void loop() ( / / декларирайте целочислени променливи int turn, яркост; //прочетете напрежението на потенциометъра в turn, неговите стойности ще варират от 0 до 1023 turn = analogRead(POT); //запишете стойността на turn в яркостната променлива, / /разделено на 4. Ще приема стойности от 0 до 255 яркост = turn / 4; //включете светодиода с яркост, равна на стойността на яркост analogWrite(LED, яркост);

Сега нека се опитаме да напишем код за същата схема, но в чист SI в среда AtmelStudio 7. Ще изглежда така.

#включи int main(void) ( //Конфигуриране на MK щифтовете, от които се нуждаем за входове и изходи. DDRC = 0<

Сега нека се опитаме да разберем тези два примера. Факт е, че средата на Arduino е проектирана за бърз старт за начинаещи. Ако трябва да мигате светодиод или да щракнете върху реле, това може да стане за няколко минути. Средата Arduino е напълно изолирана от хардуера на микроконтролера и следователно всичко в нея се осъществява чрез функции, написани от разработчиците на този софтуер. Тези функции и техните вътрешни са скрити в дълбините на програмата. Средният потребител може да извика само необходимите функции за конфигуриране на хардуерните компоненти на MK. Изглежда, че това прави програмирането много по-лесно. По принцип това е вярно. Следователно средата и платките Arduino са много популярни сред начинаещите ентусиасти на MK проекти. Има обаче и недостатъци, например тези, които програмират Arduino, не могат да програмират микроконтролери, които не се поддържат от Arduino IDE. Например, изглежда невъзможно да се програмира който и да е модел на микроконтролера Attiny AVR. И други модели на Atmega, които не са включени в платките на Arduino, също са пропуснати. По принцип, ако проектите не са особено сложни, тогава можете да се отдадете, тогава средата на Arduino е достатъчна. Ако имате нужда от нещо голямо и сложно, тогава разбира се чисти правила SI. Но тогава ще трябва да разберете MK регистрите, как работят определени MK възли. Трябва да прочетете документацията, да проучите и разберете самия SI. Въпреки това, ако вече имате опит в писането на скици в средата на Arduino, тогава с времето ще бъде възможно да разберете и SI.

Сега нека се опитаме да разгледаме кода SI и да разберем, че не е толкова страшно.

Например линията #включи
свързва заглавния файл, в който е избран желаният от нас MK. Средата AtmelStudio 7 прави това автоматично при създаване на нов проект.

DDRC=0<PORTC= 0<DDRD=1<PORTD = 0<

Тези линии конфигурират щифтовете на платката Arduino, от които се нуждаем като вход или изход. PC0това е същото като A0на платката, този щифт трябва да бъде конфигуриран като вход, тъй като към него е свързан потенциометър. И стойността на ADC ще бъде прочетена от този щифт.

Регистрирайте се ADMUXИ ADCSRAНие конфигурираме самия ADC възел в режима, от който се нуждаем. По-специално, ние го конфигурираме така, че ADC автоматично постоянно да чете стойността от изхода A0и съхранява тази стойност в регистър ADCH.

MK има хардуерни таймери, това също са възли, които правят възможно работата с PWM щифтове, например, PWM щифт ~3, към който е свързан светодиодът, принадлежи към вътрешния Таймер2. Atmega 328 има повече Таймер0И Таймер1. И така, използвайки регистри TCCR2AИ TCCR2B, нека настроим нашия Timer2 в режим FAST_PWM, това ни дава възможност да работим с пин ~3 на платката Arduino. Е, в главния цикъл на програмата веднага прехвърляме стойността от ADC към нашия Таймер2. Това се прави в един ред OCR2B=ADCH.

Единственият въпрос е как да кача код, написан на SI, в нашия Arduino в AtmelStudio? Това може да стане директно от средата на AtmelStudio. Вярно е, че преди това трябва да прочетете и запишете буутлоудъра от платката Arduino със същия програмист. В противен случай платката Arduino няма да може да работи със средата на Arduino. По всяко време можете да използвате програмиста, за да върнете буутлоудъра на мястото му.

В този експеримент добавяме част от яркостта към светодиода с един бутон и я намаляваме с другия.

СПИСЪК НА ЧАСТИТЕ ЗА ЕКСПЕРИМЕНТА

- 1 Arduino Uno платка;

- 1 брейдборд без запояване;

- 2 бутона за часовник;

- 1 резистор с номинална стойност 220 ома;

- 1 LED;

- 7 мъжки-мъжки проводника.

Електрическа схема

СХЕМА НА МАКЕТ

МОЛЯ, ОБЪРНЕТЕ ВНИМАНИЕ

  • Ако преработвате веригата от предишния експеримент, имайте предвид, че този път трябва да свържем светодиода към порт, който поддържа ШИМ.

СКИЦА

изтегляне на скица за Arduino IDE
#define PLUS_BUTTON_PIN 2 #define MINUS_BUTTON_PIN 3 #define LED_PIN 9 int яркост = 100; boolean plusUp = вярно; boolean minusUp = вярно; void setup() ( pinMode(LED_PIN, OUTPUT); pinMode(PLUS_BUTTON_PIN, INPUT_PULLUP); pinMode(MINUS_BUTTON_PIN, INPUT_PULLUP); ) void loop() ( analogWrite(LED_PIN, яркост); // отговаря на щраквания, използвайки функцията, която написахме plusUp = handleClick(PLUS_BUTTON_PIN, plusUp, +35); minusUp = handleClick(MINUS_BUTTON_PIN, minusUp, -35); // Собствена функция с 3 параметъра: номерът на щифта с бутона // (buttonPin), състоянието преди проверка (wasUp) и градация // на яркостта, когато щракнете върху бутона (делта). Функцията връща // (на английски return) новото, текущо състояние на бутона boolean handleClick(int buttonPin, boolean wasUp, int delta) ( boolean isUp = digitalRead(buttonPin); if (wasUp && !isUp) ( delay(10 ); isUp = digitalRead(buttonPin); // ако е имало щракване, променя яркостта от 0 на 255 if (!isUp) brightness = constrain(brightness + delta, 0, 255 ) return isUp; // връща стойността обратно към кода на обаждащия се).

ПОЯСНЕНИЯ КЪМ КОДА

  • Можем да използваме не само вградени функции, но и да създаваме наши собствени. Това е оправдано, когато трябва да повторим едни и същи действия на различни места в кода или, например, трябва да извършим едни и същи действия с различни данни, както в този случай: обработка на сигнала от цифрови портове 2 и 3.
  • Можете да дефинирате свои собствени функции навсякъде в кода извън кода на други функции. В нашия пример дефинирахме функция след цикъл .
  • За да дефинираме нашата собствена функция, имаме нужда от:
    • Декларирайте какъв тип данни ще върне. В нашия случай е така булево. Ако функцията изпълнява само някои действия и не връща никаква стойност, използвайте ключовата дума невалиден
    • Задайте на функцията име - идентификатор. Тук важат същите правила, както при именуване на променливи и константи. Функциите са именувани в същия стил likeVariables .
    • В скоби избройте параметрите, предадени на функцията, като посочите типа на всеки. Това е декларация на променливи, които са видими в новосъздадената функция и само в нея. Например, ако в този експеримент се опитаме да получим достъп wasUpили еНагореот цикъл ()Ще получим съобщение за грешка от компилатора. По същия начин променливите, декларирани в цикъл, не са видими за други функции, но техните стойности могат да бъдат предадени като параметри.
    • Между чифт фигурни скоби напишете кода, изпълняван от функцията
    • Ако функцията трябва да върне някаква стойност, използвайте ключовата дума връщанеукажете каква стойност да върнете. Тази стойност трябва да е от типа, който сме декларирали
  • Така наречените глобални променливи, т.е. Променливите, които могат да бъдат достъпни от всяка функция, обикновено се декларират в началото на програмата. В нашия случай това е яркост .
  • Вътре във функцията, която създадохме handleClickСлучва се същото като в експеримента.
  • Тъй като при стъпка на увеличаване на яркостта от 35, след не повече от осем последователни кликвания върху един от бутоните, стойността на израза яркост + делтаще излезе извън интервала . Използване на функцията ограничавамограничаваме разрешените стойности за променливата яркостопределени интервални граници.
  • В израза plusUp = handleClick(PLUS_BUTTON_ ПИН , плюс нагоре, +35)имаме достъп до променливата плюсНагоредва пъти. Тъй като = поставя стойността на десния операнд в левия, като първо изчислява какво ще върне handleClick. Така че, когато я дадем плюсНагорекато параметър все още има старата стойност, изчислена при последното извикване handleClick .
  • Вътре handleClickизчисляваме новата стойност на яркостта на LED и я записваме в глобална променлива яркост, които при всяка итерация цикълтоку-що премина към analogWrite .

ВЪПРОСИ, ДА СЕ ТЕСТВАТЕ

  1. Какво означава ключовата дума? невалиден ?
  2. Как се държи една програма, когато една променлива се споменава от различни страни на оператора за присвояване = ?

ЗАДАЧИ ЗА САМОСТОЯТЕЛНО РЕШАВАНЕ

  1. Променете кода, така че стъпката на промяна на яркостта да се регулира на едно място.
  2. Създайте друга функция и преработете кода, така че една функция да отговаря за проследяването на натисканията на клавиши, а друга да отговаря за изчисляването на яркостта на светодиода и връщането му към analogWrite .

Функцията analogWrite() се използва за отслабване на светодиода и постепенното му включване.

AnalogWrite използва широчинно-импулсна модулация (PWM), която позволява на цифровия щифт да се включва/изключва с висока скорост, генерирайки ефект на затихване.

Какво ще ви трябва за проекта

  • Ардуино платка
  • Бредборд
  • LED
  • резистор 220 ома

Схема на свързване на LED към Arduino

Свържете анода (по-дълъг, положителен крак) на светодиода към цифровия щифт 9 на платката Arduino чрез резистор от 220 ома. Свържете катода (по-къс, отрицателно зареден крак) към земята.

Електрическа схема на светодиод, свързан към Arduino


Опция за екран с LED за Arduino

Описание на програмата за Arduino

След деклариране на пин 9 като ledPin, тялото на функцията setup() не е необходимо да се попълва.

Функцията analogWrite(), която ще използвате в главния цикъл, изисква два аргумента: един за указване на щифта за запис и един за показване на PWM стойността, която се записва.

За да светнете постепенно и да изключите вашия светодиод, постепенно увеличете стойността на ШИМ от 0 до 255, след това обратно до 0, за да завършите цикъла. В скицата по-долу стойността на ШИМ се използва за променлива, наречена яркост. Всеки път, когато цикълът завърши, той увеличава стойността на променливата.

Ако яркостта достигне своята гранична стойност (0 или 255), fadeAmount променя стойността си на отрицателна. С други думи, ако fadeAmount е 5, стойността му се променя на -5. При следващата итерация на цикъла това кара променливата за яркост да се промени.

analogWrite() позволява на PWM стойността да се променя бързо, така че забавянето в края на скицата да контролира скоростта на затихване. Опитайте да промените стойността на закъснението и вижте как работи програмата.

Скица за Arduino IDE

Този пример показва как да осигурите затихване на пин 9 с помощта на функцията analogWrite().

int led = 9; // щифт, към който е свързан светодиодът

int яркост = 0; // LED яркост

int fadeAmount = 5; // колко да се увеличи яркостта на светодиода

// функцията за настройка се изпълнява веднъж след рестартиране на платката:

// декларира пин 9 като изход:

pinMode(led, OUTPUT);

// цикълът се повтаря безкрайно:

// задава яркостта на пин 9:

analogWrite(LED, яркост);

// промяна на яркостта при следващата итерация с помощта на цикъл:

яркост = яркост + fadeAmount;

// променя стойността на затихване до подобна с обратен знак при гранични стойности:

ако (яркост == 0 || яркост == 255) (

fadeAmount = -fadeAmount ;

// забавяне от 30 за проследяване на ефекта на избледняване

Сега нека разгледаме многоцветния светодиод, който често се нарича съкращение: RGB LED. RGB е съкращение, което означава: Red - червено, Green - зелено, Blue - синьо. Тоест вътре в това устройство са поставени три отделни светодиода. В зависимост от типа, RGB LED може да има общ катод или общ анод.

1. Смесване на цветове

Защо един RGB LED е по-добър от три конвенционални? Всичко се дължи на способността на нашето зрение да смесва светлина от различни източници, разположени близо един до друг. Например, ако поставим сини и червени светодиоди един до друг, тогава на разстояние няколко метра тяхната светлина ще се слее и окото ще види една лилава точка. И ако добавим и зелено, точката ще ни изглежда бяла. Точно така работят компютърните монитори, телевизорите и външните екрани. Телевизионната матрица се състои от отделни точки с различни цветове. Ако вземете лупа и погледнете през нея към монитора, който е включен, лесно можете да видите тези точки. Но на външен екран точките не са разположени много плътно, така че да се различават с просто око. Но от разстояние няколко десетки метра тези точки са неразличими. Оказва се, че колкото по-близо са многоцветните точки една до друга, толкова по-малко разстояние е необходимо на окото, за да смеси тези цветове. Оттук и заключението: за разлика от три отделни светодиода, смесването на цветовете на RGB LED се забелязва още на разстояние 30-70 см. Между другото, RGB LED с матова леща се представя още по-добре.

2. Свързване на RGB LED към Arduino

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

3. Програма за управление на RGB LED

Нека създадем проста програма, която ще освети всеки от трите цвята на свой ред.<3; i++) pinMode(rgbPins[i], OUTPUT); } void loop() { digitalWrite(rgbPins, LOW); digitalWrite(rgbPins, HIGH); delay(500); digitalWrite(rgbPins, LOW); digitalWrite(rgbPins, HIGH); delay(500); digitalWrite(rgbPins, LOW); digitalWrite(rgbPins, HIGH); delay(500); }

const байт rPin = 3; const байт gPin = 5; const байт bPin = 6; void setup() ( pinMode(rPin, OUTPUT); pinMode(gPin, OUTPUT); pinMode(bPin, OUTPUT); ) void loop() ( // изключване на синьо, включване на червено digitalWrite(bPin, LOW); digitalWrite( rPin, HIGH; // изключване на червено, включване на зелено digitalWrite (gPin, HIGH); // изключване на зелено, включване на синьо digitalWrite (gPin, LOW). , HIGH); delay(500); Заредете програмата в Arduino и наблюдавайте резултата. Вашият браузър не поддържа видео маркера. Нека оптимизираме малко програмата: вместо променливите rPin, gPin и bPin ще използваме масив. Това ще ни помогне в следващите задачи.

const byte rgbPins = (3,5,6); void setup() ( for(byte i=0; i
  • 4. Седем цвята на дъгата
  • Сега нека се опитаме да осветим два цвята едновременно. Нека програмираме следната последователност от цветове:
  • червено
  • червено + зелено = жълто
  • зелено
  • зелено + синьо = светло синьо
синьо<3; i++) pinMode(rgbPins[i], OUTPUT); } void loop() { // перебираем все шесть цветов for(int i=0; i<6; i++){ // перебираем три компоненты каждого из шести цветов for(int k=0; k<3; k++){ digitalWrite(rgbPins[k], rainbow[i][k]); } delay(1000); } } В результате работы программы получается: Your browser does not support the video tag.

синьо + червено = лилаво

Пропуснахме оранжевия цвят за простота. И така, оказаха се шест цвята на дъгата 🙂 const byte rgbPins = (3,5,6); const byte rainbow = ((1,0,0), // червено (1,1,0), // жълто (0,1,0), // зелено (0,1,1), // синьо ( 0,0,1), // синьо (1,0,1), // лилаво); void setup() ( for(byte i=0; i analogWrite 5. Плавна промяна на цвета<3; i++){ pinMode(rgbPins[i], OUTPUT); } // начальное состояние - горит красный цвет analogWrite(rgbPins, 255); analogWrite(rgbPins, 0); analogWrite(rgbPins, 0); } void loop() { // гасим красный, параллельно разжигаем зеленый for(int i=255; i>Не напразно свързахме RGB LED към щифтове 3, 5 и 6. Както знаете, тези щифтове ви позволяват да генерирате PWM сигнал с различни работни цикли. С други думи, ние не можем просто да включим или изключим светодиода, но и да контролираме нивото на напрежение върху него. Това става с помощта на функцията

. Нека направим така, че нашият светодиод да преминава между цветовете на дъгата не рязко, а плавно.

  1. Температурен индикатор. Нека добавим термистор към веригата и да го свържем към аналоговия вход. Светодиодът трябва да променя цвета си в зависимост от температурата на термистора. Колкото по-ниска е температурата, толкова по-син е цветът, а колкото по-висока е температурата, толкова по-червен е.
  2. RGB лампа с регулатор. Нека добавим три променливи резистора към веригата и да ги свържем към аналоговите входове. Програмата трябва непрекъснато да чете стойностите на резистора и да променя цвета на съответния RGB LED компонент.