vili_topor Postat Mai 17, 2019 Partajează Postat Mai 17, 2019 (editat) Incerc sa imi umplu timpul si sa fac ceva util, asa ca am inceput sa lucrez la un proiect cu PIC 16F628A pentru interfatarea unui senzor temperatura/umiditate DTH11. Am cumparat 4 senzori, nici unul nu da raspuns la secventa de "trezire" initiata de PIC. Pun codul dupa ce am taiat tot din el, lasand numai secventa de initiere a comuniacrii cu senzorul. Voi atasa si datasheet senzor. Poate ma ajuta cineva care a lucrat cu asa ceva sau a intampinat problema. Am sapat pe net, totul pare OK, numai ca nu functioneaza. Se aprinde LED pe RB3 in bucla MILISECUNDA si se stinge dupa ce iese din bucla, semn ca PIC-ul pune linia de date LOW. Apoi aceasta ramane tot timpul HIGH prin rezistenta de pull-up, senzorul nu o pune LOW si ramane in bucla detestare a liniei pentru aparitia statusului LOW(portiunea de cod BOLD) PROCESSOR 16F628A ;interfata cu 16F628A pentru modul digital temperatura/umiditate DTH11 ;se foloseste oscilator extern, quartz de 4 Mhz #include "p16f628a.inc" __CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF CBlock 0x20 multiplicare;folosit la setarea delay de forma multiplicare x micosecunda, etc timp1;folosit la secunda timp2;folosit la secunda timp3;folosit la secunda; timp4;folosit la milisecunda timp5;folosit la milisecunda timp7;folosit la microsecunda grade zecimeGrade umiditate zecimeUmiditate paritate cifra1 cifra2 cifra3 cifra4 temporar;stochez cate 8 biti din sirul de date transmis de senzor apoi il copii in variabila corespunzatoare(grade, umiditate, etc) contor;folosit in bucla de stocare a bitilor in temporar setVariabila;alege in care din variabile este copiat temporar endc org 0000 goto main org 0004;intreruperi return;daca apare o intrerupere accidentala, se duce inapoi ;goto loop;se intoarce in bucla dupa o intrerupere main movlw 41;pentru calculul secundei movwf timp1; movlw 156 movwf timp2; movlw 50; movwf timp3; movlw b'11111110';cifra zero movwf cifra1 movwf cifra2 movwf cifra3 movwf cifra4 movlw 8 movwf contor;contor folosit la numarul de rotatii rlf temporar pt a sesiza cand au fost opt rotatii. clrf PORTB bsf STATUS, RP0 movlw b'00000000';{PORTB setat pentru OUTPUT movwf TRISB bcf STATUS, RP0 call secunda;pentru stabilizarea alimentarii circuitelor clrf T2CON;pregateste TMR2 clrf TMR2 citire;initiaza o citire a senzorului clrf temporar;se reseteaza in vederea stocarii sirului de biti ;linia de date este intre RB0 si pinul DATA al modului DHT11 ;linia este pull-up printr-o rezistenta de 4.7 Kohm bcf PORTB, RB0; se pune RB0 low pentru 20 milisecunde call milisecunda bsf STATUS, RP0 movlw b'00000001';se pune RB0 pe input, restul pe output movwf TRISB bcf STATUS, RP0 btfsc PORTB, RB0;verifica daca RB0 e HIGH prin rezistenta de pull-up si stinge ledul pe RB3 BCF PORTB, 3 ;DE AICI NU MAI FUNCTIONEAZA ;se citeste raspunsul senzorului, care trebuie sa puna RB0 pe low 80 microsec apoi pe high 80 microsec. btfsc PORTB, RB0;ramane in bucla cat timp linia de date e HIGH prin rezistenta de pull-up. Cand linia e comandata low de senzor executa urmatoarele linii goto $-1 bsf PORTB, 1;aprinde ledul pe RB1, pentru a arata ca linia a trecut in LOW btfss PORTB, RB0;ramane in bucla cat linia de date e LOW prin comanda data de senzor. Cand senzorul nu mai comanda LOW, linia trece HIGH prin rezistenta de pull-up goto $-1 bsf PORTB, 2;aprinde eldul pe RB2 pentru a semnala ca linia de date a trecut in HIGH loop goto loop secunda decfsz timp1, 1 goto faza2 movlw 41;initializeaza timp1 pentru 1 secunda timp1=41. Se creste la 80 pa a avea aporx 2 sec intarziere movwf timp1 return faza2 decfsz timp2, 1 goto faza3 movlw 156;initializeaza timp2 movwf timp2 goto secunda faza3 movlw 50;initializeaza timp3 movwf timp3 decfsz timp3, 1 goto $-1 goto faza2 ;goto faza2 milisecunda;20100 instructiuni, adica 20,1 milisecunde btfss PORTB, RB0 bsf PORTB, 3;semnaleasa ca RB0 e LOW in urmatoarele 20 milisecunde movlw 33 movwf timp4 faza4 decfsz timp4, 1 goto faza5 return faza5 movlw 200 movwf timp5 decfsz timp5, 1 goto $-1 goto faza4 microsecunda;la frecventa de 4 mhz , o instructiune pt o microsecunda. decfsz multiplicare, 1 goto microsecunda return end DHT11 senzor temperatura si umiditate.pdf Editat Mai 17, 2019 de vili_topor Pentru o mai buna intelegere a problemei Link spre comentariu
cimitavita Postat Mai 17, 2019 Partajează Postat Mai 17, 2019 senzorul nu da valori exacte pentru duratele bit 1 si bit 0. Valorile pentru bit 1 si bit 0 variaza in anumite limite, chiar la acelasi senzor. Daca faci programul pentru valori exacte ale duratelor bit 1 si bit 0 o sa obtii numai erori. In plus, intre octetii cititi de la senzor, trebuie sa mai lasi o pauza de 80 - 120us, pentru-ca interfata senzorului sa aiba timp sa puna la iesire urmatorul octet. Bit 0: Tlow_low_sgn = 50 us (48-55us), TH0_high_sgn = 26 us (22-30us) Bit 1: Tlow_low_sgn = 50 us (48-55us), TH1_high_sgn = 70 us (68-75us). Link spre comentariu
vili_topor Postat Mai 17, 2019 Autor Partajează Postat Mai 17, 2019 Multumesc de raspuns...insa nu am ajuns la citirea datelor, probabil abia acolo incepe distractia. Dupa ce PIC pune linia LOW pentru mai mult de 18 milisecunde si pinul de la linia de date intra in starea INPUT, ar trebui ca senzorul sa puna linia LOW pentru 80 microsecunde, apoi sa o elibereze pentru alte 80 microsecunde(linia HIGH prin rezistenta de pull-up)ca raspuns la semnalul PIC-ului. Nu se intampla chestia asta, nu pune linia pe zero logic...deci nu se pune problema datelor atata timp cat senzorul "doarme". Vad ca timing-ul este altul decat in datasheet-ul atasat de mine. Voi incerca sa ma ghidez...Mai am o nelamurire. Din grafic reiese ca PIC pune linia 1 logic dupa maximum 20 milisecunde. Cum o face, efectiv? Din status OUTPUT pune pinul liniei la 5V sau intra in status INPUT si elibereaza linia, aceasta fiind HIGH prin rezistenta de pull-up? Ca pe net am vazut sfaturi si asa, si asa si nu stiu cum e corect. Mie nu mi-a functionat in nici un mod(folosind graficul de timing din datasheet DHT11). Link spre comentariu
cimitavita Postat Mai 17, 2019 Partajează Postat Mai 17, 2019 de unde 18ms? Linia date trebuie pusa low pentru 1ms adica 1000us. Apoi este trecuta in 1 pentru maxim 200us. In astea 200us senzorul trebuie sa raspunda punand linia de date la masa. Link spre comentariu
vili_topor Postat Mai 17, 2019 Autor Partajează Postat Mai 17, 2019 La AM2302 si DHT22 este 1 milisecunda insa la DHT11 in datasheet scrie ca trebuie sa fie low cel putin 18 milisecunde... Aveti datasheet DHT11 atasat in primul post Link spre comentariu
XAN77 Postat Mai 18, 2019 Partajează Postat Mai 18, 2019 Da ai mult timp de umplut dacă faci în limbaj de asamblare. Nu te-ai gândit să te orientezi spre un limbaj cu ajutorul căruia să ajungi mai repede la rezultatul dorit? Posibil compilatorul să aibă exemple în el cu acel senzor iar de nu, găsești pe net o librărie pentru el, fie pentru PIC sau Arduino și o adaptezi. Link spre comentariu
cimitavita Postat Mai 18, 2019 Partajează Postat Mai 18, 2019 x_dadu Daca stii electronica, mai ales digitala, tocmai ca in limbaj de asamblare e cel mai usor de facut si se pierde si cel mai putin timp. Pentru DHT22 mi-a luat vreo 4 ore sa scriu programul. Mai mult timp am pierdut cu documentatia ca sa vad exact cum merge DHT22. Am testat cateva zeci de DHT22 si am gasit cativa care mergeau bine, dar care tineau linia de date low un pic mai mult decat este scris in datasheet si din cauza asta nu mergeau pe Arduino. La senzori 1-wire ar trebui ca intreruperile sa fie oprite complet iar calculul temporizarilor sa fie facute pe durata instructiunilor si numarul lor. Din cauza ca PIC-urile vechi nu aveau intructiuni jr conditie, am trecut pe atmega si 8051. Trebuie neaparat sa faci programul ca sa accepte variatii. De pilda, pentru 50us, programul trebuie sa accepte 48 - 52us sau chiar 46 - 54us. E foarte greu sa gasesti un senzor digital care sa dea date exact ca in datasheet. AM2302_sensor.asm Link spre comentariu
vili_topor Postat Mai 18, 2019 Autor Partajează Postat Mai 18, 2019 Am ales limbaj de asanblare pentru ca chiar vreau sa inteleg ce se intampla in spatele unei functii. In codul postat nu ma folosesc de intreruperi sau de timer-e ci doar de bucle care testeaza o conditie si atungi cand este indeplinita, trece mai departe. Am verificat prin LED punerea liniei low de catre PIC si eliberarea ei dupa 20 milisecunde(ledul aprins pe perioada de 20 milisecunde(evident, abia se aprinde ca se si stinge din cauza inertiilor). Testul e realizat prin verificarea conditiei liniei de date si aprinderea/stingerea ledului de pe pinul 4(RB3) al portului B. Dupa care, senzorul ar trebui sa puna linia low pentru un timp. Prin BTFSC PORTB, RB0, urmat de GOTO $-1 testez cand senzorul pune linia din high in low, deci nu conteaza interavlul de timp cat este linia high . Am ales aceasta solutie tocmai din temerea ca nu toti senzorii lucreaza fix dupa timingul din datasheet. Daca linia este low, se sare instructiunea GOTO si se aprinde ledul de pe RB1, pentru a vizualiza indeplinirea conditiei. Ei, asta nu se intampla, ceea ce ma face sa cred ca linia ramane high. De ce oare? Ori secventa de start este gresita ca timpi low/high(desi am testat variante diverse), ori senzorul defect..Dar am testat patru...Poate din cauza ca linia e pull-up atat prin rezistenta externa cat si prin cea de pull-up intern? Din datasheet am inteles ca la o linie de conectare dintre PIC si senzor mai lunga de 20 m e necesara scaderea rezistentei de pull-up extern(din cauza rezistentei liniei, ce se inseriaza)ceea ce presupune ca e necesar un anume curent minim pentru a tine senzorul pull-up. Link spre comentariu
cimitavita Postat Mai 18, 2019 Partajează Postat Mai 18, 2019 in locul senzorului pune un led de la Vcc la iesirea uC si mareste pauzele de 100 ori, inasa fel ca pauza de 18ms sa devina 1,8 secunde. Vezi daca ledul sta aprins 1,8 secunde si daca microcontrolerul trece pe urma pe intrare si citeste high pe acea intrare. Asta se poate vedea aprinzand un al doilea led daca intrarea e high. Trebuie sa pui si cate o rezistenta de 0,5 - 1K in serie cu ledurile respective altfel o sa distrugi iesirile. Link spre comentariu
vili_topor Postat Mai 18, 2019 Autor Partajează Postat Mai 18, 2019 (editat) Multumesc de sfat, am sa incerc si asa. Insa intre timp am mai citit documentatia PIC 16F628A si la TRISB/PORTB am gasit o precizare legata de comportament atipic in conditiile in care se scrie la PORTB iar portul are setati pini si pe OUTPUT si pe INPUT(cazul meu, cand aveam input pentru RB0 unde era linia de date si OUTPUT pe ceilalti pini). Inserez: 5.3 I/O Programming Considerations 5.3.1 BIDIRECTIONAL I/O PORTS Any instruction that writes, operates internally as a read followed by a write operation. The BCF and BSF instructions, for example, read the register into the CPU, execute the bit operation and write the result back to the register. Caution must be used when these instructions are applied to a port with both inputs and outputs defined. For example, a BSF operation on bit5 of PORTB will cause all eight bits of PORTB to be read into the CPU. Then the BSF operation takes place on bit5 and PORTB is written to the output latches. If another bit of PORTB is used as a bidirectional I/O pin (e.g., bit 0) and is defined as an input at this time, the input signal present on the pin itself would be read into the CPU and rewritten to the data latch of this particular pin, overwriting the previous content. As long as the pin stays in the Input mode, no problem occurs. However, if bit 0 is switched into Output mode later on, the content of the data latch may now be unknown. Asa ca am lasat pe portul B numai linia de date la RB0, am dezactivat comparatoarele si VREF pe PORTA(pinii 0-3) si am pus ledurile pe pinii 0, 1 si 2. Acum se aprind cele doua leduri care indica schimbarea starii liniei din HIGH in LOW si din LOW in HIGH ca raspuns dat de senzor la semnalul de start. Mai vad maine daca se comporta cum trebuie si pe secventa de date...Voi posta rezultatul. Multumesc de sprijin si o seara frumoasa. Si inca o precizare: am schimbat rezistenta externa de pull-up din 4.7k in 5.1k. Daca in varianta de 4.7 aveam pe linia de date prin pull-up, in conditia de linie necomandata, in jur de 5 V, prin rezistenta de 5.1, cu linia de date necomandata, am cam 3.5 V. Asa de mare diferenta? Maine pun din nou rezistenta de 4.7 si vad ce se intampla, pt a fi sigur care a fost cauza blocajului(daca intr-adeavr am scapat de el...) Editat Mai 18, 2019 de vili_topor Precizari suplimentare 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