Začátečník arduino - pomoct s tlačítky - bazén (přesunuto)
Moderátor: Moderátoři
Na zakmity by som sa vybodol. Ked tam budes mat displej alebo niecocpodobne kym sa znova otestuju tlacidla prejde 50ms, ak nie kludne tam daj taky delay nic sa nestane obsluha to nezisti.
Navyse pre kludne pouzivanie by si mal vstupycosetrit RC clenom tak ze zakmity uz budu nepodstatne.
Kód: Vybrat vše
const int G = A0; // 3x LED
const int Y = A1;
const int B = A2;
int zelena;
int modra;
const int Tl1 = 2; // tlačítka
const int Tl2 = 3;
int ledState = LOW;
int gState = LOW;
int bState = LOW;
unsigned long previousMillis = 0;
const long interval = 500;
unsigned long times;
unsigned long prevtime = 0;
int Tl1State;
int Tl2State;
int lastTl1State = LOW;
int lastTl2State = LOW;
int out = LOW;
long lastDebounceTime = 0;
long debounceDelay = 50;
void setup() {
Serial.begin(9600);
pinMode(G,OUTPUT);
pinMode(Y,OUTPUT);
pinMode(B,OUTPUT);
pinMode(Tl1,INPUT_PULLUP);
pinMode(Tl2,INPUT_PULLUP);
}
void loop(){
buttons("zelena", "Tl1", "Tl1State", "lastTl1State", "G");
}
//buttons("zelena", "Tl1", "Tl1State", "lastTl1State", "G");
void buttons(String barva, String input, String inputState, String lastInputState, String output) {
barva = digitalRead(input);
// zelená dioda
if(barva != HIGH) {
barva = LOW;
}
if(barva != lastInputState) {
lastDebounceTime = millis();
if (inputState == HIGH) {
out = !out;
}
}
if ((millis() - lastDebounceTime) > debounceDelay) {
inputState = barva;
}
//
digitalWrite(output, out);
lastInputState = barva;
}
digitalWrite(output, out);
lastInputState = barva;
}
Snad se ten kód dá trochu pochopit...
Prostě pokud zavolám funkci
buttons("zapni", "LED");
tak se v příslušné funkci buttons(X,Y) dosadí X=zapni a Y= LED.
Čímdál víc vidím, že to nebude tak jednoduché jak se to na první pohled zdálo...
Pokud chci něco rozumného "vygooglit", tak najdu max jak blikat z ledkou nebo jak se připojovat k internetu. Jedno je pro naprosté začátečníky a to druhé pro "normální" používání k ničemu... Nechápu proč by se všechno muselo hned připojovat k internetu... No ale to už jsem zašel mimo...
Poradí někdo jak jít na ty vlastní funkce a přiřazovat ty proměnné?
Díky
EDIT: v tom kódu je definovaných víc věcí, zkouším to na jednom programu co mi funguje...
Kód: Vybrat vše
void loop(){
// zavolání funkce s parametry
funkce("zapni", "LED");
}
funkce(X, Y){
Serial.print(X); // vypíše zapni
Serial.print(Y); // vypíše LED
}
Teď už to snad bude pochopitelnější...
Pokud nic nevrací, tak je typu void.
Předávané parametry musí mít uvedený typ.
(to, myslím, platí i v php)
Kód: Vybrat vše
void setup()
{
Serial.begin(9600);
// zavolání funkce s parametry
funkce("zapni\n", "LED\n");
}
//----------------------------
void loop()
{
}
//----------------------------
void funkce(char* X, char* Y)
{
Serial.print(X); // vypíše zapni
Serial.print(Y); // vypíše LED
}Kód: Vybrat vše
const int G = A0; // LED
const int Y = A1;
const int B = A2;
int zelena, modra;
int ledState, gState, bState = LOW;
unsigned long previousMillis = 0; // čas
const long interval = 500;
unsigned long times;
unsigned long prevtime = 0;
const int Tl1 = 2; // tlačítka
const int Tl2 = 3;
int Tl1State, Tl2State;
int lastTl1State,lastTl2State = LOW;
long lastDebounceTime = 0;
long debounceDelay = 50;
void setup() {
Serial.begin(9600);
pinMode(G,OUTPUT);
pinMode(Y,OUTPUT);
pinMode(B,OUTPUT);
pinMode(Tl1,INPUT_PULLUP);
pinMode(Tl2,INPUT_PULLUP);
}
void loop() {
zelena = digitalRead(Tl1);
modra = digitalRead(Tl2);
//--------------------První tlačítko---------------
// zelená dioda
if(zelena != HIGH) {
zelena = LOW;
}
if(zelena != lastTl1State) {
lastDebounceTime = millis();
if (Tl1State == HIGH) {
gState = !gState;
}
}
if ((millis() - lastDebounceTime) > debounceDelay) {
Tl1State = zelena;
}
digitalWrite(G, gState);
lastTl1State = zelena;
//-------------------Druhé tlačítko---------------
// modrá dioda
if(modra != HIGH) {
modra = LOW;
}
if(modra != lastTl2State) {
lastDebounceTime = millis();
if (Tl2State == HIGH) {
bState = !bState;
}
}
if ((millis() - lastDebounceTime) > debounceDelay) {
Tl2State = modra;
}
digitalWrite(B, bState);
lastTl2State = modra;
if(bState == HIGH) {
HlavniProg();
}
}
// program co se spustí po zapnutí druhého tlačítka (blikající dioda)...
void HlavniProg() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(Y, ledState);
}
}1) snimat klavesnicu
2) blikat s ledkou
takze snimanie klavesnice je periodicky dej, ktory chces vykonavat v pravidelnych intervaloch, blikanie ledky je napodobne velmi jednoducha cinnost, staci aby v spravny okamih procesor zdvihol stav na drote a potom ho zas zhodil.. zvysok casu procak nema co robit...V zasade CPU vacsinu casu otaca hlavnou sluckou a periodicky si odskoci do prerusenia, kde sa pozrie na stav tlacidiel a napise to (ak je stlacene alebo pustene) do nejakych premennych. Tieto premenne su potom kontrolovane hlavnou sluckou a vykonaju akciu...Periodicke prerusenie je dobry sposob ako robit nieco v presne stanovenych casovych okamzikoch. Priklad chcem blikas s LEDkou tak ze pol sekundy bude zasvietena a pol sekundy bude zhasnuta..
Urobis jednu globalnu premennu typu integer - pocitadlo preruseni. Ked ti prerusenie chodi kazdych 50ms, tak musis naratat do 10 aby presla pol sekunda, vtedy zmenis stav ledky na opacny
stavy celeho automatu si znacim bitovo a potom ich aj bitovo testujem.
(zopar globalnych bytov) Mozes si to pisat aj do bytov to ti zozere troska viac ramky.. NEPOUZIVAT ZIADNE FUNKCIE DELAY. Snimanie klavesnice som popisal skor (pripadne si to precitaj este raz, a pogoogli, porozmyslaj ako som to myslel)
priklad: uzivatel stlaci tlacidlo 1) a chcem aby sa o pol sekundy nieco stalo.
uint_8 status = 0; //inicializaciu toho treba dat do init
uint_8 timer_counter;
#define POL_SEC_FLAG 0b00000001
//toto spravis v hlavnej slucke ako reakciu na tlacidlo 1
//je to signal preruseniu, ze ma zacat ratat do 10 povedzme
timer_counter = 10;
status |= POL_SEC_FLAG;
//v preruseni bude napisane:
if (status & POL_SEC_FLAG){
if (timer_counter >0){
timer_counter--;
}else{
//ZASVIET LEDKU
status = &~POL_SEC_FLAG; //akcia bola spravena, zhodime vlajocku
}
}
}
Počítám, že bude ještě dlouho trvat, než ti zpoždění bude vadit.
Teď v začátcích by ti to jenom komplikovalo život.
Nenazývej svoji vlastní funkci Hlavní().
Za hlavní funkci se tady považuje smyčka loop().
Podívej se na příklad níže.
(po stisku tlačítka Led bliká, po dalším zhasne, atd.)
Kód: Vybrat vše
#define Yellow_led 13
#define TL2 12
unsigned long currentMillis, previousMillis;
unsigned int interval=500;
boolean TL2_state;
//-------------------------------
void setup()
{
pinMode(Yellow_led,OUTPUT);
pinMode(TL2,INPUT_PULLUP);
}
//-------------------------------
void loop()
{
currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
blink(); //call blink() every 500 ms
previousMillis = currentMillis;
}
if ((digitalRead(TL2) == 0)) //if button pressed
{
delay(50); //debounce
TL2_state = !TL2_state; //toggle the state
while((digitalRead(TL2) == 0)); //wait for button released
delay(50); //debounce
}
}
//----------------------------
void blink()
{
if(TL2_state == 1)
digitalWrite(Yellow_led,(!digitalRead(Yellow_led)) ); //toggle Led
else
digitalWrite(Yellow_led, LOW);
}
Co se týká "hlavní" funkce, tak je to jen začátek celého projektu. Pak to bude pojmenované přímo funkcí, kterou to bude dělat (pokud se mi to teda podaří)...
Ve výsledku tam blikat nic nebude. Mám to jen na zkoušku. V podstatě by to jedno tlačítko mělo sepnout dva výstupy. Jeden by měl být sepnutý cca 60 minut a druhý jen 40 sekund.
Jinak jsem se díval i na to přerušení, což by asi (určitě) bylo nejlepší řešení, protože pokud bude nějaká "externí" akce (tlačítka), tak by se měl hlavní program (časové spínání relé a hlídání teploty) přerušit a běžet program co je pod tím tlačítkem...
1/ každé tlačítko má svůj pin - fungovat bude bez problému
2/ všechny tlačítka jsou na "jednom" drátu - dají se nějak adresovat?
To druhé bude asi blbost co?
- Přílohy
-
Screenshot_20171210_092601.png- (9.97 KiB) Staženo 191 x
http://www.ct2.wz.cz/Studium/schmitt.htm
Ak mas vela tlacidiel a malo drotov pouziva sa matica, zopar drotov z CPU vysiela a zopar prijima a su prekrizene do matice, kod daneho tlacidla je potom kombinaciu vysielacich a prijimanych drotikov. Ale to ti netreba.
Edit: pozeram lepsie na tvoje zapojenie, ha zvyknem tlacidla nejakym pull up odporom opriet o 5v, aby si procakom v pripade nezatlacenia nemal len tak drotik v lufte (zbyknu byt v cpu pull upy) ale na mojom poslednom projekte s tym bol problem, kazdopadne 5k6 oproti log "1" neuskodi..
Kód: Vybrat vše
pinMode(pin,INPUT_PULLUP);