Encoder with atmega168pa

Hi all! I decided to make blinking LEDs using an atmega168pa encoder. Individually, the LEDs "run" perfectly to the left when the encoder is turned to the left and to the right when the encoder is turned to the right. I have a conflict when combining these modes so that the LEDs blink left and right. What could be the problem? Here is my code:

ISR(ADC_vect) {
	//PORTC |= (1 << PC1); // turn on the LED clockwise
	
	uint16_t val = ADC;

	// Determine the current state of the encoder depending on the value on pin PC3
	if (val > 1023 * 0.95) {
		enc_state = 0b00000000;
		
		} else if (val > 1023 * 0.47 && val < 1023 * 0.53) { // according to documentation (val > 1023 * 0.47 && val < 1023 * 0.53)
		enc_state = 0b00000010;
		
		} else if (val > 1023 * 0.37 && val < 1023 * 0.43) {	// according to documentation (val > 1023 * 0.37 && val < 1023 * 0.43)
		enc_state = 0b00000011;
		
		} else if (val > 1023 * 0.65 && val < 1023 * 0.68) {	// according to documentation (val > 1023 * 0.65 && val < 1023 * 0.68)
		enc_state = 0b00000001;	
		
		} 		
		
			if (enc_state != lastState) { // if the state has changed
			
			if ((lastState == 0b00000001 && enc_state == 0b00000011) || // if the sequence is 01 -> 11 -> 10 -> 00
			(lastState == 0b00000011 && enc_state == 0b00000010) ||
			(lastState == 0b00000010 && enc_state == 0b00000000) ||
			(lastState == 0b00000000 && enc_state == 0b00000001)) {
				
				enc_dir = 1;
				PORTC &= ~(_BV(PC0)); // turn off the LED counterclockwise
				PORTC |= _BV(PC1); // turn on the LED clockwise
			}
			
			else if ((lastState == 0b00000001 && enc_state == 0b00000000) || // if the sequence is 01 -> 00 -> 10 -> 11
			(lastState == 0b00000000 && enc_state == 0b00000010) ||
			(lastState == 0b00000010 && enc_state == 0b00000011) ||
			(lastState == 0b00000011 && enc_state == 0b00000001)) {

				enc_dir = -1;
				PORTC &= ~(_BV(PC1)); // turn off the LED clockwise
				PORTC |= _BV(PC0); // turn on the LED counterclockwise
			}
			else{
				enc_dir = 0;
			}
		}
		lastState = enc_state; // remember the current state of the encoder
		_delay_us(60);
		ADCSRA |= (1 << ADSC); // Starting the next measurement
	}

Please post your entire sketch

I posted the critical code of my project in full.

No, you did not. You have several variables in your ISR that are not declared in the code you posted. Nobody else knows what type they are.
Nobody knows how you have configured the ADC to generate interrupts since that code is not shown either.
Nobody knows what _delay_us(60) does since it is not defined. Interrupts are not running when it is called so it better not be using micros().

Again, please post your entire sketch that people can copy and compile. Help others help you.

why are you reading the encoder as an analog input instead of as 2 digital inputs?
doesn't each encoder output have pullup resistors

why doesn't the ISR just handle the encoder, why are the LEDs processed within the ISR?

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.