Diaľkové ovládanie zosilňovača
Zo stránky SensorWiki
Záverečný projekt predmetu MIPS / LS2025 - Dávid Bungyi
Zadanie
Zapojiť a naprogramovať IR diaľkové ovládanie s Atmega328P pre ovládanie tlačidiel vypínania a Loudness a potenciometra hlasitosti zosilňovača.

Literatúra:
Analýza a opis riešenia
Správu odvysielanú IR diaľkovým ovládačom bolo treba nejakým zariadením prijať, spracovať v mikropočítači a na základe prijatej správy aktivovať solenoid, ktorý zatlačí tlačidlo na zosilňovači alebo pootočiť servomotorček ovládajúci potenciometer hlasitosti.
Postup riešenia
• Vysielanie správ
Správy odosielame pomocou IR diaľkového ovládania, ktoré sa bežne používa s Arduinom.

• Prijímanie správ
Signál odvysielaný ovládačom prijímame IR prijímačom, ktorý modulovaný 38KHz signál demoduluje a spracuje na logické jednotky a nuly.

• Spracovanie prijatého signálu
Prijatý signál spracováva Arduino nižšie uvedeným programom. Po spracovaní signálu Arduino spína na pol sekundy digitálne piny 6 a 7 alebo pootočí servomotorček pomocou zmeny pwm signálu na pine 9. Signál vstupujúci do Arduina má zamenené logické jednotky a nuly kvôli použitému pull-up rezistoru, toto je kompenzované v programe pri vyhodnocovaní logických stavov prijímaného signálu.
Protokol nec
Pre rozšifrovanie správ bolo potrebné pochopiť ako funguje protokol nec ktorým ovládač posiela správy. Museli sme zistiť úvodnú správu a spôsob ktorým sú reprezentované logické jednotky a nuly. Najdôležitejšie bolo si uvedomiť, že rozdiel medzi logickou jednotkou a nulou je v dĺžke nulovej časti signálu, ktorá nasleduje kladnú časť. Rozdiel v logickej jednotke a nule je totiž v tom, že nulová časť je pri logickej jednotke tri krát dlhšia, ako pri logickej nule. Z nich sa následne skladá adresa zariadenia, špecifická pre výrobcu a niekedy aj model zariadenia a príkaz určujúci vybranú funkciu na ovládači. V rýchlosti doplním len že v nec protokole je konštantná dĺžka správy realizovaná vďaka dvojnému odosielaniu adresy a príkazu v správe. Jedna z týchto adries a príkazov vždy obsahuje pôvodnú správu s invertovanými bitmy. Vďaka tomu je počet logických jednotiek a núl v správe vždy rovnaký a mení sa iba ich poradie, preto je správa vždy rovnako dlhá. Polovica bitov teda pre určenie stlačeného tlačidla nie je potrebná, preto sme museli z celej správy vyselektovať 32-25 a 16-9 bity.
Schéma zapojenia
Algoritmus a program
Celý program je napísaný v jednom súbore bez použitia vlastných funkcií a knižníc. Ako prvé sme si pridali knižnice a funkcie a zadefinovali vstupné a výstupné piny. Pridali sme si funkciu delay. Následne sme si definovali premenné a inicializovali počítadlo. Prvá polovica programu v maine nám rozšifruje správu zaslanú ovládačom cez protokol nec. Táto časť programu rozlíši poslané logické jednotky a nuly a prevedie ich na hexadecimálny kód. V ďalšej časti programu sa tento kód porovnáva so známymi kódmi priradenými k funkciám. Ak sa prijatý kód zhoduje s kódom funkcie, funkcia sa vykoná. Keďže 8 bitové počítadlo nám nestačilo na čítanie kódu ani generovanie PWM, bolo potrebné počítadlo medzi týmito dvomi časťami programu prekonfigurovať. To sa deje na začiatku každej z daných častí programu. Rozhodli sme sa pre prácu s normalizovanými hexadecimálnymi kódmi diaľkových ovládačov a preto bolo potrebné prirátať k premennej count číslo 2.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
#include <math.h>
#define set_bit(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
#define clear_bit(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))
#define IR1 PB0 // IR snimac
#define ZAP PD7 // Vypinac
#define LOUD PD6 // Loudness
#define VOL PB1 // Volume
void delay(int delay) // vlastna funkcia, lebo inak je max 16ms
{
for (int i=1; i<=delay; i++)
_delay_ms(1);
}
int main(void)
{
DDRB &= ~(1<<IR1); // PB0 je vstup
DDRD |= (1<<ZAP); // PD7 je vystup
DDRD |= (1<<LOUD); // PD6 je vystup
DDRB |= (1<<VOL); // PD5 je vystup
PORTB |= (1<<IR1); // zapnuty pull-up
int counter,bit,count,poc=2000; // deklaracia premennych a nastavenie pociatocnej polohy servomotorceka
unsigned int tlac;
while(1)
{
TCNT1 = 0x0000; // initialize (CLEAR) counter
ICR1 = 0; // nulovanie pre pouzitie ako casovac
OCR1A = 0; // nulovanie pre pouzitie ako casovac
TCCR1A = 0b10000000; // nastavenie akcie pri zhode pocitadla
TCCR1B = 0b00000010; // nastavenie preddelicky na 8
if (bit_is_clear(PINB, IR1))
{
TCNT1 = 0xDE67; // nastavenie pocitadla aby doslo k preklopeniu po 8,6mS
while( ((TIFR1 & (1<<TOV1)) != 0x01 ) && (bit_is_clear(PINB, IR1))) // cakaj kym neubehlo aspon 8,6mS v log. 1
{
}
while(bit_is_set(PINB, IR1)) // nastavenie pocitadla v pripade ze log. 1 nebola dlha aspon 8.6mS
{
TCNT1 = 0xDE67; // nastavenie pocitadla aby doslo k preklopeniu po 8,6mS
}
if(((TIFR1 & (1<<TOV1)) == 0x01 )) // ak sa pocitadlo preklopilo
{
delay(2);
while(bit_is_set(PINB, IR1)) // cakaj na log. 0
{
}
bit=15; // nastavenie pre vypocet hexadecimalneho cisla
count=0;
for(int i=32;i>=0;i--) // cyklus pre precitanie 32 bitov spravy
{
while(bit_is_clear(PINB, IR1)) // cakaj na log. 1
{
}
TCNT1 = 0x0000; // nulovanie pocitadla pre zaciatok pocitania noveho bitu
while(bit_is_set(PINB, IR1)) // cakaj na log. 0
{
}
counter = TCNT1;
if((i<=31)&&(i>=24) || (i<=15)&&(i>=8)) // vyselektovanie dolezitych bitov spravy
{
if ((counter>=700)&&(counter<=1500)) // ak je log. 1...
count = count + pow(2,bit); // ...prirataj 2 umocnene na poziciu daneho bitu
bit--;
}
}
tlac = count+2; // kompenzacia pre pracu s normalizovanymi hexadecimalnymi kodmi dialkovych ovladacov
if (tlac == 65437) //Kod tlacidla pre vypinanie
{
set_bit(PORTD,ZAP);
delay(500);
clear_bit(PORTD,ZAP);
}
if (tlac == 65391) //Kod tlacidla pre loudness
{
set_bit(PORTD,LOUD);
delay(500);
clear_bit(PORTD,LOUD);
}
TCNT1 = 0; // Set Initial Timer value
ICR1 = 4000; // set TOP for counting
TCCR1A = 0b10000010; // nastavenie fast PWM a akcie pri zhode pocitadla
TCCR1B = 0b00011010; // nastavenie fast PWM a preddelicky 8
if (tlac == 65367 && poc <3900) //Kod tlacidla pre pridanie hlasitosti
poc = poc+100;
if (tlac == 65311 && poc >2000) //Kod tlacidla pre ubratie hlasitosti
poc = poc-100;
OCR1A = poc; // zapis do casovaca pre generovanie PWM
delay(100);
}
}
}
}
Zdrojový kód: IR_Ovladanie_Zosilnovaca_David_Bungyi.zip
Overenie
Celé zariadenie sa ovláda štyrmi tlačidlami ovládača tlačidlá + a - ovládajú pohyb servomotorčeka a tlačidlá CH a EQ ovládajú solenoidy stláčajúce tlačidlá zosilňovača. Solenoidy sú v ukážke reprezentované LED diódami.

Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.