www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Arduino UNO in encoder
Pojdi na stran Prejšnja  1, 2, 3  Naslednja
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Arduino sekcija
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
igo
Član
Član



Pridružen-a: Sre 11 Okt 2006 19:11
Prispevkov: 3638
Aktiv.: 17.11

PrispevekObjavljeno: Pet Mar 08, 2019 10:53 pm    Naslov sporočila:   Odgovori s citatom

Znotraj loop() dodaj
Koda:

 noInterrupts(); // prepreči spremembo obrat in count
 obrat4lcd = obrat; // shrani njuni trenutni vrednosti
 count4lcd = count;
 interrupts(); // dovoli spreminjanje


Tako se bosta obrat za lcd in count za lcd spremenila samo enkrat v zanki in bo lahko lcd v miru izpisal njuni trenutni vrednosti.
Če bi izpisoval direktno count in obrat in bi se med izpisovanjem count parkrat spremenil, nato pa še obrat, bi nastala velika zmeda. Sploh, če bi vmes še kaj računal ali primerjal z obrat in count.
Novi spremenljivki morata biti enakega tipa kot originalni.

Ukaz za pisanje na lcd je odvisen od tega, katero knjižnico imaš.
Običajno je nekaj v stilu
Pisi2lcd(spremenljivka, vrstica, stoplec); //Pisi2lcd je izmišljeno ime
Dobro pa je imeti še število cifer, leva/desna poravnava in pa polnilo za vodilno ničlo.
Potem izpišeš približno takole:
Pisi2lcdTXT("OBRATI:", 0, 0);
Pisi2lcdNUM(obrat4lcd, 0, 8, 4, desno, " "); // tisti " " presledek je polnilo spredaj. 4 pozicije.
Pisi2lcdTXT(".", 0, 12);
Pisi2lcdNUM(count4lcd, 0, 13, 3, desno, "0"); // "0" je polnilo med . in prvo od 0 različno cifro. 3 pozicije

Preveri svojo knjižnico za izpis na lcd. Kako se imenuje, kako izpišeš besedilo in kako številko.

_________________
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
marko11
Član
Član



Pridružen-a: Ned 14 Dec 2003 17:47
Prispevkov: 866
Aktiv.: 3.90
Kraj: Dobrepolje

PrispevekObjavljeno: Sob Maj 04, 2019 3:56 pm    Naslov sporočila:   Odgovori s citatom

Hi

Nabavil sem od Kitajca nov encoder, ima 10 razdelkov na obrat, da bo lažje za računat! Čakal zelo dolgo.
Spodaj je slika encoderja.

S priloženo kodo pa je nekaj narobe v interrupt funkciji, tam kjer šteje dol (CCW),
pa prosim za pomoč.

Opis napake:

- ko sem na poziciji 0.0 in zavrtim v nasprotni smeri ure CCW, bi moral izpisati -0.9 izpiše pa -1.9

Koda:


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

void setup()
{
    Serial.begin(115200);
    pinMode(2, INPUT_PULLUP); // A_PHASE
    //pinMode(3, INPUT_PULLUP);  // Z_PHASE
    pinMode(4, INPUT_PULLUP);  // B_PHASE
     
    attachInterrupt(digitalPinToInterrupt(2), pulse, RISING); // Interrupt 0 se zgodi na Pin 2
    //attachInterrupt(0, pulse, FALLING);
}

void loop()
{
   Serial.print(obrat);  // ko naredi encoder EN obrat (360 stop.)
   Serial.print(".");
   Serial.println(count); // encoder ima 10 razdelkov
   delay(50);       
}

void pulse()    // Interrupt funkcija
{
    if(digitalRead(4) == HIGH) // steje GOR ( CW )
    {
        count++;
        if(count > 9)
        {
            count=0;
            obrat++;
        }
    }
    else          // steje DOL ( CCW )
    {
        count--;
        if(count > 9)
        {
            count=9;
            obrat--;
        }
    }
}



Encoder_2_foto.jpg
 Opis:
 Velikost datoteke:  2.01 MB
 Pogledana:  1 krat

Encoder_2_foto.jpg


Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
dejko1
Član
Član



Pridružen-a: Ned 16 Mar 2008 0:21
Prispevkov: 265
Aktiv.: 1.36
Kraj: Ljubljana

PrispevekObjavljeno: Sob Maj 04, 2019 4:27 pm    Naslov sporočila:   Odgovori s citatom

Verjetno te moti, da se obrat postavi na -1 že pri prvem koraku v nasprotno smer urinega kazalca.

Na začetku je count = 0, torej pri prvem CCW koraku preide v count = 255 ter takoj v count = 9 in obrat = -1.

Zakaj raje ne šteješ le korakov in obrate izračunaš kot:
Koda:
obrat = count / 10

(nisem sicer siguren če ti ne bo bolj všeč prikaz kot ga imaš sedaj)

Ena od pomanjkljivosti tvoje kode je tudi, da v primeru poskakovanja na pinu 2 ali premikanja na mestu za del periode koda šteje narobe.

Standardni tipi kot so uint8_t in int8_t so lažji za direktno ugotovit njihov obseg vrednosti.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
marko11
Član
Član



Pridružen-a: Ned 14 Dec 2003 17:47
Prispevkov: 866
Aktiv.: 3.90
Kraj: Dobrepolje

PrispevekObjavljeno: Sob Maj 04, 2019 9:50 pm    Naslov sporočila:   Odgovori s citatom

dejko1@ (nisem sicer siguren če ti ne bo bolj všeč prikaz kot ga imaš sedaj)

Ena od pomanjkljivosti tvoje kode je tudi, da v primeru poskakovanja na pinu 2 ali premikanja na mestu za del periode koda šteje narobe.

Standardni tipi kot so uint8_t in int8_t so lažji za direktno ugotovit njihov obseg vrednosti.

Ja, najbolj mi odgovarja ,da izpisuje v obliki naprimer 0.9.
Ja, opazil sem tudi, da premikanje na mestu levo desno ni več točno.
Kaj misliš stem unit8_t...?

Kako naj popravim kodo, da se bo točno izvajala glede na zahteve?

Že na začetku posta sem napisal, da se z arduino in C++ prvič seznanjam in da mi je to vse velika neznanka, zato prosim za nasvete.

lp,marko
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
igo
Član
Član



Pridružen-a: Sre 11 Okt 2006 19:11
Prispevkov: 3638
Aktiv.: 17.11

PrispevekObjavljeno: Sob Maj 04, 2019 10:27 pm    Naslov sporočila:   Odgovori s citatom

V bistvu mora šteti
0,2
0,1
0,0
-0,1
-0,2
...

Najlažje je dodati pomožno spremenljivko countX.
Koda:

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

void setup() 

    Serial.begin(115200); 
    pinMode(2, INPUT_PULLUP); // A_PHASE 
    //pinMode(3, INPUT_PULLUP);  // Z_PHASE 
    pinMode(4, INPUT_PULLUP);  // B_PHASE 
      
    attachInterrupt(digitalPinToInterrupt(2), pulse, RISING); // Interrupt 0 se zgodi na Pin 2 
    //attachInterrupt(0, pulse, FALLING); 


void loop() 

   Serial.print(obrat);  // ko naredi encoder EN obrat (360 stop.) 
   Serial.print("."); 
   Serial.println(count); // encoder ima 10 razdelkov 
   delay(50);        


void pulse()    // Interrupt funkcija 

  if(digitalRead(4) == HIGH) // steje GOR ( CW ) 
    { 
        countX++; 
        if(countX > 19) 
        { 
            countX=10; 
            obrat++; 
        } 
    } 
    else          // steje DOL ( CCW ) 
    { 
        countX--; 
        if(countX < 1) 
        { 
            countX=10; 
            obrat--; 
        } 
    }
  count = countX - 10;
}

_________________
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
igo
Član
Član



Pridružen-a: Sre 11 Okt 2006 19:11
Prispevkov: 3638
Aktiv.: 17.11

PrispevekObjavljeno: Ned Maj 05, 2019 8:18 am    Naslov sporočila:   Odgovori s citatom

Oh, problem bo s predznakom med 0.0 in -0.9 .


Bo treba imeti samo
volatile int count;
volatile int countCEL;
volatile byte countDEC;

znotraj if stavkov v prekinitvi samo count++ in count--,
pred izhodom iz prekinitve pa
countCEL = count / 10; // celi del pri deljenju z 10
countDEC = abs(count % 10); // absolutna vrednost ostanka pri deljenju z 10.

Pri izpisu v loop() pa vmes med countCEL in countDEC vriniti vejico.

_________________
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
marko11
Član
Član



Pridružen-a: Ned 14 Dec 2003 17:47
Prispevkov: 866
Aktiv.: 3.90
Kraj: Dobrepolje

PrispevekObjavljeno: Ned Maj 05, 2019 11:53 am    Naslov sporočila:   Odgovori s citatom

dejko1 je napisal/a:


Ena od pomanjkljivosti tvoje kode je tudi, da v primeru poskakovanja na pinu 2 ali premikanja na mestu za del periode koda šteje narobe.

Standardni tipi kot so uint8_t in int8_t so lažji za direktno ugotovit njihov obseg vrednosti.


Kaj si mislil s tem poskakovanjem, oziroma kako popraviti kodo?

lp,
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
dejko1
Član
Član



Pridružen-a: Ned 16 Mar 2008 0:21
Prispevkov: 265
Aktiv.: 1.36
Kraj: Ljubljana

PrispevekObjavljeno: Pon Maj 06, 2019 5:21 pm    Naslov sporočila:   Odgovori s citatom

Enkoder ki ga imaš verjetno deluje na optičnem ali magnetnem principu, torej ni bouncinga, ki bi ga pričakoval pri mehanskem. Še vedno obstaja možnost, npr. da je ena linija na 0, ter da se enkoder večkrat levo-desno premakne preko meje na drugi liniji, ki ti proži interrupt (posledično tvoja koda šteje premike v eno smer).

Mislim, da moraš za debouncing uporabiti obe fronti signala (ali fronti obeh signalov) v interruptu ter upoštevati zdajšnje in prejšnje stanje signalov.

Npr. pri vrednosti vhodov AB 00 pričakuješ prehod v 10 v eno smer in 01 v drugo smer.

Primer z interrupti (nisem preizkusil, ampak mislim, da je ok):
https://www.instructables.com/id/Improved-Arduino-Rotary-Encoder-Reading/

Zadevo se da izvest tudi s pollingom (periodičnim branjem stanja vhodov):
https://www.best-microcontroller-projects.com/rotary-encoder.html

Glede tipov:
uint8_t je tip, ki je ekvivalenten byte v tvoji kodi, le da se direkto iz definicije vidi, da ima 8 bitov, je unsigned in integer.

uint8_t = 6;

Z uprabo opisnih tipov kot sta char in byte ni nič narobe, dokler veš kaj predstavljata na dotičnem sistemu Smile
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Obišči avtorjevo spletno stran
ElGrigon
Član
Član



Pridružen-a: Pon 24 Jul 2006 22:38
Prispevkov: 3880
Aktiv.: 18.03
Kraj: okolica Lenarta

PrispevekObjavljeno: Pon Maj 06, 2019 5:30 pm    Naslov sporočila:   Odgovori s citatom

Če pogledaš datasheet enkoderja, se proži phaseZ vsako celo periodo ali pahseA ali phaseB. Razlika je le v smeri kar določiš ali B zaostaja ali A zaostaja.
_________________
lp, ElGrigon
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Jaka57
Moderator
Moderator



Pridružen-a: Ned 12 Dec 2004 21:47
Prispevkov: 5766
Aktiv.: 25.97
Kraj: Grosuplje

PrispevekObjavljeno: Pon Maj 06, 2019 6:21 pm    Naslov sporočila:   Odgovori s citatom

Da ne boste o poskakovanju, je tukaj pdf.
Očitno ga je edino ElGrigon pogledal.



e6b2-c_ds_csm491-25665.pdf
 Opis:

Download
 Ime datoteke:  e6b2-c_ds_csm491-25665.pdf
 Velikost datoteke:  326.02 KB
 Downloadano:  12 krat


_________________
Lp, Jaka
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
marko11
Član
Član



Pridružen-a: Ned 14 Dec 2003 17:47
Prispevkov: 866
Aktiv.: 3.90
Kraj: Dobrepolje

PrispevekObjavljeno: Tor Maj 07, 2019 5:29 pm    Naslov sporočila:   Odgovori s citatom

Jaka57 je napisal/a:
Da ne boste o poskakovanju, je tukaj pdf.
Očitno ga je edino ElGrigon pogledal.


Zdravo generacijo, kako kaj?

Ta encoder na sliki, je verjetno optični, zato mislim, da tukaj ni nekega poskakovanja.

Z brskanjem po spletu sem našel tole spletno stran: https://playground.arduino.cc/Main/RotaryEncoders/
kjer je veliko različnih programov, preveril sem vse programe, ta spodaj pa se mi zdi, da je najbolj točen, če enkoder ročno premikam naprej nazaj in je izhodiščna točka vedno pravilna.

Ne vem pa če se da program preurediti tako, ker sedaj našteje za en obrat 40 razdelkov, rad bi da ko napravi en obrat pretvori teh 40 v 1.0 obratov in tako naprej v tej obliki:
-0.2
-0.1
0.0
1.1
1.2
1.3

Koda iz predlagane povezave, ki je nekje zelo točna, uporablja dve interrupt linije:


Koda:


#define encoder0PinA  2
#define encoder0PinB  3

volatile int encoder0Pos = 0;

void setup() {
  pinMode(encoder0PinA, INPUT);
  pinMode(encoder0PinB, INPUT);

  // encoder pin on interrupt 0 (pin 2)
  attachInterrupt(0, doEncoderA, CHANGE);

  // encoder pin on interrupt 1 (pin 3)
  attachInterrupt(1, doEncoderB, CHANGE);

  Serial.begin (9600);
}

void loop() {
  //Do stuff here
}

void doEncoderA() {
  // look for a low-to-high on channel A
  if (digitalRead(encoder0PinA) == HIGH) {

    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinB) == LOW) {
      encoder0Pos = encoder0Pos + 1;         // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
  }

  else   // must be a high-to-low edge on channel A
  {
    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinB) == HIGH) {
      encoder0Pos = encoder0Pos + 1;          // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }
  }
  Serial.println (encoder0Pos, DEC);
  // use for debugging - remember to comment out
}

void doEncoderB() {
  // look for a low-to-high on channel B
  if (digitalRead(encoder0PinB) == HIGH) {

    // check channel A to see which way encoder is turning
    if (digitalRead(encoder0PinA) == HIGH) {
      encoder0Pos = encoder0Pos + 1;         // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;         // CCW
    }
  }

  // Look for a high-to-low on channel B

  else {
    // check channel B to see which way encoder is turning
    if (digitalRead(encoder0PinA) == LOW) {
      encoder0Pos = encoder0Pos + 1;          // CW
    }
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }
  }
}


Jaka57, mislim, da si na temu področju pravi mačo, pa te prosim, če malo pokomentiraš oziroma svetuješ kaj in kako naprej, pa tudi kdo drug je dobrodošel z nasveti. Hvala.

LP,marko
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Jaka57
Moderator
Moderator



Pridružen-a: Ned 12 Dec 2004 21:47
Prispevkov: 5766
Aktiv.: 25.97
Kraj: Grosuplje

PrispevekObjavljeno: Tor Maj 07, 2019 11:23 pm    Naslov sporočila:   Odgovori s citatom

Marko, nisem ravno taka perla, kot misliš Very Happy .
Me pa motijo rezultati, ki jih dobiš iz tvojega programa.
Prvo, od kje decimalne vrednosti?
Drugo pa, tvoj program šteje vse prehode iz 0 na 1 in obratno, kajti do prekinitve pride ob vsaki spremembi stanja.
Tvoj enkoder ima resolucijo 10impulzov/obrat tvoj program pa jih vrne 40?

Naslednja stvar, ki me moti je, da imaš v interupt rutini A Serial.println.
Interupt rutina naj bi bila, kar se da kratka!
Če želiš gledat štetje impulzov lahko to narediš void loop() saj je spremenljivka encoder0pos globalna in je dosegljiva od kjerkoli.

Kar se pa tiče 40->1 lahko to narediš tudi v prekinitveni rutini z dodatno globalno spremenljivko (ni pa nujno, kot lahko vidiš iz spodaj omenjenega primera), ki jo povečuješ ali zmanjšuješ za 1, ko pride do 40 ali -40.
Pri tipih spremenljivk se moraš tudi zavedati, da gre int od -32768 do 32767.

Kakorkoli, že nekaj časa je, kar sem se hecal s klasičnim enkoderjem.
Uporabil sem knjižnjico, ki je v prilogi.
Uporabil sem jo tako, kot je to narejeno v Interuptrotator.ino.
V tem primeru lahko vidiš na koncu programa, ko pride do >66 čaka 6.6 sekunde, vendar impulze šteje naprej.
Tukaj lahko enostavno postaviš pozicijo na 0, ko prešteje do 40 in za eno povečaš vrednost spremenljivke, recimo obrati, ali zmanjšaš, če pride na -40.

Zakaj pa misliš uporabiti ta enkoder, kajti prav hitro ga ne moreš vrteti (recimo za kakšno hitro štetje obratov).
V končni fazi, bi lahko prekinitev uporabil na Z izhodu in ko pride do prekinitve program pogleda kaj je na A in B na podlagi tega, pa določi ali gre CW ali CCW, šteje pa samo Z impulze.



RotaryEncoder.rar
 Opis:

Download
 Ime datoteke:  RotaryEncoder.rar
 Velikost datoteke:  7.37 KB
 Downloadano:  2 krat


_________________
Lp, Jaka


Nazadnje urejal/a Jaka57 Pet Maj 10, 2019 1:21 am; skupaj popravljeno 2 krat
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
marko11
Član
Član



Pridružen-a: Ned 14 Dec 2003 17:47
Prispevkov: 866
Aktiv.: 3.90
Kraj: Dobrepolje

PrispevekObjavljeno: Čet Maj 09, 2019 4:27 pm    Naslov sporočila:   Odgovori s citatom

Jaka57 je napisal/a:


Drugo pa, tvoj program šteje vse prehode iz 0 na 1 in obratno, kajti do prekinitve pride ob vsaki spremembi stanja.
Tvoj enkoder ima resolucijo 10impulzov/obrat tvoj program pa jih vrne 40?

Zakaj pa misliš uporabiti ta enkoder, kajti prav hitro ga ne moreš vrteti (recimo za kakšno hitro štetje obratov).
V končni fazi, ti lahko prekinitev uporabil na Z izhodu in ko pride do prekinitve program pogleda kaj je na A in B na podlagi tega, pa določi ali gre CW ali CCW, šteje pa samo Z impulze.


Ko sem v programu popravil ta del iz CHANGE na Falling pa šteje pravilno 10 pulzov/obrat


Koda:
attachInterrupt(0, doEncoder, FALLING);  //  CHANGE


Ta enkoder bi rabil za štetje ovojev, max 1500 obratov/minuto. Zato rabim decimalke, da veš kje se nahajaš.

Igo je napisal
Citiram:


Bo treba imeti samo
volatile int count;
volatile int countCEL;
volatile byte countDEC;

znotraj if stavkov v prekinitvi samo count++ in count--,
pred izhodom iz prekinitve pa
countCEL = count / 10; // celi del pri deljenju z 10
countDEC = abs(count % 10); // absolutna vrednost ostanka pri deljenju z 10.

Pri izpisu v loop() pa vmes med countCEL in countDEC vriniti vejico.


Sem ta del kode vpisal v spodnji program.

Štetje GOR (CW) deluje in pravilno izpisuje.

Štetje DOL (CCW) pa mi NE deluje, javi napako, ko vpišem vrstico z countDEC.
Brez te vrstice pe celi del izpisuje pravilno.

Koda:

#define encoder0PinA  2
#define encoder0PinB  3

volatile int count = 0; 
volatile int countCEL = 0;
volatile int countDEC = 0;

void setup() {
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // turn on pull-up resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // turn on pull-up resistor

  attachInterrupt(0, doEncoder, FALLING);  // FALLING, RISING, CHANGE
  Serial.begin (9600);
  Serial.println("start");                // a personal quirk
}

void loop() {
   Serial.print(countCEL);  // ko naredi encoder EN obrat (360 stop.)
   Serial.print(".");
 Serial.println (countDEC);
 delay(300);
 
}

void doEncoder()
{
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
    {
    count++;                // štej gor CW
    countCEL = count/10;
    countDEC = abs(count % 10);
       
    }
  else
    {
    count--;                //štej dol CCW
    countCEL = count/10;
    //countDEC = abs(count % 10);  //tukaj javi napako

    }
}


void doEncoder_Expanded() {
  if (digitalRead(encoder0PinA) == HIGH) {   // found a low-to-high on channel A
    if (digitalRead(encoder0PinB) == LOW) {  // check channel B to see which way
      // encoder is turning
      count = count - 1;         // CCW
    }
    else {
      count = count + 1;         // CW
    }
  }
  else                                        // found a high-to-low on channel A
  {
    if (digitalRead(encoder0PinB) == LOW) {   // check channel B to see which way
      // encoder is turning
      count = count + 1;          // CW
    }
    else {
      count = count - 1;          // CCW
    }

  }

}



LP, marko
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
igo
Član
Član



Pridružen-a: Sre 11 Okt 2006 19:11
Prispevkov: 3638
Aktiv.: 17.11

PrispevekObjavljeno: Čet Maj 09, 2019 6:39 pm    Naslov sporočila:   Odgovori s citatom

Pripni besedilo napake.

Za abs(x) piše, da naj ne bi bilo nobene operacije znotraj oklepajev. Morda je to vzrok, a potem tudi za ++ ne bi delalo.
Koda:

void doEncoder() 

  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) 
    { 
    count++;                // štej gor CW     
    } 
  else 
    { 
    count--;                //štej dol CCW
    } 

    countCEL = count % 10;  // trik, da ni treba uvesti dodatne spremenljivke
    countDEC = abs(countCEL); // decimalni del je ostanek pri deljenju z 10
    countCEL = count / 10; // ponoven izračun celega dela


Pa daj si malo preberi stvari na strani Arduino Reference:
https://www.arduino.cc/reference/en/

_________________
Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
Jaka57
Moderator
Moderator



Pridružen-a: Ned 12 Dec 2004 21:47
Prispevkov: 5766
Aktiv.: 25.97
Kraj: Grosuplje

PrispevekObjavljeno: Pet Maj 10, 2019 1:59 am    Naslov sporočila:   Odgovori s citatom

Ni mi sicer jasno, zakaj tako kompliciranje?
Kaj naredi funkcija abs(x)?
Vrne absolutno vrednost argumenta, t.j., če x negativen, vrne x.
Vse kar kvačkaš v prekinitveni rutine se lahko naredi pri samem izpisu.
Recimo takole:

Koda:
#define encoder0PinA  2
#define encoder0PinB  3

volatile int count = 0;
int dec=0; 

void setup() {
  pinMode(encoder0PinA, INPUT);
  digitalWrite(encoder0PinA, HIGH);       // turn on pull-up resistor
  pinMode(encoder0PinB, INPUT);
  digitalWrite(encoder0PinB, HIGH);       // turn on pull-up resistor

  attachInterrupt(0, doEncoder, FALLING);  // FALLING, RISING, CHANGE
  Serial.begin (9600);
  Serial.println("start");                // a personal quirk
}

void loop() {
   Serial.print(count/10);  // ko naredi encoder EN obrat (360 stop.)
   Serial.print(".");
   dec=count%10;
 Serial.println (abs(dec));               //zaradi izpisa se znebimo minusa
 delay(300);
 
}

void doEncoder()
{
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
    {
    count++;                // štej gor CW
      }
  else
    {
    count--;                //štej dol CCW
       }
}

_________________
Lp, Jaka
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Arduino sekcija Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran Prejšnja  1, 2, 3  Naslednja
Stran 2 od 3

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 48 dni


Powered by phpBB © 2001, 2005 phpBB Group