Dear members,
I am a newbie to programming and just started to learn. Arduino is the ideal start environment for the uninitiated like me.
I found this code for PGA2310/11 on the internet which works perfectly with an IR, I wanted to add additional functionality through a quadrature rotary encoder, I found a working code for EC1 series of encoder, the code uses timer 1.
However, when I combine the encoder code with the PGA code, IR still works but the encoder doesnt, I was wondering if experts can can provide some help. Here is the code. Encoder code original is attached as zip file. :o :o :o
/*
Arduino pins:
- digital pin 13 (SCK) = SPI SCLK (PGA2311 pin 6)
- digital pin 12 (MISO) = not used
- digital pin 11* (MOSI) = SPI SDI/MOSI (PGA2311 pin 3)
- digital pin 10* (SS) = SPI \CS (PGA2311 pin 2)
- digital pin 9* = LCD Red (LCD pin RED)
- digital pin 8 = LCD RS (LCD pin RS)
- digital pin 7 = LCD Enable (LCD pin E)
- digital pin 6* = IR receiver data
- digital pin 5* = LCD D4 (LCD pin D4)
- digital pin 4 = LCD D5 (LCD pin D5)
- digital pin 3* = LCD D6 (LCD pin D6)
- digital pin 2 = LCD D7 (LCD pin D7)
- digital pin 1 = not connected
- digital pin 0 = not connected
is a PWM pin
LCD schematic
LCD R/W pin to ground
10K resistor:
ends to +5V and ground
wiper to LCD VO pin (pin 3)
IR detector data = pin 6
PGA2311 gain: N = 1 to 255
Gain (dB) = 31.5 − [0.5*(255 − N)]
SPI interface:
/CS (pin 2)
SCLK (pin 6)
SDI (pin 3)
SDO (pin 7)
Encoder
Analog pin 0 = Encoder Pin A
Analog pin 1 = Encoder Pin B
Analog pin 2 = Encoder Switch
*/
#include <IRremote.h>
#include <LiquidCrystal.h>
#include <stdlib.h>
#include <SPI.h>
#include <ClickEncoder.h>
#include <TimerOne.h>
int redPin = 9;
int red = 0;
const int slaveSelectPin = 10;
int RECV_PIN = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
LiquidCrystal lcd(8, 7, 5, 4, 3, 2); // RS, Enable, D4, D5, D6, D7
char cGain[17];
String gain;
char icGain[6];
float iGain = -95.5;
float nGain = 1;
boolean mute = false;
// custom LCD characters for the volume bar
byte v0[8] = {B00000, B00000, B00000, B00000, B00000, B00000, B00000};
byte v1[8] = {B00000, B00000, B00000, B00000, B00000, B00000, B11111};
byte v2[8] = {B00000, B00000, B00000, B00000, B00000, B11111, B11111};
byte v3[8] = {B00000, B00000, B00000, B00000, B11111, B11111, B11111};
byte v4[8] = {B00000, B00000, B00000, B11111, B11111, B11111, B11111};
byte v5[8] = {B00000, B00000, B11111, B11111, B11111, B11111, B11111};
byte v6[8] = {B00000, B11111, B11111, B11111, B11111, B11111, B11111};
byte v7[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111};
ClickEncoder *encoder;
int16_t last, value;
void timerIsr() {
encoder->service();
}
void setup() {
lcd.createChar(0, v0);
lcd.createChar(1, v1);
lcd.createChar(2, v2);
lcd.createChar(3, v3);
lcd.createChar(4, v4);
lcd.createChar(5, v5);
lcd.createChar(6, v6);
lcd.createChar(7, v7);
lcd.begin(16, 2);
pinMode(redPin, OUTPUT);
analogWrite(redPin, red);
lcd.write(" HiFi IR Volume ");
irrecv.enableIRIn();
pinMode(slaveSelectPin, OUTPUT);
SPI.begin();
encoder = new ClickEncoder(A1, A0, A2);
Timer1.initialize(1000);
Timer1.attachInterrupt(timerIsr);
last = -1;
}
void decodeIR(int value) {
switch (value) {
case 0xFF22DD:
mute = !mute;
lcd.setCursor(0, 0);
if (mute == true) {
lcd.write("Muted ");
setGain(1);
}
if (mute == false) {
setGain(nGain);
setVolumeBar(nGain);
}
delay(1000);
break;
case 0xFFC23D:
if (nGain < 255) {
nGain = nGain + 1;
setGain(nGain);
setVolumeBar(nGain);
}
else {
lcd.setCursor(0, 0);
lcd.write("Maximum Reached");
delay(500);
}
break;
case 0xFF629D:
if (nGain > 1) {
nGain = nGain - 1;
setGain(nGain);
setVolumeBar(nGain);
}
else {
lcd.setCursor(0, 0);
lcd.write("Minimum Reached ");
delay(500);
}
break;
}
red = nGain;
analogWrite(redPin, ~red);
}
void getValue(int value) {
if (value >0) {
if (nGain < 255) {
nGain = nGain + 1;
setGain(nGain);
setVolumeBar(nGain);
}
else {
lcd.setCursor(0, 0);
lcd.write("Maximum Reached");
delay(500);
}
}
if (value <0) {
if (nGain > 1) {
nGain = nGain - 1;
setGain(nGain);
setVolumeBar(nGain);
}
else {
lcd.setCursor(0, 0);
lcd.write("Minimum Reached ");
delay(500);
}
}
}
void setGain(int nGain) {
digitalWrite(slaveSelectPin, LOW);
SPI.transfer(nGain); // right channel
SPI.transfer(nGain); // left channel
digitalWrite(slaveSelectPin, HIGH);
}
void setVolumeBar(int nGain) {
// convert gain to a decibal string, and write to the lcd
iGain = 31.5 - 0.5 * (255 - float(nGain));
gain.toCharArray(icGain, 6);
dtostrf(iGain, 4, 1, icGain);
gain = String(icGain);
lcd.clear();
("Volume: " + gain + " dB").toCharArray(cGain, 17);
lcd.setCursor(0, 0); //first line
lcd.write(cGain);
// write the volume bar
lcd.setCursor(0, 1); //second line
for (int i = 0; i < 16; i++) {
if (nGain / 2 > i * 8) {
lcd.setCursor(i, 1);
lcd.write(round(i / 2));
}
}
}
void loop() {
// receive an IR signal
if (irrecv.decode(&results)) {
decodeIR(results.value);
irrecv.resume();
}
value += encoder->getValue();
if (value != last) {
last = value;
}
}
encoder-arduino.zip (6.76 KB)