Nejste přihlášen/a.
Dobrý den,
doufám, že zde pořád máme odborníky všech oborů. Potřeboval bych pomoc s řešením měření napětí pomocí ATtiny85 případně arduina. Patlám se od včera v návodech a díky mé špatné matematice mi to těžce nedává logiku jak problém vyřešit.
Příkladem máme měřené napětí 0-25V, což je potřeba přetáhnout přes dělič. Ten se mi pořádně nedaří spočítat. Zvolil jsem tedy 33 kohm a 8,2 kohm. Poměr by měl být 4,02 (to nevím jak využít). Dle aplikace bude při 25V na výstupu 4,98V.
Reference je napájecí napětí 5V. Takže rozsah 0-5V na děliči je ideální. Bohužel mi napětí reálně nesedí. Při měření musím napsat kód jako analogRead(Ubat) (* 25 / 1023). Takto to nějak funguje ale s špatnou přesností. Ostatní v návodech počítají s napájecím napětím tudíž analogRead(Ubat) * 5 / 1023. jenže tenhle výpočet je úplně mimo když pak měřím napětí.
Navíc hodně uživatelů počítá s poměrem rezistorů a i když zadám do kalkulačky jejích rezistory, poměr mi vyjde jiný než počítají oni. Příkladem jeden zvolil rezistory 10 a 22 kohm a údajný poměr mu vychází na 3,93.
Jednoduše ze všech návodů neumím zvolit výpočet v kódu jak vlastně měřit a převádět hodnoty 0-1023 na reálné napětí. Jak přijít na poměr rezistorů, jak z něj přijít na výpočet. Pořád v tom z desítek příkladů nevidím návaznosti a logiku. Navíc mám pocit, že to každý počítá jinak.
Prosím o nějakou pomoc abych se už konečně zorientoval. Děkuji
AD: příkladem v obrázku počítá vzorec na poměr rezistorů. Ovšem v příkladu má uveden vzorec R1 / (R1+R2), proč tam přidává napětí (které nevím kde vzal)?
> Zvolil jsem tedy 33 kohm a 8,2 kohm. Poměr by měl být 4,02
> analogRead(Ubat) * 5 / 1023
S měřením napětí pomocí ATtiny85 nemám žádnou zkušenost, ale z tvého popisu bych logicky řekl, že:
napětí_na_výstupu_děliče = 5 * ( analogRead(Ubat) / 1023 )
napětí_před_děličem = 4,02 * napětí_na_výstupu_děliče
> Poměr by měl být 4,02
Asi překlep. Má být 5,02.
8,2 / (8,2+33) = 0,199 neboli napětí na tom odporu 8,2kohm bude 0,199 krát napětí na té sériové kombinaci 33+8,2.
Převodový poměr je 1 / 0,199 = 5,02
napětí_před_děličem = 5,02 * napětí_na_výstupu_děliče
Zajímavé díky. Myslím, že to je jeden z bodů, který se přeskakuje, protože všichni měří max 5V napětí. Třeba takto:
// přečte vstup A0:
int sensorValue = analogRead(A0);
// Převede analogový vstup (od 0 do 1023) na napětí (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
Jenže, jsem i v návodech na vyšší napětí neviděl, že by někdo počítal ještě s poměrem reziostorů. I když to dává logiku (při počítání na kalkulačce) ale reálně jsem to neviděl. Odpoledne budu pokračovat a snad už přesnost vyřeším. Ještě jsem uvažoval přejít na 1,1V referenci, ale jak spočítat vše kolem jsem zase zmatený. Věřím, že je to jednoduchá logika, ale programování není tak silná stránka a matika už vůbec.
Při referenci 1,1V bys musel upravit ten dělič, aby ti zmenšil 25V na 1,1V (zmenšením těch 8,2kohm na 1,52kohm nebo zvětšením 33kohm na 178,2kohm pro převodový poměr 22,7 ) a pak změnit řádek
float voltage_v_rozsahu_0_až_1,1V = sensorValue * (1.1 / 1023.0);
voltage_v_rozsahu_0_až_25V = 22,7 * voltage_v_rozsahu_0_až_1,1V
> Možná tu hodnotu špatně chápu
Chápeš jí blbě. Máš tam uvedeno, že těch 4,02 je poměr R1/R2, tedy poměr napětí na R1 a R2. Ty ale chceš poměr napětí na (R1+R2) a R2.
Protože R1+R2 obsahuje přesně o jedno R2 více než jen R1, tak ten poměr vychází přesně o jedna menší než převod celého děliče.
Nevím, jestli se převod děliče v učebnicích udává jako R1/R2 nebo (R1+R2)/R2. Já vycházel ze vstupujícího a vystupujícího napětí děliče.
Jestli chceš použít těch 4,02, tak v tvém programu musíš přičítat jedničku:
voltage_v_rozsahu_0_až_25V = (4,02 + 1) * voltage_v_rozsahu_0_až_5V
Dobře, už se začínám trochu orientovat. Díky ti za tvůj čas.
Z aplikace tedy pravá hodnota uprostřed je poměr. (vout/vin) Protože v prvním příkladu ti vyšlo 0,199, aplikace 0,2 a v druhém 0,044 (1/0,044) vyjde 22,7.
Odpoledne to zkusím podle těch dvou výpočtů zda bude hodnota sedět lépe. Přidat
napětí_před_děličem = 22,7 * napětí_na_výstupu_děliče
k základnímu přepočtu. A samozřejmě změním odpory.
Jinak v podstatě stavím regulátor na soláry. Mám na okně dva 5W. Takže procesor bude měřit baterii, připínat soláry a odpojovat a ještě hlídat zátěž (odpojí při určitém napětí a znovu připojí) Jenže to musí celkem dobře měřit napětí a zatím nastavím v programu nějaké napětí, ale měřené je jinde. Plus to taky trochu chodí jednou vypne tak a jednou o 0,5V jinde.
Ten dělič funguje tak, že na větším odporu je i větší napětí a na menším je napětí menší.
(A "divné" hodnoty odporů se používají proto, že zrovna odpory s těmito hodnotami jsou na skladě všude, protože je jednodušší vyrábět jen některé hodnoty, které jsou asi tak rovnoměrně rozhozené.)
Když si spočítáš R1/R2 = 33 / 8.2 = 4.02 tak ti vyjde, že protože je větší odpor (R1) asi 4x větší než ten menší (R2), tak na něm bude vždy asi tak 4x větší napětí (přesněji 4.02x). To je sice fajn, ale až tak moc to nepomůže.
My chceme přivést napětí na sériovou kombinaci těch odporů a měřit napětí na jednom z nich (jako to máš na tom obrázku).
Potom teda je celkový odpor R1+R2 = 33+8.2 = 41.2 kOhm a na tom R2 teda bude (R1+R2) / R2 = 41.2 / 8.2 = 5.024x menší napětí, než na celé té kombinaci. Což je fajn, protože když na tu kombinaci dáme těch 25V, tak na tom R2 bude 5x míň, čili asi 5V (4.854V přesně) a to už Arduinem měřit umíme.
Což je právě ta rovnice pro napětí - Vstup / ( (R1+R2) / R2) = Výstup
Dál víme, že Arduino analogRead pro napětí na pinu 5V ukáže číslo 1023 a pro 0V ukáže 0, což je 1023 dílků, každý o velikosti 5V / 1023 = 4.887 mV
Takže pokud Arduino ukáže nějaké číslo, tak ho vynásobíme těma 4.887mV = (5V/1023), tím dostaneme, kolik voltů je na pinu a protože víme, že na vstupu děliče je (R1+R2)/R2 krát tak to tím vynásobíme a máme, kolik voltů je na fotovoltaice.
Takže dohromady to vypadá takhle:
float R1=33;
float R2=8.2;
int Merici_pin = A0;
float Celkove_napeti = analogRead(Merici_pin) * ( 5 / 1023 ) * (R1+R2)/ R2;
if ( Celkove_napeti > 12.0 ) {
// muzeme to pouzit jako 12V zdroj ...
};
Jen to shrnu:
int Uref = 5V
int sensorValue = analogRead(A0);
// Převede analogový vstup (od 0 do 1023) na napětí (0 až Uref):
float voltage = sensorValue * ( Uref / 1023.0);
// Převede rozsah od 0 do Uref na výstupu děliče na od 0 do 25V na vstupu děliče
skutečný_voltage = ( (R1/R2) + 1) * voltage
Já bych si vše shrnul do jedné celočíselné konstanty:
#define R1 90
#define R2 10
#define U_REF 2560
#define U_Prenos (U_REF*((R1/R2)+1)/1024) //(2560*10/1024=25)
a výsledek bych udával v milivoltech.
uint16_t sensorValue = analogRead(A0);
uint16_t voltage = sensorValue * U_Prenos; // dalo by se to i sloučit na jeden řádek
25000 by se do uint16_t (i int16_t) mělo vejít (maximum je 65535 resp. 32768), jen je potřeba ohlídat, co udělá preprocesor s tou konstantou, jestli nedojde po cestě k nějakému přetečení (nemělo by), ale každopádně, když je to takto přes #define, tak se to spočítá při překladu a v programu je to jen jako číslo.
U procesoru, který nemá floating point operace (jasně že je kompilátor poskládá z toho, co procesor má) má smysl se jim vyhnout, ušetří se značně strojového času. A při násobení konstantou možná ještě víc, i když možná je to jedno.
Doporučuju pro větší přesnost použít interní referenci (případně i externí, ale to je zase kus hw navíc) a ne 5V, které kolísá s napájením. Pak zjistim, že místo napětí děliče měřim kolísání napájení.
Vše další už tu zaznělo, pokud potřebujete měřit 25V, tak spočítáte dělič tak, aby při 25V bylo na výstupu 1.1 nebo 2.56 V podle zvolené reference.
Takže bych bral odpory např. 100k a 10k tím by byl poměr 11:1, pro 25 V by na výstupu bylo 2.27. Při použití všech 10 bitů by rozlišení bylo 27.5 mV a maximum by bylo 2.56*11=28.16 V.
Pro poměr 1:10 je dobrá paralelní kombinace 18k. Nahoře 100k a dole dva 18k (dohromady 9k), to kdyby bylo z nějakého důvodu výhodné dělit deseti. Pak by maximum bylo 25.6 a rozlišení 25 mV. S tím by se dobře počítalo. Samozřejmě při přesných odporech (dají se koupit 0.1% stávaly 11 korun za kus, ale výběr hodnot býval omezený), jinak by se museo korigovat podle skutečně změřené hodnoty odporů (teda pokud se taková přesnost vyžaduje).
V datasheetu píšou, že ADC je optimalizovaný pro zdroj signálu a odporem 10k a míň, to by oba mnou navržené děliče splňovaly (první má 9 a druhý 8.2).
Ty odpory obráceně: Nahoře 2x po 180k (90k) a dole 10k, pak je poměr 10:1 a vnitřní odpor 9k. 180k i 10k v přesném 0.1% provedení má gme skladem na všech třech prodejnách.
Neneseme odpovědnost za správnost informací a za škodu vzniklou jejich využitím. Jednotlivé odpovědi vyjadřují názory jejich autorů a nemusí se shodovat s názorem provozovatele poradny Poradte.cz.
Používáním poradny vyjadřujete souhlas s personifikovanou reklamou, která pomáhá financovat tento server, děkujeme.