Program Arduino nano

3mgo
Příspěvky: 6
Registrován: 08 bře 2022, 18:16
Reputation: 0

Program Arduino nano

Příspěvek od 3mgo » 08 bře 2022, 18:27

Zdravím, jsem začátečník, a snažím se o program který by počítal impulzy na vstupu, a při každých 180 impulzech se poslala vysoká úroneň na výstup. Koupil jsem si totiž encoder který má 360 impulzu na otáčku, což je pro mě moc. Rozhodl jsem se to tak vyřešit cestou arduina, a impulzy zregulovat. Něco jsem napsal ale bohužel mi to z nějákého důvodu nejede.

Kód: Vybrat vše

int cnt;

void setup() {
 pinMode(2, INPUT_PULLUP);
 pinMode(12, OUTPUT);
 Serial.begin(9600);
 cnt=0;
}

void loop() {
    pocitej_impulzy;  //pocita impulzy, kdyz je vstup 2 aktivni (je v LOW) pricte se k promene cnt 1
    posilej_impulzy;  //kdyz je promena cnt delitelna 180(x2 impulzy encoderu na jednu otacku), a zbytek deleni je 0, posle se impulz 500ms na pin 12
}

void pocitej_impulzy (void) {
  if(digitalRead(2) == LOW) {
    cnt+1;
  }
}

void posilej_impulzy (void) {
  if(cnt % 180 == 0) {
    digitalWrite(12, HIGH);
    delay(500);
    digitalWrite(12, LOW);
  }
}


KamilV
Příspěvky: 479
Registrován: 03 dub 2018, 15:27
Reputation: 0
Bydliště: Olomouc

Re: Program Arduino nano

Příspěvek od KamilV » 08 bře 2022, 18:58

Co se stane, když natočíš enkoder tak, že na pinu 2 bude delší dobu beze změny LOW stav?
Loop se vykoná opravdu hodněkrát za vteřinu a každý průchod navýší cnt.
Resp. navýšil by, kdyby tam bylo cnt = cnt+1, nebo cnt += 1 nebo cnt++;
Tak jak je to teď se nikdy cnt nenavýší.

Nepočítej tedy průchody loopem, patrně chceš počítat jen tehdy, když se změní stav s HIGH na LOW. Pozor na zákmity, které musíš deboucnout.

To, že se během "posílej_impulzy" další impulzy nepočítají je záměr nebo nechtěný fakt?
A nemělo by se cnt po odeslání vynulovat?

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Program Arduino nano

Příspěvek od martinius96 » 08 bře 2022, 19:12

Ahoj, aký je to enkóder (typ, označenie)?

Z tvojho programu to chápem tak, že tvoj enkóder má iba jeden výstup.
Ten výstup máš pripojený k Arduinu a na tom očakávaš stav LOW pri prechode cez krok, alebo na kroku?
Potom by ti to rátalo +1 do nekonečna, nemáš tam ani nejaké časové rozlíšenie pre počítanie dvoch po sebe idúcich pulzov, či debouncing proti zákmitom ako takým.
Počas stavu medzi krokmi je úroveň na GPIO HIGH?
Skús si vypísať v na UART stav toho vstupu Arduina napr. raz za 50 ms, alebo pri zmene.

Robil som len s enkóderom KY-040, ktorý má 20 pulzov na 360° otáčku a moje poznatky k nemu sú takéto:
Má výstupy DT a CLK ktoré sú pripojené k otočnej časti mechanizmu enkódera.
Výstupy boli napájané priamo z enkódera, nemusel som používať INPUT_PULLUP.
Vždy som musel v programe overovať 2 výstupy, aby som zistil ich aktuálne stavy a na základe starých stavov som dokázal určiť, či sa pri zmene o krok enkóder otočil o daný krok v smere hodinových ručičiek (doprava), alebo proti smeru (doľava). Na základe toho som sa vedel softvérovo pohybovať v menu na displeji napr. 1 až 5 položka...

3mgo
Příspěvky: 6
Registrován: 08 bře 2022, 18:16
Reputation: 0

Re: Program Arduino nano

Příspěvek od 3mgo » 08 bře 2022, 20:27

KamilV píše:
08 bře 2022, 18:58
Co se stane, když natočíš enkoder tak, že na pinu 2 bude delší dobu beze změny LOW stav?
Loop se vykoná opravdu hodněkrát za vteřinu a každý průchod navýší cnt.
Resp. navýšil by, kdyby tam bylo cnt = cnt+1, nebo cnt += 1 nebo cnt++;
Tak jak je to teď se nikdy cnt nenavýší.

Nepočítej tedy průchody loopem, patrně chceš počítat jen tehdy, když se změní stav s HIGH na LOW. Pozor na zákmity, které musíš deboucnout.

To, že se během "posílej_impulzy" další impulzy nepočítají je záměr nebo nechtěný fakt?
A nemělo by se cnt po odeslání vynulovat?
Když bude delší dobu beze změny Low stav, tak by se nemělo dít nic, protože arduino reaguje na náběžnou hranu? Když se tedy v loopu jeden impulz zpracuje vícekrát než jednou, mám pocitej_impulzy psát mimo loop? Jak by arduino pracovalo s kódem který není napsaný v loop a ani v main? A ano je to nechtěný fakt.. :D Počítal jsem s tím že se cnt nulovat nemusí, jelikož pracujeme s násobky 180 (cnt % 180 == 0).
Jak tedy udělat aby se jeden impulz zpacoval vždy pouze jednou, a cnt se tímto impulzem navýšil vždy pouze o 1?

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Program Arduino nano

Příspěvek od kiRRow » 08 bře 2022, 20:31

Kdyz je enkoder na Low pricti si +1 a zaroven si poznamenej ze uz jsi pricetl.... Pokud je Low a pricetl jsi, nedelej nic. Pokud je high, tak nastav ze jsi jeste necetl.

3mgo
Příspěvky: 6
Registrován: 08 bře 2022, 18:16
Reputation: 0

Re: Program Arduino nano

Příspěvek od 3mgo » 08 bře 2022, 20:34

martinius96 píše:
08 bře 2022, 19:12
Ahoj, aký je to enkóder (typ, označenie)?

Z tvojho programu to chápem tak, že tvoj enkóder má iba jeden výstup.
Ten výstup máš pripojený k Arduinu a na tom očakávaš stav LOW pri prechode cez krok, alebo na kroku?
Potom by ti to rátalo +1 do nekonečna, nemáš tam ani nejaké časové rozlíšenie pre počítanie dvoch po sebe idúcich pulzov, či debouncing proti zákmitom ako takým.
Počas stavu medzi krokmi je úroveň na GPIO HIGH?
Skús si vypísať v na UART stav toho vstupu Arduina napr. raz za 50 ms, alebo pri zmene.

Robil som len s enkóderom KY-040, ktorý má 20 pulzov na 360° otáčku a moje poznatky k nemu sú takéto:
Má výstupy DT a CLK ktoré sú pripojené k otočnej časti mechanizmu enkódera.
Výstupy boli napájané priamo z enkódera, nemusel som používať INPUT_PULLUP.
Vždy som musel v programe overovať 2 výstupy, aby som zistil ich aktuálne stavy a na základe starých stavov som dokázal určiť, či sa pri zmene o krok enkóder otočil o daný krok v smere hodinových ručičiek (doprava), alebo proti smeru (doľava). Na základe toho som sa vedel softvérovo pohybovať v menu na displeji napr. 1 až 5 položka...
Encoder posílám v příloze. Má dva výstupy generující dva impulzy, které jsou proti sobě posunuty o půlperiodu, to je ale kvůli tomu aby bylo poznat na kterou stranu se točí, to já nepotřebuju. Může se tedy stát že se s encoderem otočí a zastaví v poloze kdy bude dávat impulz, tedy LOW stav.
Přílohy
rotační encoder 360 pulsu.pdf
(288.23 KiB) Staženo 88 x

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Program Arduino nano

Příspěvek od martinius96 » 09 bře 2022, 01:37

Vyskúšaj tento kód. Mal by počítať kroky bez ohľadu na točenie v smere / proti smeru hodinových ručičiek.
Je tam prerušenie, ktoré zareaguje na stav prechodu z LOW do HIGH (RISING hrana signálu).
Stále si myslím, že je potrebné mať oba výstupy v programe.

Pretože ten priebeh výstupov v smere hodinových ručičiek je:

Kód: Vybrat vše

01 00 10 11
a proti smeru hodinových ručičiek je priebeh následovný:

Kód: Vybrat vše

10 00 01 11
Ten kód o ktorý sa snažíš zareaguje až na každý druhý krok z dôvodu, že sa mení pri následujúcom kroku po detekcii druhý výstup a prvý (detekovaný programom) ostáva v pôvodnom stave. Teda 180 pulzov by to malo namerať až na celú otáčku enkódera o 360°.

Edit: Vyskúšal som ten program v simulátore a funguje to, počíta to každý krok. Som z toho prekvapený :shock:
Po krokoch enkódera je priebeh jedného signálu: 0 0 1 1 v smere hod. ručičiek, resp. 1 0 0 1 oproti. Ak by to šlo striedavo 1 0 1 0 tak by som to ešte chápal, že to funguje.

Kód: Vybrat vše

volatile unsigned int counter = 0;
unsigned int temp = 0;
void setup() {
  Serial.begin (9600);
  pinMode(2, INPUT_PULLUP); // internal pullup input pin 2
  pinMode(12, OUTPUT);
  attachInterrupt(0, ISR_routine, RISING); //interrupt 0 = D2

}

void loop() {
  if ( counter != temp ) { //pocitadlo krokov --> vypis pri zmene
    Serial.println (counter);
    temp = counter;
  }

  if (counter >= 180) {
    counter = 0;
    digitalWrite(12, HIGH);
    delay(500);
    digitalWrite(12, LOW);
  }
}

void ISR_routine() {
  counter++;
}

3mgo
Příspěvky: 6
Registrován: 08 bře 2022, 18:16
Reputation: 0

Re: Program Arduino nano

Příspěvek od 3mgo » 09 bře 2022, 11:40

kiRRow píše:
08 bře 2022, 20:31
Kdyz je enkoder na Low pricti si +1 a zaroven si poznamenej ze uz jsi pricetl.... Pokud je Low a pricetl jsi, nedelej nic. Pokud je high, tak nastav ze jsi jeste necetl.
Díky za kód @martinius96, a pravděpodobně ho ještě budu potřebovat :D zkusil jsem ale ještě experimentovat s tím mým výtvorem.
Upravil jsem ho podle Kirrowa návodu, a dopadlo to nějak takto:
Výstřižek.PNG
Háže mi to tam chybku, kterou ale nejsem schopnej najit, podle mě je ten kód správně, takže prosim o pomoc. Nastává ale přece zase ten stejný problém, když bude cnt = 180, pin 12 bude v HIGH, a encoder se bude pořád točit další impulzy se k cnt nebudou počítat, dokud pin 12 zase nespadne na LOW, ne?

martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

Re: Program Arduino nano

Příspěvek od martinius96 » 09 bře 2022, 12:36

Máš definované priceTL_jsem ale používaš priceLT_jsem
Je tam gramatická chybka :lol:

Druhá časť otázky k počítaniu pulzov.
Áno, nebude to počítať, pretože si program zablokuješ o dĺžku vykonávania delayu().

Môj program to počíta, lebo využíva prerušenie pre počítanie.
Teda i z delayu() dokáže vyskočiť, obslúžiť prerušenie (pripočíta +1) a vráti sa späť do programu a vykonáva delay() ďalej.

V tvojom prípade by si to počítanie mohol vyriešiť použitím funkcie millis() namiesto delayu(), kedy nastavíš na D12 HIGH, odmeriaš čas z funkcie millis() uložíš ho do premennej unsigned long + si môžeš dať nejaký boolean príznak (tzv. flag) napr. LED_ON = true. Nebude ti to blokovať program.

Klasicky bude v loope podmienka, ak millis()-ulozeny cas je viac alebo rovný 500 ms a zároveň príznak LED_ON bude true, D12 nastavíš na LOW a príznak LED_ON nastavíš na false (aby sa to nevykonalo znova v loope pri jeho následujúcom behu), ale až znova bude celkový počet pulzov 180, ktorý nastaví znova príznak LED_ON na true.

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Program Arduino nano

Příspěvek od kiRRow » 09 bře 2022, 16:31

A neulozi se ti to do promenne protoze tam mas == . To se pouziva v podminkach prave pro odliseni od prirazeni hodnoty promenne.

Edit : Kód prosím vkládej do tagu code ... když ho někdo chce zkusit tak ho nemusí celý opisovat z obrázku

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 14 hostů