Vlad Mihai Postat Noiembrie 18, 2012 Partajează Postat Noiembrie 18, 2012 Salut, vreau sa fac un termometru care sa afiseze temperatura in grade Celsius, fahrenheit, Kelvin si Rankine, am incerc eu sa fac un cod pe baza documentatiei dar nu cred ca merge ma ajuta cineva sa il termin? folosesc lm35 ca senzor care are 10mV pe grad celsius. De asemenea am cuart de 12Mhz si un 2x16 LCD. Conversia temp...http://ro.wikipedia.org/wiki/Celsius sbit LCD_RS at RB4_bit;sbit LCD_EN at RB5_bit;sbit LCD_D4 at RB0_bit;sbit LCD_D5 at RB1_bit;sbit LCD_D6 at RB2_bit;sbit LCD_D7 at RB3_bit;sbit LCD_RS_Direction at TRISB4_bit;sbit LCD_EN_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB0_bit;sbit LCD_D5_Direction at TRISB1_bit;sbit LCD_D6_Direction at TRISB2_bit;sbit LCD_D7_Direction at TRISB3_bit;unsigned int val1,val2,val3,valm; unsigned int t,a, b; unsigned long u;unsigned char ch;void main(){ //TRISA = 0xFF; // designate PORTA as input //INTCON = 0; // Disable all interrupts //IRP_bit = 1 ; Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Cmd(_LCD_CLEAR); // Clear display Delay_ms(100); LCD_Out(1,2,"Termometer"); LCD_Out(2,2,"EA 1341A"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); // Clear display LCD_Out(1,2," Alexandru"); LCD_Out(2,2," Bujorean"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); // Clear display LCD_Out(1,2,"Prof. Gaitan"); LCD_Out(2,2,"Cristina-MC"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); while (1) { for (b ; b < 2; b++) { Lcd_Cmd(_LCD_CLEAR); } // Voltage val1=ADC_read(0); // get ADC value for U from channel 1 delay_ms(30); val2=ADC_read(0); delay_ms(30); val3=ADC_read(0); delay_ms(30); valm=((val3+val2+val1)/3); u=(long)valm*5000; // covert adc reading to milivolts u=u/1023; t=(valm*0.48876);//Convert to Degree Celcius LCD_Chr_CP(t); }} Link spre comentariu
10vid Postat Noiembrie 18, 2012 Partajează Postat Noiembrie 18, 2012 Am dat google dupa acel numar misterios: 0.48876. Si a aparut tot in proiecte similare cu pic si lm35. E un factor de conversie precalculat. Daca ai inceput cu val*5000 etc, care e acelasi lucru, doar scris labartat, e clar ca nu-l mai inmultesti inca o data cu acel factor.Si apropo, ADC are 1024 nivele, nu 1023. Stiu, multi fac greseala asta, sa inmultesca si sa imparta cu 1023, probabil si profesori. :bataieDeci, dupa calcularea mediei celor trei citiri, urmeaza:t=(valm*500)/1024 Link spre comentariu
Vlad Mihai Postat Noiembrie 18, 2012 Autor Partajează Postat Noiembrie 18, 2012 la afisare nu prea stiu cum sa fac dupa ce o convertesc, nu stiu cum sa afisez pe prima linie prima coloana temperatura in grade urmat de a 2 coloana cea in Kelvin, iar pe linia a 2 coloana 1 in grade F iar pe linia2 coloana 2 grade R. Link spre comentariu
francezu Postat Noiembrie 18, 2012 Partajează Postat Noiembrie 18, 2012 10vid a spus: Si apropo, ADC are 1024 nivele, nu 1023. Stiu, multi fac greseala asta, sa inmultesca si sa imparta cu 1023, probabil si profesori. Rezolutia , in volti, a unui adc este raportul dintre intervalul tensiunilor permise la intrare si numarul de intervale incadrate in scala adc-ului. Daca adc-ul este pe 10 biti, inseamna ca poate cuantifica 1024 nivele distincte , dar intre acestea sunt doar 1023 de intervale de tensiune. Stiu ca e mai greu sa imparti la 1023 decat la 1024, dar asa se face.http://ww1.microchip.com/downloads/en/A ... 01152A.pdfhttp://en.wikipedia.org/wiki/Analog-to- ... _converter Link spre comentariu
Vlad Mihai Postat Noiembrie 19, 2012 Autor Partajează Postat Noiembrie 19, 2012 Domnilor am modificat cum aţi spus mai departe cu afişarea nu înţeleg. ataşez ce ma făcut eu: sbit LCD_RS at RB4_bit;sbit LCD_EN at RB5_bit;sbit LCD_D4 at RB0_bit;sbit LCD_D5 at RB1_bit;sbit LCD_D6 at RB2_bit;sbit LCD_D7 at RB3_bit;sbit LCD_RS_Direction at TRISB4_bit;sbit LCD_EN_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB0_bit;sbit LCD_D5_Direction at TRISB1_bit;sbit LCD_D6_Direction at TRISB2_bit;sbit LCD_D7_Direction at TRISB3_bit;unsigned int val1,val2,val3,valm; unsigned int t,a, b; unsigned long u;unsigned char ch;void main(){ //TRISA = 0xFF; // designate PORTA as input //INTCON = 0; // Disable all interrupts //IRP_bit = 1 ; Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Cmd(_LCD_CLEAR); // Clear display Delay_ms(100); LCD_Out(1,2,"Termometer"); LCD_Out(2,2,"EA 1341A"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); // Clear display LCD_Out(1,2," Alexandru"); LCD_Out(2,2," Bujorean"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); // Clear display LCD_Out(1,2,"Prof. Gaitan"); LCD_Out(2,2,"Cristina-MC"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); LCD_Out(1, 1,"Temp:"); LCD_Out(2, 1,"Temp:"); while (1) { for (b ; b < 2; b++) { } // Voltage val1=ADC_read(0); // get ADC value for U from channel 1 delay_ms(30); val2=ADC_read(0); delay_ms(30); val3=ADC_read(0); delay_ms(30); valm=((val3+val2+val1)/3); t=(valm*500)/1024; // covert adc reading to milivolts t=(valm*0.48876);//Convert to Degree Celcius if (ch==0) { LCD_Chr(1,6, 32); // write empty space if digit is 0 } else { LCD_Chr(1,6,48+ch); // write ASCII digit at 1st row, 2nd column } LCD_Chr_CP("C"); }} Stiu ca am gresit dar daca imi arati odata codul, stiu dupa cum se face. Link spre comentariu
Liviu M Postat Noiembrie 19, 2012 Partajează Postat Noiembrie 19, 2012 Vlad Mihai a spus: for (b ; b < 2; b++) { } De unde stie compilatorul cat trebuie sa fie b la intrarea in for? La ce e buna secventa asta? Vlad Mihai a spus: t=(valm*500)/1024; // covert adc reading to milivolts t=(valm*0.48876);//Convert to Degree Celcius Cum ti-a zis si 10vid, 0.48876 pare a fi 500/1023, asa ca una din operatii pare in plus. Vlad Mihai a spus: if (ch==0) { LCD_Chr(1,6, 32); // write empty space if digit is 0 } else { LCD_Chr(1,6,48+ch); // write ASCII digit at 1st row, 2nd column } LCD_Chr_CP("C"); }} Cine e ch si de unde sa stie el ce vrei tu sa scrii? Inainte sa folosesti ch, trebuie sa-l "umpli". Drept pentru care trebuie sa transformi temperatura din numar in sir de caractere si sa afisezi caracterele respective. Metoda pe care o folosesc eu e (cu variabilele tale ): if(t<0) LCD_char(1,6,'-'); // semnul - pentru temperaturi negative ch = t/100; //=> afisez sutele if(ch) LCD_char(1,7,'0'+ch); //eu prefer ca trasformarea din char in ascii s-o fac cu ajutorul lui '0', nu cu 48. E acelasi lucru, da' eu citesc mai usor codul astfel scris else LCD_char(1,7,' '); //aici e o pauza intre ' ' (caracterul pauza ) ch = ...; //=> afisez zecile if(ch) LCD_char(1,8,'0'+ch); else LCD_char(1,8,' ');...Sper ca am inteles bine ce-ti trebuie. Link spre comentariu
Vlad Mihai Postat Noiembrie 19, 2012 Autor Partajează Postat Noiembrie 19, 2012 multumesc de raspuns, dar tot nu am priceput.. poti modifica tu astfel incat sa apara temperatura in grade Celsius pe prima linie si prima colonă?? si eu după sa ma joc cu el, după ce e bun. Multumesc! Link spre comentariu
Liviu M Postat Noiembrie 19, 2012 Partajează Postat Noiembrie 19, 2012 N-am inteles ce n-ai inteles. Cum se transforma "LSB in grade", cum afisezi ce ai obtinut, ambele? La prima intrebare am asa o senzatie ca t (din t=(valm*500)/1024; sau t=(valm*0.48876)) e fix ce-ti trebuie. La afisare ti-am scris mai sus "algoritmul", n-ai decat sa-l termini si sa-l corectezi - ce am scris eu afiseaza pornind din linia 1, coloana 6 (sper ca-ti e clar ca temperatura nu poate fi afisata "pe linia 1 coloana 1 decat daca e intre 0 .. 9 °C). Mai departe incearca si singur, ca nu-i asa greu. Link spre comentariu
Vlad Mihai Postat Noiembrie 20, 2012 Autor Partajează Postat Noiembrie 20, 2012 am mai facut ceva acum dar apare tot timpul 0.0 grade celsius.. nu am idee ce trebuie sa fac. sbit LCD_RS at RB4_bit;sbit LCD_EN at RB5_bit;sbit LCD_D4 at RB0_bit;sbit LCD_D5 at RB1_bit;sbit LCD_D6 at RB2_bit;sbit LCD_D7 at RB3_bit;sbit LCD_RS_Direction at TRISB4_bit;sbit LCD_EN_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB0_bit;sbit LCD_D5_Direction at TRISB1_bit;sbit LCD_D6_Direction at TRISB2_bit;sbit LCD_D7_Direction at TRISB3_bit;unsigned int val1,val2,val3,valm; unsigned int t,a, b; unsigned long u;unsigned char ch;void main(){ //TRISA = 0xFF; // designate PORTA as input //INTCON = 0; // Disable all interrupts //IRP_bit = 1 ; Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_Cmd(_LCD_CLEAR); // Clear display Delay_ms(100); LCD_Out(1,2,"Termometer"); LCD_Out(2,2,"EA 1341A"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); // Clear display LCD_Out(1,2," Alexandru"); LCD_Out(2,2," Bujorean"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); // Clear display LCD_Out(1,2,"Prof. Gaitan"); LCD_Out(2,2,"Cristina-MC"); Delay_ms(1500); Lcd_Cmd(_LCD_CLEAR); LCD_Out(1, 1,"Temp:"); LCD_Out(2, 1,"Temp:"); while (1) { for (b ; b < 2; b++) { } // Voltage val1=ADC_read(0); // get ADC value for U from channel 1 delay_ms(30); val2=ADC_read(0); delay_ms(30); val3=ADC_read(0); delay_ms(30); valm=((val3+val2+val1)/3); t=(valm*0.48876);//Convert to Degree Celcius if (ch==0) { LCD_Chr(1,6, 32); // write empty space if digit is 0 } else { LCD_Chr(1,6,48+ch); // write ASCII digit at 1st row, 2nd column } ch=(u/100) %10; // extract 01.00 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point LCD_Chr_CP('.'); // write '.' at cursor point ch=(u/10) %10; // extract 00.10 U digit LCD_Chr_CP(48+ch); // write ASCII digit at cursor point LCD_Chr_CP('C'); }} Link spre comentariu
Liviu M Postat Noiembrie 20, 2012 Partajează Postat Noiembrie 20, 2012 Cine-i u? Unde scrii ceva in u, a.i u sa nu fie 0? Mie mi se parea clar exempul meu. Temperatura ta sta in t. In primul if din exemplul meu testez daca temperatura e negativa (la tine n-are de unde sa fie negativa, da' am tratat cazul general). Daca e, afisez semnul -, daca nu las o pauza. Urmeaza afisarea fiecarei cifre din temperatura. Am exagerat putin si am presupus ca temperatura ta poate fi peste 100°C,drept pentru care pot afisa si sutele de grade. Cu operatia ch = t/100 am extras sutele din valoarea temperaturii (t, la tine temperatura sta tot timpul in t). Cu LCD_char(1,7,'0'+ch); afisez caracterul corespunzator sutelor (am scris in comentartiu de ce folosesc '0'). Chiar nu vad ce e neclar. PS Ca sa ai o "rezolutie" ceva mai buna, foloseste un tip "cu virgula" (single, double)pentru t, nu intreg ca pana acum. In cazul asta o sa ai si ceva de afisat dupa virgula. Link spre comentariu
Vlad Mihai Postat Noiembrie 20, 2012 Autor Partajează Postat Noiembrie 20, 2012 nu e mai uşor să îmi ce să scriu şi unde? decât aşa?(zic şi eu) ca să pricep după ce şi cum e făcut.... Link spre comentariu
Liviu M Postat Noiembrie 20, 2012 Partajează Postat Noiembrie 20, 2012 Pai asta am facut in postul cu codul. Mai aveai sa scrii doua formule pentru extras zecile (ch=(t/10)%10), respectiv unitatile (ch=t%10) din t si sa le afisezi la locurile lor: if(t<0) LCD_char(1,6,'-'); // semnul - pentru temperaturi negative ch = t/100; //=> afisez sutele if(ch) LCD_char(1,7,'0'+ch); else LCD_char(1,7,' '); ch = (t/10)%10; LCD_char(1,8,'0'+ch); ch = t%10; LCD_char(1,9,'0'+ch); Asa-i ca nu era chiar asa greu?. Ce-i drept, codul de mai sus afiseaza 0 la zeci cand temperatura e mai mica de 10°C, da' te mai joci singur sa-l faci sa afiseze mai bine (trebuie sa testezi daca ai ceva la sute, daca ai afisezi 0, daca n-ai nu afisezi nici la zeci nimic). LE Mai trebuie, desigur, sa afisezi °C dupa valoare. Link spre comentariu
Vlad Mihai Postat Noiembrie 20, 2012 Autor Partajează Postat Noiembrie 20, 2012 merge, mulţumesc de ajutor, de acum trebuie să fac pe a 2 linie conversia în grade Fahrenheit! Link spre comentariu
Liviu M Postat Noiembrie 20, 2012 Partajează Postat Noiembrie 20, 2012 Sa nu-mi zici ca ai si acolo probleme. Calculezi intai valoarea ca numar (fahr=f(t), unde f e functia de conversie din °C in fahrenheit) dupa care la afisare aplici acelasi "algoritm" inlocuind t cu fahr in formulele de calcul pentru ch si adaptand coordonatele de afisare. Link spre comentariu
Vlad Mihai Postat Noiembrie 23, 2012 Autor Partajează Postat Noiembrie 23, 2012 revin cu termomerul meu am scris softul în simulator merge perfect, dar in practica nu merge, Lm35z l-am pierdut dar am făcut rost de un Lm335 care conform datasheet are 10mv/grad kelvin, deci acolo unde trebuia să indice celsius trebuia să indice kelviu doar că senzorul pare defect la temperatura camerei circa 20 de grade C da la ieşire o tensiune de 2.3v iar pe Lcd afisează 230. deci bănuiesc senzorul defect, am văzut pe google că se inseria si un rezistor de 2k2 cu borna 5v la senzor , dacă fac asta scade la 1.4v la ieşire din senzor. Deci? online photo storage 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