Diskuze: Arduino - časovane sepnuti pinu
Člen
Zobrazeno 11 zpráv z 11.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
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.