Operácie

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.

Vývojová doska Arduino UNO

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.

IR Diaľkový ovládač

• 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.

IR Prijímač

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

Správa protokolu nec


Schéma zapojenia

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.

Zapojenie zariadenia

Video:



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