Sari la conținut
ELFORUM - Forumul electronistilor

Termostat - PIC16F877


Postări Recomandate

Intrebari:

 

1.Cred ca aici este o gresala de sintaxa....nu imi ia incrementul cu 0,5...poate ar trebui inversat + cu =....

2.la o functie void, ceea ce se pune imediat in paranteza, este ceea ce returneaza functia, sau se declara variabile?


void buttonPress(char button) {
	
   if (display_page == 1) { // daca pagina actuala este 1 schimbam pe pagina 2 pt vizualizare
	display_page = 2;
	return;
   }   
	// altfel incrementam sau decrementam
	
  if (button == 1) { // incrementam cu pasi de 0.5C
	refTemp += 0.5;    
  }
  if (button == 2) { // decrementam cu pasi de 0.5C
	refTemp -= 0.5;    
  }	
}
Editat de catalin004
Link spre comentariu

Am creat alt bufer, in aceeasi functie...inca lucrez sa vad ce zice


Am facut...imi afizeasa cu zecimala, insa cand apas pe + sau - nu imi apare 0,5 la sfarsit...adica 29.5 sau 30.5...imi schimba doar cu 1 grd

#include "LCD_config.h"
#define LED1_dir TRISD0_bit              //LED pentru avarie >60 grade
#define LED1 PORTD.F0
#define RELR_dir TRISD3_bit              //iesire releu incalzire(cuplare rezistenta)
#define RELR PORTD.F3
#define RELV_dir TRISD7_bit             //iesire releu ventilator(racire)
#define RELV PORTD.F7

#define Pbutton_dir TRISC7_bit           //increment buton
#define Pbutton PORTC.F7
#define Mbutton_dir TRISC0_bit           //decrement buton
#define Mbutton PORTC.F0

#define OUTPUT 0
#define INPUT 1

//anonymous enumeration
enum{
OFF=0, ON=1};

float temp;
int tmp;
float setTemp=30;       //temperatura setata initial

void get_ADC(){
tmp = ADC_Read(1);              //Read ADC voltage
temp = ((long)tmp*4880)/1023;   //
}

//buffer function for show float temperature
void tempToStr(float, char*);
char strTemp[] = "00.0";
char strSetTemp[] = "00,0";
void tempToStr(float temp, char *buffer) {
  int value = (int)temp;
  buffer[3] = value % 10+48;
  buffer[1] = value/10 % 10+48;
  buffer[0] = value/100 % 10+48;
}
  void SetTempToStr(float SetTemp, char *buff) {
  static unsigned int val;
  val = (int)SetTemp*10;
  buff[3] = val % 10+48;
  buff[1] = val/10 % 10+48;
  buff[0] = val/100 % 10+48;
}

void digital_comand(){
if(!Pbutton){
//increment ++
            delay_ms(10);
            if(!Pbutton){
                          if(setTemp>=0 && setTemp<=59){
                                                         setTemp+=0.5;
                                                         }
                         }
              else
              {
              //do nothing
              }
             }
if(!Mbutton){
//decrement --
            delay_ms(10);
            if(!Mbutton){
                         if(setTemp>=1 && setTemp<=60){
                                                        setTemp-=0.5;
                                                      }
                         }
              else
              {
              //do nothing
              }
            }
//if temp >60 degrees
if(temp>=600){
                  LED1 = ON;
   //             LCD_Out(2,0, "1234567890123456");
                  LCD_Out(2,0, "                ");
                  LCD_Out(2,0, "    WARNING!    ");
                  }
                  else{
                       LED1 = OFF;
                       //show setTemp
                       SetTempToStr(SetTemp, &strSetTemp);
                       LCD_Out(2,0, "                ");
                       LCD_Out(2,3, "SetTemp=");
                       LCD_Out(2,11, strSetTemp);
                       LCD_Chr_Cp(223);      //simbol character for degrees
                       LCD_Chr_Cp('C');      //Celsius character to end of row
                  }
}

//comanda relee in functie de temperatura
void REL_out(){
static unsigned int Stemp;
Stemp =(int)Settemp*10;  //convertire temperatura setata in mV
if(temp<STemp){
                 RELR = ON;
                 }
                 else
                 {
                 RELR = OFF;
                 }
if(temp>STemp){
                 RELV = ON;
                 }
                 else
                 {
                 RELV = OFF;
                 }
if(temp == Stemp)
{
//do nothing
}
}

//initializare hardware
void hw_init(){
TRISA.F1 = 1;                //ADC input to RA01
TRISA.F1=0xFF;
ADCON1=0x80;                 //ADC  reference to 5V Vdd

LED1_dir = OUTPUT;
RELR_dir = OUTPUT;
RELV_dir = OUTPUT;
Pbutton_dir = INPUT;
Mbutton_dir = INPUT;

LED1 = OFF;
RELR = OFF;
RELV = OFF;
}


void main(){
hw_init();
ADC_Init();                  //ADC start
LCD_Init();                  //LCD Init
LCD_Cmd(_LCD_CURSOR_OFF);
LCD_Cmd(_LCD_CLEAR);
LCD_Out(1,4, "Temp=");
           for(;;){
                  get_ADC();
                  digital_comand();
                  REL_out();
                  //show readTemp
                  tempToStr(temp, &strTemp); // conversie a unui nr tip FLOAT intr-un STRING
                  delay_ms(200);
                  LCD_Out(1, 9, strTemp);  // afisarea string-ului
                  LCD_Chr_Cp(223);
                  LCD_Chr_Cp('C');
                  }
}

gata: :)

  int val = SetTemp*10;

Bun...toate bune pana acum....mai am o ultima problema despre acest termostat:cand sunt egale temperaturile , ambele relee sa fie in 0 logic...adica cand am 23 grade referinta si ajung la 23.5 cea citita, sa nu am comanda...cred ca trebuie aleasa doar partea intreaga a temperaturilor...insa am incercat cu (int) in fata si nu merge...rog o sugestie

Link spre comentariu

Comenzile acestea mi le face, doar egalitatea nu o face, adica cand ambele relee sunt oprite....value si val sunt valori intregi ale lui temp si set temp, ca var globale

/comanda relee in functie de temperatura
void REL_out(){
a=(int)value/10;
b=(int)val/10;
if (a == b){
            RELV = OFF;
            RELR = OFF;
            }
if(value<val){
                 RELR = ON;
                 }
                 else
                 {
                 RELR = OFF;
                 }
if(value>val){
                 RELV = ON;
                 }
                 else
                 {
                 RELV = OFF;
                 }
}
Link spre comentariu

Doar acuma observ ca ati facut inca o functie de convertire la afisare, "SetTempToStr", la una se face inmultire cu 10 la celalalt nu.. deci nu e nici o mirare ca la afisare va da la fell si la comparare nu. Acolo trebuie sa ramana doar functia care are inmultirea si cealalta sa dispara, iar ambele temeraturi sa foloseasca aceasi functie ( cu bufferele de char[] diferite cum aveti strTemp respectiv, strSetTemp) si o sa vedeti atunci de ce nu va intra in conditia de egal.

 

Apelati in loc de tempToStr(temp, &strTemp); , SetTempToStr(temp, &strTemp); si vedeti daca va mai da egal la afisare.

 

Edit: O sa observati ca la afisarea temperaturii reale o sa va afiseze mai mult decat ar trebuii findca e gresit calularea in functia ADC, ori impartit rezultatul actual cu inca 10 sau inmultit pur si simplu rezultatul obtinut cu ADC_Read cu 0.477 si o sa va dea temperatura corecta

Editat de Bandi Szasz
Link spre comentariu

Salutare...m-am gandit azi, ca o noua provocare pentru mine, sa fac urmatoarea aplicatie: in momentul in care se seteaza temperatura mai mare decat cea citita, pana la atingerea temperaturii setate sa flash-uie temperatura setata....si respectiv invers, tem_set sa faca flash pe display pana scade la cea setata, dupa ce senzorul se raceste...

 

Ma gandeam sa bag toata comanda logica in interrupt, insa cred ca nu este profesional....asa ca rog cateva idei....

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări