Problémy s nastavením registrů u časovaču u Arduina.

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
Celeron
Příspěvky: 16140
Registrován: 02 dub 2011, 02:00
Bydliště: Nový Bydžov

Problémy s nastavením registrů u časovaču u Arduina.

#1 Příspěvek od Celeron »

O víkendu jsem si hrál s Arduinem, do kterýho jsem chtěl namastit generátor pulzů, kterej 1 x za 2 minuty vymrskne na výstupu impulz 20ms. Není žádnej problém to udělat s delay (20) a delay (120000) ale je to baterkový zařízení, tak by to chtělo kvůli spotřebě na 2 minuty nastavit časovač, uspat procík, po dvou minutách ho vzbudit přerušením od časovače, vygenerovat přes delay ten 20ms impulz, shodit ho a zase uspat procík a stále dokola.
Je to oblbovač proti vypnutí odměřování, co se tu řešilo s časovačem TPL5111.
Něco jsem našel na netu jak řešit nastavení časovače a to uspání. Ještě jsem k tomu domastil další, co budu potřebovat.

Kód: Vybrat vše

#include <avr/sleep.h>

// pin pro generování pulzu
#define PULSE_PIN 3

volatile bool timer_fired = false;

ISR(TIMER1_COMPA_vect)        // přerušení od časovače,
{timer_fired = true; }        // nastavení že timer vypršel

//************************************************
void setup() {
  pinMode(PULSE_PIN, OUTPUT);  // nastavení pinu pro generování pulzu
//-------------------------------  
  // inicializace časovače
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1B |= (1 << WGM12);     // nastavení časovače do CTC módu
//  OCR1A = 15624;            // nastavení hodnoty pro 1 minutu (při 16 MHz)
  OCR1A = 31248;              // nastavení hodnoty pro 2 minuty (při 16 MHz)
  TIMSK1 |= (1 << OCIE1A);    // povolení přerušení při dosažení hodnoty OCR1A
//-------------------------------  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // nastavení režimu uspání
  sleep_enable();
  
  sei();                      // povolení globálních přerušení
}
//*************************************************
void loop()                 
 {                           // čekání na přerušení po dvou minutách (časovač 1)
    while (!timer_fired)
        {sleep_mode();}
  
  timer_fired = false;            // reset příznaku přerušení
  
  digitalWrite(PULSE_PIN, HIGH);  // generujeme pulz 20 ms
  delay(20);
  digitalWrite(PULSE_PIN, LOW);
  
  sleep_cpu();                   // uspat procesor na další dvě minuty
}
Dělal jsem to na PC v dílně a stále mi to hlásilo, že nejsou deklarovaný TCCR1A a další v sekci inicializace časovače. Tak jsem s tím praštil a před chvílí to znova zkusil na jiným PC se stejnou verzí Arduina IDE. No a světe div se, na tomhle PC kompilátor nehlásí žádnou chybu. Jestli to chodí jsem ale zatím nezkoušel. Proč to na jednom PC zkompilovat nejde a na druhým jo? Knihovna avr/sleep.h je na obou PC stejná ale stejně v ní definice pro časovač nejsou.
Nevíte prosím někdo, v který vnitřní knihovně jsou ty definice časovačů schovaný? Co s tím? Napadá mě v dílně zkusit překopírovat všechny složky s názvem Arduino (v Program Files a Users) těma z PC, kde kompilace chodí. Jsou tam kupy definičních texťáků a netuším, kde je rozdíl nejspíš od nějaký aktualizace knihoven nebo desek.
Jirka

Proč mi nemůže všechno chodit hned ?!!

Uživatelský avatar
JirkaZ
Moderátor
Moderátor
Příspěvky: 1429
Registrován: 26 úno 2021, 01:00

#2 Příspěvek od JirkaZ »

https://duckduckgo.com/?q=error%3A+%27T ... =h_&ia=web

Máš správně nastavenou "desku" (tedy typ procesoru)?
Kdo chce, hledá způsob;
kdo ne - hledá důvod.

Ze dvou možností často volím tu třetí.

Uživatelský avatar
Celeron
Příspěvky: 16140
Registrován: 02 dub 2011, 02:00
Bydliště: Nový Bydžov

#3 Příspěvek od Celeron »

To ale není můj problém, já mám na obou PC nastavenou stejnou desku a stejnej procesor . V odkazu řeší UNO s ATmega328P kontra UNO WiFi s ATmega 4809. Tam je to jasný, mají rozdílný názvy registrů časovačů.

On je tam jinej problém. Všechny knihovny začínající AVR/xxx jsou součástí balíku AVRlib pro jiný kompilátory než je IDE. Ten balík se ale neinstaluje jako jiný knihovny ze ZIP souboru ale ručně se namastí do podsložky Hardware/avr. Jenže těch tam je víc a já nevím kam přesně. Proto si myslím, že by mohlo pomoci kopírování funkčního prostředí IDE na PC v dílně.
Jirka

Proč mi nemůže všechno chodit hned ?!!

Uživatelský avatar
JirkaZ
Moderátor
Moderátor
Příspěvky: 1429
Registrován: 26 úno 2021, 01:00

#4 Příspěvek od JirkaZ »

Tohle?
You can install AVRlib anywhere you like, however, it's suggested that you install it in a directory alongside your own AVR code projects. Create or choose a top-level directory to hold both AVRlib and the project folders which you will create to hold the code for each individual project you work on. The directory you choose should not contain spaces in its name or path.
...
Finally, you need to create an environment variable AVRLIB which points to the directory where you "installed" or unzipped the AVRlib files so the compiler can find them. An example might be:

Kód: Vybrat vše

AVRLIB = c:/code/avr/avrlib         <-- change to actual AVRlib install directory
If you are unsure how to set environment variables on your system, look at the WinAVR/AVR-GCC installation guide elsewhere on this site or consult the web.
...
Kdo chce, hledá způsob;
kdo ne - hledá důvod.

Ze dvou možností často volím tu třetí.

Uživatelský avatar
Celeron
Příspěvky: 16140
Registrován: 02 dub 2011, 02:00
Bydliště: Nový Bydžov

#5 Příspěvek od Celeron »

Né tak úplně. To je popis pro kompilátory AVR-GCC nebo WinAVR. Na IDE to nefunguje, nebo nevím jak se to má nastavit. V každým případě v tom PC, co mi kompilace projde, jsem žádnou ruční instalaci balíku AVRlib nedělal.
Jirka

Proč mi nemůže všechno chodit hned ?!!

Uživatelský avatar
bdn
Příspěvky: 436
Registrován: 16 led 2020, 01:00

#6 Příspěvek od bdn »

Problém může být v mixování C++ a C. Ve stejném adresáři, kde je skeč, přidej dva extra soubory "unit.c" a "unit.h" a do nich nasypej funkce a proměnné napsané v C. V hlavním "sketch.ino" si nechej pouze funkce setup() a loop(). Na začátek sketch dej #include "unit.h"
Do "unit.h":
Just put

#ifdef __cplusplus
extern "C" {
#endif

At the beginning of the .h file describing the API, and

#ifdef __cplusplus
} // extern "C"
#endif

at the end of the file.
Zdroj:https://forum.arduino.cc/t/does-the-ide ... s/453372/4

Uživatelský avatar
bdn
Příspěvky: 436
Registrován: 16 led 2020, 01:00

#7 Příspěvek od bdn »

definice časovače by se měla získat pomocí #include <avr/io.h>

Uživatelský avatar
Celeron
Příspěvky: 16140
Registrován: 02 dub 2011, 02:00
Bydliště: Nový Bydžov

#8 Příspěvek od Celeron »

Tak už jsem na to přišel kde je problém. Pokud ten prográmek zkompiluju jako UNO nebo ProMini, tak bez problémů projde. Včera večer jsem už z toho blbnul a na tom "funkčním PC" jsem měl omylem nastavenou desku UNO a né ATtiny.
Problém je v doplňku podpory ATtiny v Arduino IDE od Drazzy.com. 328P a tiny 85 je jinej procík a tak je možný, že ty registry mají jiný názvy. Stejnej problém sem dával odkaz JirkaZ, tam byl zase rozdíl v názvech registrů mezi UNO s ATmega328P kontra UNO WiFi s ATmega 4809.
Jo a Jirko, omlouvám se za mystifikaci, stejný desky jsem nastavený neměl. :oops:

Teď jsem mluvil s kámošem, co s AVR-kama dělá již delší dobu a prý existuje konverzní program na nastavování registrů časovačů, WD a jiných speciál registrů pro různý platformy. Zatím jsem ho nenašel. V nejhorším se budou muset porovnat datašíty.
Jirka

Proč mi nemůže všechno chodit hned ?!!

Uživatelský avatar
JirkaZ
Moderátor
Moderátor
Příspěvky: 1429
Registrován: 26 úno 2021, 01:00

#9 Příspěvek od JirkaZ »

V pohodě, hlavně že to běhá. Člověk si leckdy něco myslí a ono je to jinak, stává se to samozřejmě i mně.
Kdo chce, hledá způsob;
kdo ne - hledá důvod.

Ze dvou možností často volím tu třetí.

Uživatelský avatar
Celeron
Příspěvky: 16140
Registrován: 02 dub 2011, 02:00
Bydliště: Nový Bydžov

#10 Příspěvek od Celeron »

No ono to neběhá na procíku kterej potřebuju. Ale už se blížím v čem je problém. ATtiny má zcela jinak pojmenovaný registry časovače 1 kterej jsem použil. A taky bitový významy jsou jiný. A navíc některý časovače zabírá funkce Delay a Milits. Ale časovač 0 vypadá skoro stejně aspoň názvy ale bity jsem zatím nezkoumal.
Našel jsem na netu kalkulačku časovačů pro různý platformy. No a z ní jsem zjistil, že moje doměnka, že budu časovačem generovat přímo 1 minutu je blbost. Záleží na kmitočtu hodin, jestli je konkrétní časovač 8 nebo 16 bitů a prescaleru jakej je nejnižší kmitočet z děličky.
Tak třeba u 328P co běhá obvykle na 16 MHz je Timer1 16 bitů a prescaler nejvíc 1024. Ze vzorce fOCXA = fclk / (1 x N x (1 + OCRXA)), (kde N je hodnota deličky) vyleze, že nejnižší kmitočet je 0,239Hz. Pokud se použije Timer2 je 8 bitu a na 16MHz a prescaleru 1024 vyleze nejnižší kmitočet 60,8Hz.
U ATtiny85 jsou jen časovače 8bitů a prescaler nejvíc 1024. Pokud se použije clock 8MHz, tak nejnižší kmitočet generovanej časovačem je 30,4Hz. U ATtiny se dá fuskama nastavit dělič oscilátoru na 8, takže hodiny budou pak 1MHz. S nima je nejnižší časovačem generovaný přerušení 3,8Hz.
Takže na dlohý časy to jde obejít pouze čítačem počtu přerušení a těch požadovaných 60 sekund u ATtiny85 s přerušením každých 3,8 Hz a vygenerovat pulz až při každým 240 přerušení. Nojo, ale když se procík 4 x za sekundu uspí a zase probere, asi ta energetická úspora baterky bude dost napytel. Jedině zkusit, jestli ATtiny 85 poběží na "hodinkovým krystalu" 32768. Pak bych se k těm 60 sekundám přímo od časovače dostal. Sakra, to je výzkum. :roll:
Jirka

Proč mi nemůže všechno chodit hned ?!!

Uživatelský avatar
monterjirka
Příspěvky: 2761
Registrován: 14 čer 2003, 02:00
Bydliště: Blížejov

#11 Příspěvek od monterjirka »

Celeron píše:... A navíc některý časovače zabírá funkce Delay a Milits. ...
pro nějaké zpoždění musíš použít millis, nejde použít DELAY, pokud využíváš přerušení.
To je celkem známé, i když někdy trochu protivné, omezení

Uživatelský avatar
Ruprecht
Příspěvky: 1114
Registrován: 28 zář 2005, 02:00
Bydliště: ZČ + JM

#12 Příspěvek od Ruprecht »

Použil bych interní watchdog oscilátor 128kHz s maximální děličkou, což dá asi 8s. Watchdogem generovat interrupt (ne reset), který probudí uspaný procesor jen asi 8x za minutu kvůli přičtení jedničky a zase uspí.
Kampaň, účelovka, nepodepsal, Palermo, ODS, Kalousek, je líp a jsou na to čísla, nastudujte si to.

Uživatelský avatar
Celeron
Příspěvky: 16140
Registrován: 02 dub 2011, 02:00
Bydliště: Nový Bydžov

#13 Příspěvek od Celeron »

Jo, to už jsem si na 328P odzkoušel, jedno bliknutí za 8 sekund a zase spát. Ale když jsem to zkusil na Tiny 85, tak podobnej problém jako s časovačema, názvy registrů WD u 328P a Tiny85 jsou jiný, musel bych do datašítů a porovnat jak se jmenují a jaký mají významy.
Ale našel jsem na netu dva příklady WD pro Tiny85 a tak se s tím snad prokoušu.
Jirka

Proč mi nemůže všechno chodit hned ?!!

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“