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.
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á.
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.
#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.