Go Down

Topic: PGA2310/11 with Quadrature Rotary Encoder  (Read 62 times) previous topic - next topic

teecham

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

Code: [Select]

/*
  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;
  }
}



Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy