Hi folks,
Newbie here needing a little help.
I'm using a rotary encoder, sensed through the Uno interrupts.
The volatile variable used to control the effective volume is encoderPos,
this value is supposed to be among 0 and 255. I've added two lines of code to avoid that
the count continues after reaching the Max Val of 255, same for Min Val, i.e. 0.
This value is then converted in binary form to be used by the volume controlling external circuitry.
I'm also using an IR remote function, however, in the listed code below, I skipped it, as it works just fine.
The problem is just on the interrupt/encoder section.
The problem is:
when the encoderPos variable value reaches '0', which is supposed to be the minimum
allowed, if I continue turning the rotary encoder down, I still get pulses on the binary decoded output,
when reaching maximum (255), turning the encoder up, gives neg. pulses for a split second to the decoded bit port.
that is an 8-bit parallel port, named ledPin.
In words, when at min. (0), the decoded bit port is '00000000', and it is supposed to remain
in this state even if I continue to decrease the rotary encoder.
By contrast, if I continue to decrease, for a fraction of a second I get '11111111' decoded.
The same specular things happens when at maximum value.
The decoded binary value is '11111111', and even if I encrease the encoder, it is supposed to remain there,
on the contrary, I get pulses of '00000000' whenever I continue to increase the encoder.
The strange thing is that I have this behaviour only using the rotary encoder, not if using the remote.
Something to do with the interrupts?
I came to a complete stop, can you help?
The code I'm using:
#include <boarddefs.h>
#include <IRremote.h>
#include <EEPROM.h>
int receiver = 13; // TSOP pin 1 to Arduino pin13
const int screenWidth = 128; // set Width for Right justification
const int dly1 = 90; // set delay for IR receiver antibounce
#define encDelay 120 // set delay for encoder anti-bounce
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;
/* -------------------------
-- Pin Assignments -----
------------------------
*/
enum PinAssignments {
encoderPinA = 2, //interrupt 2
encoderPinB = 3, //interrupt 3
clearButton = 4 //pushButton
};
/*
Variable declarations
*/
volatile int encoderPos = 0;
int lastReportedPos = 1;
int z = 0;
int volAddr1 = 0; //Address 1 for EEPROM Volume store
int volAddr2 = 1; //Address 2 for EEPROM Volume store
int volAddr3 = 2; //Address 3 for EEPROM Volume store
int volAddr4 = 3; //Address 4 for EEPROM Volume store
// Define variable to store last code received
unsigned long lastCode;
//8-bit parallel port
int ledPin[] = {5, 6, 7, 8, 9, 10, 11, 12}; //LSB to MSB
// D0 D1 D2 D3 D4 D5 D6 D7
boolean A_set = false;
boolean B_set = false;
//--------------------
//----- SET-UP -------
//--------------------
void setup() {
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(clearButton, INPUT);
digitalWrite(clearButton, HIGH);
for (int i = 0; i < 8; i++)
{
pinMode(ledPin[i], OUTPUT);
}
// encoder pin A on interrupt 0 (pin 2)
attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin B on interrupt 1 (pin 3)
attachInterrupt(1, doEncoderB, CHANGE);
irrecv.enableIRIn(); // Start the receiver
}
/* -------------------------
----- App start ---------
-------------------------
*/
void loop(void) {
/*
Rotary encoder position limited between 0 and 255
*/
if (encoderPos > 255) {
encoderPos = 255;
}
if (encoderPos < 0) {
encoderPos = 0;
}
//calculate 'z' for dB print
z = (128 - ((encoderPos + 1) / 2.0)) * 10;
if (lastReportedPos != encoderPos) {
lastReportedPos = encoderPos;
displayBinary(encoderPos); // 8-bit parallel port decoding
delay(10);
}
/* --------
--MUTE--
--------
*/
if (digitalRead(clearButton) == LOW) {
encoderPos = 0;
}
/* -----------------
---IR Receiver---
-----------------
*/
//skipped
} //end loop
/* -----------
Subroutines
-----------
*/
// Interrupt on A changing state
void doEncoderA() {
// Test transition
A_set = digitalRead(encoderPinA) == HIGH;
// and adjust counter + if A leads B
encoderPos += (A_set != B_set) ? +1 : -1;
delay(encDelay);
}
// Interrupt on B changing state
void doEncoderB() {
// Test transition
B_set = digitalRead(encoderPinB) == HIGH;
// and adjust counter + if B follows A
encoderPos += (A_set == B_set) ? +1 : -1;
delay(encDelay);
}
// decimal to 8-bit binary converter
void displayBinary(byte numToShow)
{
for (int i = 0; i < 8; i++)
{
if (bitRead(numToShow, i) == 1)
{
digitalWrite(ledPin[i], HIGH);
}
else
{
digitalWrite(ledPin[i], LOW);
}
}
}