mr_wibble
Beer Odd
Hi-yas,
I have a rotary encoder: http://australia.rs-online.com/web/p/optical-rotary-encoders/6633182/?origin=PSF_433027
Data Sheet: http://australia.rs-online.com/web/p/optical-rotary-encoders/6633176/
I wired in two 0.10 uF capacitors across the encoder pins to ground, this helped debouncing a much cheaper (non-optical) encoder I was playing with.
I want to use it for setting the temperature on my HLT.
Eventually the Arduino will drive a relay, to switch the heating element, but that's for another post.
Right now the encoder is doing my head in.
It mostly works.
Turn the knob one way, and the set-temperature increases, turn it the other, and it decreases.
However, if you give it a good flick, sometimes the reading jumps backwards, despite a forward turn (and vice-versa).
For example, say it's already it's at 100, if I turn the knob quickly to *add* more temperature, it can jump back to say 95 and start increasing again from there.
Is it emitting signals too fast for the poor little Arduino to catch them all?
Maybe I'm dropping interrupts?
It's not a big problem, but it's rubbing my inner perfectionist in entirely the wrong way.
I haven't coded stuff this low-level since I used to do z80 assembly language as a kid.
Any help much appreciated.
I have a rotary encoder: http://australia.rs-online.com/web/p/optical-rotary-encoders/6633182/?origin=PSF_433027
Data Sheet: http://australia.rs-online.com/web/p/optical-rotary-encoders/6633176/
I wired in two 0.10 uF capacitors across the encoder pins to ground, this helped debouncing a much cheaper (non-optical) encoder I was playing with.
I want to use it for setting the temperature on my HLT.
Eventually the Arduino will drive a relay, to switch the heating element, but that's for another post.
Right now the encoder is doing my head in.
It mostly works.
Turn the knob one way, and the set-temperature increases, turn it the other, and it decreases.
However, if you give it a good flick, sometimes the reading jumps backwards, despite a forward turn (and vice-versa).
For example, say it's already it's at 100, if I turn the knob quickly to *add* more temperature, it can jump back to say 95 and start increasing again from there.
Is it emitting signals too fast for the poor little Arduino to catch them all?
Maybe I'm dropping interrupts?
It's not a big problem, but it's rubbing my inner perfectionist in entirely the wrong way.
I haven't coded stuff this low-level since I used to do z80 assembly language as a kid.
Any help much appreciated.
Code:
/*
* Test sketch to handle a rotary encoder for setting kettle temperature
* NOTE: Fails to handle very fast turns
*/
#define ENCODER_PIN_A 2 /* must be pin2 for interrupt */
#define ENCODER_PIN_B 3 /* must be pin3 for interrupt */
#define ENCODER_BUTTON_PIN 4
/* Temperature is an integer for speed, divide by 10 for the real value */
#define TEMPERATURE_DEFAULT 500
#define TEMPERATURE_STEP 5
#define TEMPERATURE_MAX 1000
#define TEMPERATURE_MIN 0
volatile int temperature_setpoint = TEMPERATURE_DEFAULT;
void setup()
{
pinMode(ENCODER_PIN_A, INPUT);
pinMode(ENCODER_PIN_B, INPUT);
pinMode(ENCODER_BUTTON_PIN, INPUT);
digitalWrite(ENCODER_PIN_A, HIGH); // turn on pullup resistor
digitalWrite(ENCODER_PIN_B, HIGH); // turn on pullup resistor
digitalWrite(ENCODER_BUTTON_PIN, HIGH); // turn on pullup resistor
// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, encoderPinChanged, RISING); //CHANGE);
Serial.begin(115200);
}
void loop()
{
static int last_printed = 0;
/* Only write the temperature if it changes */
if (abs(temperature_setpoint - last_printed) > 0)
{
last_printed = temperature_setpoint;
float setpoint = (float)temperature_setpoint / 10.0;
Serial.print("Set Temp: "); Serial.println(setpoint);
}
/* poll for encoder button presses */
if (digitalRead(ENCODER_BUTTON_PIN) == LOW)
{
temperature_setpoint = TEMPERATURE_DEFAULT;
Serial.println("Reset Temp");
delay(200);
}
}
// Interrupt on either encoder line A or B changing state
void encoderPinChanged()
{
noInterrupts();
int pin_a = digitalRead(ENCODER_PIN_A);
int pin_b = digitalRead(ENCODER_PIN_B);
if (pin_a == HIGH)
{
if (pin_b == LOW)
{
temperature_setpoint -= TEMPERATURE_STEP; // CCW
if (temperature_setpoint < TEMPERATURE_MIN)
temperature_setpoint = TEMPERATURE_MIN;
}
else
{
temperature_setpoint += TEMPERATURE_STEP; // CW
if (temperature_setpoint > TEMPERATURE_MAX)
temperature_setpoint = TEMPERATURE_MAX;
}
}
else // pin_a == LOW
{
if (pin_b == LOW)
{
temperature_setpoint += TEMPERATURE_STEP; // CW
if (temperature_setpoint > TEMPERATURE_MAX)
temperature_setpoint = TEMPERATURE_MAX;
}
else
{
temperature_setpoint -= TEMPERATURE_STEP; // CCW
if (temperature_setpoint < TEMPERATURE_MIN)
temperature_setpoint = TEMPERATURE_MIN;
}
}
interrupts();
}