Diskuze: Arduino - časovane sepnuti pinu

Člen

Zobrazeno 11 zpráv z 11.
K personalizaci obsahu a reklam, poskytování funkcí sociálních médií a analýze naší návštěvnosti využíváme soubory cookie. Informace o tom, jak náš web používáte, sdílíme se svými partnery pro sociální média, inzerci a analýzy. Partneři tyto údaje mohou zkombinovat s dalšími informacemi, které jste jim poskytli nebo které získali v důsledku toho, že používáte jejich služby.
Používáme nezbytné cookies pro fungování webu a s tvým souhlasem také analytické a marketingové cookies.
Zajišťují základní funkce, bezpečnost a služby, které sis vyžádal. Nelze je vypnout.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| ITnetwork | ITnetwork | Provoz webu, relace, přihlášení a uložení nastavení cookies. | PHPSESSID, auth_token, sid, itn_consent_impression, __Host-itn_consent | Relace až 1 rok |
| Google Tag Manager | Správa značek a načítání měřicích nástrojů webu. | Žádné | Neukládá se | |
| Google Fonts | Načítání typografie webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google Hosted Libraries | Načítání potřebných knihoven a stylů webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google reCAPTCHA | Ochrana formulářů a webu před zneužitím. | _GRECAPTCHA, rc::a, rc::b, rc::c, rc::f | Relace až 180 dní | |
| YouTube | Přehrávání vloženého video obsahu. | localStorage, IndexedDB; cookies after playback interaction | Relace až trvalé úložiště | |
| Vimeo | Vimeo | Přehrávání vloženého video obsahu. | __cf_bm, _cfuvid, vuid, localStorage, IndexedDB | Relace až 2 roky |
| Facebook Login | Meta | Přihlášení pomocí účtu třetí strany. | Úložiště řízené poskytovatelem | Relace až 1 rok |
| GoPay | GoPay | Zpracování uživatelem vyžádané platby. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
Pomáhají nám porozumět používání webu a zlepšovat ho.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Analytics 4 | Měření návštěvnosti a používání webu. | _ga, _ga_* | Až 2 roky | |
| Microsoft Clarity | Microsoft | Měření návštěvnosti a používání webu. | _clck, _clsk, _cltk | Relace až 1 rok |
Slouží k měření kampaní, personalizaci reklamy a marketingové komunikaci.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Ads | Měření kampaní, reklama a remarketing. | _gcl_au, _gcl_ls | Relace až 90 dní | |
| Meta Pixel | Meta | Měření kampaní, reklama a remarketing. | _fbp, _fbc, localStorage | Až 90 dní |
| Sklik | Seznam.cz | Měření kampaní, reklama a remarketing. | retargeting, sid, szn:* | Relace až trvalé úložiště |
| LinkedIn Insight | Měření kampaní, reklama a remarketing. | bcookie, li_gc, lidc, __cf_bm | Relace až 1 rok | |
| Ecomail | Ecomail.cz | Měření kampaní, reklama a remarketing. | ecmid, Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
| Atribuce kampaní ITnetwork | ITnetwork | Přiřazení návštěvy a objednávky ke kampani. | campaign_clid[*], user_session_context | Až 1 rok |


Stoprocentně přes timer
při první aktivaci si nastav nějaký příznak a ten shoď po uplynutí času - při každém dalším přerušení pak ten příznak zkontroluj a podle něj buď nastav čas a nebo ne
stačí takhle - zvládneš to?
Jsem to zkoušel přes millis a rele si děla co chce.
Co jsem po ?
unsigned long aktualnicas;
unsigned long Time;
void setup() {
Serial.begin(9600);
digitalWrite(13, HIGH);
pinMode(13, OUTPUT);
aktualnicas = millis();
pinMode(2, INPUT);
attachInterrupt(0, detekce, RISING);
}
void loop() {
if(aktualnicas >= (Time + 60000)){
digitalWrite(13, HIGH);
Time = aktualnicas;
}
}
void detekce() {
Serial.println("Zaznamenana detekce pohybu");
digitalWrite(13, LOW);
aktualnicas = millis();
}
Jsi si jistý,k že uvádíš správnou hodnotu prvního parametru funkce attachInterrupt? Také s k ní přčti dokumentaci - https://www.arduino.cc/…achInterrupt. Nezdá se mi, že by bylo vhodné v ní provádět synchronní sériovou komunikaci. Odhadoval bych, že ta funkce detekce je volána v rámci přerušení, takže by měla proběhnout co nejrychleji. A sériová komunikace je pomalá, v závislosti na baudrate může trvat klidně pěkných pár milisekund.
. A sériová komunikace je pomalá, v závislosti na baudrate může trvat klidně pěkných pár milisekund.
"Slušně vychované" (rozuměj dobře napasné) funkce pracující s periferiemi mcu - jako třeba zde arduinovské print/println s USARTem nijak nezdržují program.
ve skutečnosti to funguje tak, že zpráva se uloží do bufferu a pak se
nezávisle na programu po jendotlivých bajtech odešle.
Využívá se k tomu přerušení od UDRE (USART data register empty)
void HardwareSerial::_tx_udr_empty_irq(void)
{
// If interrupts are enabled, there must be more data in the output
// buffer. Send the next byte
unsigned char c = _tx_buffer[_tx_buffer_tail];
_tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;
*_udr = c;
// clear the TXC bit -- "can be cleared by writing a one to its bit
// location". This makes sure flush() won't return until the bytes
// actually got written
sbi(*_ucsra, TXC0);
if (_tx_buffer_head == _tx_buffer_tail) {
// Buffer empty, so disable interrupts
cbi(*_ucsrb, UDRIE0);
}
}
Nejdřív jsem chtěl napsat, co všechno je ve tvém kódu špatně , ale
pak jsem se rozhodl, že ti radši ukážu, jak to má vypadat správně.
Příklad využívá ten Timer, co jsem ti doporučil, ale tys radši zvolil
špatné řešení s millis()
knihovnu si stáhni tady
komentáře snad dostatečně vysvětlují, jak se to chová - všimni si taky, že v hlavní smyčce loop() není žádný kód , takže vše funguje "na pozadí" mimo hlavní program
#include <TimerOne.h>
#define PIR 2// pohybove cidlo
#define OUT 13//spinany vystup
unsigned long t1_tick = 1000000;//preruseni kazdych 1000000 us (1 sec)
int nastaveny_cas;//cas sepnuti vystupu po aktivaci z cidla
void setup()
{
//inicializace timeru a periody, zaroven timer spusti
Timer1.initialize(t1_tick);
//jeste ho nepotrebujem, tak ho vypnem
Timer1.stop();
//prirazeni funkce,ktera se ma vykonat
Timer1.attachInterrupt(Counter);
Serial.begin(9600);
pinMode(PIR, INPUT);
pinMode(OUT, OUTPUT);
//prirazeni vstupu a funkce,ktera se ma vykonat
attachInterrupt(digitalPinToInterrupt(PIR), detekce, HIGH);
}
void loop()
{
/* add main program code here */
}
//funkce vykonavana v preruseni od EXT INT
//nastavi cas na 60 sekund
//spusti Timer1
//nastavi pozadovanou hodnotu na vystup
void detekce()
{
Serial.println("Zaznamenana detekce pohybu");
nastaveny_cas = 60;
Timer1.start();
digitalWrite(OUT, LOW);
}
//funkce vykonavana v preruseni od Timer1
//kazdou sekundu odecte z nastavene hodnoty 1
//po uplynuti doby zastavi timer
void Counter()
{
if (--nastaveny_cas == 0)
{
digitalWrite(OUT, HIGH);
Timer1.stop();
}
}
pokud bys chtěl naopak vstup během probíhajícího času blokovat - stačí jednoduchá úprava ve funci detekce()
void detekce()
{
if (nastaveny_cas != 0)return;// pokud bezi cas odejdi
Serial.println("Zaznamenana detekce pohybu");
nastaveny_cas = 6;
Timer1.start();
digitalWrite(OUT, LOW);
}
Jestli je to takto asynchronně, tak pohoda. Jen jsem viděl dost USART knihoven pro MCU, která byly právě napsány dosti primitivně (synchronně). Podonbě I2C.
Arduinovské (oficiální, nebo jimi doporučené) knihovny jsou v tomto ohledu kvalitní
Zobrazeno 11 zpráv z 11.