Uživatel:Vicarpet

Z MAM wiki

(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
m (Myslenka systému zobrazeni)
(Měření teploty)
Řádka 213: Řádka 213:
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
volatile int iTemperature = 20; // Zmerena teplota  
volatile int iTemperature = 20; // Zmerena teplota  
-
int iHighTemp = 30; // spinani pri 30 degC
+
volatile int Tnastavena = 20; //Nastavena teplota
-
int iLowTemp = 20; // vypinani pri 20 degC
+
const int Kzahrivani = 0;////Kzahrivani - (0-chladi,1-zahryva)- nastavuje zda ovladany prvek snizuje nebo zvysuje teplotu
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
SIGNAL (ADC_vect)
SIGNAL (ADC_vect)
Řádka 237: Řádka 237:
void UpdateOutput()
void UpdateOutput()
{
{
-
if(iTemperature >= iHighTemp)
+
 
-
PORTB = PORTB | (1 << 2);
+
//Kzahrivani - (0-chladi,1-zahryva)- nastavuje zda ovladany prvek snizuje nebo zvysuje teplotu
-
if(iTemperature < iLowTemp)
+
//n - pocet urovni intenzity aktivity prvku (napriklad vetrak sepnut pomoci pcm 0-9 pulzu z doby 9->n=10)
-
PORTB = PORTB & ~(1 << 2);
+
//K - odchylka o jeden stupen zpusoby zapnuti na uroven 1*K (v pripade o n stupnu udela n*K az do hodnoty n)
 +
//Tnastavena - udrzovana teplota
 +
//Treal - zmerena teplota
 +
 
 +
//funkce nastavuroven - nastavi uroven predanou v parametru 0-vypnuto, N-1 maximalni vykon
 +
 
 +
int deltaT=(iTemperature-Tnastavena)*(-1)^Kzahrivani;
 +
if(deltaT>0)
 +
{
 +
  int uroven_chlazeni_tmp=deltaT*K;
 +
  if(uroven_chlazeni_tmp>N-1)
 +
  {
 +
    uroven_chlazeni_tmp=N-1;
 +
  }
 +
  nastavuroven(uroven_chlazeni_tmp);
 +
}
 +
else
 +
{
 +
  nastavuroven(0);//(vypnuto)
 +
}
 +
 
 +
 
 +
// if(iTemperature >= iHighTemp)
 +
// PORTB = PORTB | (1 << 2);
 +
// if(iTemperature < iLowTemp)
 +
// PORTB = PORTB & ~(1 << 2);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

Verze z 9. 5. 2010, 19:30

petr vičar


Obsah

vybrana semestralni prace:

- možnost kalibrace na lokálni teplotu


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) 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) schema 3,3V bude realizovano nejspise stabilizatorem zakmity od tlacitek reseny softwarove zdrojak do Eagle



Ukoly

funkce void nastav(int uroven)
nastavi uroven 0 az N-1 na pcm vystupu (zaklady na jednom cviceni)

zjisteni teploty - precteni hodnoty z A/D prevodniku+nejaka korekce
int zjistiteplotu()
<b>korekci zdiskutovat</b>

probouzeni
jednoduse jednou za x ms + pri stisku tlacitka

ovladani tlacitkama
inkrementace/dekrementace nejake hodnoty, bacha na zakmity, (asi udelam ja)
void xyz () // edituje promenou nastavena teplota

funkce zobrazeni teploty
prevod binarni cislo na dve binarni hodnoty (mod,div) a zobrazeni
void zobrazteplotu(int)

Myslenka systému zobrazeni

 void zobraz(int cislo)
 {
event_DisableIRQ(); 
 //port D jako out - dopsat
 //cast portu c 2,3 taky
 //prvni cislo
 PORTD=mod(cislo,10);
 _delay_ms(1);
 PORTC=PORTC|0x02;
 _delay_ms(1);
 PORTC=PORTC&0xFD;
 _delay_ms(1);
 //druhy cislo
 PORTD=div(cislo,10);
 _delay_ms(1);
 PORTC=PORTC|0x04;
 _delay_ms(1);
 PORTC=PORTC&0xFC;
 _delay_ms(1);
event_EnableIRQ();
 }

Myslenka systému regulace chlazeni (pseudokod)

nejmensi rozlisitelna jednotka je pro nase potreby jeden stupen.

nastaveni:

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)
K - odchylka o jeden stupen zpusoby zapnuti na uroven 1*K (v pripade o n stupnu udela n*K az do hodnoty n)
Tnastavena - udrzovana teplota
Treal - zmerena teplota

funkce nastavuroven - nastavi uroven predanou v parametru 0-vypnuto, N-1 maximalni vykon

deltaT=(Treal-Tnastavena)*(-1)^Kzahrivani;
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)
 }

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:

bool stav=PD.2;
   delay (20ms);
   while (stav!=PD.2)
      {
         delay (20ms);
         stav=PD.2;
      }
   if (stav=...)
   .
   .
   .
   tady už bude co dělat, když se stiskne + nebo - atd...

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


#include <avr/io.h> 
#include <avr/iom168.h> 
#include <util/delay.h> 

volatile unsigned char teplota;

void event_DisableIRQ (void)
{
 __asm {
  MRS r1, CPSR
  ORR r1, r1, #0x80
  MSR CPSR_c, r1
 }
}


void event_EnableIRQ (void)
{
 __asm {
  MRS r1, CPSR
  BIC r1, r1, #0x80
  MSR CPSR_c, r1
 }
}

%stara se o registraci preruseni//nutno upravit na nase
__irq void IRQHandler (void)
{
    volatile unsigned int *base = (unsigned int *) 0x80000000;
    if (*base == 1)       // which interrupt was it?
    {
        C_int_handler();  // process the interrupt
    }
    *(base+1) = *base;    // clear the interrupt
}



void main (void){ 

// nastaveni portu D na vstupy

  PORTD=0x00;
  DDRD=0x00; 

....zde jsou draci

  }

void preruseni (void)
 { //jen osetruji aby jsme nepodtekli/nepretekli
//sem jeste zakazani preruseni
       event_DisableIRQ(); 
       
       _delay_ms(20); 
   	if(PIND.2==0&&teplota!=100)teplota++;
	if(PIND.3==0&&teplota!=0)teplota--;
//sem povoleni preruseni
      event_EnableIRQ();
  } 

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

Zatím je to jen aby ventilátor spínal při 30°C a vypínal při 20°C.

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

//------------------------------------------------------------------------------
volatile int iTemperature = 20; // Zmerena teplota 
volatile int Tnastavena = 20; //Nastavena teplota
const int Kzahrivani = 0;////Kzahrivani - (0-chladi,1-zahryva)- nastavuje zda ovladany prvek snizuje nebo zvysuje teplotu
//------------------------------------------------------------------------------
SIGNAL (ADC_vect)
{
	int iAdcValue = ADCW;
	iTemperature = (iAdcValue * 28) >> 8;
}
//------------------------------------------------------------------------------
void InitAdc()
{
	ADMUX = (1 << REFS1) | (1 << REFS0) | 2; // Reference 1.1V, kanal ADC2
	ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | (1 << ADIE) | 7; // Povoleni ADC, preddelicka 128
	ADCSRB = 0;
}
//------------------------------------------------------------------------------
void InitPorts()
{
	DDRB = (1 << 2); // PB2 jako vystup
	PORTB = 0;
}
//------------------------------------------------------------------------------
void UpdateOutput()
{

//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)
//K - odchylka o jeden stupen zpusoby zapnuti na uroven 1*K (v pripade o n stupnu udela n*K az do hodnoty n)
//Tnastavena - udrzovana teplota
//Treal - zmerena teplota

//funkce nastavuroven - nastavi uroven predanou v parametru 0-vypnuto, N-1 maximalni vykon

int deltaT=(iTemperature-Tnastavena)*(-1)^Kzahrivani;
if(deltaT>0)
 {
   int uroven_chlazeni_tmp=deltaT*K;
   if(uroven_chlazeni_tmp>N-1)
   {
     uroven_chlazeni_tmp=N-1;
   }
   nastavuroven(uroven_chlazeni_tmp);
 }
else
 {
   nastavuroven(0);//(vypnuto)
 }


//	if(iTemperature >= iHighTemp)
	//	PORTB = PORTB | (1 << 2);
//	if(iTemperature < iLowTemp)
	//	PORTB = PORTB & ~(1 << 2);
}
//------------------------------------------------------------------------------
void main()
{
	InitAdc();
	UpdateOutput();
}
//------------------------------------------------------------------------------

Tým

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