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 
Sponsored by SiOL

Arduino UNO in encoder
Pojdi na stran Prejšnja  1, 2, 3
 
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
marko11
Član
Član



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

PrispevekObjavljeno: Pet Maj 10, 2019 9:01 pm    Naslov sporočila:   Odgovori s citatom

Hi

Jaka, saj sem vedel, da ti to obvladaš. Program je posodobljen in deluje, ampak, ko pa zavrtim nazaj štej dol CCW, ko sem na 0.0, pa ko bi moral izpisati -0.1 ne izpiše minusa.
Minus izpiše šele, ko doseže -1.0

izpisuje takole:
0.0
0.1
....
....
0.9
-1.0
-1.2
....

Tukaj spodaj je pa celoten program:

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
    }
   
}

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
Jaka57
Moderator
Moderator



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

PrispevekObjavljeno: Pet Maj 10, 2019 10:02 pm    Naslov sporočila:   Odgovori s citatom

Ja, Marko drži, na to včeraj (danes Very Happy ) ponoči nisem pomislil.
En If stavek bi moral to rešit, recimo:
Koda:
void loop() {
   dec=count%10;
   if (count/10==0 && dec<0) Serial.print("-");
   Serial.print(count/10);  // ko naredi encoder EN obrat (360 stop.)
   Serial.print(".");
   Serial.println (abs(dec));               //zaradi izpisa se znebimo minusa
   delay(300);
}

_________________
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: 682
Aktiv.: 4.06
Kraj: Dobrepolje

PrispevekObjavljeno: Pet Maj 10, 2019 11:27 pm    Naslov sporočila:   Odgovori s citatom

Hi

Jaka, hvala in ostali. Sedaj pa to deluje tako kot mora.

Samo zanima me do katere hitrosti ga lahko obračam, kako se to zračuna?

Sedaj pa je to treba samo še na LCD napisat, bom probal tako kot je Igo predlagal.

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: 5133
Aktiv.: 30.55
Kraj: Grosuplje

PrispevekObjavljeno: Pet Maj 10, 2019 11:59 pm    Naslov sporočila:   Odgovori s citatom

Hm, preštet moraš prevedene strojne inštrukcije kontrolerja.
Večina inštrukcij se izvede v enem ciklu ure.
Torej 1500o/min=25o/s, kar pomeni, da imaš pri tej hitrosti 250 prekinitev na sekundo oz do prekinitve pride vsake 4ms. Da izvede eno strojno inštrukcijo pa potrebuje (velja za večino inštrukcij, ne pa za vse) mega328 pri 16MHz oscilatorju 0.625uS.
Sedaj pa kalkulator v roke in štet Very Happy .
V glavnem v 4ms lahko izvede 6400 strojnih ciklov.

_________________
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: 682
Aktiv.: 4.06
Kraj: Dobrepolje

PrispevekObjavljeno: Tor Maj 14, 2019 4:19 pm    Naslov sporočila:   Odgovori s citatom

Jaka, hvala za razlago.

Tu spodaj je celotna koda , ki število ovojev izpisuje na LCD, upam, da sem codo pravilno sestavil.

Koda:

#define encoder0PinA  2
#define encoder0PinB  3
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 7, en = 8, d4 = 9, d5 = 10, d6 = 11, d7 = 12;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

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

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Stevec");
  delay(1000); 
}

void loop() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Ovoji:");
  lcd.setCursor(7,0);
 
   dec=count%10;   
   if (count/10==0 && dec<0) lcd.print("-");
   
   lcd.print(count/10); 
   lcd.print(".");
   lcd.print (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
    }
   
}

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
    }

  }

}


Sedaj pa bi rad, da se na LCD v drugo vrstico izpišejo tudi trenutni obrati/minuto ( RPM ).

Na spletu sem našel kodo, ki deluje, jo pa ne znam "vkomponirati" v zgornjo kodo, da bi se to istočasno izvajalo.

lp,marko

Koda:


unsigned long start;
const byte encoderPinA = 2;//A pin -> interrupt pin 0
const byte encoderPinB = 3;//B pin -> digital pin 3
volatile long pulse;
volatile bool pinB, pinA, dir;
const byte ppr = 10, upDatesPerSec = 2;
const int fin = 1000 / upDatesPerSec;
const float konstant = 60.0 * upDatesPerSec / (ppr * 2);
int rpm;


void setup() {
  Serial.begin(9600);
  attachInterrupt(0, readEncoder, CHANGE);
  pinMode(encoderPinA,INPUT);
  pinMode(encoderPinB,INPUT);
}

void loop() {
  if(millis() - start > fin)
  {
    start = millis();
    rpm = pulse * konstant;
    Serial.println(rpm);
    pulse = 0;
  }
}

void readEncoder()
{
  pinA = bitRead(PIND,encoderPinA);
  pinB = bitRead(PIND,encoderPinB);
  dir = pinA ^ pinB;          // if pinA & pinB are the same
  dir ? --pulse : ++pulse;    // dir is CW, else CCW
}
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
gustinmi
Član
Član



Pridružen-a: Tor 26 Feb 2019 13:41
Prispevkov: 14
Aktiv.: 1.77

PrispevekObjavljeno: Sre Maj 22, 2019 2:21 pm    Naslov sporočila:  Naslov sporočila: Arduino UNO in encoder Odgovori s citatom

Encoder bi bilo res najbolj efektivno narediti v AVR zbirniku, z uporabo prekinitev na pinih (katerikoli PIN je lahko konfiguriran kot interrupt pin).

Rečeno je (za ATMEGA328, Arduino UNO):

"The interrupt execution response for all the enabled AVR interrupts is four clock cycles minimum."

To pomeni 4 x 62.5 ns se porabi za odziv na prekinitev (beri spremembo stanja na pinu). (16 MHZ).

Še opozorilo pred rabo DELAY - to dejansko blokira procesor in se dodaja na časovno os izvajanja. Ni najboljša strategija za merjenje nečesa.

Če ti slučajno zbirnik ni tuj, si poglej demo kodo za delo z prekinitvami : [url] https://github.com/gustinmi/avr-programming/blob/master/AssemblerApplication1/AssemblerApplication1/main.asm [/url]
Nazaj na vrh
Odsoten 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
Stran 3 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: 174 dni


Powered by phpBB © 2001, 2005 phpBB Group