Sari la conținut
ELFORUM - Forumul electronistilor

Computer de bord MOTO+bord electronic!


Cilibiu

Postări Recomandate

Revin cu problema afisari a turatiei, domnul @ratza a gasit o solutie.

Foarte bine, atunci. Lasă liber pinul de ICP (PE7, pinul 9 sau PD4, pinul 29) şi continuăm în celălalt topic. Îţi explic cum faci captura de timp, e mult mai precis decît să stai să numeri.

Astept in continuare explicatia sau exemple de cod.Cu respect tuturor. :da
Link spre comentariu
  • Răspunsuri 235
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Cilibiu

    115

  • ratza

    19

  • Liviu M

    10

  • stefan_k

    10

Top autori în acest subiect

Imagini postate

Ca să foloseşi input capture, trebuie să configurezi timerul astfel încît să ai activă întreruperea de ICP şi să facă trigger pe front, fie rising, fie falling. Atenţie! Front, nu nivel. Ca să fii sigur că nu ai overflow, trebuie să ai grijă ca timerul să nu poată ajunge la maxim în cea mai mare perioadă.

 

Exemplu: presupunem că turaţia minimă e de 600rpm, ceea ce e destul de puţin plauzibil pentru motocicletă, rezultînd o frecvenţă de 10Hz, respectiv o perioadă de 100ms. Cum timerul e pe 16 biţi, rezultă că durata dintre două numărări trebuie să fie:

100ms/65536 = 0,001526ms
adică 1,526us.

 

Presupunem că frecvenţa la care funcţionează microcontrolerul e de 8MHz. Asta înseamnă că o instrucţiune durează 1/8MHz = 125ns, ceea ce nu e foarte aproape de ce ne trebuie nouă. Verificăm să vedem dacă e bună sau nu, deci înmulţim cu numărul care semnifică de cîte ori poate număra timerul:

125ns * 655536 = 8,192ms
adică o frecvenţă de
1/8,192 = 122,07Hz (7324rpm)

Frecvenţa rezultată e mai mare decît cea care ne trebuie, dar putem vedea de cîte ori:

122,07/10 = 12,207.
Ar însemna că valoarea prescalerului trebuie să fie ori 16, ori 8. Cum 16 nu există, iar un cuarţ de 4MHz ar încetini execuţia programului, alegem 8. Înmulţim perioada obţinută anterior cu valoarea prescalerului şi vedem ce se întîmplă:

8,192 * 8  = 65,536ms, adică 915rpm.
Aceasta e valoarea minimă a turaţiei. Sub ea vor fi afişări eronate, fără muncă adiţională. Din cîte ştiu, Honda are vreo 1100-1300rpm la relanti, deci ar trebui să fie OK.

 

Avînd timerul setat, trecem la pasul următor: captura de timp. Aceasta va fi făcută în întreruperea de ICP, care nu e altceva decît o funcţie oarecare, dar care e apelată automat de hardware. Primul lucru pe care-l faci în întrerupere e să citeşti valoarea la care a ajuns timerul. Valoarea asta o pui într-o variabilă pe 16 biţi, şi va reprezenta perioada. În momentul în care ai terminat de citit, timerul se resetează automat, fără să aibe nevoie de intervenţia ta.

 

Bun, care e unitatea de măsură? Simplu: 1 incrementare a timerului se face la fiecare puls rezultat al împărţirii frecvenţei de ceas la valoarea prescalerului, adică 8MHz/8=1MHz, adică 1us. Cu alte cuvinte, valoarea timerului reprezintă exact durata în microsecunde. Ca să afli frecvenţa, treci valoarea sub numitor, adică:

rpm = (1000000 * 60)/perioadă

Cam asta e.

Link spre comentariu

Eu aveam senzatia ca problema cu turatia era una de afisare (prea rar, o data la 600 ms => salturi bruste), nu una de "masurare".

Link spre comentariu

600rpm, ceea ce e destul de puţin plauzibil pentru motocicletă, rezultînd o frecvenţă de 10Hz

Nu am citit tot, dar daca semnalul pentru informatia de turatie este preluata de la aprindere, pentru un motor in 4 timpi monoclindru la 600 rpm, frecventa este de 5Hz.

Conversie in frecventa a impulsurilor provenite de la aprindere.

Motor in 4 timpi

n= nr.cilindrii

F=(n*RPM)/120

Link spre comentariu

Eu aveam senzatia ca problema cu turatia era una de afisare (prea rar, o data la 600 ms => salturi bruste), nu una de "masurare".

Are dreptate, eu am problema de afisare, nu de citire eronata a frecventei.Ciudat fapt ca eu am desfacut motorul motocicletei si la fiecare rotatie a arborelui cotit am un impuls la bobina pick-up.Motorul este in 4 timpi.
Link spre comentariu

Aha! Păi atunci problema poate fi rezolvată foarte simplu. Nu ştiu BASCOM, dar îţi dau bucăţi din codul meu. Chiar dacă e scris în C, cred că e suficient de bine scris încît să nu necesite prea multe explicaţii.

Inspirat de tine, îmi fac un computer de bord pentru Corsa. :)

 

Să zicem că faci update la display o dată la jumătate de secundă pentru chestiile care nu mişcă prea mult, dar vrei 33 de milisecunde pentru o animaţie. Foloseşti unul din timere să generezi 10ms ca la fiecare 1ms incrementezi o variabilă. Asta înseamnă că afişarea rară se face de fiecare dată cînd variabila ajunge la 500, iar cea deasă de fiecare dată cînd termină de numărat pînă la 32. Întreruperea arată aşa:

// Timer 0 output compare A interrupt service routine// Occurs at each millisecond.#pragma vector = TIM0_COMPA__interrupt void _menu_refresh(void){  display_update++;}
Codul prin care reînoiesc datele de pe afişaj arată aşa:

if (display_update > UPDATE_THRESHOLD) // ăsta e de fix 500{  show_speed(0,0);  show_temperature(19,0);  show_time(0,1);  show_rpm(8,1);  show_instant_fuel(18,1);  display_update = 0; // aici şterg valoarea pentru a pregăti următoarea afişare}else if ((display_update % 33) == 32){  // aici am animaţia pentru RPM, ca un fel de VU-metru  rpm_bargraph(8, 0);}

EDITAT: am pus nişte valori prea tîmpite.

Link spre comentariu

am desfacut motorul motocicletei si la fiecare rotatie a arborelui cotit am un impuls la bobina pick-up.

Motorul este in 4 timpi.

Da, am citit chiar aici pe forum cred, ca la motocicletele actuale cu CDI apare si o scanteie la sfarsitul evacuarii, se pierde energia aferenta dar se pare ca simplifica instalatia.
Link spre comentariu

Eu refreshul la display il am intarziat din cauza calcului turatiei si a vitezei, insa la viteza folosesc un encoder care genereaza 2048 de impusuri intr-o rotatie, asa ca prin impartiri imi afiseaza corect viteza de deplasare, insa pentru turatie problema sta exact opus, frecventa este mica, iar eu trebuie sa afisez valoarea mare, de aici apare inmutirile cu oridun zecilor si sutelor, problema fiind ca atunci cand inmutesti cu 10 ca sa ajung la frecventa citita corect in HZ dupa care o inmutesc cu 60 ca sa am afisar RPM, de aici e clar, orice numar inmutit cu 600 da aiurea.Ex:1x10x60=600 RPM2x10x60=1200 RPMUnde 1 si 2 sunte datele citite. 10 este inmutirea ce rezulta in HZ.Eu la fiecare 100ms citesc T1, care imi zice>>>> ai 1 inpuls la 100ms, asta inseamna 10HZ (10 inpusuri intr- o secunda) iar de aici trebuie sa transform in RPM adica sa inmutesc cu 60. De aici rezulta ca am o rezolutie de doar 600 in 600 RPM.Ca sa reduc la 120 RPM am nevoie un refres de 500ms. Cea ce este un pic cam nasol, afisand multe date, reactualizarea datelor nu va fi "liniara" ci "logaritmica" deoarece sare de la o cifra la alta brusc din cauza refreshului.Pana la urma cred ca voi folosi refres la 500ms, asta in caz ca nu am alta idee.Insa si aici am probleme de afisare.1x2x60=1202x2x60=240.........=360.........=480Arata cam ciudat fata de :100200300400500600.....Cu respect.

Link spre comentariu

Nu am folosit niciodata tipul asta de display, dar... nu poti rescrie DOAR campul unde afisezi turatia la fiecare loop? Adica sa scrii "peste" ce aveai inainte. Eu am facut asa la afisarea unei temperaturi cu zecimale pe un display 20X4. Scriam la fiecare loop doar campul cu valoarea temperaturii (in realitate era val_camp = 0,99 x val_camp + 0,01 x val_citita; ca sa reduca zgomotul).Se poate? Sau vorbesc prostii?

Link spre comentariu

Se poate, cum să nu. Aşa folosesc şi eu, ca să nu pierd timpul scriind 48 de caractere, din moment ce-mi trebuie doar cîteva la un moment. La fel e şi la grafic, e împărţit pe blocuri şi poţi scrie cîte unul o dată. Nu e nevoie să reafişezi tot.

Link spre comentariu

Pai si atunci ar putea afisa turatia dupa fiecare calcul si "din cand in cand" sa faca update la viteza, nu?Si si mai rar (10 sau 20 sau poate chiar mai multe secunde) sa faca update la nivel de benzina, la vreo 3-5 sec teperatura motorului... etc..In felul asta ar economisi mult timp, nu?

Link spre comentariu

Daca face functie pt afisarea fiecarui camp, atunci poate sa faca ce vrea si mai ales cand vrea; o unele le temporizeaza iar altele in functie de "eveniment".Nu am vazut codul, vorbesc din imaginatie.

Link spre comentariu

Deci sa lamuresc treaba cu afisarea.Afisez o data graficul si ramane asa.Eu doar rescriu partea de "cifre" sa zic asa.Problema care este la mine, tine strict de turatie, sa nu vorbim de restul, ne axam pe turatie.Eu vreau sa am afisarea din 100 RPM in 100RPM, dar aceasta valoarea vreau sa aibe un refresh de 100ms.Cum FAC?Sa inteles acum cea ce vreau? De ce vreau refres la 100ms??? Pai mie imi place "liniaritatea" afisari, de exemplu >>> chiar daca ridic turatie mediu, sa vad pe display ca apare, 100...300....500, (asta sa zicem la 100ms) dar daca pun refresh la 500ms, eu voi vedea valori..... 100........800.....1700....sper ca se intelege ce vreau.Cu respect.L.E . Eu in tot programul DO...LOOP nu am nici un CLS (clear screen).Iar grafica este afisata pana sa intru in prgramul DO...LOOP.

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