Koda: |
noInterrupts(); // prepreči spremembo obrat in count obrat4lcd = obrat; // shrani njuni trenutni vrednosti count4lcd = count; interrupts(); // dovoli spreminjanje |
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--; } } } |
Koda: |
obrat = count / 10 |
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; } |
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. |
Jaka57 je napisal/a: |
Da ne boste o poskakovanju, je tukaj pdf.
Očitno ga je edino ElGrigon pogledal. |
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 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. |
Koda: |
attachInterrupt(0, doEncoder, FALLING); // CHANGE |
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. |
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 } } } |
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 } |
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 } } |