catalin004 Postat Noiembrie 10, 2017 Autor Partajează Postat Noiembrie 10, 2017 (editat) Acum se pare ca este ok....o sa modific in loc de 5000 (vref) 4880 #include "LCD_config.h" float temp; int tmp; void get_ADC(){ tmp = ADC_Read(0); //Read ADC voltage temp = ((long)tmp*5000)/1023; // temp = temp/10; //Convert mV in Celsius } char strTemp[] = "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 main(){ TRISA.F0 = 1; //ADC input to RA01 TRISA=0xFF; ADCON1=0x80; //ADC reference to 5V Vdd ADC_Init(); //ADC start LCD_Init(); //LCD Init LCD_Cmd(_LCD_CURSOR_OFF); LCD_Cmd(_LCD_CLEAR); LCD_Out(2,1, "Merge nenea!"); for(;;){ get_ADC(); tempToStr(temp, &strTemp); // conversie a unui nr tip FLOAT intr-un STRING delay_ms(200); LCD_Out(1, 1, strTemp); // afisarea string-ului } } Bun....am rezolvat....acum trebuie sa fac 2 pagini, adica o sa am 3 butoane... o sa am + - si set....intr-o pagina se va seta temperatura de referinta, iar in prima pagina se va face afisarea si un mesaj Ex: wait for warm sau wait for could....as dori niste sfaturi... Editat Noiembrie 10, 2017 de catalin004 Link spre comentariu
mars01 Postat Noiembrie 10, 2017 Partajează Postat Noiembrie 10, 2017 Aveti functia definita de 2 ori, linia "void tempToStr(float, char*);" trebuie stearsa. Incearca te rog sa compilezi programul in cazul in care functiile sunt asezate ca mai jos. Mai compileaza fara erori oare? Eu zic ca nu, dar daca acea linie care tu spui ca este gresita este prezenta (si asezata la inceputul programului) atunci programul se va compila. Acea linie se numeste prototipul functiei. Nu toate programele se realizeaza in ordinea: declaratie variabile, declaratii si definitii functii, functia main(). #include "LCD_config.h" float temp; int tmp; void get_ADC(){ tmp = ADC_Read(0); //Read ADC voltage temp = ((long)tmp*5000)/1023; // temp = temp/10; //Convert mV in Celsius } char strTemp[] = "00.0" ; void main(){ TRISA.F0 = 1; //ADC input to RA01 TRISA=0xFF; ADCON1=0x80; //ADC reference to 5V Vdd ADC_Init(); //ADC start LCD_Init(); //LCD Init LCD_Cmd(_LCD_CURSOR_OFF); LCD_Cmd(_LCD_CLEAR); LCD_Out(2,1, "Merge nenea!"); for(;;){ get_ADC(); tempToStr(temp, &strTemp); // conversie a unui nr tip FLOAT intr-un STRING delay_ms(200); LCD_Out(1, 1, strTemp); // afisarea string-ului } } 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; } Link spre comentariu
catalin004 Postat Noiembrie 10, 2017 Autor Partajează Postat Noiembrie 10, 2017 (editat) Mie nu imi dadea eroare...doar ca nu imi afisa pe display ceva concret...doar hieroglife....cum am spus mai sus mergea...se pare ca acum am eroare la programul dvs Merge si cu acea linie si fara...d Editat Noiembrie 10, 2017 de catalin004 Link spre comentariu
mars01 Postat Noiembrie 10, 2017 Partajează Postat Noiembrie 10, 2017 (editat) Exact punctul meu de vedere. Ca sa fiu mai clar pentru ca se pare ca te-am incurcat. Atunci cand functiile sunt utilizate in ordinea urmatoare: 1. declar si definesc functia 2. utilizarea functiei in programul principal main() Numai este neaparat necesar ca sa fie utilizat si prototipul functiei. Dar atunci cand functiile sunt folosite intr-o ordine diferita, de ex: 1. apelez functia in programul principal main() 2. declar si definesc corpul functiei Este absolut necesara includerea in program (undeva la inceputul sau) a prototipului functiei. In cazul de mai sus, daca se include prototipul functiei, programul se va compila corect. Adica asa: #include "LCD_config.h" void tempToStr(float, char*); float temp; int tmp; void get_ADC(){ tmp = ADC_Read(0); //Read ADC voltage temp = ((long)tmp*5000)/1023; // temp = temp/10; //Convert mV in Celsius } char strTemp[] = "00.0" ; void main(){ TRISA.F0 = 1; //ADC input to RA01 TRISA=0xFF; ADCON1=0x80; //ADC reference to 5V Vdd ADC_Init(); //ADC start LCD_Init(); //LCD Init LCD_Cmd(_LCD_CURSOR_OFF); LCD_Cmd(_LCD_CLEAR); LCD_Out(2,1, "Merge nenea!"); for(;;){ get_ADC(); tempToStr(temp, &strTemp); // conversie a unui nr tip FLOAT intr-un STRING delay_ms(200); LCD_Out(1, 1, strTemp); // afisarea string-ului } } 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; } Editat Noiembrie 10, 2017 de mars01 Link spre comentariu
catalin004 Postat Noiembrie 10, 2017 Autor Partajează Postat Noiembrie 10, 2017 Da....am citit si eu intr-o carte, si scrie ca daca o functie se declara dupa functia main, atunci trebuie definit prototipul functiei la inceput...altfel nu o va recunoaste...insa daca se declara inainte de main nu mai trebuie declarat prototipul...cred ca imi amintesc bine treaba asta...deci prefer sa o declar la inceput...prezint programul care merge...chiar si cu linia aceea #include "LCD_config.h" float temp; int tmp; void get_ADC(){ tmp = ADC_Read(1); //Read ADC voltage temp = ((long)tmp*4880)/1023; // temp = temp; //Convert mV in Celsius } void tempToStr(float, char*); char strTemp[] = "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 main(){ TRISA.F1 = 1; //ADC input to RA01 TRISA=0xFF; ADCON1=0x80; //ADC reference to 5V Vdd ADC_Init(); //ADC start LCD_Init(); //LCD Init LCD_Cmd(_LCD_CURSOR_OFF); LCD_Cmd(_LCD_CLEAR); LCD_Out(2,1, "Merge nenea!"); for(;;){ get_ADC(); tempToStr(temp, &strTemp); // conversie a unui nr tip FLOAT intr-un STRING delay_ms(200); LCD_Out(1, 1, strTemp); // afisarea string-ului LCD_Chr_Cp(223); LCD_Chr_Cp('C'); } } Link spre comentariu
Bandi Szasz Postat Noiembrie 10, 2017 Partajează Postat Noiembrie 10, 2017 (editat) Da este o limitatie a limbajului C, "vede" doar metodele declarate anterior fata de C++ / Java / etc.. unde poti apela in prima functie declarata si ultima functie. Pentru a crea mai multe pagini eu sa proceda in felul urmator: - activez timer0 la 1ms si incep sa le numar ( functia millis() din arduino) - declar o variabila prin care setez care pagina o vreau - intr-o functie verific valoarea paginii dorite si decid ce scriu pe LCD - in loop-ul principal din millis verific cat timp a trecut de la ultima afisare si daca a trecut mai mult decat un anumit timp setat chem functia de afisare care va decide care pagina va fi afisata, un 250ms / 500ms zic e e destul. - tot in loop-ul principal verific starea butoanelor si daca se apasa + sau - schimb valoarea variabilei care decide pagina selectata. In cazul in care pagina deja este a doua atunci incrementez si temperatura de referinta, astfel la prima apasare se va chimba doar pagina pentru vizualizare fara a incrementa valoarea. - tot in loop mai verific daca pagina selectata este a doua si daca a trecut un anumit timp de la ultima apasare de buton, sa zicem 15s schimb inapoi pe pagina 1. Editat Noiembrie 10, 2017 de Bandi Szasz Link spre comentariu
catalin004 Postat Noiembrie 11, 2017 Autor Partajează Postat Noiembrie 11, 2017 da...pare ok...insa sa o luam cu inceputul....prima data cum fac sa setez temp adica stiu sa fac i++ sau - cu butoanele...dar cum memorez ? adica cum memorez temp setata? tot cu pointer? ce inseamna ca verificam pagina? Link spre comentariu
catalin004 Postat Noiembrie 11, 2017 Autor Partajează Postat Noiembrie 11, 2017 (editat) Cred ca asa se face...ma gandeam sa fac si un debounce pe butoane insa am inteles ca nu trebuie sa lucrez cu delay-uri...este necesar debounce?sau daca este musai trebuie sa fac si intrerupere...parei?idei? #define Pbutton_dir TRISC0_bit #define Pbutton PORTC.F0 #define Mbutton_dir TRISC1_bit #define Mbutton PORTC.F0 #define Warning_dir TRISC7_bit #define Warning PORTC.F6 void set_temp(){ static unsigned int setTemp=30; if(!Pbutton){ //increment ++ if(setTemp>=0 && setTemp<=59) { setTemp++; } else { //do nothing } } if(!Mbutton){ //decrement -- if(setTemp>=1 && setTemp<=60) { setTemp--; } else { //do nothing } } if(setTemp>=60){ Warning = 1; } else { Warning = 0; } } si afisare settemp...i-am dat o valoare initiala la 30...asta ca sa am ceva setat...oricum o sa fac probabil si un buton de start (un comutator), care sa pornesc termostatul doar la initializarea lui... In legatura cu meniul, ma gandeam la ceva total diferit:switch case, iar timerul sa revina in default, sau case: 1 Editat Noiembrie 11, 2017 de catalin004 Link spre comentariu
Bandi Szasz Postat Noiembrie 11, 2017 Partajează Postat Noiembrie 11, 2017 (editat) Temperatura de referinta se tine intr-o variabila simpla ( int sau float, depinde daca vreti si zecimale sau nu). La buton trebuie facut debounce in general, sunt cazuri in care merge si fara dar e mai bine daca exista. Verificati libraria Button din mikroC are tot ce va trebuie inclusiv debounce. La buton se poate introduce si un delay de 1-2ms, de obicei se evita delay-urile mari de sute de ms, pentru buton se poate pune linistit in mic delay. Daca o sa am timp in seara asta o sa va scriu un mic exemplu cum as face eu si sa "furati' de acolo cateva idei si solutii, imi ieste mult mai usor sa explic pe un cod scris decat asa teoretic in vorbe. Editat Noiembrie 11, 2017 de Bandi Szasz Link spre comentariu
catalin004 Postat Noiembrie 11, 2017 Autor Partajează Postat Noiembrie 11, 2017 astept codul.... Link spre comentariu
catalin004 Postat Noiembrie 13, 2017 Autor Partajează Postat Noiembrie 13, 2017 Din ce vad....modificarea temperaturii se face cu 0,48 grade, adica la fiecare schimbare pe LCD imi creste/scade cu 0,48....este corect? Multumesc Link spre comentariu
Bandi Szasz Postat Noiembrie 13, 2017 Partajează Postat Noiembrie 13, 2017 (editat) Nu am apucat sa va scriu codul in weekend, dar imi fac azi timp pana seara. ADC-ul cu Vref de 5V are o precizie de 4.88mV, LM35 are la iesire 10mV/C deci este corect findca in acei 10mV/C incap doar doua valori de ADC cu pas de 4.88mV. Pentru o precizie mai mare trebuie o referinta externa pentru ADC, cam pe la 2.5V care ar venii cu o precizie de 2.44mV deci in pasi de aprox. 0.2C Editat Noiembrie 13, 2017 de Bandi Szasz Link spre comentariu
catalin004 Postat Noiembrie 13, 2017 Autor Partajează Postat Noiembrie 13, 2017 Va ramane asa....multumesc pentru raspuns....si astept codul....stima Link spre comentariu
Bandi Szasz Postat Noiembrie 13, 2017 Partajează Postat Noiembrie 13, 2017 Aveti aici un mic exemplu de cod de unde sa va inspirati, posibil sa fie greseli in el find scris in notepad pentru ca nu am in momentul de fata acces la MikroC. #define DISPLAY_REFRESH 250 #define BUTTON_RESET 10000 volatile unsigned long millis = 0; unsigned long display_time = 0; unsigned long button_time = 0; char display_page = 1; float refTemp = 0; bit button1_old, button2_old; void Interrupt(){ if (TMR0IF_bit){ TMR0IF_bit = 0; TMR0 = 6; millis++; } } void InitTimer0(){ // trebuie recalculata pentru frecventa folosita OPTION_REG = 0x4; TMR0 = 6; INTCON = 0xA0; } void display_temp() { // Afisare temperatura curenta } void display_refTemp() { // Afisare temperatura setata } void refreshDisplay() { if(display_time < millis) { // daca au trecut cel putin 250ms facem refresh la display if (display_page == 1) { display_temp(); } else if (display_page == 2) { display_refTemp(); } display_time = millis + DISPLAY_REFRESH; } } 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; } } void checkButtons() { if(Button(&PORTC, 6, 1, 0)) { // buton + pe PORTC - 6 cu debounce de 1ms if (button1_old == 0) { buttonPress(1); button_time = millis; // retinem cand am apasat ultima data pe buton button1_old = 1; } } else if(button1_old) { // prin verificarea "button1_old" va trebuii sa dam drumul la buton pentru al lua din nou in considerare button1_old = 0; } if(Button(&PORTC, 5, 1, 0)) { // buton - pe PORTC - 5 cu debounce de 1ms if (button1_old == 0) { buttonPress(2); button_time = millis; button2_old = 1; } } else if (button2_old) { button2_old = 0; } if (button_time + BUTTON_RESET < millis) { // daca au trecut 10s de la ultima apasare si pagina este a 2-a il schimbam pe 1 if (display_page == 2) { display_page = 1; } } } void main() { InitTimer0(); button1_old = button2_old = 0; while(1) { refreshDisplay(); checkButtons(); } } Link spre comentariu
catalin004 Postat Noiembrie 13, 2017 Autor Partajează Postat Noiembrie 13, 2017 (editat) multumesc...intru la studii...pana o sa folosesc metoda dvs o sa pun si metoda mea pe forum, insa fara pagini #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; unsigned int setTemp=30.0; //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 digital_comand(){ if(!Pbutton){ //increment ++ delay_ms(10); if(!Pbutton){ if(setTemp>=0 && setTemp<=59){ setTemp++; } } else { //do nothing } } if(!Mbutton){ //decrement -- delay_ms(10); if(!Mbutton){ if(setTemp>=1 && setTemp<=60){ setTemp--; } } 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 ByteToStr(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 = Settemp*10; //convertire temperatura setata in mV if(temp<STemp){ RELR = ON; } else { RELR = OFF; } if(temp>STemp){ RELV = ON; } else { RELV = OFF; } } //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'); } } Editat Noiembrie 13, 2017 de catalin004 Link spre comentariu
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum