Sari la conținut
ELFORUM - Forumul electronistilor

Ajutor cu ADC si 128x64 Grafic LCD. Cum pot "sparge" cifrele


Vizitator biker1987

Postări Recomandate

Vizitator biker1987

Buna dimineata, am un lcd grafic pe care vreau sa afisez o valoare citita de pe un adc, aceasta valoare vreau s-o sparg in cifre separat, de exemplu am codul de mai jos.

Si vreau sa extrag fiecare cifra pe care s-o folosesc la niste bucle

De exemplu la 5V am 4997 dec value, vreau sa pot extrage si lucra separat cu fiecare cifra din aceea valoare decimala, respectiv 4,9,9 si 7.

Am incercat folosind o varianta de mai jos si din pacate nu merge, pe fiecare linie de pe glcd imi afiseaza valoarea totala (4997).

As vrea putina indrumare...

Multumesc

char txt[5];unsigned long adc_0,adcmath;void main() {trisa=0xff;adc_init();trisb=0x00;trisc=0x00;trisd=0x00;ccp1con=0x00;Glcd_Init();glcd_fill(0);adc_0=adc_read(0);adcmath=adc_0*5000>>10;longtostr(adcmath,txt);Glcd_write_text(txt[0],10,1,1);Glcd_write_text(txt[1],10,2,1);Glcd_write_text(txt[2],10,3,1);Glcd_write_text(txt[3],10,4,1);}
Link spre comentariu
  • Răspunsuri 28
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Acum ca am ajuns acasa (mesajul precedent era de pe iPhone-ul consoartei - "a pain in the butt" sa scrii mesaje pe forumuri :nebunrau: din parc cu copii).

 

Uite cum afisez eu cu succes o tensiune masurata - cu Glcd_Write_Char nu cu Glcd_write_text. Este primul si unicul meu proiect, asa mi-a mers. Nu mai pot edita mesajul precedent, dar este o solutie buna totusi; insa acuma poti folosi codul de mai jos.

adc_rd0 = ADC_read(0)      temp0 = (adc_rd0 * 200) / 1023      ch0 = temp0      ByteToStr(ch0, PSUvolt)      Glcd_Write_Char(PSUvolt[0], 92, 5, 1)      Glcd_Write_Char(PSUvolt[1], 98, 5, 1)      Glcd_Write_Char(".", 104, 5, 1)      Glcd_Write_Char(PSUvolt[2], 111, 5, 1)
Citeste helpul:

' Write character 'C' on the position 10 inside the page 2:Glcd_Write_Char("C", 10, 2, 1)

Codul tau:

Glcd_write_text(txt[0],10,1,1);Glcd_write_text(txt[1],10,2,1);Glcd_write_text(txt[2],10,3,1);Glcd_write_text(txt[3],10,4,1);
Tu vrei sa afisezi valoarea ADC pe verticala? Asa pare din codul tau.
Link spre comentariu
  • 5 luni mai târziu...

Uite cum afisez eu cu succes o tensiune masurata - cu Glcd_Write_Char nu cu Glcd_write_text.

      ByteToStr(ch0, PSUvolt)      Glcd_Write_Char(PSUvolt[0], 92, 5, 1)...
Intotdeauna am avut senzatia ca functiile astea "de biblioteca", generale, nu sunt si neaparat optime, da' n-am avut cum sa testez.

Asa ca as fi interesat daca vreunul din voi (utilizatorii de MikroC) poate face o comparatie intre varianta "ByteToStr()" folosita de Thunderer si varianta /%mentionata de Mondan:

//unitati   cifra = Nr % 10;   Glcd_Write_Char(cifra +'0', 111, 5, 1);   Glcd_Write_Char(".", 104, 5, 1)//zeci   cifra = (Nr / 10) % 10;   Glcd_Write_Char(cifra +'0', 98, 5, 1);//sute   cifra = Nr % 100;   Glcd_Write_Char(cifra +'0', 92, 5, 1);
Daca reusiti sa faceti testul, as fi interesat de rezultat (sa stiu daca ma mai chinui sa-mi fac propriile functii "optime" sau folosesc functii gata facute).

Multumesc

Link spre comentariu

Liviu, o comparatie intre restul impartirii la 10 si functia din compilator pentru un Word. PIC-ul este un 16F88. Ar fi trebuit sa fie un 16F676 dar, la vremea aia, am folosit FloattoStr si nu incapea (vezi jos explicatii). Apoi am invatat metoda cu 10, dar prea tarziu ca 16F88 era deja angajat in proiect.

 

' Voltage U1          adc_rd0 = ADC_read(0)        ' Read ADC channel 0          tlong0 = adc_rd0 * 5000 * 12.5           tlong0 = tlong0 >> 10          ch0 = tlong0 div 10000 '          if ch0 = 0 then'              Lcd_Out(1, 1," ")'          else              Lcd_Chr(1, 1, 48+ch0)'          end if          ch0 = (tlong0 div 1000) mod 10          Lcd_Chr(1, 2, 48+ch0)'          Lcd_Chr(1, 3, ".")          ch0 = (tlong0 div 100) mod 10          Lcd_Chr(1, 4, 48+ch0)          ch0 = (tlong0 div 10) mod 10          Lcd_Chr(1, 5, 48+ch0)          ch0 = (tlong0 div 1) mod 10          Lcd_Chr(1, 6, 48+ch0)
La compilare: RAM(11 ocupat/89 liber), ROM(46 ocupat/54 liber)

' Voltage U1          adc_rd0 = ADC_read(0)        ' Read ADC channel 0          tlong0 = adc_rd0 * 5000 * 12.5           tlong0 = tlong0 >> 10          ch0 = tlong0 div 10000          WordtoStr(ch0, txt)          Lcd_Out(1,1, txt)
La compilare: RAM(12 ocupat/88 liber), ROM(45 ocupat/55 liber)

 

In primul exemplu am comentat IF-ul si virgula ca sa fie ambele coduri pe picior de egalitate.

 

La Byte (ocupa 3 caractere LCD) si Word (ocupa 5 caractere LCD) este uneori convenabil sa folosesti functiile compilatorului (rapid sa testezi un cod pe hardware). Dar la Float deja devine o risipa de memorie si de caractere pe LCD. Float cere 11 caractere si daca vrei sa afisezi 2 float-uri pe o linie de LCD, este foarte aleator ce vezi la afisare. Asta chiar in conditiile in care definesti variabila txt ca fiind un char de 4 caractere. Compilatorul ignora si LCD are cifre suprapuse.

 

Folosesc foarte rar, in ultima vreme, acele functii din compilator in programele finale.

 

In C nu programez de la zero, doar modific dupa cum inteleg, ca nu stiu sintaxele. Poate cineva testeaza acest cod:

http://www.elforum.info/viewtopic.php?f=41&t=158568&start=45#p1450370.

Link spre comentariu

La functii "optime" , nu numai ROM/RAM - ul ocupat conteaza.La optimizare sunt 2 optiuni : prima este cea perezentata in functie de ROM/RAM , acea ce se numeste optimizare pe baza de memorie si sacrificare de timp. Nu in toate cazurile un cod mai scurt este varianta "optima" in timpul de executie.Acea ce vreau sa spun , cum se stie in programare sunt 2 mari categorii de operatii :1. + -2. * /Prima categorie (+-) sunt o serie de operatii mai usor de executat decat a doua categorie (*/) , deci daca ne intereseaza optimizarea pentru timpul de executie , atunci sacrificam ceva memorie in plus.De exemplu vrem sa facem 8 operatii de inmultire:1. facem pur si simplu cele 8 operatii.2. Cautam asa numitul "relatie de recurenta" daca gasim unu-l si reusim sa reducem cele 8 inmultiri la numai 7 inmultiri dar trebuie sa facem 4-5 operatii de adunare , pentru majoritatea utilizatorilor pare mult mai lent decat daca facem cele 8 inmultiri (findca o sa fie in loc de 8 operatii , 12 operatii) dar nu , nu este mai lent ci mai rapid faindca microprocesorul poate executa mai usor/rapid cele 5-6 adunari decat o singura inmultire.Deci , depinde in ce sens vrem "optimizare" : timp de executie sau memorie untilizata , oricare dintre ele am alege inseamna sacrificarea celuilalt.

Link spre comentariu

@bandi12: de obicei functiile "de biblioteca" sunt "mai generale" decat functiile dedicate unei operatii anume, asa ca ma astep ca ultimele sa fie si mai mici, si mai rapide.Nu cred ca in cazul conversiei anterioare (numar in sir) functiile "de biblioteca" folosesc "algoritmi" mult diferiti de operatiile mele individuale, numai ca, de exemplu, daca eu pot sa ma opresc la un anumit numar de cifre, o functie "de biblioteca" trebuie macar sa "afle" numarul de cifre din numar => pierde si la cantitate de memorie si la viteza.PS Multe picuri din seria 18F au multiplicatori hardware, asa ca realizeaza inmultirile intr-un ciclu. Cel putin asa se lauda uChip.

Link spre comentariu

bandi12, operatia de "inmultire" nu se realizeaza prin adunari repetate.postarea ta nu-si are rostul.cel putin in acest context.

Acolo exista si o expresie : "relatie de recurenta". Daca nu ma crezi scrie pe google : "Algoritmul Strassen" Se refera la optimizarea unui functii de inmultire a 2 matrici de 2x2. Prin reducerea a 8 inmultiri la 7 inmultiri prin efectuarea unor serii de pre calcule de adunari si scaderi ( astea se numesc relatii de recurenta ), dupa care cu ajutorul acestor pre calcule se poate obtine rezultatul celor 8 inmultiri cu ajutorul numai a 7 inmultiri.Cu acest lucru timpul de executie T(n) = O(n^3) , se reduce la T(n) = O(n^log(7)) , cum log(7) este undeva in jur de 2.8 este mai mic decat 3 , acesta demonstreaza ca algoritmul Strassen prin acele pre calcule reduce timpul de executie a functiei.Acuma acel 0.2 nu este mult la programare de PIC - uri pentru ca nu lucram cu date imense , dar la programare PC , sa zicem un Joc unde se proceseaza sute de MB - de date acel 0.2 conteaza enorm de mult. Si stiu ca la programare PIC , ne bazam mai mult pe memorie findca suntem limitati de el , eu am vrut doar sa spun pentru cei interesanti , ca exista 2 tipuri de "optimizare".@Liviu M , din pacate nu sunt mare cunoscator al PIC -urilor , nu stiu cum sunt concepute bibliotecile , sau daca au niste smecherii de care zici. Eu in mare pare ma ocup de programare PC , PIC - urile sunt un mic hobby in timpul liber.
Link spre comentariu

... cum log(7) este undeva in jur de 2.8 este mai mic decat 3

la mine log(7) este subunitar :)ps: vrei tu sa zici ceva interesant dar nu prea ai inteles despre ce este vorba si nici nu se aplicain cazul subiectului discutat.eu inteleg ca initiatorul acestui topic vrea sa obtina reprezentarea ascii a unui integer.
Link spre comentariu

... cum log(7) este undeva in jur de 2.8 este mai mic decat 3

la mine log(7) este subunitar :)ps: vrei tu sa zici ceva interesant dar nu prea ai inteles despre ce este vorba si nici nu se aplicain cazul subiectului discutat.eu inteleg ca initiatorul acestui topic vrea sa obtina reprezentarea ascii a unui integer.
1. Eu am inteles foarte clar despre ce este vorba cand vine vorba de "optimizare" , am mentionat deja ca ma ocup in domeniul de programare PC ......2. Am mentionat deja ca "STIU" ca la PIC uri nu se prea aplica aceatsa optimizare findca este o diferenta foarte mica cand lucram cu date mici.3. Liviu a dat 2 exemple si a fost curios daca bibliotecile sunt "optime" sau mai bine sa conceapa functii proprii , cum eu nu am experianta redusa in PIC - uri , am explicat cam pe ce se bazaeaza "optimizarea" ( in domeniul PC - urile care la randul lor fulosesc tot microprocesoare) in asa fel ca sa poata verifica cat de optime sunt bibliotecile. Eu ma retrag din acest topic , ca nu are nici un sens sa ne contrazicem / certam pe ce se bazeaza "optimizarea" si lucrurile se duc rau de tot in afarea subiectului discutat.@Liviu M da este log2 pentru ca formula este : (n^log de baza n (7+o(1))) , exlemplul dat este o matrice patratica n = 2 , 7 este numarul inmultirilor , o(1) este timpul necesar procesarii operatiilor + - in pre calcule.
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