
-----------------------------------
AVD
26 Ian 2024 18:01

DIY ASCOM powerbox
-----------------------------------
Salutare! 

Zilele astea am lucrat la un fel de copie de PegasusAstro PocketPower advanced minus hub usb si iesire variabila si voiam sa impartasesc cu voi schema, codul si driver-ul de arduino. 

Aveti aici tot ce e necesar pentru a construi aceasta jucarie. 
https://github.com/florindumitrescu94/DashBoardASCOMPowerBox

Sper sa va fie de folos! 

-----------------------------------
varadinagypal
26 Ian 2024 18:39


-----------------------------------
de la dev la dev:
(0) macar ai readme :)
(1) titlu readme -- lipsa
(2) abstract
(3) onboarding (requirements, dependencies, installation)
(4) known issues, restrictions, use case limitations
(5) future improvements being planned
(6) invitation to contribute, rules, feedback
(7) cu proiectele pe care le am publice, am fost cam neglijent, si nu le am nici eu pe toate de mai sus, insa unde e cu miza, la firma de pilda, il am pe Herr Jürgen mit das Kürligäpule care supravegheaza calitatea softului: 

https://csillagtura.ro/walksonanearbyplanet/findthis_jurgen.html

:)

-----------------------------------
varadinagypal
26 Ian 2024 18:45


-----------------------------------
PS: pentru cei precum subsemnatul care cadem cu parasuta, un block diagram e extrem de util, vezi:

https://csillagtura.ro/the-soapbox-mountpusher-guider/

nu stiu de ce nu merge img, e cam retardat softul de pe acest forum




-----------------------------------
AVD
26 Ian 2024 18:56


-----------------------------------
Multumesc  de sugestii! 
N-am scris prea mult pentru ca am mers pe ideea ca cine vrea sa faca asa ceva, nu o sa fie chiar tufa de venetia si o sa aiba niste intelegere despre ascom si electronica. Dar am sa mai dezvolt acea pagina si am sa tin cont de punctele acestea :D 


de la dev la dev:
(0) macar ai readme :)
(1) titlu readme -- lipsa
(2) abstract
(3) onboarding (requirements, dependencies, installation)
(4) known issues, restrictions, use case limitations
(5) future improvements being planned
(6) invitation to contribute, rules, feedback
(7) cu proiectele pe care le am publice, am fost cam neglijent, si nu le am nici eu pe toate de mai sus, insa unde e cu miza, la firma de pilda, il am pe Herr Jürgen mit das Kürligäpule care supravegheaza calitatea softului: 

https://csillagtura.ro/walksonanearbyplanet/findthis_jurgen.html

:)

-----------------------------------
varadinagypal
26 Ian 2024 19:16


-----------------------------------
Pai, gandeste asa -- iti zic astea ca senior dev care am trecut prin niste chestii, nu intamplator desenez si webcomic. Nu stiu, poate te ajuta. 

De la big picture la detalii.

Readme-ul e poarta in proiect, o invitatie daca vrei, prin care cei care ajungem acolo, unii obositi de gimnastica mentala la care suntem supusi de niste code simians corporatisti, vedem daca suntem bineveniti. 

Daca s-a gandit autorul la noi, cei neinitiati sau nu. Daca are un plan sa faca turul proiectului, si dozeaza informatia sau are pretentia sa fim telepati. Divizorul de tensiune si diodele de reverse voltage respectiv flyback sunt triviale, detalii de pus intr-o nota la subsol, la fel variantele de 5/20/30A. Insa ne asteptam la un BOM de pilda: aflu asa trecator, parca detaliu nesemnificativ, dupa un tabel si exemple de cod, ca proiectul se bazeaza pe un Arduino Nano.

Eh, in rest succes.

-----------------------------------
nobody
26 Ian 2024 22:30


-----------------------------------
Protectia asigurata de D2 este prin autodistrugere ? Si dupa aia ? Iar la un eventual scurtcircuit ?

C3 n-ar trebui sa afecteze procesorul sau USB, probabil e o problema tranzitorie la circuitul de masa/impamantare.

In loc de releu ai putea folosi un P-channel Power MOSFET.

-----------------------------------
varadinagypal
26 Ian 2024 23:06


-----------------------------------
much better :)

-----------------------------------
varadinagypal
26 Ian 2024 23:35


-----------------------------------
legat de connection drop, FOARTE MARE ATENTIE la chichite aparent nesemnificative precum forma mufei. Am mufa de 5.5x2.5 standard doua variante, una din care plusul (centru) iese printr-o mica proeminenta, si exista riscul sa faca scurt daca gnd este deja comun. Am alta mufa, aparent identica, care insa are varful plastic, si plusul din mijloc nu poate fi atins nicicum.  Eventual pui un sumator de doua diode schottky ca VCC-ul care iti iese din modulul de 12V->5V sa nu se amestece cu 5V care iese din USB ca face balarii de numa.



Ori, daca ai scaderi, vezi de exemplu solutiile cu un boost:
https://csillagtura.ro/my-encoder-based-focuser

-----------------------------------
AVD
27 Ian 2024 01:56


-----------------------------------
Momentan lucrez la o a doua versiune plus documentatie pentru proiect. Am sa adaug si sigurante fuzibile pe fiecare iesire si pe intrare. Initial, voiam sa fac cu un P-MOSFET, dar am avut la indemana, mai degraba, un releu, deci mi-a fost mai usor sa pun mana pe el decat sa astept curierul. 
Sigur, cu un P-MOS as fi minimizat si mai mult design-ul si as fi scapat de o componenta mecanica, dar ca prim design, si un releu functioneaza destul de bine pentru mine. Iteratiile viitoare vor avea circuit cu P-MOSFET + o protectie de polaritate inversa cu un P sau N MOSFET (poate si protectie la supra-tensiune, desi aici trebuie sa "cercetez" putin.. standardul este 12V, dar tensiunile folosite in astro depasesc si 13V, daca avem bateriile bine incarcate).

Mufa pe care am folosit-o este cu plastic pe varf si plusul in centru.. Cred ca e o problema cu masa, posibil o diferenta de potential, ori problema la sursa folosita. Am sa incerc si cu bateria pentru iesiri, sa vad daca face la fel. Cat despre modul de 12V-5V, nu folosesc. Tensiunea folosita de ACS712, DHT22 si releu este luata direct din arduino, care e alimentat doar de la USB.

-----------------------------------
Erwin
27 Ian 2024 08:41


-----------------------------------
Zicea cineva că DHT22 nu este de mare încredere în privin&#539;a măsurării umidită&#539;ii. Are cineva experien&#539;ă cu acest lucru? În paralel cu un senzor de precizie cum se prezintă? În specifica&#539;ii scrie că toleran&#539;a lui este de 2%, pentru determinarea dew point cred că este suficient.

-----------------------------------
AVD
27 Ian 2024 13:42


-----------------------------------
Este prima oara cand il folosesc intr-un proiect. Am mai folosit DHT11, iar despre acela pot spune ca este nasol. Umiditate doar intre 20% si 80% iar la temperatura nu stie sub 0 grade. N-am apucat sa testez afara senzorul asta, dar, in casa, pare ca citeste acceptabil.

-----------------------------------
nobody
27 Ian 2024 16:09


-----------------------------------
Cam in plaja asta de 20%-80% RH te poti baza pe astfel de senzori.

Condensul incepe peste 80%.

Senzorul cica stie sub 0 grade, dar Arduino nu interpreteaza bine valorile negative citite de la senzor.
Test and Calibrate DHT22 Hygrometers Compare DHT22, DHT11 and Sensirion SHT71 Wide range of Hygrometers: DHT22, AM2302, AM2320, AM2321, SHT71, HTU21D, Si7021, BME280 https://www.kandrsmith.org/RJS/Misc/Hygrometers/calib_many.html

-----------------------------------
AVD
27 Ian 2024 20:28


-----------------------------------
Multumesc de link-uri! 

Inca nu am apucat sa il testez la temperaturi scazute. Probabil am sa il scot in noaptea asta sau maine pe balcon, sa vedem ce spune. Momentan, deja am "adunat" pareri si sugestii si lucrez la versiunea 2 a placii si soft-ului.
Daca se dovedeste ca acest DHT22 nu este destul de bun (desi marja de eroare e mai mult decat acceptabila pentru ce vreau eu sa fac cu el), am sa ma uit in alta directie.

-----------------------------------
varadinagypal
27 Ian 2024 23:50


-----------------------------------
Odata am prins ceva bad batch de SHT, la cat a costat, e eroare de rotunjire. i2c deci, avea registrul puscat si un bit era mereu setat, asa ca umiditatea citita era destul de funny. 

In geenral iti recomand modulele Bosch, BMP 180 sau 280 pentru temperatura si presiune, pentru umiditate BME 680 era parca de incredere.

----
Sunt de acord cu nobody, trebuie cel putin citita libraria propusa de baietii care contribuie la arduino, ca am prins corner case la un sensor de lumina unde returna un float de pe stack, neinitializat, valori nedefinite. Insa, lucrand in breasla, pot sa afirm ca cei mai mari producatori de microchipuri si librariile aferente fac niste greseli de numa, si apoi vezi tu ce atitudine au daca le scrii (dupa ce le-ai evaluat un sample si a picat testele). Mizeria din embedded-ul profi, pana si automotiv, te face sa nu mai vrei sa vezi tehnologie, si inca nu am pomenit de electronica falsificata, contrafacuta, recuperata dar vanduta ca noua etc etc.

-----------------------------------
varadinagypal
28 Ian 2024 00:42


-----------------------------------
apropo crapware de la vendor (ca is softist in primul rand, electronica numa cat sa nu confund vcc cu gnd) https://csillagtura.ro/walksonanearbyplanet/00448.html

-----------------------------------
nobody
28 Ian 2024 03:04


-----------------------------------
Pai vendorii is permit AI enhacend crapware.

Pentru AVR am mai folosit un compilator dragut, culmea facut in Romanai: http://www.hpinfotech.ro/cvavr-features.html
Merge mai bine ca GCC, mai ailes la constantele stocate in FLASH.
Arduino iti face buffer overflow la stringuri daca n-ai grija, le trateaza ca obiecte, le tot muta si rasmuta pana ajunge de-ti scrie si peste registrii si IO. Cand am facut debugging si m-am uitat in surse, n-avea nici o urma de protectie in bibliotecile de baza. This sht is not for me. Scuze de divagatie, eu am facut scoala pe Z80. 16k ROM, 6k video RAM, si restu pana la 64k, RAM liber. 

Ca senzor as alege unu ce are o interfata standad hardware, i2C, SPI,  nu bit-bang. Iti mai salveaza timp de procesor si mai putine sanse de rateuri la comunicatie.

-----------------------------------
zoth
28 Ian 2024 09:38


-----------------------------------
 ... eu am facut scoala pe Z80.

Uau!! inseamna ca nu suntem departe  :D , eu am facut-o pe 8080 si apoi am rafinat-o pe Z80.
Poate si din cauza asta nu mi-au mai placut microcontrolerele cu arhitectura lor oarecum impusa ...

Scuze de oftopic si spor pe mai departe!

-----------------------------------
varadinagypal
28 Ian 2024 15:51


-----------------------------------
offtopic, dar na, am pornit ceva aici,

Sunt putin mai tinerel se pare, eu am inceput cu asm x86 pe de o parte, si citind codul sursa de librarii din delphi proaspat aparut pe cealalta parte. De aceea recunosc cand cineva bate campii ca legacy code, dar pe vremea aia era bun - nu, nene, nici in urma cu treizeci de ani nu se scriau balarii cum intalnesc mai peste tot.

Eh, stringuri, folosesc exclusiv partea de C in arduino, pana si cu ESP32. Fara C++, tocmai ca sa nu am surprize. Am dispozitive care ruleaza brici de luni de zile, si se reseteaza doar cand se ia curentul. Iar cu constantele in flash, subscriu, am mai scris cod javascript ca sa genereze cod C in diferite gusturi: cu FP, cu concatenari sau zstringuri ca sa vad cand cum arata binarul respectiv ramii disponibili.

La locul lor, sunt dispozitive foarte mega capabile jucariile astea arduino. Iar legat de vendorii profi, va pot arata document public de la Renesas in care le cere utilizatorilor sa nu foloseasca mijlocul ramilor daca cpu ruleaza la 240MHz ca apar flag-uri de paritate, nu si erori, dar flag-uri.

-----------------------------------
valy
28 Ian 2024 19:12


-----------------------------------
Tot offtopic, dar cred ca Arduino este mai curand pt. rapid prototyping, nefiind un sistem sa zicem "critical mission aerospace grade"...totusi.


.. in schimb procesorul principal e pe rezonator ceramic, de te doare capul daca ai nevoie de un timing mai precis.
Deci d'aia imi "sarea pasi" cand l-am pus sa comande PWM un motor!?

-----------------------------------
nobody
29 Ian 2024 19:59


-----------------------------------
Rezonatorul ala ceramic iti baga un drift care se acumuleaza in timp.
Toleranta la asta folosit pe Arduino e de +-0.5% ... nu pare mult la prima vedere, dar un ceas cu pendula e mult mai precis.
Culmea e ca la procesorul cu USB de pe aceeasi placa au folosit un cuart de aceeasi frecventa... de ce ?
Pentru ca in toleranta aia nu ar functiona partea de USB.
Si tot culmea este ca puteau folosi acel clock si la procesorul principal, ca are iesire de buffered clock pe un pin care sta nefolosit.
Adica o carpeala hardware.

Pe forumuri raspunsul este "da la ce-ti trebuie asa precizie?" ... ca sa reglez un ceas cu cuc, nu invers.

Nu stiu de ce "sarea pasi" la tine, nu cred ca are legatura cu acest drift, poate altceva, de exemplu milisecunda bisecta Arduino:
millis() is incremented (for 16 MHz AVR chips and some others) every 1.024 milliseconds, then incrementing by 2 (rather than 1) every 41 or 42 ticks, to pull it back into synch; thus some millis() values are skipped :roll:

-----------------------------------
valy
29 Ian 2024 21:15


-----------------------------------
Parca am folosit micros(), nu mai stiu exact..

Nu e o gresala in specs, milis se incrementeaza la 1024 microseconds?

-----------------------------------
varadinagypal
29 Ian 2024 21:50


-----------------------------------
Legat de Arduino, eu as aprecia aspectul ca exista in primul rand ca idee. E un layer de abstractizare, un standard chiar portabil, decent pentru serial, decent pentru i2c, decent pentru GPIO, decent pentru intreruperi si decent pentru timp. Nu e aero-space-medical-automotiv ready, si ce, nici nu pretinde ca ar fi, deci e within specs. Au si familia Portenta.

Function/prototype hoisting cand ai un singur fisier, sau macar in cadrul aceluias fisier, la fel mi se pare o idee buna. Deci serios, warning: implicit declaration of function cand e acolo cu trei linii mai jos? Who needs that? Am vazut cod serios stricand stackul la variadic arguments, ca insista ca functia din acelasi fisier nu ar avea antetul declarat, si zbam, byebye double, ca remapat la int32 (arhitectura) si arrivederci stack.

Plus, sa nu uitam ca ESP32 are nucleu Arduino, are si microul RP2040, nu e doar familia AVR.

Nu vreti sa stiti cate artificii am vazut in cod "profi", cat scarpinat la picioare de lemn, roti reinventate sub forma nitel patratica, las' ca merge si asa, si pentru ca acei genii - stiti voi, garda veche - nu au scris absolut niciun layer de abstractizare, functii inline macar, macrouri macar, ci au trantit copy-paste-paste-paste dar cu variabilele locale pe unde si ce, cateodata shadowed global, cateodata nu, ca "economisim la callstack", nici dumnezeul nu mai face ca acel business logic sa ruleze pe alt micro fara sa rescrii din temelie.

Daca e sa aleg intre Arduino si demiurgii din garda veche (in afara de chiar top gen Knuth si din astia, ori cu kernelul), aleg Arduino x100.

-----------------------------------
varadinagypal
29 Ian 2024 22:03


-----------------------------------
Oh, Renesas Synergy mai e cat de cat decent ca RTOS, cu niste mentiuni de rigoare: timpul e un pain in the ass, calibrarea rtc-ului e un pain in the ass, filesystem-ul e un pain in the ass la patrat rau de tot, networking-ul e un pain in the ass ca-i poti otravi lejer packet pool-ul, plus, acum s-a bagat microsoft, ca nu au stricat deja destul in lume, isi mai acapareaza domenii de stricat. Dar siliconul e acceptabil. Am mai pomenit de parity in rami. 

Ei, arduino uno rev4 e bazat pe silicon renesas, nu mai e avr. DAR: ramane interfata soft. Pentru ca e una sa numeri bitii din registri si alta sa scrii programe, ie business logic.

-----------------------------------
nobody
30 Ian 2024 16:33


-----------------------------------
La UNO R4 au rezolvat cu cuartu' ... l-au scos de tot ... au trecut pe oscilatorul intern +-2%

P.S. Pentru mine ideea de 'microcontroller' este legata de 'real-time operating'. Mi se apre ca Arduino se indeparteaza de acest concept tocmai pe principiul 'las' ca merge si asa'.

-----------------------------------
varadinagypal
30 Ian 2024 22:55


-----------------------------------
@nobody si ceilalti, va invit la acest fir din forum, pentru a-i lasa aer colegului cu proiectul, ca ne-am cam bagat peste el ca niste :D :D derbedei :D :D cu offtopic-ul nostru

https://www.astronomy.ro/forum/viewtopic.php?p=230039

-----------------------------------
AVD
07 Feb 2024 17:07


-----------------------------------
Dupa ceva timp de lucrat si testat, am revenit cu versiunea 2. Imbunatatita si rafinata. 


https://github.com/florindumitrescu94/DashBoard_PowerBox_V2

Imbunatatiri fata de prima versiune:

-Cate o siguranta resetabila de 2.5A pe fiecare iesire si o siguranta mare de 15A pe intrare
-Protectie la tensiune inversa
-Comutatie a celor 4 mufe DC prin P-MOS
-Automatizare a incalzitoarelor anti-roua (momentan, doar prin atasarea unor termistori ce vor fi montati sub incalzitoare, dar planuiesc sa gasesc o metoda de a controla puterea doar pe baza conditiilor atmosferice (dew point, umiditate relativa si temperatura ambientala)


Documentatia completa poate fi gasita pe pagina Wiki.

varadinagypal - Multumesc de sugestiile si exemplele de documentatie. Sper ca am facut o treaba macar pe jumatate buna cu aceasta noua versiune :D 

Orice sugestie este binevenita
Spor la construit!

-----------------------------------
varadinagypal
08 Feb 2024 18:54


-----------------------------------
da :)

-----------------------------------
nobody
11 Feb 2024 00:08


-----------------------------------
Felicitari pentru progresele de la Layer 1 !

Acu' la layere superioare:
Measuring voltage, current, power and total power consumption

Since we are dealing with mostly PWM controlled power, calculating the current usage without implying a means to average out the readings will yeld to very jumpy and innacurate results. Therefore, I have implemented an array that gets updated over time, then average the sum of all the values in the array to obtain the average current usage over 150 cycles. The GET_POWER() function runs in a loop everytime.

To determine the total power consumption since device has been connected, we need to measure the total power consumption in W*h per each cycle, then add that up to a total. Since the Arduino Nano floating point only allows for 2 decimals of precision, we need to first calculate the power in milliseconds, then divide that power by 3600000 (number of milliseconds in an hour).

Nu prea am inteles la ce te referi cand zici ca float are numai 2 zecimale precizie.
In principiu are 23 de biti brut (fara semne si exponent).
Dar poti folosi intregi daca alegi subunitati de masura mai potrivite si mai intuitive, de ex. mV, uV, mA, uA ...
Asa eviti si multe impartiri, coversii de tip (multe implicite/ascunse), confuzii si alte complicatii inutile.

Cu un layer si mai sus, mie mi se pare ca functia GET_POWER() face altceva decat crezi sau intentionezi.
Poate am inteles gresit, te rog sa ma corectezi daca-i cazul.

PWR_TOTAL vrea sa fie energia in Wh consumata/acumulata pe tot timpul functionarii ca un contor de consum de la instalatia electrica.
Iei un timestamp 'time1' la inceputul masuratorii.
Iei un burst 150 de samples de tensiune si faci media aritmetica in V.
Iei un burst 150 de samples de curent si faci media aritmetica in A.
Valoarea asta medie o salvezi intr-un array (wrap arround) care tine ultimele 150 de medii.
Parcurgi tot array-ul si calculezi media pe ultimele 150 de medii ca un filtru pentru fluctuatiile date de PWM.
Calculezi puterea mendie PWR = VOLT * AMP in W.
Iei un timestamp 'time2' la sfarsitul masuratorii.

Apoi integrezi energia consumata inmultind puterea medie PWR cu timpul cat a durat masuratoarea (time2-time1) si adaugand-o la consumul cumulat anterior in Ws (PWR_TOTAL_S). Aici poate mai bine folosesti submultiplii zeicmali de genul mWh, uWh. Dar nu asta e problema, ci acel interval de timp subliniat mai sus. Tu acumulezi numai energia doar din timpul masuratorii, nu de la o masuratoare la alta. asta se poate corecta usor folosind un timestamp anterior de cand ai apelat ultima data PWR_TOTAL.
Cred ca mai poti simplifica masuratorile si mediile intr-un singur ciclu, masori alternativ curentul si tensiunea (si la tensiune poti avea fluctuatii in timpul PWM) sa fie cat mai apropiate si faci o medie generala de putere, sau energie consumata.

-----------------------------------
AVD
11 Feb 2024 02:24


-----------------------------------
Mul&#539;umesc!

&#536;i mul&#539;umesc de observa&#539;ia legata de timpul între ciclurile de rulare ale Get_power.. nu mi-am dat seama ca vor fi câteva milisecunde pierdute în care nu masor nimic. Legat de precizie, am încercat sa atribui unei variabile raportul a altor doua variabile, care îmi rezulta 0.9834(..). În momentul când am folosit acea variabila intr-o formula, a fost tratata ca 0.1. Când am încercat sa folosesc un calcul care sa îmi măsoare energia consumata direct în Wh, din nou, m-am lovit de aceea&#537;i problema. Energia consumata în 20mS era 0.000ceva. Formula folosita anterior era energia_totala += (puterea*delta_t)/3600000. Aceasta formula rezulta 0.000ceva &#537;i era trunchiat la 0.00. Pe parcursul întregii seri, energia_totala a rămas 0 (dacă adaugi 0.00 la 0, tot 0 ramane). Scrie lucrul asta &#537;i pe site-ul arduino (&#537;i double tot aceea&#537;i problema are), dar poate nu m-am exprimat eu corect.. 

Get_power se ocupa de măsurarea tuturor datelor despre energia electrica (curent, tensiune, putere, energie consumata). Am încercat sa fac media curentului intr-un singur ciclu &#537;i varia foarte mult, asa ca am mers pe o medie pe un timp mai lung, in care orice schimbare brusca este amortizata.

-----------------------------------
nobody
11 Feb 2024 04:22


-----------------------------------
Ai niste exemple concrete sa le testez ?
O bucata de cod care nu functiona cum te asteptai sau chiar exemple de pe site-ul arduino.

Probleme de genul asta se pot rezolva cu 'type casting', chiar compilatorul iti mai da warning-uri ca este o situatie ambigua. Asta daca nu sunt chiar bug-uri, double e cam buggy in AVR gcc, dar float ar trebui sa functioneze.

P.S.
Daca e vorba de rotunjiri si trunchieri de precizie la float ca aici:
https://forum.arduino.cc/t/strange-float-or-rounding-error/469408
atunci este si o problema de optimizare a formulelor, sau a unitatilor de masura alese.
Float-ul poti sa-l consideri ca o scara logaritmica, rezolutia este relativa la ordinul de marime.
De ex. daca aduni un numar mic la un numar mare, vei pierde din precizie la numarul mic, sau il pierzi chiar de tot.

-----------------------------------
varadinagypal
11 Feb 2024 12:33


-----------------------------------
De obicei, cand vin juniorii -- fiindca faculatea invata avioane in baza 13 si 16, dar nu si asta lucrurile importante, ma uit la tine acum, Babes-Bolyai -- , le dau exercitii de gandire de genul:

x == (x+1)
ori
(7*n) != (n+n+n+n+n+n+n, sper ca am scris de sapte ori)

si sigur se vor uita ciudat, ce vrea nenea cu "practica vs teorie". Tocmai ca nu, ca tot teorie e: nenea vorbeste despre alte avioane, complexitati si densitatea de informatie, sfidarea distributivitii si asociativitatii din cauza acumularii de erori de rotunjire, parfumuri din astea care devin importante cand comparam margini sau formulam SQL, ori devin perechi de adevarat-fals in functie de abordare, si in SQL va functiona intr-un fel (ca rotunjeste sau nu la doua zecimale), or 

de ce oare, in softul meu de astro, in loc de arcsinus folosesc safeArcsinus?

Ori, de pilda acest "unit-test":

                            Online C Compiler.
                Code, Compile, Run and Debug C program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <stdio>
#include <stdint>
int main(){
    uint32_t uintA = 0xFFFFFF00;
    float floatA = (float) uintA;
    uint32_t inspectionStart = uintA+1;
    uint32_t inspectionEnd   = inspectionStart+128;
    for (uint32_t a = inspectionStart; a < inspectionEnd; a++){
        int e = ((float)a == floatA);
        printf("Expecting 0 (not equal), getting %d %s for (%lu == %0.f)\r\n", e, e ? "(__equal__)" : "(not equal)", a, floatA);
    }
    return 0;
}

-----------------------------------
nobody
11 Feb 2024 21:33


-----------------------------------
warning: format &#8216;%lu&#8217; expects argument of type &#8216;long unsigned int&#8217;, but argument 4 has type &#8216;uint32_t&#8217; {aka &#8216;unsigned int&#8217;}

Poate asa este mai intuitiv ce se intampla cand inghesui 32bit de UINT in 23bit de FLOAT:
printf("getting %d %s for (UINT a %u to (float)a %0.f == FLOAT %0.f)\r\n", e, e ? "(__equal__)" : "(not equal)", a, (float)a, floatA);

getting 1 (__equal__) for (UINT a 4294967041 to (float)a 4294967040 == FLOAT 4294967040)
...
getting 1 (__equal__) for (UINT a 4294967167 to (float)a 4294967040 == FLOAT 4294967040)
getting 0 (not equal) for (UINT a 4294967168 to (float)a 4294967296 == FLOAT 4294967040)


Dar deocamdata nu stim care a fost problema.
Parerea mea este ca ar fi trebuit sa mearga si cu float la ce fel de calcule se fac, chiar daca este f. ineficient. Poate e de vina doar ordinea in care se fac calculele, formulele matematice 'corecte' presupun o precizie infinita. La fel de bine poti s-o dai in bara si cu DOUBLE64, si pe 128 ... un clasic exemplu este Windows Calculator ... calculezi radical din 4 iar din rezultat scazi 2  ... vezi cei iese  :)

-----------------------------------
AVD
12 Feb 2024 14:50


-----------------------------------
Ai niste exemple concrete sa le testez ?
O bucata de cod care nu functiona cum te asteptai sau chiar exemple de pe site-ul arduino.

Probleme de genul asta se pot rezolva cu 'type casting', chiar compilatorul iti mai da warning-uri ca este o situatie ambigua. Asta daca nu sunt chiar bug-uri, double e cam buggy in AVR gcc, dar float ar trebui sa functioneze.

P.S.
Daca e vorba de rotunjiri si trunchieri de precizie la float ca aici:


Exact exemplul pe care l-am dat: am incercat sa calculez tensiunea folosind valoarea masurata la pin-ul analogic (care era masurata prin divizorul de tensiune) impartita la raportul dintre valorile rezistoarelor din divizorul de tensiune. Le-am pus in doua constante, vdiv1 si vdiv2. 

int vdiv2 = 100800
int vdiv1 = 10000
double volt_temp
double volt;

[...]

volt_temp = (media valorilor masurate in 150 de sample-uri) 
volt = volt_vemp / (vdiv1/vdiv2).



Acel raport ar fi trebuit sa dea 0 .992, dar, in formula, a fost tratat doar ca 0.99.

Tin sa mentionez (deoarece am vazut ca am intrat in detalii despre codare): Nu am un background prea stufos de codare. Am invatat codare in pascal si C++ in liceu, acum mai bine de 10 ani si, de atunci, nu am mai avut contact cu acest domeniu (cu exceptia micilor proiecte arduino, dar foarte rar).

-----------------------------------
auriga
12 Feb 2024 15:09


-----------------------------------
Tocmai la UBB se tine un curs de Radu Trambitas numit Calcul Numeric unde se studia si Teoria erorilor si aritmetica &#305;n virgula flotanta.

-----------------------------------
varadinagypal
12 Feb 2024 15:30


-----------------------------------
prima chestie e

int x = 123456 // mai mare decat 16 biti, chiar si fara bitul de semn
...
cat e range-ul intului pe arduino uno (sau nano, 328P e nucleul, hint: e garantat sa aiba minim 16 biti, dar...)?

https://www.geeksforgeeks.org/int-1-sign-bit-31-data-bits-keyword-in-c/

a se observa diferenta dintre int, long int, si int32_t si int64_t, respectiv daca era pe esp32 int-ul era...

INT_MAX, sizeof(int),

si mai vezi notatia cu de UL de pilda -- cand unei constante hard coded ii fortam marimea, e o nebunie cu type promotion etc

uint32_t x = 1234567UL;

-----------------------------------
varadinagypal
12 Feb 2024 15:42


-----------------------------------
Tocmai la UBB se tine un curs de Radu Trambitas numit Calcul Numeric unde se studia si Teoria erorilor si aritmetica &#305;n virgula flotanta.

mie mi-a tinut curs doamna Lector Doctor. Cand s-a prezentat, in loc sa inceapa cu eu sunt, zic si eu un nume, Sanziana, a inceput cu: "Eu sunt Lector Doctor ..." -- si am decis ca numele oamenilor de acest soi, cu iz de inginer-academician-prof-univ-codoi nu merita sa il retin.

Deci doamna Lector Doctor ne-a predat acolo cu virgula flotanta, conversii pe hartie, apoi a instistat, tot conversii pe hartie, cu baza 13 si baza 7, pe langa cele traditionale, de 10, 16 si eventual 8. Foarte fain la adunare si inmultire, cu latimea de biti, si cu complementul lui mami. DAR de carry flag din procesor nimic, de bitii extra la float din procesor, nimic, de erorile de rotunjire in practica - desi rezulta din teorie, asta recunosc - dar nimic in practica. 

Norocul meu ca stiu din astea pe cont propriu, si m-am inscris ulterior la faculte, doar pentru hartie, sa am si eu diploma, sa nu comenteze vreo HR-itza desteapta cand imi pune CV-ul in teancul verde sau in folderul spam.

Deci UBB, ai tu un deget mijlociu din partea mea, bine ca ne miram de ce tampiti ne vin la interviu, ca interni sau ca juniori, cu acte in regula si pretentii de "om diplomat" si banii arabiei saudite ca salar.

-----------------------------------
nobody
13 Feb 2024 06:03


-----------------------------------
prima chestie e

int x = 123456 // mai mare decat 16 biti, chiar si fara bitul de semn
...
cat e range-ul intului pe arduino uno (sau nano, 328P e nucleul, hint: e garantat sa aiba minim 16 biti, dar...)?

Din prima incercare pe Arduino:

warning: overflow in implicit constant conversion [-Woverflow]
 int vdiv2 = 100800;


Table 1. Data Types on AVR 8-bit Microcontrollers in <stdint>
Data type	Size
signed char / unsigned char = int8_t / uint8_t = 8-bit
signed int / unsigned int = int16_t / uint16_t = 16-bit
signed long / unsigned long = int32_t / uint32_t = 32-bit
signed long long / unsigned long long = int64_t / uint64_t = 64-bit

-----------------------------------
AVD
13 Feb 2024 13:14


-----------------------------------
Daca tot am deturnat, din nou, pagina de proiect in discutii si tutoriale, sa adaug si eu ceva:

Cred ca am reusit sa imi rezolv problema. Aparent, daca impart 2 variabile int (fie ele long, uint16, uint32, etc.), nu va merge. Solutia a fost sa fac acele doua variabile de tip float si sa le adaug .0 la final. 

Exemplu despre ce vreau sa spun in urmatoarele poze. 

Logica mie mi-ar dicta ca nu are de ce sa functioneze ce am facut eu, pentru ca rezultatul impartirii il atribui unui numar float, deci nu vad de ce numerele de dinainte nu ar putea sa fie int.
Cel mai sigur imi scapa modul in care microprocesorul executa, de fapt, operatia de impartire.

Disclaimer, din nou: Nu sunt programator de meserie, n-am mai pus mana pe cod din liceu, de peste 10 ani. Go easy on me :D

-----------------------------------
valy
13 Feb 2024 13:30


-----------------------------------
Sunt importante tipurile, sunt importante cast-urile automate, fiecare cu regula lui.
Impartirea e cea mai parsiva operatie, cateodata chiar si simpla adunare, de ex daca incrementezi 0 cu 0.01 de 100 de ori la final o sa ai anumite surprize...
Testarea este importanta, modul cum functioneaza compilatoarele, limbajele, hardwareul este important, chiar si cum definesti o simpla constanta poate fi crucial.

Este si o capcana asta cu sistemele "simple" gen arduino, cat timp te joci si aprinzi un led acasa e ok, cu conditia sa nu dai foc la ceva :)


Logica mie mi-ar dicta ca nu are de ce sa functioneze ce am facut eu, pentru ca rezultatul impartirii il atribui unui numar float, deci nu vad de ce numerele de dinainte nu ar putea sa fie int.
De obicei cast-ul se face la atribuire, atunci se schimba tipul, impartirea ia tipul operanzilor:
float x = 1/3 -> x = 0

Sunt multe reguli implicite, implicate in programare, ca sa mearga treaba trebuie sa le cunosti. Din pacate nu gasesti nicaieri lista completa a lor, pe care daca o inveti gata esti programator certificat. Si astfel se pune intrebarea cum de merg aplicatiile facute de programatori?! Sunt unii care stiu regulile si le aplica, sunt altii care verifica ce au facut unii. Daca cel putin una din categorii isi face treaba, ai sanse (relativ mici) ca programul sa mearga (relativ) ok.

-----------------------------------
varadinagypal
13 Feb 2024 13:54


-----------------------------------
putina practica
=========

atribuirea se face la un float, dupa ce operatia s-a facut asupra unor inturi. 


putine teorie
========

Daca te-ai intalnit cu notatia poloneza care reflecta precedenta, asociativitatea etc:

1*(2+3) se scrie *+2,3,1

// varianta pentru muritori, cu functii de prototip: numar operator(operand1: numar, operand2: numar)

mul(1, add(2,3))

Sa se sesizeze ca si conversiile de tip (cast) dar si integer/float promotion (de pilda la sprintf, chiar si cand ele nu sunt scrise explicit) sunt functii cu un singur operand: f(x): y

unde x si y sunt variabile, adica perechi de { tip, valoare }

practica
=====

astfel, mai pe C-lang

int x = 3
int y = 1
int z = 1
// float a = toFloat(integerDivision(x, intAdd(y, z))
float a = x / (y+z);

rezultat: a == 1.00000000

teorie de limbaj si compilator
==================

python si cu javascript si cu php si c# si c si c++ si ce o mai fi, in functie de preferintele celor care au facut/comandat limbajul, de strictetea si garantiile / lejeritate care trebuie date de parser/compilator, la compiletime/runtime,

au alte idei despre type-inference, type-conversion, rotunjiri, despre teoria de tipuri, adica despre {tip, valoare} in general si conversiile de {tip1, valoare1} => {tip2, valoare2}, despre operator overload, in cazul c++ de pilda explicit, ori implicit la javascript unde problemele incep cu ordinea de numar+string sau string+numar, + fiind cu overload pentru concatenare si adunare aritmetica, dar - fiind doar scadere aritmetica

iti recomand, pe langa manualele de facultate sau liceu, unele de kkt, altele chiar bune, serialul lui Bartosz Milewski de pe youtube, despre teoria categoriilor, daca te intereseaza astfel de perversiuni intelectuale. Ca in practica, fix de din astea te vei lovi, si in python, si in C

-----------------------------------
AVD
13 Feb 2024 14:58


-----------------------------------
Multumesc de recomandari! 

Am rezolvat si problema cu PWR_TOTAL, si anume calculul ei in 2 pasi, cu PWR_TOTAL_S, apoi TOTAL_H. Aceeasi rezolvare: time1 si time2 ii initiam ca si long. I-am initiat ca float si acum nu mai am nicio problema. De asemenea, am facut un artificiu care sa imi masoare/estimeze puterea consumata intre cicluri. 

    time1=millis();
    [...]
    PWR_TOTAL = PWR_TOTAL+ ((((prev_pwr+PWR)/2)*(time1-time2))/3600000); // total power in W*h 
    prev_pwr=PWR;
    time2=millis();
    PWR_TOTAL = PWR_TOTAL+ ((PWR*(time2-time1))/3600000); // total power in W*h 

Sper ca se intelege ce am vrut sa fac aici: tin minte puterea din ciclul trecut, fac media cu puterea din ciclul asta si le inmultesc cu diferenta de timp intre finalul ciclului trecut si inceputul ciclului actual. Apoi atribui valori noi pentru prev_pwr si time2 si calculez puterea consumata in ciclul curent.

-----------------------------------
nobody
13 Feb 2024 15:03


-----------------------------------
Un pic mai simplu, asta depinde de cum interpreteaza compilatorul, microprocesorul doar executa codul generat de compilator.
Logica mie mi-ar dicta ca nu are de ce sa functioneze ce am facut eu, pentru ca rezultatul impartirii il atribui unui numar float, deci nu vad de ce numerele de dinainte nu ar putea sa fie int.
Cel mai sigur imi scapa modul in care microprocesorul executa, de fapt, operatia de impartire.

Disclaimer, din nou: Nu sunt programator de meserie, n-am mai pus mana pe cod din liceu, de peste 10 ani. Go easy on me :D

Daca faci o atribuire de genul
float_c = int_a / int_b
compilatorul (implicit dupa primul operand int_a) face impatirea ca intregi si pe urma atribuie rezultatul intreg la float

Daca vrei un rezultat in float trebuie sa-i spui explicit sa trasforme primul operand in float
float_c = (float)int_a / int_b

In schimb daca primul operand este deja float, nu mai este nevoie de casting (dar nici nu strica):
float_c = float_c / int_b;

Am facut un exemplu mai jos cu uint16_t ca sa se vada si un overflow.


#include <stdio>
#include <stdint>

int main()
{

uint16_t int_a = 100000;
uint16_t int_b = 7;
float float_c;

float_c = int_a / int_b; 
printf ("int overflow:             int_a = %6i  int_b = %i  float_c = %18.12f\n", int_a, int_b, float_c);

int_a = 100;
float_c = int_a / int_b;
printf ("implicit int division:    int_a = %6i  int_b = %i  float_c = %18.12f\n", int_a, int_b, float_c);

float_c = (float)int_a / int_b; // type casting to float
printf ("explicit float division:  int_a = %6i  int_b = %i  float_c = %18.12f\n", int_a, int_b, float_c);

float_c = 100;
float_c = float_c / int_b;
printf ("implicit float division:  int_a = %6i  int_b = %i  float_c = %18.12f\n", int_a, int_b, float_c);

    return 0;
}

main.c: In function &#8216;main&#8217;:
main.c:15:18: warning: unsigned conversion from &#8216;int&#8217; to &#8216;uint16_t&#8217; {aka &#8216;short unsigned int&#8217;} changes value from &#8216;100000&#8217; to &#8216;34464&#8217; [-Woverflow]
   15 | uint16_t int_a = 100000;
      |                  ^~~~~~

int_a overflow (100000)   int_a =  34464  int_b = 7  float_c =  4923.000000000000
implicit int division:    int_a =    100  int_b = 7  float_c =    14.000000000000
explicit float division:  int_a =    100  int_b = 7  float_c =    14.285714149475
implicit float division:  int_a =    100  int_b = 7  float_c =    14.285714149475


-----------------------------------
nobody
13 Feb 2024 15:26


-----------------------------------
Inca nu mai ai nicio problema ... inca ... dar ai o potentiala pierdere de precizie de la 32 bit (unsigned long) la 23 de bit (float) care poate duce la "Catastrophic cancellation" Aceeasi rezolvare: time1 si time2 ii initiam ca si long. I-am initiat ca float si acum nu mai am nicio problema. 
millis() Number of milliseconds passed since the program started. Data type: unsigned long

-----------------------------------
valy
13 Feb 2024 15:41


-----------------------------------
Acel /360000...se aplica tuturor termenilor, fiecare aplicare duce la erori de aproximare, nu mai bine il aplici o singura data?

x/2+y/2 = (x+y)/2

Asa ai si optimizare, 3 vs 2 operatii per total.

Operatiile pe int sunt de obicei mai rapide si mai eficiente energetic decat float/double, la numarator poti face calcule doar pe int. O alta optimizare. 
Casturile consuma si ele timp.

Dar sa vezi, tot adunand, sa nu depasesti capacitatea tipului de date.

-----------------------------------
AVD
13 Feb 2024 15:59


-----------------------------------
Nu inteleg la ce te referi cu acel /3600000 care se aplica tuturor termenilor si poate fi aplicat o singura data... cum adica sa il aplic o singura data? Mie din calculul ala imi pare ca asta fac.. impart puterea calculata * timpul in milisecunde la 3600000, sa o transform in W*h. 


Chiar nu imi pot da seama cum as putea imbunatati aici calculul, incat sa si functioneze cum trebuie. PWR total nu va depasi niciodata float, cu siguranta. time1 si time2, insa, cresc foarte rapid. Nu stiu daca pot depasi float intr-o sesiune de observatii, care va dura, in medie, sa zicem, 5 ore maxim. 5h * 3600000 inseamna 18 milioane de milisecunde.

-----------------------------------
valy
13 Feb 2024 16:20


-----------------------------------
Pare un algoritm de forma:

t = 0

t = t + a1/2
t = t + a2/2
t = t + a3/2
.....
=>
t = 0 + a1/2 + a2/2 + a3/2+...
=>
t = 0 +(a1+a2+a3+..)/2

Astfel algoritmul se transforma in:

a = 0
a = a + a1
a = a + a2
a = a + a3
...
=> t = 0 + a/2

-----------------------------------
varadinagypal
13 Feb 2024 16:46


-----------------------------------
Un programator low level care se respecta, cand vede un numar din asta de 36000000, isi ia medicamentul de inima (de prune, de exemplu) si isi da jos ochelarii, ca nu mai are ce sa faca. 

Inmultirea de orice natura impnge biti in stanga, impartirea in dreapta, imagineaza-ti multe carti pe biblioteca mai modesta, iar repetand pasii, succesiv, cartile cazute raman cazute si nimeni nu le mai recupereaza. Motiv pentru care hotii, scuze, bancherii nu folosesc float, bancile folosesc fie int, fie big decimal, fie de din astea. 

Conversiile din astea, menite utilizatorilor de camp (userus vulgaris), de obicei se fac in ultimul pas si nu pe parcurs, iar retinerea datelor se face dinamic (ca la float), cu rezolutie mare la valori mici, si cu rezolutie mica la valori mari. Ca nu te intereseaza daca consumul a fost 1000002Wh sau 1000001Wh, adica 1.00e6 sau 1.00e6, dar de intereseaza daca a fost 1 sau 2, adica 1e0 sau 2e0.


Mai e bancul cu muzeul de paleontologie. Apare sub scheletul de T-rex ca 71 milioane de ani, 3 saptamani si 2 zile. Si se uita elevii, cu proful de biologie, ca nu inteleg treaba. Cum adica 71 mil. de ani 3 saptamani si 2 zile. Pai, zice muzeologul, a fost un mare expert din Bucuresti, luna trecuta, si a datat scheletul ca fiind de 71 mil de ani.

Si la job acum dezbatem (adica tin prelegerea) despre epsilon, despre functiile de trigonometrie cu limita la 1.0 care ce sa faca sau sa nu faca cu numerele obtinute din aritmetica cu valori de gen 1.00000000000002, care in mod evident e mai mare decat 1, in afara intervalului de -1..+1, deci cat e gen arcsin(1.00000000000002), nedefinit????

-----------------------------------
AVD
13 Feb 2024 17:03


-----------------------------------
Pare un algoritm de forma:

t = 0

t = t + a1/2
t = t + a2/2
t = t + a3/2
.....
=>
t = 0 + a1/2 + a2/2 + a3/2+...
=>
t = 0 +(a1+a2+a3+..)/2

Astfel algoritmul se transforma in:

a = 0
a = a + a1
a = a + a2
a = a + a3
...
=> t = 0 + a/2

Adica, asa ceva ar fi mai frumos? 
time1 si time2 sunt din nou unsigned long.
    time1=millis();
    [...]
    prev_pwr_used = (prev_pwr+PWR/2)*(time1-time2);
    prev_pwr=PWR;
    time2=millis();
    current_pwr_used = PWR*(time2-time1);
    total_pwr_used = prev_pwr_used + current_pwr_used;
    PWR_TOTAL = PWR_TOTAL + total_pwr_used / 3600000 ; // total power in W*h

-----------------------------------
valy
13 Feb 2024 17:21


-----------------------------------
Nu prea e ok, pare ca defapt e acelasi lucru ca in versiunea originala. 
Sper sa nu stricam corectitudinea. dar acea impartire n-ar trebui sa apara deloc, decat la final detot dupa ce calculezi ultima iteratie. Desigur daca pe parcurs afisezi puterea pana la mom. respectiv, va trebui sa faci impartirea, dar doar pt afisare, insa banui ca nu te intereseaza la fiecare milisec ce ai consumat.

Ultima linie ar trebui sa fie:
PWR_TOTAL = PWR_TOTAL / 3600000....

Ai multe variabile locale pe acolo, e un algoritm iterativ si pare incomplet specificat, nici eu nu sunt foarte atent acum... dar ca idee schematica, ce am zis eu doua posturi mai sus cred ca se valideaza matematic. Daca acea abordare corespunde cu algoritmul tau, eu asa as face. Pana la urma conteaza sa fie corect si mai putin important sa fie optimizat.

Dar aici subscriu la ce zicea colegul pal mai sus, acea impartire la 3600000 e naspa, rostogolesti niste erori de nu te vezi...


..Motiv pentru care hotii, scuze, bancherii nu folosesc float, bancile folosesc fie int, fie big decimal, fie de din astea. Ai vazut Office space? Spune ca da!!

-----------------------------------
AVD
13 Feb 2024 17:27


-----------------------------------
Nu prea e ok, pare ca defapt e acelasi lucru ca in versiunea originala. 
Sper sa nu stricam corectitudinea. dar acea impartire n-ar trebui sa apara deloc, decat la final detot dupa ce calculezi ultima iteratie. Desigur daca pe parcurs afisezi puterea pana la mom. respectiv, va trebui sa faci impartirea, dar doar pt afisare, insa banui ca nu te intereseaza la fiecare milisec ce ai consumat.

Ultima linie ar trebui sa fie:
PWR_TOTAL = PWR_TOTAL / 3600000....


Nu cred ca ne gandim la acelasi rezultat :D PWR_TOTAL este un "Gauge" in NINA, care este updatat odata pe secunda de driver (driverul "citeste" valoarea stocata pe variabila PWR_TOTAL in arduino si o atribuie acelui camp din NINA). Nu e o valoare pe care o citesc cand sting lumina.

Codul complet este asta: functia ruleaza in bucla (in void loop()).
Cand pe serial vine comanda care cere valoarea, pur si simplu se trimite PWR_TOTAL prin serial.

 void GET_POWER() {
    time1=millis();
    if (AVERAGE_COUNT == 150) AVERAGE_COUNT = 0;
    float VOLTAGE_SAMPLE_SUM=0;
    for (int v=0;v<150;v++) 
    {
      PIN_VALUE_V =  analogRead(VM);
      VOLTAGE_SAMPLE_SUM +=PIN_VALUE_V;     
    }
    VOLTAGE_SAMPLE_SUM /=150;
    VOLT_TEMP = (VOLTAGE_SAMPLE_SUM * 5.0) / 1024.0;   
    VOLT = VOLT_TEMP / 0.0982;        
    if (VOLT < 0.1) VOLT=0.0;    
    CURRENT_SAMPLE_SUM=0;
    for (int i=0;i<150;i++)
    {
      PIN_VALUE_A= analogRead(AM);
      CURRENT_SAMPLE_SUM = CURRENT_SAMPLE_SUM + PIN_VALUE_A;
    }
    AMP_AVERAGE[AVERAGE_COUNT] = (2.494 - ((CURRENT_SAMPLE_SUM/150)*(5.0/1024.0))) / ACS_resolution;
    AVGAMP=0;
    for (int c=0;c<150;c++) AVGAMP += AMP_AVERAGE[c];
    AMP = AVGAMP/150;
    if (AMP< 0.01) AMP=0.0;
    PWR = VOLT * AMP;
    AVERAGE_COUNT = AVERAGE_COUNT + 1;
    prev_pwr_used = (prev_pwr+PWR/2)*(time1-time2);
    //PWR_TOTAL = PWR_TOTAL+ ((((prev_pwr+PWR)/2)*(time1-time2))/3600000); // total power in W*h 
    prev_pwr=PWR;
    time2=millis();
    current_pwr_used = PWR*(time2-time1);
    total_pwr_used = prev_pwr_used + current_pwr_used;
    PWR_TOTAL = PWR_TOTAL + total_pwr_used / 3600000 ; // total power in W*h                                
}

-----------------------------------
valy
13 Feb 2024 17:31


-----------------------------------
Acu' sincer, prefer sa fac un algoritm decat sa inteleg ce au facut altii.  :lol:   :lol:


Codul complet este asta: functia ruleaza in bucla (in void loop()).
Cand pe serial vine comanda care cere valoarea, pur si simplu se trimite PWR_TOTAL prin serial.

Pai nu vad ce faci cu  PWR_TOTAL, pare ca doar se actualizeaza si atat.

-----------------------------------
AVD
13 Feb 2024 17:35


-----------------------------------
Codul sursa pentru Arduino este in link-ul pus mai sus. Am observat ca lumea adauga sugestii si comentarii bazate pe cod, deci mi-am imaginat si am presupus ca ati inteles ce face. Stiu, greseala mare, sa presupui :D 

As fi complet de acord sa se faca impartirea odata la final si gata. Asa are foarte mult sens, daca vreau sa obtin o valoare finala. Doar ca eu vreau sa o actualizez in timp real pentru ca ea sa fie adusa in NINA, tot in timp real.

-----------------------------------
valy
13 Feb 2024 17:40


-----------------------------------
Da, assumption is the mother of all Fuckups.

 Doar ca eu vreau sa o actualizez in timp real pentru ca ea sa fie adusa in NINA, tot in timp real.Daca prin timp real intelegi ca dupa fiecare calculatie sa o exporti, pare logic sa faci impartirea de fiecare data. De cate ori pe sec se intampla o astfel de calculatie?

-----------------------------------
AVD
13 Feb 2024 17:42


-----------------------------------
Am masurat time2-time1 si este 20ms. Timpul intre cicluri este si el cam 100ms, deci cam de 8-10 ori pe secunda.

-----------------------------------
varadinagypal
13 Feb 2024 17:50


-----------------------------------
alta softareala: model, view, controller. Tu ai nevoie de valoarea interna, un acumulator, si ai nevoie de un view value, care afiseaza valoarea respectiva pe serial in cazul asta. Is doua lucrurui diferite. As putea tine o prelegere si despre asta, dar ma abtin, si mentionez doar ca m-am lovit odata de careva destept care facea conversii celsius-fahrenheit-kelvin, cu o singura cifra dupa virgula, si se mira ca iterand intre unitatile de masura, i se tot schimba valoarea de celsius... pai, C-F e o formula urata, dar si K-C e cu .15 la capat, nu .2 si nu .1. Ca nu avea valoare in spate { valoare model, unitate: microcelsius} => { valoare view, unitate: celsius/f/k }, ci avea {valoare, unitate} si... nu-i iesea. Vai cate din astea as putea povesti, ca in PLM ca nu se face ucenicie si mentorat pe bune in programare, si firmele multicultinationale, carora nu le pasa, arunca cu titluri dupa niste bebe care stiu sa se dea pe bicicleta, senior tati, si nu mai ajungi tu sa comentezi ce a facut maria sa.
