I have been given to understand the ATTiny88 is very similar to the Arduino Uno / ATMega328 MCU. There does not seem to be a tag for the ATTiny88, so that is why I chose the tags I did. I do not have a high enough reputation to create a tag, yet. Thanks to the generous help of timemage, Edgar Bonet, and others, my MCU board is now responding, albeit very erratically, to pulses on pins 12 and 13, designated Phase_B and Phase_A, respectively, in the code below. I have not yet entirely ruled out a hardware issue (I will do so), but a software issue is still likely. I don't quite know what. The MCU is registering pulses, but it very often misses large numbers of turns in either direction. What's more, it frequently reports the wrong direction, strongly favoring a CW rotation, but sometimes reporting a CCW rotation when the knob is turned CW. It is definitely not an overflow issue, as the anomalous effects are seen in abundance when in the mid range of the variables.
#include <Arduino.h>
#include <TM1637Display.h>
#include "PinChangeInterrupt.h"
volatile uint8_t counter = 0;
volatile bool Update = false;
volatile int currentStatePhase_B;
volatile int lastStatePhase_B;
volatile int pulses = 0;
// Shutdown Output
#define SW 11
// Rotary Encoder Inputs
#define Phase_A 13
#define Phase_B 12
// TM1637 I/O ports
#define DIO 3
#define CLK 4
TM1637Display display(CLK, DIO);
void setup() {
// Set encoder pins as inputs
pinMode(Phase_A,INPUT);
pinMode(Phase_B,INPUT);
pinMode(SW, OUTPUT);
// Read the initial state of Phase_B
lastStatePhase_B = digitalRead(Phase_B);
// Call updateEncoder() when any high/low changed seen
// on interrupt 0 (pin 2), or interrupt 1 (pin 3)
attachPCINT(digitalPinToPCINT(Phase_A), updateEncoder, RISING);
attachPCINT(digitalPinToPCINT(Phase_B), updateEncoder, RISING);
display.setBrightness(0x0f);
display.clear();
display.showNumberDec(0, false);
}
void loop() {
if (Update){
// Show decimal numbers with/without leading zeros
display.showNumberDec(pulses, false);
delay(1000);
display.showNumberDec(counter, false);
Update = false;
}
}
void updateEncoder(){
// Read the current state of Phase_B
currentStatePhase_B = digitalRead(Phase_B);
// If last and current state of Phase_B are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStatePhase_B != lastStatePhase_B && currentStatePhase_B == 1){
// If the Phase_A state is different than the Phase_B state then
// the encoder is rotating CCW so decrement
if (digitalRead(Phase_A) != currentStatePhase_B) {
counter --;
} else {
// Encoder is rotating CW so increment
counter ++;
}
}
if (counter > 1023){
counter = 1023;
}
if (counter < 0){
counter = 0;
}
pulses ++;
// Remember last Phase_B state
lastStatePhase_B = currentStatePhase_B;
Update = true;
}
counter
depending on the state of phase_B ... also setUpdate
flag