| General > General Technical Chat |
| Schmitt Buffer/Trigger with Encoder and buttons - Inverting... |
| << < (6/8) > >> |
| elcrni:
Something like this, seems to work... again, uses 2 pins, not sure how i do it with one pin though. --- Code: ---#define encoderA 2 #define encoderB 3 volatile int8_t altAB = 0; volatile int encoderCount = 0; int8_t steps[16] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; ISR(TIMER1_COMPA_vect) { altAB <<= 2; altAB &= B00001100; altAB |= (digitalRead(encoderA) << 1) | digitalRead(encoderB); encoderCount += steps[altAB]; } void setup() { pinMode(encoderA, INPUT); pinMode(encoderB, INPUT); noInterrupts(); TIMSK1 |= (1<<OCIE1A); TCCR1A = 0; TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10); // Frequency = 16000000 / 1024 / 31 = sampling rate; OCR1A = 31; interrupts(); } void loop() { } --- End code --- btw, i would love to test this frequency but not sure how to connect the oscilloscope, to what pins that is Many thanks, Alek |
| MarkF:
You will have to check my code. I typically use Microchip PIC processors and rarely do any Arduino coding. :D Answer to #1: Two pins, one read. You have pins 2 and 3 for the encoder. I believe these are PortB bits 2 and 3. Let's assume the encoder switch is on pin 1 (PortB bit 1) with pull-up resistor. Answer to #2: To check the ISR() timing with a Mega pin, pick an unused pin and toggle it inside the ISR() routine. Let's pick pin 0 (PortB bit 0) for timing check. Hence: --- Code: --- // global variables int count=0; // encoder turn count used in loop() function uint8_t sw0=0; // encoder switch flag used in loop() function uint8_t last_sw0=0; ISR(TIMER1_COMPA_vect) { uint8_t pins, pinA, pinB, pinS; digitalWrite(0, HIGH); // set pin 0 high when entering ISR(), check this pin with scope // Read encoder pins = PORTB; // Read both encoder inputs at once to avoid any time delay between pin sampling pinS = (pins >> 1) & 0x01; // encoder switch pinA = (pins >> 2) & 0x01; // encoder A pinB = (pins >> 3) & 0x01; // encoder B // Decode gray_code . . . // Encoder switch if (last_sw0 != 0 && pinS == 0) { sw0 = 1; // set switch flag when depressed } last_sw0 = pinS; digitalWrite(0, LOW); // set pin 0 low when leaving ISR() } void loop() { int local_count; if (count != 0) { local_count = count; count = 0; // reset encoder turn count // process encoder turns here using local_count variable . . . } if (sw0) { sw0 = 0; // reset encoder switch flag // process encoder switch depressed . . . } // Do non-encoder tasks here . . . } void setup() { pinMode(0, OUTPUT); // scope timing check pinMode(1, INPUT); // encoder switch pinMode(2, INPUT); // encoder A pinMode(3, INPUT); // encoder B } --- End code --- |
| MarkF:
In order to read Port B, I believe the command should be pins = PINB; and not pins = PORTB; |
| elcrni:
Many thanks MarkF. In a meantime i got the code changed: --- Code: ---#define encoderA 2 #define encoderB 3 volatile int encoderCount = 0; boolean A_set = false; boolean B_set = false; ISR(TIMER1_COMPA_vect) { if ( digitalRead(encoderA) != A_set ) { // debounce once more A_set = !A_set; if ( A_set && !B_set ) encoderCount ++; } if ( digitalRead(encoderB) != B_set ) { B_set = !B_set; if ( B_set && !A_set ) encoderCount --; } } void setup() { pinMode(encoderA, INPUT); pinMode(encoderB, INPUT); TIMSK1 |= (1<<OCIE1A); TCCR1A = 0; TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10); // Frequency = 16000000 / 1024 / 15 = sampling rate; OCR1A = 31; sei(); Serial.begin(115200); } void loop() { while(true) { Serial.println(encoderCount); delay(100); } } --- End code --- I added Serial just so i can check if it's working. It does work, nicely, although on restart it starts at 1 rather than at 0, for some reason, but it works. Now, will have to study your code, seems more elegant to my untrained eye :-) thanks, Alek |
| MarkF:
I would set the prescaler to 256 and the OCR1A to 125. You do not want a fractional divisor. In your case the timing is not critical. Best case is to always try to have an integer divisor. 16000000 / 256 / 500 = 125 16000000 / 1024 / 500 = 31.25 |
| Navigation |
| Message Index |
| Next page |
| Previous page |