Вітаю всіх. Одного разу сподобався мені скляну кулю, який в темряві випромінює світло, накопичений за день, та й до того ж в підставці до нього була RGB підсвічування. Однак підсвічування ця була настільки халтурно (8 кольорів, та й ті стрибком змінювалися), що було вирішено зробити свою, та ще й з пляшками. Основа схеми - мікроконтролер AVR Attiny13. Хоча він підтримує тільки 2 канали апаратного ШІМ (широтно-імпульсна модуляція), а RGB світлодіод вимагає 3, не проблема - реалізуємо програмний ШІМ. Плюшки наступні крім ШІМ регулювання RGB світлодіодів: регулювання швидкості зміни кольорів від 1 секунди на цикл зміни кольорів до 1000 секунд, а також можливість зупинити світлові ефекти натисненням кнопки і заморозити поточний колір. Назвав я цю функцію "Стоп-колір". Про кількість квітів: тут також реалізована фішка - зміна кольорів відбувається не тільки лінійно від червоного до фіолетового за кольорами веселки, а й по поєднанню нульових і максимальних значення кольору - тобто від 100 процентну насиченість до нульової насиченості кольорів, тобто до білого кольору. Програма зміни кольору лінійна, строго задана програмою. Флеш пам'ять Attiny13 не дозволила реалізувати рандомноє непередбачуване зміна кольору. Може це й на краще.
Схема вийшла ось такий:
Що так як робилося. Регулювання швидкості. Почнемо з затримок функцією _delay_ms () ;. звичайне її використання зводиться до запису в дужки якогось значення, в перебігу якого повинна проходити затримка, але якщо ж в скобочки поставити змінну, то розмір програми різко збільшиться. Це зовсім не годиться, адже вже ризикуємо НЕ влізти в пам'ять Attiny13. Вихід простий - організуємо цикл виклику кінцевого числа раз він включає зсув тривалістю, скажімо 1 милі секунда. Розмір програми для контролера знову в нормі. Тепер цю функцію можна використовувати для регулювання швидкості виконання світлового ефекту. Далі звідки брати динамічна зміна змінної затримки? Теж все просто, Тиньков має на борту АЦП (аналого-цифровий перетворювач) 10 біт, значення від 0 до 1024 - відмінно згодиться для значення затримки. Тобто виходить, що затримка між збільшенням або зменшенням яскравості буде від 1 милі секунди до 1 секунди. Від 1 тому, що при нульовій затримці буде просто мельтішеніе, некрасиво, тому нуль виключений. Отже, беремо значення з АЦП і штовхаємо в значення змінної затримки. Також значення АЦП можна брати як 10 біт, тобто 1024 відліку, так і просто поділити це значення на 2, 4, 8 і так далі і вийде більш вузький діапазон регулювання. Апаратно регулювання буде здійснюватися потенціометром або змінним резистором, підключеним крайніми висновками до плюса і мінуса харчування, а середнім до входу АЦП мікроконтролера. R3 для захисту порту, токоогранічительний. R1 обмежує напругу таким чином, щоб максимальне значення АЦП було 1000, решта 24 відліку планувалося для підключення ще однієї кнопки, але чіткої функціоналу вона не отримала, тому залишилося так для можливості в майбутньому що-небудь "допив". Джерелом опорного напруги АЦП вибрано напруги живлення 5 вольт мікроконтролера. Що відносно зупинки ефекту зміни кольору, то при натисканні кнопки S2 відбувається перекидання з основного нескінченного циклу зі світловим ефектом в інший порожній нескінченний цикл, повторне натискання кнопки перекидає виконання програми назад в основний нескінченний цикл. Просто і сердито.
У програмі задіяно 2 переривання: переривання по переповнення таймера 0 для опитування стану кнопки, а також переривання по завершенню перетворення АЦП. Як зазначалося, зміна кольорів відбувається не тільки від кольору до кольору, але і зі зміною їх насиченості, тобто не тільки горизонтально, але і вертикально. При мінімальній насиченості кольору будуть розмиватися один з одним (див. Малюнок нижче) і врешті-решт вийде білий колір, хоча по палітрі на малюнку там присутній і сірий, але можливості RGB світлодіодів не дозволяють передати його, як і чорний колір. Виходить просто яскравість білого кольору замість переходу від чорного до білого. Тому рівні чорного кольору не було навіть спроби реалізувати))
Програмно справа виходить так (програмний код на gcc):
Мінлива k відповідає за зупинку зміни кольору, перекидає в різні цикли програми.
Мінлива n відповідає за перехід від 100% насиченості квітів до розмиття їх до білого, не може бути більше ніж 1/2 від pwm
Мінлива pwm - значення дискретизації ШІМ
Це вся головна програма роботи мікроконтролера для даного пристрою.
Готове пристрій вийшов ось такого виду (зібрано з застосуванням макетної плати власного виробництва для tiny13):
Область застосування цього пристрою, як і майже будь-якого іншого, обмежує лише фантазія інженера або радіоаматора. Пристрій може бути легко модернізовано під будь-яку іншу мету завдяки простоті, повторюваності і можливості просто вносити свої зміни в схему.
Фьюз біти для програмування мікроконтролера Attiny13:
список радіоелементів
Красиво, особливо вразила робота з квітами. Єдине неясно (можливо помиляюся) щодо функції затримки і обсягу пам'яті. Наскільки помниться при компіляції функція компілюється один раз, а потім може бути викликана скільки завгодно раз з будь-якими вхідними параметрами. Т.ч. якщо написати исходник (наприклад ініціалізацію периферії) і натиснути компіляцію - отримаємо якийсь обсяг програми, далі впишемо нашу функцію - програма збільшиться на обсяг функції + можливо команду переходу (якщо компілятор вирішить вписати функцію окремо), Землі в исходник продовжувати вписувати нашу функцію - обсяг програми бидіт увелісіваться на команду переходу + можливі попередні переміщення змінних (щоб їх могла прийняти функція) тобто незначно в порівнянні з пера вписуванням функції. for - теж свого роду функція, яка також викликається і має попередні переміщення мінливих. Т.ч. обсяг неоюходімой пам'яті ++). Загалом потрібно взяти конкретний компілятор і перевірити. Дякуємо за увагу)
Мабуть якісь "індивідуальні особливості" компілятора, в code vision такого не помічалося, коли то на attiny2313 виробляв форматний висновок через UART, там сама функція printf забрала близько 800 байт, а наступні її виклики забирали потроху. Ще питання якщо дозволите чи не може бути це через те що Ви пишете _delay_ms, а не delay_ms (в сенсі без підкреслення перед словом delay)?
Просто в AS немає функції delay_ms (виклик в такому вигляді видасть помилку), тільки можна викликати функцію затримки у вигляді _delay_ms. У контролерах пожирнее взагалі всі такі затримки можна не використовувати (якщо їх багато), а використовувати операційну систему, RTOS який-небудь