Operácie

Diaľkové ovládanie zosilňovača: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
Bez shrnutí editace
StudentMIPS (diskusia | príspevky)
Bez shrnutí editace
(32 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 6: Riadok 6:
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.
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.


[[Obrázok:600px-UNO.jpg|400px|thumb|center|Vývojová doska Arduino UNO.]]
[[Obrázok:600px-UNO.jpg|400px|thumb|center|Vývojová doska Arduino UNO]]


'''Literatúra:'''  
'''Literatúra:'''  
* [https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf Dokumentácia k Atmega328P]
* [https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf Dokumentácia k Atmega328P]
* [https://sibotic.wordpress.com/wp-content/uploads/2013/12/adoh-necinfraredtransmissionprotocol-281113-1713-47344.pdf Dokumentácia k Protokolu NEC]




Riadok 17: Riadok 18:


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.  
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====
====• Vysielanie správ====
Je
Správy odosielame pomocou IR diaľkového ovládania, ktoré sa bežne používa s Arduinom.
[[Obrázok:ovladac.jpg|200px|thumb|center|IR Diaľkový ovládač]]
====• Prijímanie správ====
====• Prijímanie správ====
Je
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.
[[Obrázok:prijimac.jpg|100px|thumb|center|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. 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.




[[Súbor:GeminiAI-image3.jpg|400px|thumb|center|Celkový pohľad na zariadenie.]]
=== Protokol nec ===


Nezabudnite doplniť schému zapojenia! V texte by ste mali opísať základné veci zo zapojenia, samotná schéma nie je dostačujúci opis.
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.


[[Súbor:GeminiAI-image2.jpg|400px|thumb|center|Schéma zapojenia.]]
[[Súbor:NecProtokol.PNG|600px|thumb|center|Správa protokolu nec]]
 
 
 
=== Schéma zapojenia ===
 
[[Súbor:SchemaIROvladanie.PNG|400px|thumb|center|Schéma zapojenia]]




=== Algoritmus a program ===
=== Algoritmus a program ===


Algoritmus programu využíva toto a toto, základné funkcie sú takéto a voláma ich tuto...  
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.
Výpis kódu je nižšie...




<tabs>
<tabs>
<tab name="AVR C-code"><syntaxhighlight  lang="c++" style="background: LightYellow;">
<tab name="AVR C-code"><syntaxhighlight  lang="c++" style="background: LightYellow;">
#define F_CPU 16000000UL
#include <avr/io.h>
#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)
int main(void)
{
{  
  unsigned int measuredValue;
DDRB &= ~(1<<IR1);   // PB0 je vstup
 
DDRD |= (1<<ZAP); // PD7 je vystup
  while (1)
DDRD |= (1<<LOUD); // PD6 je vystup
   {
DDRB |=  (1<<VOL);  // PD5 je vystup
    /* relax */   
PORTB |= (1<<IR1);   // zapnuty pull-up
  }
 
  return(0);
}
 
</syntaxhighlight ></tab>
<tab name="filename.h"><syntaxhighlight  lang="c++" style="background: LightYellow;">
#include <avr/io.h>


void adc_init(void);                                   // A/D converter initialization
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);
}
 
}
}
}


unsigned int adc_read(char a_pin);
</syntaxhighlight ></tab>
</syntaxhighlight ></tab>
</tabs>
</tabs>


Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x ''zdrojaky.zip'':


Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
Zdrojový kód: [[Médiá:IR_Ovladanie_Zosilnovaca_David_Bungyi.zip|IR_Ovladanie_Zosilnovaca_David_Bungyi.zip]]


=== Overenie ===
=== Overenie ===


Ako ste overili funkciu, napríklad... Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia.
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.
Na konci uvádzame fotku hotového zariadenia.  


[[Súbor:GeminiAI-image1.jpg|400px|thumb|center|Aplikácia.]]
[[Súbor:ZapojenieIROvladanie.jpg|600px|thumb|center|Zapojenie zariadenia]]


'''Video:'''
'''Video:'''
<center><youtube>D0UnqGm_miA</youtube></center>
<center><youtube>cXLb0B8ZQKA</youtube></center>





Verzia z 20:28, 18. máj 2025

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

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

Zapojenie zariadenia

Video:



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