Απάντηση: Re: Υλοποίηση preamplifier PGA23xx
Ξεκίνησα να παίζω και γω με το συγκεκριμένο PGA. To άρχισα με τα βασικά για να μάθω τη λειτουργία του μέχρι να ολοκληρώσετε το project σας.
Το βασικό κύκλωμα και κώδικα τον δανείστηκα από
http://irvolume.blogspot.gr/2014/02/this-project-remotely-controls-volume.html ενσωματώνοντας
και ένα rotary encoder. Μήπως Δημήτρη γνωρίζετε πως μπορούμε να περάσουμε τον κώδικα σε ένα Atiny2313 ώστε να λειτουργεί με αυτό το κύκλωμα και όχι με το arduino?
Παρακάτω ο κώδικας
#include <IRremote.h>
/*
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)
*/
#include <IRremote.h>
#include <LiquidCrystal.h>
#include <stdlib.h>
#include <SPI.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;
unsigned long currentTime;
unsigned long loopTime;
const int pin_A = 9; // pin 9
const int pin_B = 1; // pin 1
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
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};
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(pin_A, INPUT);
pinMode(pin_B, INPUT);
currentTime = millis();
loopTime = currentTime;
pinMode(slaveSelectPin, OUTPUT);
SPI.begin();
}
void decodeIR(int value) {
switch (value) {
case 16748655:
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 16756815:
if (nGain < 255) {
nGain = nGain + 1;
setGain(nGain);
setVolumeBar(nGain);
}
else {
lcd.setCursor(0, 0);
lcd.write("Maximum Reached");
delay(500);
}
break;
case 16773390:
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 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() {
// get the current elapsed time
currentTime = millis();
if(currentTime >= (loopTime + 5)){
// 5ms since last check of encoder = 200Hz
encoder_A = digitalRead(pin_A); // Read encoder pins
encoder_B = digitalRead(pin_B);
if((!encoder_A) && (encoder_A_prev)){
// A has gone from high to low
if(encoder_B) {
// B is high so clockwise
if (nGain < 255) {
nGain = nGain + 1;
setGain(nGain);
setVolumeBar(nGain);
}
else {
lcd.setCursor(0, 0);
lcd.write("Maximum Reached");
delay(500);
}
}
else {
// B is low so counter-clockwise
if (nGain > 1) {
nGain = nGain - 1;
setGain(nGain);
setVolumeBar(nGain);
}
else {
lcd.setCursor(0,0);
lcd.write("Minimum Reached ");
delay(500);
}
}
}
encoder_A_prev = encoder_A; // Store value of A for next time
loopTime = currentTime; // Updates loopTime
}
// receive an IR signal
if (irrecv.decode(&results)) {
decodeIR(results.value);
irrecv.resume();
}
}