Close

Zbyšek Voda

Vytvořené odpovědi

Aktuálně je na stránce zobrazeno 15 příspěvků - 76. až 90. (celkem z 203)
  • Autor
    Příspěvky
  • odpověď na: Přerušení #8231
    Zbyšek Voda
    Správce

    Problém bude v nesprávné interpretaci „přerušení“ 🙂
    K přerušení dojde, když program v reakci na nějakou událost „odskočí“ na chvilku ze standardního běhu a rychle se provede něco jiného. Přerušení může být vyvolané například vnitřním časovačem, nebo také změnou napětí na pinu – to vás asi zmátlo. Obsloužení přerušení probíhá tak, že pomocí funkce attachInterrupt() řeknete, co se má stát v reakci na jakou událost. Více o přerušeních na https://www.arduino.cc/en/Reference/AttachInterrupt a https://www.arduino.cc/en/Reference/Interrupts.

    Vy ale vlastně ani přerušení nepotřebujete. Problém v programu je ten, že pokud použijete funkci delay(), dojde k čekání programu po určitou dobu. V té době program nereaguje na koncové spínače, ani neobsluhuje posun motorů.

    Navrhuji místo tohoto „pasivního“ čekání použít funkci millis(), která vrací dobu v milisekundách od začátku běhu programu. Tento problém je popsaný v https://bastlirna.hwkitchen.cz/arduino-zaklady-blikani-bez-funkce-delay/.

    Jestli to dobře chápu, používáte delay kvůli tomu, že ventil musí určitou dobu běžet, než je zasunutý/vysunutý. Pokud ale stačí pro každý ventil mít jenom dva stavy – vysunutý/zasunutý a nepotřebujete nic mezi, to čekání vlastně vůbec nepotřebujete.
    Stačí vytvořit podmínku ve stylu: pokud je koncový vypínač 1 rozepnutý, nech ventil zapnutý, jakmile se k. vypínač sepne, vypni ventil. Chápeme se? 🙂

    odpověď na: Přerušení #8207
    Zbyšek Voda
    Správce

    Dobrý den, můžete sem prosím nasdílet váš program? Děkuji

    odpověď na: Co se děje v paměti? #8193
    Zbyšek Voda
    Správce

    Kdybyste pole naplnil pomocí cyklu, místo memset, jak to dopadne?

    odpověď na: Arduino – problém s nastavením pinu v kódu #7955
    Zbyšek Voda
    Správce

    Dobrý den,
    kód je naprosto v pořádku. Asi bych zkusil buďto přeinstalovat prostředí a když ani to nepomůže, tak vyzkoušet nějakou starší verzi 🙂

    odpověď na: nahodný výstup z Nextion display #7934
    Zbyšek Voda
    Správce

    Dobrý den, napadá mě, že by problém mohl být v porovnání:
    heslo !=""
    Jazyk C++ má totiž řetězce implementované jako objekty – vy používáte objekt String. A u nich je potíž, že nejdou jednoduše porovnávat jako primitivní datové typy. Dojde totiž k porovnání jejich refenrencí a ne jejich hodnot (aspoň myslím).

    Takže u

    String s1 = "A";
    String s2 = "A";

    myslím neplatí rovnost s1 == s2.

    Vy tedy porovnáváte objekt heslo, který je typu String s prázdným řetězcem „“. Dojde k porovnání referencí (něco jako adresa v paměti). Ty dva se ve vašem případě nikdy rovnat nebudou, tedy bude podmínka heslo !="" vždy true.

    K porovnávání hodnot řetězců se používá metody equals – viz https://www.arduino.cc/en/Reference/StringEquals

    Tento problém s porovnáváním řetězců tam pak máte několikrát.

    Snad to pojede 🙂

    odpověď na: nahodný výstup z Nextion display #7925
    Zbyšek Voda
    Správce

    Dobrý den,
    máte dobře nastavenou rychlost komunikace v sériovém monitoru?
    Kdyžtak sem prosím nasdílejte kód a zkusíme to nějak pořešit.

    odpověď na: Barevná hudba #7859
    Zbyšek Voda
    Správce

    Dobrý den,
    asi nejjednodušší je pomocí mikrofonu zjišťovat hlasitost přehrávané hudby a podle toho blikat – odkáži vás například sem. Čtení „hlasitosti“ probíhá na na analogových pinech.

    Nebo můžete analyzovat frekvence, které vaše přehrávaná hudba obsahuje a podle toho blikat ledkami apod. To můžete udělat například pomocí nějaké knihovny implementující FFT. Zkuste se podívat na google, určitě něco najdete 🙂

    odpověď na: I2C displej + I2C BMP180 #7576
    Zbyšek Voda
    Správce

    Už jsem to jednou k vašemu příspěvku psal Aleši, ale napíšu to znovu.
    Logické úrovně 5V a 3.3V (a další) není dobré míchat dohromady. Některé piny mohou být tolerantní, ale může se také stát, že najednou zapojení přestane fungovat, protože to daný pin už prostě nevydrží a dá docela práci odhalit, že nějaký pin odešel.
    Takže ano, zapojení většinou funguje, ale není to dobrá praktika…

    Zbyšek Voda
    Správce

    Dobrý den,
    moc nerozumím vašemu popisu.
    Jestli chcete odeslat „X100“, za kterým následuje nový řádek, tak stačí napsat:
    Serial.println("X100");
    Když to dáte dohromady s tím tlačítkem, v nejjednodušším případě vypadá kód takto:

    if (digitalRead(11) == LOW){
        Serial.println("X100");
    }
    Zbyšek Voda
    Správce

    Dobrý den, tento problém je trochu zapeklitý.

    Hlavní příčinou problému je to, že funkce, kterou připojujete pomocí attachInterrupt() nesmí mít žádný parametr. Vaše funkce void mmT25::_irqHandler(); sice viditelně žádný parametr nemá, ale jelikož je metodou objektu, je jí automaticky předávám parametr, který je instancí objektu, ke kterému náleží.

    Odtud pochází také error, který při kompilaci váš kód hlásí:
    cannot convert ‚mmT25::_irqHandler‘ from type ‚void (mmT25::)()‘ to type ‚void (*)()‘
    neboli nemůžu překonvertovat funkci, která má jeden parametr – instanci objektu mmT25 – na funkci, která nemá žádný parametr.

    Přiznám se, že neznám řešení vašeho problému, ale na tomto fóru: https://forum.arduino.cc/index.php?topic=41713.0 problém řeší a zjevně i úspěšně 🙂

    odpověď na: Jak na název s automatickým posunem jména #7407
    Zbyšek Voda
    Správce

    To vytvoření pole přes
    Bounce bouncer[5];

    jsem také zkoušel, ale nějak to kompilátor nebral. Přitom by to takto mělo C++ podporovat.
    Proto jsem šel tou cestou přes malloc().

    odpověď na: Jak na název s automatickým posunem jména #7390
    Zbyšek Voda
    Správce

    Dobrý den, pošlu vám celý kód určený pro LEDky ze článku.

    class LED{
        private: 
            int pin;
            boolean stav = LOW; //výchozí stav LED je vypnuto
            void nastav(boolean);
    
        public: 
            LED(int);
            void zapni();
            void vypni();
            void prepni();
            boolean vratStav();
    };
    
    LED::LED(int p){
        pin = p;
        pinMode(pin, OUTPUT);
        digitalWrite(pin, stav);
    }
    
    void LED::zapni(){
        nastav(HIGH);
    }
    
    void LED::vypni(){
        nastav(LOW);    
    }
    
    void LED::prepni(){
        nastav(!stav); //nastaví LED na obrácenou hodnotu (0->1, 1->0)
    }
    
    void LED::nastav(boolean s){
        stav = s;
        Serial.print("Nastavuji ");
        Serial.print(stav);
        Serial.print(" na pinu ");
        Serial.println(pin);
        digitalWrite(pin, stav);
    }
    
    boolean LED::vratStav(){
        return stav;     
    }
    
    #define NO_OBJECTS 6
    
    LED *LEDS = (LED*)malloc(NO_OBJECTS * sizeof(LED));
    
    void setup() {
        Serial.begin(9600);
        
        for(int i = 0; i < NO_OBJECTS; i++){
            LEDS[i] = LED(i);
        }
       
        for(int i = 0; i <= 10; i++){
            LEDS[2].prepni();
            delay(500);    
        }
    }
    
    void loop() {
    }

    Důležité části jsou:

    #define NO_OBJECTS 6
    Řekne programu, že bude celkem 6 LEDEK/TLAČÍTEK…

    LED *LEDS = (LED*)malloc(NO_OBJECTS * sizeof(LED));
    Vytvoří se ukazatel na datový typ LED. Funkce malloc alokuje v paměti prostor pro budoucí pole – potřebuje vědět, jak bude velké. Proto se jí jako parametr předá velikost jednoho objektu LED (sizeof) ponásobená počtem objektů v poli. Funkce malloc vrací datový typ void*, takže je potřeba ho ještě před uložením do LEDS přetypovat na LED*. Dále už se dá s LEDS pracovat jako s normálním polem.

    Nevím, jestli je toto nejjednodušší cesta, ale nenapadla mě jednodušší.

        for(int i = 0; i < NO_OBJECTS; i++){
            LEDS[i] = LED(i);
        }

    Do pole LEDS poukládá objekty LED na daných pinech.

       for(int i = 0; i <= 10; i++){
            LEDS[2].prepni();
            delay(500);    
        }

    Postupně bliká ledkami.

    Snad to je pochopitelné. Kód by měl jednoduše jít předělat pro vaše potřeby. Pole by mohlo vypadat takto:

    RBD::Button *pole = (RBD::Button*)malloc(NO_OBJECTS * sizeof(RBD::Button));

    Jeho naplnění potom:

    for(...){
        pole[i] = RBD::Button(i);
    }
    odpověď na: impuls #7231
    Zbyšek Voda
    Správce

    Tak si to musíte nějak podmínit. Když to je přímo v loopu, tak ten se spouští pořád dokola. Potom se „impulz“ vysílá pořád dokola.

    Nevím, jak přesně to má fungovat. Ale třeba na stisknutí tlačítka může reagovat takto (zjednodušeno).

    void setup(){
        pinMode(2, INPUT);
        pinMode(3, OUTPUT);
    }
    void loop(){
        if(digitalRead(2) == HIGH){
            digitalWrite(3, HIGH);
            delay(500);
            digitalWrite(3, LOW);
            delay(1000);
        }
    }
    odpověď na: impuls #7222
    Zbyšek Voda
    Správce

    Dobrý den. Krátký impulz uděláte tak, že na výstup „nastavíte“ HIGH a po malé chvilce zase LOW.

    Takže třeba

    digitalWrite(pin, HIGH);
    delay(500);
    digitalWrite(pin, LOW);

    Nastaví na půl sekundy výstup do logické 1.

    odpověď na: Arduino UNO a WiFi Shield #7198
    Zbyšek Voda
    Správce

    Dobrý den, jestli se nepletu, tak knihovna WiFi.h je určena pro oficiální WiFi shield.

    ESP je možné ovládat pomocí AT příkazů, které budete posílat přes sériovou linku, např:

    Serial.println("AT");

Aktuálně je na stránce zobrazeno 15 příspěvků - 76. až 90. (celkem z 203)