www.elektronik.si
Arduino UNO in encoder
Pojdi na stran 1, 2, 3  Naslednja  :||:
www.elektronik.si -> Arduino sekcija

Avtor: marko11Kraj: Dobrepolje PrispevekObjavljeno: Sre Mar 06, 2019 3:57 pm    Naslov sporočila:  Arduino UNO in encoder
----------------------------------------------------------------------------
Lep pozdrav

Dobil sem Arduino uno ploščico. Do sedaj sem vedno delal z Bascom AVR programom.
Sedaj pa bi se rad malo preizkusil še na temu področju.
Ker se tukaj uporablja C++, je pa to zamene čisto nekaj novega, še nikoli delal s tem programom.
Na internetu je mnogo primerov. Utripanje ledice, pisanje na lcd... to sem že preizkusil.

Imam pa Baumer-jev BDE encoder s 125 razdelki na obrat in sem ga priklopil na UNO ploščico, z interneta potegnil spodnji programček, ki verjetno pravilno deluje.

Rad pa bi v Void pulse() spremenil oziroma dodal še if stavek, ki bi, ko count prešteje do 124, count postavil na 0 in novo spremenljivko obrat povečal za 1, oziroma zmanševal za 1 v obratni smeri vrtenja.

Ker mi ti if stavki, še niso čisto jasni, bi prosil nekoga za pomoč.

Pa še to: ali bi ta program sledil 1000 obr/min ?

LP, marko


Koda:

int count = 0;
int obrat = 0;

void pulse()
{
    if(digitalRead(3) == LOW)
      count++;
    else
      count--;     
}

void setup()
{
    Serial.begin(9600);
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    //attachInterrupt(0, pulse, LOW);
    attachInterrupt(0, pulse, FALLING);
}

void loop()
{
   
//    digitalWrite(ledPin, HIGH);
//    delay(50);
//    digitalWrite(ledPin, LOW);
//    delay(50);
    Serial.println(count);
   
}   


Avtor: igo PrispevekObjavljeno: Sre Mar 06, 2019 8:21 pm    Naslov sporočila:  Re: Arduino UNO in encoder
----------------------------------------------------------------------------
... Baumer-jev BDE encoder s 125 razdelki na obrat ...
Rad pa bi v Void pulse() spremenil oziroma dodal še if stavek, ki bi, ko count prešteje do 124, count postavil na 0 in novo spremenljivko obrat povečal za 1, oziroma zmanševal za 1 v obratni smeri vrtenja.
Pa še to: ali bi ta program sledil 1000 obr/min ? ...


1000obr/60sek * 125i/obr = 125000i / 60sek = pribl. 2100 impulzov/sekundo

To je možno šteti, a bo ostalo zelo malo časa za ostale stvari.
Kaj nameravaš početi s preštetimi impulzi? Bo to za pozicijo ali kaj podobno preciznega?
Če je možno s kakim 74HC ... delilnikom malo zmanjšati vhodno frekvenco (in s tem kotno ločljivost zasuka gredi), bi se Arduino dosti bolje počutil.
Koda:

volatile unsigned byte count = 0; // zadostuje 8-bitno 0 ... 255
volatile unsigned int obrat = 0; // 0 do 65535
// volatile int obrat = 0; // od -32768 do 0 in naprej do 32767

void pulse()
{
    if(digitalRead(3) == LOW) // steje GOR
    {
        count++;
        if(count > 124)
        {
            count=0;
            obrat++;
        }
    }
    else // steje DOL
    {
        count--;
        if(count > 124) // dol grede iz 0 na 255 ...
        {
            count=124;
            obrat--;
        }
    }
}

void setup()
{
    Serial.begin(9600);
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);
    //attachInterrupt(0, pulse, LOW);
    attachInterrupt(0, pulse, FALLING);
}

void loop()
{
   
//    digitalWrite(ledPin, HIGH);
//    delay(50);
//    digitalWrite(ledPin, LOW);
//    delay(50);
    Serial.println(count);
   
}   




Telefon in (ne)preglednost ...
Popravljeno: Dodan en } takoj za obrat--;


Nazadnje urejal/a igo Sre Mar 06, 2019 9:04 pm; skupaj popravljeno 2 krat

Avtor: marko11Kraj: Dobrepolje PrispevekObjavljeno: Sre Mar 06, 2019 8:52 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Igo hvala.

Kodo sem skopiral pa mi javi napako glede zavitih oklepajev.

error: a function-definition is not allowed here before '{' token

Avtor: igo PrispevekObjavljeno: Sre Mar 06, 2019 9:18 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sem kar zgoraj popravil

Avtor: marko11Kraj: Dobrepolje PrispevekObjavljeno: Sre Mar 06, 2019 9:47 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Sedaj je pa drug problem.
Štetje na GOR deluje v redu, štetja na DOL pa sploh ni.

lp,marko

Avtor: igo PrispevekObjavljeno: Sre Mar 06, 2019 10:08 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Verjetno tudi prej ni štelo dol ...
Če daje enkoder ven impulze samo na enem izhodu, ne pa CW/CCW impulze (2 izhodna signala, premaknjena za 90° 00 01 11 10), bi moralo tole zadostovati:

attachInterrupt(0, pulse, CHANGE); // možne so: rising/change/falling

Ampak sedaj bo 2-krat več prekinitev kot prej. Kaj šteješ? Si lahko privoščiš deljenje z 2, s 4 ali z 10 ali kaj podobnega?

Avtor: marko11Kraj: Dobrepolje PrispevekObjavljeno: Čet Mar 07, 2019 2:17 pm    Naslov sporočila:  
----------------------------------------------------------------------------
igo je napisal/a:
Verjetno tudi prej ni štelo dol ...


Prej je štel dol in gor.

Mislim da tale del kode za else ni dobro napisano, verjetno bi bilo potrebno daje count < 1 pa sprobavam pa se mi zdi, da do else sploh ne pride, ker na zaslonu nič ne izpisuje.

Popravil sem tudi:
Serial.println(count); v Serial.println(obrat);, da izpisuje število obratov.

Pa tudi to ne sprejme " volatile unsigned byte count = 0; ", ko byte spremenim v int pa sprejme.



Koda:


// s tem delom kode nekaj ni vredu

    else // steje DOL
    {
        count--;
        if(count > 124) // dol grede iz 0 na 255 ...
        {
            count=124;
            obrat--;
        }
    }

Avtor: igo PrispevekObjavljeno: Čet Mar 07, 2019 5:04 pm    Naslov sporočila:  
----------------------------------------------------------------------------
volatile byte count
ali
volatile unsigned char
sta oba 8-bitna, saj več bitov ni smiselno uporabiti.

Primeri in sintaksa funkcij:
https://www.arduino.cc/reference/en/

attachIntertupt(stevilkaPina, kajOdpre, obDogodku)
Prekinitev ti prožijo dogodki na pinu 0. Ti imaš enkoder na pinih 2 in 3.
To uredi, da bo prekinitev prožila sprememba na pinu 2.

Napiši popolno oznako enkoderja.

Običajno se na enem vhodu (naprimer "2") zaznava sprememba (prekinitev ob CHANGE), znotraj prekinitve pa se preveri stanje drugega vhoda ("3").
Tisti else je čisto v redu.
Ker je zaporedje pin2 pin3 = ... 00, 01, 11, 10 , 00, 01, 11, 10 , ... in se prekinitev sproži ob spremembi na pin2, se iz stanja na pin3 ugotovi v katero smer kroži zaporedje.

Avtor: marko11Kraj: Dobrepolje PrispevekObjavljeno: Čet Mar 07, 2019 5:41 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Oznaka encoderja:

Baumer BDE 05.05A125-5-1

Igo, ti lahko meni tolmačiš, sem že v uvodu napisal, da sem privič na C++, zato pa prosim za bolj domačo razlago, hvala.

lp

Avtor: igo PrispevekObjavljeno: Čet Mar 07, 2019 9:46 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Lej, se ti čis pu dumače pišim, d bu prou loufal, če uš prou zviezu enkoder.
Shocked d'oh! Anxious

Uf, še enkrat ... Arrow ... pina od enkoderja morata biti priklopljena na Arduino vhoda 2 in 3.
Potem daš znotraj Setup
atrachInterrupt(2, Pulse, CHANGE); // prekinitev ob spremembi na pinu 2

Sedaj imaš tam (0, ... in prožiš prekinitve ob motnjah na pinu 0.

Tisti "volatile" mora biti pred vsemi spremenljivkami, ki nastopajo znotraj prekinitev. To sta "count" in "obrat". Tako pač je.
"count" je največ 125, zato zadostuje nepredznačena 8-bitna spremenljivka (byte ali char), s katero 8-bitni MCU hitreje računa kot s 16-bitno tipa "int". To je zato, da je prekinitev čim krajša in boš lažje gnal enkoder na 1000 rpm.

Za "obrat" se sam odloči, ali rabiš razpon od nepredznačene 0 do 65535 ali predznačeno od -32768 do +32767.

Ko številko pina (2, ... za prekinitev urediš, bi moral moj programček delovati.

Avtor: marko11Kraj: Dobrepolje PrispevekObjavljeno: Pet Mar 08, 2019 4:58 pm    Naslov sporočila:  
----------------------------------------------------------------------------
marko11 je napisal/a:
Sedaj je pa drug problem.
Štetje na GOR deluje v redu, štetja na DOL pa sploh ni.



Igor, rešen problem. Sedaj šteje gor in dol, program je v redu narejen.

Jaz sem imel slab stik na Arduinotu. Na netu sem našel shemo kjer so 1K upori na +5, na 2,3 pin, pa sem jih vstavil pa sem videl, da je slab kontakt, dela tudi brez uporov.
Še enkrat hvala.


Bi pa prosil, če je mogoče da bi zraven celih števil izpisoval še desetinke obrata za gor in dol?

lp,marko

Avtor: igo PrispevekObjavljeno: Pet Mar 08, 2019 6:18 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Možno je, ampak naslednjič vzemi enkoder, ki ima število impulzov že deljivo z 10.


Načinov je več.
Najprej napiši, kolikšen maksimalen razpon (od ... do ...) števila "obrat" si želiš.
Ali je še vedno v igri 1000 rpm?
Kam boš to število ob končanem projektu izpisoval? (serijsko na računalnik ni ravno najhitrejši način).

V osnovi je najhitreje v vsaki prekinitvi count povečevati/zmanjševati za 2, nato pa izpisovati obrat,_ v obliki stringa (zaporedja)
obrat,count/25 (= obrat vejica count/25)
A ni povsem vseeno, kam to izpisuješ, saj je potrebna predpriprava paketa za izpis odvisna od izbire prikazovalnika.
Koda:

void pulse()
{
 if(digitalRead(3) == LOW)
  {
    count = count+2;
    if(count > 248)
    {
      count=0;
      obrat++;
    }
  }
  else
  {
    count = count - 2;
    if(count > 248)
    {
      count = 248;
      obrat--;
    }
  }
}


Možno je tudi imeti
volatile unsigned float count; // 32 bitov z vejico
brez spremenljivke obrat, v prekinitvi šteti gor/dol po 2 in direktno izpisovati float spremenljivko
" count / 25 " , namesto obrat.

Računanje s float ni tako hitro in lahko tudi časa zmanjka. Zato je možnih več načinov, izbira najoptimalnejšega pa je odvisna od odgovorov na gornja 3 vprašanja.

Avtor: marko11Kraj: Dobrepolje PrispevekObjavljeno: Pet Mar 08, 2019 7:23 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Igor, tole si super razložil.

Kar se encoderja tiče, tega sem slučajno potegnu iz ene stare mašine, pa me to sedaj zanima kako deluje.

Zdaj pa sem se spomnil, da je bolje kot deliti, da istočasno izpisujem obrat in count.
Pa točno veš na kateri poziciji si.

Sedaj pa poizkušam in nikakor mi ne uspe v eni vrstici izpisati v tej obliki naprimer

12.123 s tem ukazom Serial.println(obrat); Serial.println(count);

Ne znam združiti dveh spremenljivk in ločiti s piko.

lp,

Avtor: igo PrispevekObjavljeno: Pet Mar 08, 2019 9:10 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Serial.print(obrat);
Serial.print(".");
Serial.println(count);

Tisti "ln" na koncu "print" pomeni, da gre po končanem izpisu v novo vrstico.

Avtor: marko11Kraj: Dobrepolje PrispevekObjavljeno: Pet Mar 08, 2019 9:45 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Super, ta izpis sem porihtal. Tukaj vidiš točno lokacijo, pa točnost encoderja.

Recimo, da bi to pisal na LCD, kolikšen naj bi bil Delay?

Bom priklopil še LCD na arduina, da vidim kako se tam obnaša.
Če mi ne bo kaj jasno bom pa povprašal.

Če dodajam program ali bo to kaj zabremzalo izvajanje?

lp,

Stran 1 od 3

Powered by phpBB © 2001,2002 phpBB Group