Elektromer-meranie napätia a prúdu každú 1ms, výpis spotreby

Jednoduché schéma můžeš mít třeba jako na obrázku. V reálu by tam samozřejmě muselo být hejno ochran, v závilosti na proudovém rozsahu také jiný způsob snímání, ale tady se na to asi nehraje.

R4 je měřený objekt.

R5+R6 je napěťový dělič. Je třeba ho nastavit podle požadovaného vstuního napětí. Pokud bys jako referenci převodníku použil +5V AVcc, tak pro vstup +40V je nutný dělič 1/8 => R5 = 7*R6. Např. tedy R6=10k, R7=70k.

R3 je snímací odpor proudu. Zase záleží na rozsahu, ale třeba pro rozsah do 0.5A můžeš mít např. 1 Ohm. Na převodníku se potom bude vyskytovat napětí 0 - 0.5V.
Abys získal napětí na měřeném zařízení, toto napětí na R3 je nutné odečíst od hodnoty spočítané z děliče (Vr4 = 8*V_adc - I_adc).
mereni_vykonu.gif

podla mna ma merat dve napetia… bude tam nejake OZ pre zosilnenie napetia zo snimacieho odporu… tak ze nekomplikovat prespikovanymi logickymi uvahami ako by sa to dalo :smiley:

Ked som bol na poslednej konzultacii v skole tak mi to nejak tak vysvetloval ako si dal tu schemu. O OZ nic nehovoril tak to tak asi nemam mat

Ako mam teraz nastavit prevodnik, aby som mohol vypisovat aj to druhe napatie s ktoreho urobim prud?

Dej sem současný stav zdrojáku - hlavně ten soubor s měřící funkcí (jako přílohu, ať nezaplácneš celou stranu).
Ale jde jen o to před začátkem převodu změnit kanál na ten, který chceš měřit (ADMUX).

tu je ten subor
Cv_2.rar (32.5 KB)

Koukám, že to zkoušíš rozdělit do více souborů. Když to neumíš, radši to namasti do jednoho, nebo se podívej do hozova vlákna.

Jinak teprve to luštím.

edit: používáš tam jakýsi “delay”. Zvaž použití vestavěné funkce v gcc :wink: Také je použita v příkladu ve zmíněném vlákně.

Hlavičkový soubor lcd4bit.h nemá ochranu proti vícenásobnému vložení.
V podmínce v souboru “some.c” chybělo rovnítko (mají být 2, jinak je to piřazení a to je vždy TRUE). Ten příkaz za ifem se má provést pouze když je podmínka TRUE? Jesli ano, bylo by vhodné ho napsat na stejný řádek s podmínkou - aby bylo vidět, že to k tomu patří.

Vím, že těch warningů není málo, ale občas sdělují užitečné informace :wink:

Doplnil jsem frekvenci mcu do nastavení projektu (zas o warning méně :slight_smile:). Soubor “tlacitko.c” je tam při současném stavu zbytečný (nemá hlavičkový soubor a jeho funkce není nikde volána). Pokud jsi ho zdědil z jiného projektu, tak ho z tohoto odeber.

Ta lcd knihovna je šílená, ale jesli chodí, tak budiž. Jen doladit její hlavičkový soubor.

Upravil jsem soubor s funkcemi ADC a vytvořil jeho hlavičkový soubor. Můžeš se dále snažit :wink:.
Cv_2.zip (22.3 KB)

Sposob ako to je napisane som prebral z velmi obmedzeneho poctu prikladov co sme robili v skole. Nejaku hlbsiu teoriu k tomu nepoznam. Mal som to len jeden semester bez nejakeho vysvetlovania a sam som sa toho vela nestihol naucit

Napsal jis zatímco jsem byl v editaci, kód máš tedy výše.

Ano jasne uz som to pozeral. Kod pre timer by mohol nejak takto byt? Ma to merat kazdu 1ms.

void init_tim(void) { TCNT1=64536; TCCR1B=0x02; TIMSK1=0x01; SREG=SREG|0x80; }

To nastavení jsem nezkoumal, ale přednastavuješ tam ručně čítač. To přednastavení se takto použije pouze 1x a pak už pojede celej. Pokud tedy TOP-64536 dá 1ms, tak další přerušení bude mnohem později. Lepší je použít některý v PWM módů (14 nebo 15 jesli se nemýlím), kde si uložíš TOP hodnotu do některého z registrů (popsáno v DS) a nemůsíš se o to již starat. Když tam např. uložíš 999, čítač bude mít délku 1000.
Ten řádek s SREG je nastavení sei? Místo toho stačí napsat “sei();”. :wink: Je to makro z interrupt.h, který musíš mít stejně pro použití přerušení vložen.

Ještě jedna věc. Pro měření výkonu bys měl vzorkovat oba kánály současně. To však není na mcu s 1 ADC možné. Bylo by tedy dobré provést alespoň obě měření ihned za sebou. První tedy spouštět timerem a druhé okamžitě po dokončení prvního.
Bojuješ stále s timerem po svém nebo zkoušíš pwm s omezením délky timeru? Nebo máš pauzu? :slight_smile:

Mal som teraz strasne vela ucenia tak som to nestihal. Pozeral som aj na tu pwm, ale fakt neviem ako to mam spravit tie merania.

Jen se pilně uč :slight_smile:
řešení máš povícero. Nejlepší by to bylo přerušeníma, ale to by pro tebe bylo asi zbytečně složité.
Nejdřív budeš potřebovat nastavit ten timer na 1ms. To kdyžtak dáme dokupy bezproblému.
Ve tvém případě bych to asi dělal co nejjednodušeji. V main testovat příznak přetečení timeru. Jakmile přeteče, vynulovat příznak (nuluje se jedničkou) a provést za sebou ta 2 měření, výpočty a pak zas čekat do další milisekundy.

To nulovanie priznaku sa robi v registri TIFR? Aspon tak nejak som to pochopil

ano

Este som to neprepocital na 1 ms, ale snad to moze byt nejak takto

[code]void Init_Timer(void)
{
TCCR1A |= (1 << WGM15);

OCR1A = 31250; //pre 1s

TCCR1B |= (1 << CS11) | (1 << CS10); //pre fcpu/64
} [/code]

nulovanie asi takto TIFR = (1 << OCF1A); len neviem kam to mam dat

Skoro :slight_smile:
Tohle jde přeložit? Neviděl jsem totiž u megy16 definici bitu WGM15 :slight_smile:
Pro mode 14/15 je třeba nastavit určité bity, ale žádný z nich není wgm15.

void timer1Init(void) { // mode 14 // delicka: 0.001 * 8e6/65536 = 0.1 => Clock Select: clkI/O/1 (No prescaling) // TOP = 0.001*8e6-1 = 7999 TCCR1A |= 1<<WGM11; TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS10); ICR1 = 7999; }

Čekání na přetečení timeru:while(!(TIFR & (1<<TOV1))); // cekej dokud nepretece TIFR |= 1<<TOV1; // vynulovat příznak přetečení // zde provést měření

To asi není přetečení (overflow) že :slight_smile:.

To WGM mam s knihy od matouska. Ked to nieje mozne tak som to asi nejak zle pozrel. Prelozit to ide.

[code]volatile unsigned int napatie, prud;

void timer1Init(void)
{
// mode 14
// delicka: 0.001 * 8e6/65536 = 0.1 => Clock Select: clkI/O/1 (No prescaling)
// TOP = 0.001*8e6-1 = 7999
TCCR1A |= 1<<WGM11;
TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS10);
ICR1 = 7999;
}

void main(void)
{
adc_init();
lcd_init();

while(!(TIFR & (1<<TOV1)));  // cekej dokud nepretece 
    TIFR |= 1<<TOV1;  // vynulovat příznak přetečení 



while(1)
{ 
//unsigned int napatie;    // pre test bude globálne a volatile 
char pom[6];
       ........[/code]

mozes sa pozriet ci som to tam dobre dal

Skoro dobře.
timer1Init() je třeba také zavolat, nejlépe za “lcd_init();”.

Čekání na přetečení timeru by mělo být uvnitř nekonečné smyčky hned před měřením (“napatie = adc_read(0);”). Takhle bys počkal 1x na začátku a potom když by ses do smyčky dostal, už by nečekal.

S WGM15 by to přeložit jít rozhodně nemělo (pokud sis to nenadefinoval sám). V definičním souboru megy16 totiž taková definice není a překladač zahlásí chybu (ověřeno).