Uživatel:Vicarpet

Z MAM wiki

(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
m
m (kategorie)
 
(Není zobrazeno 60 mezilehlých verzí.)
Řádka 3: Řádka 3:
== vybrana semestralni prace: ==
== vybrana semestralni prace: ==
-
 
-
- možnost kalibrace na lokálni teplotu
 
'''Ovládání ventilátoru teplovzdušného rozvodu'''
'''Ovládání ventilátoru teplovzdušného rozvodu'''
-
Myslenka: k mikroprocesoru pripojen dvojmistny sedmisegmentovy displey - zobrazuje stridave nastavenou teplotu vs. teplotu skutecnou pomoci dvou tlacitek regulace nastavene teploty vetrak spinan tranzistorem mereni teploty: nejspise zdroj referencniho napeti + delic termistor, resistor(mozna vymyslim i neco presnejsiho)
+
Myslenka: k mikroprocesoru pripojen dvojmistny sedmisegmentovy displey - zobrazuje stridave nastavenou teplotu vs. teplotu skutecnou pomoci dvou tlacitek regulace nastavene teploty vetrak spinan tranzistorem mereni teploty LM35.
-
pri prekladu definovana konstanta tolerance k odchylkam(pri odchylce 1 stupen chladit na 0%...100% vykonnu vetraku)
+
-
nejaky zakladni nastrel, viz schema (schema je priblizne, popisuje myslenku, ne presne zapojeni,
 
-
to budu muset upravit podle dostupnych soucastek)
 
-
[http://xsimi.cz/kadibudka/mam-ctvrty_nastrel.png schema]
 
-
3,3V bude realizovano nejspise stabilizatorem
 
-
zakmity od tlacitek reseny softwarove
 
-
[http://xsimi.cz/kadibudka/mam.sch zdrovak do Eagle]
 
-
----
+
[http://xsimi.cz/kadibudka/mam-paty_nastrel.png schema]
 +
[http://xsimi.cz/kadibudka/mam.sch zdrojak do Eagle]
 +
[http://xsimi.cz/kadibudka/mam.pdf prezentace PDF]
 +
[http://xsimi.cz/kadibudka/mam.odp prezentace ODP] - má to být na pár minut, tak myslím že to takhle stačí
-
== Ukoly ==
+
== Zakmity ==
-
<pre>
+
Proste tlačítko neudelá normální prechod 0-1, ale párkrát zakmitá, takze se objevi cca neco takovýdleho ..01000110010001111111...
-
funkce nastav(int uroven)
+
Vyresíme jednoduse, pokud prijde interup pockame cca 20ms a pak teprve prectem hodnotu, jde to resit i hw, ale tohle je jednodussí.
-
nastavi uroven 0 az N-1 na pcm vystupu (zaklady na jednom cviceni)
+
-
zjisteni teploty - precteni hodnoty z A/D prevodniku+nejaka korekce
+
--[[Uživatel:Zikmuji1|Jiří Zikmund]] 9. 5. 2010, 14:48 (UTC)
-
<b>korekci zdiskutovat</b>
+
-
probouzeni
+
Obávám se, že nikdo nezaručí, že za 20ms tam bude určitě tutová 0. Co takhle to řešit prvním přečtením, pak 20ms počkat a znova přečíst, porovnat a když to bude stejný, tak je to OK a pokračujem dál? Ale to je jen takovej nápad. Jestliže bude vstupem třeba PD.2 viz schéma, zkusil bych jít třeba tudy:
-
jednoduse jednou za x ms + pri stisku tlacitka
+
-
ovladani tlacitkama
+
no zaruci, tak spatny tlacitka aby to kmitalo dele nez 20ms sem snad mit nebudeme :)
-
inkrementace/dekrementace nejake hodnoty, bacha na zakmity, (asi udelam ja)
+
-
funkce zobrazeni teploty
+
'''První nástřely tlačítek  v C'''
-
prevod binarni cislo na dve binarni hodnoty (mod,div) a zobrazeni
+
-
</pre>
+
- jsou to dvě tlačítka, jedno má teplotu o stupeň snížit a druhé zvýšit,
 +
porty jsou podle schématu
-
== Myslenka systému regulace chlazeni (pseudokod) ==
+
== Měření teploty ==
-
nejmensi rozlisitelna jednotka je pro nase potreby jeden stupen.
+
Tady bych se přikláněl k měření přes A/D převodník s teploměrem [http://www.national.com/mpf/LM/LM35.html#Overview LM35]
 +
 
 +
Řeší problém kalibrace (vnitřní kompenzací teploty) sám o sobě (dokonce je kalibrován na °C, má velmi malou spotřebu, rozlišení 10mV/°C), tak uvidíme, jak se k tomu vyjádří případně vedoucí cvičení. Pouzdro asi ještě doladíme, zatím LM35DZ v [http://www.gme.cz/cz/lm35dz-p313-909.html TO-92] (pakliže nebude třeba měřit záporné teploty), vychází nejlevněji.
 +
 
 +
[[Uživatel:Zikmuji1|Jiří Zikmund]] 19. 4. 2010, 17:16 (UTC)
 +
 
 +
--[[Uživatel:Zikmuji1|Jiří Zikmund]] 9. 5. 2010, 14:48 (UTC)
 +
 
 +
Takže měření teploty... použijeme vnitřní 10-bitový A/D převodník s vnitřním referenčním napětím 1,1V, vstup ADC2, výstup PB2
 +
 
 +
 
 +
 
 +
 
 +
== Kód ==
-
'''nastaveni:'''
 
<pre>
<pre>
-
Kzahrivani - (0-chladi,1-zahryva)- nastavuje zda ovladany prvek snizuje nebo zvysuje teplotu
+
//------------------------------------------------------------------------------
-
n - pocet urovni intenzity aktivity prvku (napriklad vetrak sepnut pomoci pcm 0-9 pulzu z doby 9->n=10)
+
#include <avr/io.h>
-
K - odchylka o jeden stupen zpusoby zapnuti na uroven 1*K (v pripade o n stupnu udela n*K az do hodnoty n)
+
#include <avr/interrupt.h>
-
Tnastavena - udrzovana teplota
+
#include <avr/pgmspace.h>
-
Treal - zmerena teplota
+
#include <avr/eeprom.h>
 +
#include <util/delay.h>
-
funkce nastavuroven - nastavi uroven predanou v parametru 0-vypnuto, N-1 maximalni vykon
+
#define xtal 1000000 //kmitocet krystalu 1MHz
-
deltaT=(Treal-Tnastavena)*(-1)^Kzahrivani;
+
#define TMR_CNT 65536 - 97 // cas / 1024 / 1000000, cas v sec, pro 0.1 sec
-
if(deltaT>0)
+
-
{
+
-
  uroven_chlazeni_tmp=deltaT*K;
+
-
  if(uroven_chlazeni_tmp>N-1)
+
-
  {
+
-
    uroven_chlazeni_tmp=N-1;
+
-
  }
+
-
  nastavuroven(uroven_chlazeni_tmp);
+
-
}
+
-
else
+
-
{
+
-
  nastavuroven(0);//(vypnuto)
+
-
}
+
-
</pre>
+
-
== Zakmity ==
+
//------------------------------------------------------------------------------
 +
unsigned char kteryudaj = 0;//stara se o vyber udaje co bude zobrazen (0..teplota)
 +
volatile int teplota = 20; // Zmerena teplota
 +
volatile int Tnastavena = 20; //Nastavena teplota
-
Proste tlačítko neudelá normální prechod 0-1, ale párkrát zakmitá, takze se objevi cca neco takovýdleho ..01000110010001111111...
 
-
Vyresíme jednoduse, pokud prijde interup pockame cca 20ms a pak teprve prectem hodnotu, jde to resit i hw, ale tohle je jednodussí.
 
 +
void UpdateOutput();
 +
//------------------------------------------------------------------------------
 +
//zpusobi usnuti mikroprocesoru
 +
void usni(void)
 +
{
 +
SMCR = 1;
 +
}
 +
//------------------------------------------------------------------------------
 +
//je zavolano pri stisku libovolneho tlacitka
 +
void preruseni (void)
 +
{
 +
unsigned char portVal = PINC;
-
== Tým ==
+
do {
 +
portVal = PINC & 0x30;
 +
_delay_ms(20);
 +
} while(portVal != (PINC & 0x30));
 +
     
 +
if((portVal & 0x30) == 0x20)
 +
{
 +
//prvni
 +
Tnastavena++;
 +
kteryudaj = 10;
 +
}
 +
if((portVal & 0x30) == 0x10)
 +
{
 +
//druhy
 +
Tnastavena--;
 +
kteryudaj = 10;
 +
}
 +
}
 +
//------------------------------------------------------------------------------
 +
//hlavni cast, nastavy procesor a uspi ho
 +
void ShowDisplay(unsigned char num)
 +
{
 +
PORTD = (PORTD & 0xF0) | (num / 10);
 +
PORTC = PORTC | 0x02;
 +
_delay_ms(1);
 +
PORTC = PORTC & 0xFD;
 +
 +
PORTD = (PORTD & 0xF0) | (num % 10);
 +
PORTC = PORTC | 0x08;
 +
_delay_ms(1);
 +
PORTC = PORTC & 0xF7;
 +
 +
}
 +
 +
//------------------------------------------------------------------------------
 +
int PrectiAdc()
 +
{
 +
while((ADCSRA & (1 << ADIF)) == 0);
 +
        int iAdcValue = ADCW;
 +
return((iAdcValue * 28) >> 8);
 +
}
 +
 +
//------------------------------------------------------------------------------
 +
SIGNAL(PCINT1_vect)
 +
{
 +
preruseni();
 +
}
 +
 +
//------------------------------------------------------------------------------
 +
SIGNAL(TIMER1_OVF_vect)
 +
{
 +
teplota = PrectiAdc();
 +
if(kteryudaj > 0)
 +
{
 +
ShowDisplay(Tnastavena);
 +
kteryudaj--;
 +
}
 +
else
 +
ShowDisplay(teplota);
 +
 +
UpdateOutput();
 +
 +
TCNT1 = TMR_CNT;
 +
 +
// uspani
 +
usni();
 +
}
 +
 +
//------------------------------------------------------------------------------
 +
void InitAdc()
 +
{
 +
    ADMUX = (1 << REFS1) | (1 << REFS0) | 2; // Reference 1.1V, kanal ADC2
 +
    ADCSRA = (1 << ADEN) | (1 << ADATE) | 7; // Povoleni ADC, preddelicka 128
 +
    ADCSRB = 6; // start pri preteceni T1
 +
}
 +
 +
 +
//------------------------------------------------------------------------------
 +
void UpdateOutput()
 +
{
 +
if(teplota > Tnastavena)
 +
PORTD = (PORTD & 0x7F) | 0x80;
 +
if(teplota < Tnastavena - 10)
 +
PORTD = PORTD & 0x7f;
 +
}
 +
 +
 +
 +
//------------------------------------------------------------------------------
 +
//zakladni nastaveni portu
 +
void InitPorts()
 +
{
 +
DDRD = 0x8F;
 +
DDRC = 0x0A;
 +
 +
PCICR = 0x02;
 +
PCMSK1 = 0x30;
 +
}
 +
//------------------------------------------------------------------------------
 +
 +
void InitTimer1()
 +
{
 +
TCCR1A = 0;
 +
TCCR1B = 5; // delicka 1024
 +
TCCR1C = 0;
 +
TCNT1 = TMR_CNT;
 +
TIMSK1 = 1; // povoleni preruseni od preteceni
 +
}
 +
 +
//------------------------------------------------------------------------------
 +
int main()
 +
{
 +
InitPorts();
 +
    InitAdc();
 +
        InitTimer1();
 +
sei();
 +
 +
 +
while(1);  //nekonecna smycka, aby neskoncil main
 +
    return (0);
 +
}
 +
//------------------------------------------------------------------------------
 +
</pre>
 +
 +
== Datasheets ==
 +
 +
Teploměr LM-35
 +
BCD převodník HCF4056BE
 +
Sedmisegmentovky HDSP-F203
 +
 +
== Realizace ==
 +
[[Soubor:nastav_teplomer.jpg|600px]]
 +
 +
== Tým ==
 +
 +
Petr Vičar
  Jachym Simak - simakjac@fel.cvut.cz
  Jachym Simak - simakjac@fel.cvut.cz
 +
'''[[Uživatel:zikmuji1|Jiří Zikmund]]'''
 +
 +
[[Category:Kód v C]]

Aktuální verze z 21. 2. 2011, 09:33

petr vičar


Obsah

[editovat] vybrana semestralni prace:

Ovládání ventilátoru teplovzdušného rozvodu

Myslenka: k mikroprocesoru pripojen dvojmistny sedmisegmentovy displey - zobrazuje stridave nastavenou teplotu vs. teplotu skutecnou pomoci dvou tlacitek regulace nastavene teploty vetrak spinan tranzistorem mereni teploty LM35.


schema zdrojak do Eagle prezentace PDF prezentace ODP - má to být na pár minut, tak myslím že to takhle stačí

[editovat] Zakmity

Proste tlačítko neudelá normální prechod 0-1, ale párkrát zakmitá, takze se objevi cca neco takovýdleho ..01000110010001111111... Vyresíme jednoduse, pokud prijde interup pockame cca 20ms a pak teprve prectem hodnotu, jde to resit i hw, ale tohle je jednodussí.

--Jiří Zikmund 9. 5. 2010, 14:48 (UTC)

Obávám se, že nikdo nezaručí, že za 20ms tam bude určitě tutová 0. Co takhle to řešit prvním přečtením, pak 20ms počkat a znova přečíst, porovnat a když to bude stejný, tak je to OK a pokračujem dál? Ale to je jen takovej nápad. Jestliže bude vstupem třeba PD.2 viz schéma, zkusil bych jít třeba tudy:

no zaruci, tak spatny tlacitka aby to kmitalo dele nez 20ms sem snad mit nebudeme :)

První nástřely tlačítek v C

- jsou to dvě tlačítka, jedno má teplotu o stupeň snížit a druhé zvýšit, porty jsou podle schématu

[editovat] Měření teploty

Tady bych se přikláněl k měření přes A/D převodník s teploměrem LM35

Řeší problém kalibrace (vnitřní kompenzací teploty) sám o sobě (dokonce je kalibrován na °C, má velmi malou spotřebu, rozlišení 10mV/°C), tak uvidíme, jak se k tomu vyjádří případně vedoucí cvičení. Pouzdro asi ještě doladíme, zatím LM35DZ v TO-92 (pakliže nebude třeba měřit záporné teploty), vychází nejlevněji.

Jiří Zikmund 19. 4. 2010, 17:16 (UTC)

--Jiří Zikmund 9. 5. 2010, 14:48 (UTC)

Takže měření teploty... použijeme vnitřní 10-bitový A/D převodník s vnitřním referenčním napětím 1,1V, vstup ADC2, výstup PB2



[editovat] Kód

//------------------------------------------------------------------------------
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <util/delay.h>

#define xtal 1000000 //kmitocet krystalu 1MHz

#define TMR_CNT 65536 - 97 // cas / 1024 / 1000000, cas v sec, pro 0.1 sec


//------------------------------------------------------------------------------
unsigned char kteryudaj = 0;//stara se o vyber udaje co bude zobrazen (0..teplota)
volatile int teplota = 20; // Zmerena teplota 
volatile int Tnastavena = 20; //Nastavena teplota


void UpdateOutput();
//------------------------------------------------------------------------------
//zpusobi usnuti mikroprocesoru
void usni(void)
{
	SMCR = 1;
}

//------------------------------------------------------------------------------
//je zavolano pri stisku libovolneho tlacitka
void preruseni (void)
{ 
	unsigned char portVal = PINC;

	do {
		portVal = PINC & 0x30;
		_delay_ms(20);
	} while(portVal != (PINC & 0x30));
       
	if((portVal & 0x30) == 0x20)
	{
		//prvni
		Tnastavena++;
		kteryudaj = 10;
	}
	if((portVal & 0x30) == 0x10)
	{
		//druhy
		Tnastavena--;
		kteryudaj = 10;
	}
} 


//------------------------------------------------------------------------------
//hlavni cast, nastavy procesor a uspi ho
void ShowDisplay(unsigned char num)
{
	PORTD = (PORTD & 0xF0) | (num / 10);
	PORTC = PORTC | 0x02;
	_delay_ms(1);
	PORTC = PORTC & 0xFD;

	PORTD = (PORTD & 0xF0) | (num % 10);
	PORTC = PORTC | 0x08;
	_delay_ms(1);
	PORTC = PORTC & 0xF7;

}

//------------------------------------------------------------------------------
int PrectiAdc()
{
		while((ADCSRA & (1 << ADIF)) == 0);
        int iAdcValue = ADCW;
		return((iAdcValue * 28) >> 8);
}

//------------------------------------------------------------------------------
SIGNAL(PCINT1_vect)
{
	preruseni(); 
}

//------------------------------------------------------------------------------
SIGNAL(TIMER1_OVF_vect)
{
	teplota = PrectiAdc();
	if(kteryudaj > 0)
	{
		ShowDisplay(Tnastavena);
		kteryudaj--;
	}
	else
		ShowDisplay(teplota);
	
	UpdateOutput();

	TCNT1 = TMR_CNT;
	
	// uspani
	usni();
}

//------------------------------------------------------------------------------
void InitAdc()
{
    ADMUX = (1 << REFS1) | (1 << REFS0) | 2; // Reference 1.1V, kanal ADC2
    ADCSRA = (1 << ADEN) | (1 << ADATE) | 7; // Povoleni ADC, preddelicka 128
    ADCSRB = 6; // start pri preteceni T1
}


//------------------------------------------------------------------------------
void UpdateOutput()
{
	if(teplota > Tnastavena)
		PORTD = (PORTD & 0x7F) | 0x80;
	if(teplota < Tnastavena - 10)
		PORTD = PORTD & 0x7f; 
}



//------------------------------------------------------------------------------
//zakladni nastaveni portu
void InitPorts()
{
	DDRD = 0x8F;
	DDRC = 0x0A;

	PCICR = 0x02;
	PCMSK1 = 0x30;
}
//------------------------------------------------------------------------------

void InitTimer1()
{
	TCCR1A = 0;
	TCCR1B = 5; // delicka 1024
	TCCR1C = 0;
	TCNT1 = TMR_CNT;
	TIMSK1 = 1; // povoleni preruseni od preteceni
}

//------------------------------------------------------------------------------
int main()
{
	InitPorts();
    InitAdc();
        InitTimer1();
	sei();


 	while(1);   //nekonecna smycka, aby neskoncil main
    return (0);
}
//------------------------------------------------------------------------------

[editovat] Datasheets

Teploměr LM-35 BCD převodník HCF4056BE Sedmisegmentovky HDSP-F203

[editovat] Realizace

[editovat] Tým

Petr Vičar
Jachym Simak - simakjac@fel.cvut.cz
Jiří Zikmund
Osobní nástroje