
Arduino timer
Zdravím.
Zkouším timer a asi jsem nepochopil princip
#include "Timer.h"
Timer t;
int pin = 2;
int pin1 = 13;
void setup()
{
Serial.begin(9600);
pinMode(pin1,INPUT_PULLUP);
pinMode(pin,INPUT_PULLUP);
pinMode(pin, OUTPUT);
}
void loop()
{
if (digitalRead(pin1)== LOW){
t.pulse(pin, 10 * 10 * 1000, LOW);
Serial.println("hups");
}
t.update();
Serial.println("ja si dělam co chci");
}
Co je špatně?
No takto to take nefunguje.
Takto ho vytvořím timer t.pulse(pin, 10 * 10 * 1000, LOW);
Takto ho spustim t.update();
Na tom pinu 13 není furt LOW, jen dostane impulz.
Asi nechapu princip tohoto timeru
void loop()
{
if (digitalRead(pin1)== LOW){
t.pulse(pin, 10 * 10 * 1000, LOW);
t.update();
Serial.println("hups");
}
}
t.update musi byt mimo if
Neviem co na tom nechapes, je to uplne jednoduche. t.pulse inicializuje timer a hned sa vrati, a t.update musi byt volane periodicky (z loop() bez nejakych if)
t.pulse nesmie byt volane periodicky.
Ked to urobis presne jak som pisal, tak to urcite bude fungovat.
A hlavne t.pulse(pin, 10 * 10 * 1000, LOW); nesmie byť volané dookola v loop-e - inicializuje donekonečna 100 sekúnd, ktoré nikdy vlastne neskončia...
Ved som mu to uz pisal vyssie tucne aj s prikladom :) Neviem ci pisem bielou farbou alebo co
Teda netuším, čo presne potrebuje, ale ak sa má timer spustiť len pri určitej podmienke, potom volať t.update až pri splnení tej podmienky...
A nastavujes si tam 100 sekund, tak si to preber ci chces 100sekund (10*10*1000ms)
No a co na tom nejde?
Ked pride pulz na pin 13, tak to urobi na pine2 LOW na 100sekund (1minuta 40sekund) a potom high. Co robi inac?
A v inicializacii si musis dat
boolean uzsomtoinicializoval = 0;
aby si nepouzival neinicializovane premenne.
A mas tam blbo zatvorku, mas v tom uplny gulas.
Spravne (pridal som tam aj dalsie nech to je uplne jasne):
boolean uzsomtoinicializoval = 0;
Zapnu arduino, zmačknu tlačítko, relé se sepne.
A je furt seple.
To mi děla od začatku.
Mam to tak jak jste to tu dal Vý.
Rele furt seple.
Čakáš 100 sekúnd? Ani potom nič?
čekam už 20 minut a rele furt seple.
Tak si ten kod mozno nenahral do arduina alebo nieco tam mas asi blbo.
Ten pin 13 je urcite uz na high?
Skus este to
uzsomtoinicializoval = 1;
zmenit na
uzsomtoinicializoval = TRUE;
a = 0 na =FALSE, ked to je boolean, preistotu. Ale to by na to nemalo mat vplyv.
Skopiruj ten posledny kod co som sem daval, nech mas nabeton zatvorky tak jak treba.
A zniz si to na 10sekund (10*1000), nech na to nemusis cakat minuty
Pre istotu to skúšaj napr. s LED-kou, že ako sa bude tváriť...
a toto máš prečo?
pinMode(pin,INPUT_PULLUP); <----- toto hádam vyhoď
pinMode(pin, OUTPUT); <----- potrebuješ iba tento riadok - výstup !!!
pripadne zniz si ten cas na povedzme len 100milisekund
t.pulse(pin, 100, LOW);
ze jak dlho to bude trvat to zopnutie, je mozne ze mas nejak inac clock mikroprocesora ako predpoklada ten program a nesedia casy.
Alebo aj uplne vyhod to
else
uzsomtoinizializoval = 0
aby sa ten timer nabeton inicializoval len raz, aj keby pin 13 kmital apod. Potom to tiez nefunguje?
Jsou tam připojené ty činské rele moduly které spinaji při 0
Když přepnu piny na výstup, okamžitě se rele sepnou.
Proto ty NPUT_PULLUP.
Problem bude tady t.pulse(pin, 10 * 10 * 1000, LOW);
Ono to funguje jen s HIGH t.pulse(pin,10000, HIGH);
A stejnak je to na houby.
Ono se to sepme, po chvilce rozepne a po par vteřínach sepne a seple to zustane.
Ja potřebují timer nebo hread do ktereho strčím
Takže s LED-kou ten kód tiež nefunguje?
Toto s rele funguje?
Tiež mám doma "čínske relé", ja ho najprv inicializujem:
pinMode(Relay1, OUTPUT);
digitalWrite(Relay1, HIGH);
a až následne ho spínam:
digitalWrite(Relay1, LOW); zapne
delay(2000);
digitalWrite(Relay1, HIGH); vypne
pochopiteľne je potrebné vedieť čo je to za relé a ako funguje - pri akom zapojení...
Ano ale když arduino nadjíždí, relé procvaknou.
Vždy se na pinech na par vteřín zobrazí L
Tak nastavuj priamo registre uC a precitaj si datasheet, a nepouzivaj dementne funckie pre BFU a pre deti, ked to chces mat profesionalne.
Ono bud si to vsetk nastudujes do detailu a venujes tomu XY dni-tyzdnov-rokov (zavisi na urovni aktualnych znalosti), alebo budes len lepit veci pre deti.
tam mozes nechat, ak to sposobi ze pre prepnuti na output to rele nepreklepne, je to vporiadku (suvisi to prave s tymi registrami uC a bitmi v nich, ktore si si mal uz davno nastudovat).
To neni tvoj problem. Tvoj problem je ze tam mas najskor nahraty blby program, alebo mas nieco blbo zapojene. Ten program ktory som tu dal nemoze robit to co pises.
Uz si uplne vyhodil to
a skusil si to uz bez toho? Ak ano tak viem kde je problem (bouncing).
P.S> a nastuduj si ze co to je stavovy automat, aby si chapal jak sa programuje automat. Stav bude nejaka premenna.
Skus este do toho setup() pridat to tucne:
pinMode(pin,INPUT_PULLUP);
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
nejaka zmena?
http://www.ebay.com/sch/i.html?_from=R40&_trksid=p 2050601.m570.l1313.TR0.TRC0.H0.X8+relay.TRS0&_nkw= 8+relay&_sacat=0
Ty modre.
S telatky jsem už vyzkoušel vše
Ono to funguje takto spolehlivě.
pinMode(pin,INPUT_PULLUP);
pinMode(pin, OUTPUT);
Relatka při najíždění arduina aní necvaknou.
Já řeším problém, jak sepnout rele třeba na 10 minut, tak aby arduino vykonávalo další přikazy.
Princip tohohle timeru jsem nepochopil, no škoda
Ja myslel že timer v arduinu funguje stejně jako v delphi
Timer1.Interval : = 300; nastavím čas
timer1.Enabled:=true; a spustím si ho.
a klidně si ho v procedure TForm1.Timer po prvním pruchodu mužu zastavit.
timer1.Enabled:=false
No asi ne.
Ale koukám na ArduinoThread co by mnělo muj problem vyřešít.
To vlakna dam
digitalWrite(2, LOW);
delay(1000);
digitalWrite(2, HIGH);
A pak v te podminfe to vlakno spustím
if(myThread.shouldRun())
myThread.run();
Jezisikriste skus co som pisal, alebo to zabal a daj to robit niekomu inemu. Ja to nepisem zo srandy ale preto ze napr. dementna funkcia v nejakej kniznici moze mat problem ak predtym nezavolas outpu high, apod., alebo ak sa zavola 2x, apod, zavisi od dementnej funkcie.
(a mas tam nieco zasadne blbo, a zatial len tapes v tme a hladas problem niekde inde ako skutocne je, a ani nerobis nic pre to aby si problem nasiel - debugging, mas tam debug vystupy, tie vyisuju co? atd)
Napr. kvoli bouncingu spinaca sa ti moze ta fcia zavolat viackrat, a ked potom viackrat invertuje vystup, potom by si mal efekt jak popisujes. Apod. Ked to enchces urobit poriadne tak to nerob vobec, ptz to potom nebude fungovat nikdy ptz nemas znalosti urobit to okamzite spravne - ked tam mas mechanicky spinac tak je potrebne toho hodne viac jak len jedno if a jedna funkcia.
Ked chces thready tak si pouzi thready, ale msuis potom pre mechnicky vstup urobit debouncing (aspon delay 10ms pred dalsim testom) inac sa vytvori tych threadov trebars milion, a dojde ti pamat a nepojde to zas nikdy sprvane.
Skus toto (copypastni to cele tak jak je), je tam zabranene aby sa zavolal timer znova (kvoli bouncingu tlacitka) ked timer uz bezi.
to funguje jak?
Da sa to urobit blbovzdorne X roznymi sposobmi, da sa urobit debouncing len pomocou delay(10) a nechat povodny kod, da sa to urobit komplikovany debouncing s ratatnim alebo dalsim timerom ak je prechod cez loop casovo kriticky, atd.
Alebo ked pouzijes tie tvoje thready, tak musis urobit debouncing tlacitka. V tomto co som pisal to neni nutne ptz je to fuk, pocas celeho pulzu som v stav = 1 (a pisal si ze vstupny pulz je kratsi jak vystupny).
A to t.pulse nefunguje mozno aj preto lebo pretazujes vystup, a ta funkcia po uplynuti doby invertuje vystup, a zrejme tak ze si precita stav na vystupe a invertuje ho. Ked ale vystup pretazis ze pri hodnote HIGH cita z neho napatie LOW, tak ten vystup po uplynuti doby ta funkcia "invertuje" na nespravnu hodnotu. Nechce sa mi teraz citat zdrojaky tych fcii ale tipujem ze to robi tak. Zdrojak ktory som dal teraz tu do predch.odpovede nema tento problem.
Ked nieco robis tak to musis chapat, inac nebudes schopny nikdy garantovat ze to na 100% pojde vzdy spravne.
Tak to poslední funguje jak má
už se mi to podařilo udělat i pomocí threadu
if(myThread.shouldRun())
myThread.run();
Tak pouzivaj radsej to posledni, je to asi bezpecnejsie.
Ked spustas thread mechanickym tlacitkom, tak musis aspon urobit delay(10) na debouncing. A samozrejme ze musis aj pamata stav, aby si ten thread nevytvoril 1000x (co sice nemusis vidiet hned, ale za urcitych okolnosti to potom moze uplne rohdoit cely system) T.j. napr.
if(digitalRead(pin) == HIGH && stav == 0)
{
spust thread
stav = 1;
delay(10); // debouncing
}
if(digitalRead(pin) == LOW && stav == 1)
{
stav = 0;
delay(10); // debouncing
}
Nevyhoda takehoto jednoducheho debouncingu je to ze to zastavi cele arduino na 10ms, ale je to takto najjednoduchsie.
Ked na to nemyslis a mas tam napr. debug vystup tak ten urobi opozdenie kludne aj 10ms a myslis si ze vsetko je super aj bez debouncingu a raz vyhodis ten debug vystup a zistis ze zrazu to blbne :)
JJ, děkují