#include <Wire.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// Define register values, etc to facilitate programming
// Note: Reg address is address plus R/W bit
// This is why the address here is different from the
// address in the data sheet
#define REG0 0 // Register 0 address (Volume Adjustment)
#define REG1 1 // Register 1 address (Volume Adjustment)
#define REG2 2 // Register 2 address (Volume Adjustment)
#define REG3 3 // Register 3 address (Volume Adjustment)
#define REG4 4 // Register 4 address (Volume Adjustment)
#define REG5 5 // Register 5 address (Volume Adjustment)
#define REG6 6 // Register 6 address (Volume Adjustment)
#define REG7 7 // Register 7 address (Volume Adjustment)
// The following to be used in Reg4
#define DEFAULTVOL 0x64 //-50 dB this is 50x2=100
#define MINVOL 0xC6 //-99dB this is 99X2=198. -Dac adjustment is .5 db
#define MAXVOL 0x00 //-0 dB
#define VOLUPPIN 4 // Button to increase volume
#define VOLDOWNPIN 2 // Button to decrease volume
#define IRPIN 3 // The pin for the remote sensor
#define VOLBUTTONPIN 38
#define KEY1 128 // The value when pressing the 1 key in remote
#define KEY2 129 // The value when pressing the 2 key in remote
#define KEY3 130 // The value when pressing the 3 key in remote
#define KEY4 131 // The value when pressing the 4 key in remote
#define KEY5 132 // The value when pressing the 5 key in remote
#define KEY7 134 // The value when pressing the 7 key in remote
#define KEY8 135 // The value when pressing the 8 key in remote
#define KEY9 136 // The value when pressing the 9 key in remote
#define KEYVOLUP 18 // The value when pressing volume up key in remote
#define KEYVOLDOWN 19 // The value when pressing volume down key in remote
#define KEYDISPLAY 186 // The value when pressing display key in remote
#define KEYPICTUREUP 152 // The value when pressing picture + key in remote
#define KEYPICTUREDOWN 153 // The value when pressing picture - key in remote
#define KEY1 1024 // The value when pressing 1 key in remote
#define KEY2 1025 // The value when pressing 2 key in remote
#define KEYYELLOW 462 // The value when pressing yellow text key in remote
#define IRFILSELDELAY 300 // Delay when selecting filter with remote to preven multiple selection
#define ONEPULSE 1000 // Microsecond threshold for value 1 in remote putlse
#define B 0xFF // The character for a completely filled box
#define A 0x20 // The character for blank
// The routine to create the custom characters in the LCD
void DefineLargeChar()
{
// A 1 in the binary representation of the character means it is filled in
// characters are 5 pixels wide by 8 pixels tall
// We need 7 custom characters for the OPUS DAC display.
// (Custom character 0 doesn't work in the Web4Robot LCD)
// Define Custom Characters
byte custchar1[8]= {B11100,B11110,B11111,B11111,B11111,B11111,B11111,B11111};
byte custchar2[8]= {B11111,B11111,B11111,B11111,B11111,B00000,B00000,B00000};
byte custchar3[8]={B00000,B00000,B00000,B11111,B11111,B11111,B11111,B11111};
byte custchar4[8]= {B11111,B11111,B11111,B11111,B11111,B11111,B01111,B00111};
byte custchar5[8]={B11111,B11111,B11111,B11111,B11111,B11111,B00000,B00000};
byte custchar6[8]={B00000,B11111,B11111,B11111,B11111,B11111,B00000,B00000};
byte custchar7[8]= {B00000,B11100,B11110,B11111,B11111,B11111,B11111,B11111};
lcd.createChar(1, custchar1);
lcd.createChar(2, custchar2);
lcd.createChar(3, custchar3);
lcd.createChar(4, custchar4);
lcd.createChar(5, custchar5);
lcd.createChar(6, custchar6);
lcd.createChar(7, custchar7);
}
// Array index into parts of big numbers. Numbers consist of 9 custom characters in 3 lines
// 0 1 2 3 4 5 6 7 8 9
char bn1[]={B,2,1, 2,1,A, 2,2,1, 2,2,1, 3,A,B, B,2,2, B,2,2, 2,2,B, B,2,1, B,2,1};
char bn2[]={B,A,B, A,B,A ,3,2,2, A,6,1, 5,6,B, 5,6,7, B,6,7, A,3,2, B,6,B, 5,6,B};
char bn3[]={4,3,B, 3,B,3, B,3,3, 3,3,B, A,A,B, 3,3,B, 4,3,B, A,B,A, 4,3,B, A,A,B};
void printOneNumber(uint8_t digit)
{
// Print position is hardcoded
// Line 1 of the one digit number
lcd.setCursor(0,1);
lcd.write(bn1[digit*3]);
lcd.write(bn1[digit*3+1]);
lcd.write(bn1[digit*3+2]);
// Line 2 of the one-digit number
lcd.setCursor(0,2);
lcd.write(bn2[digit*3]);
lcd.write(bn2[digit*3+1]);
lcd.write(bn2[digit*3+2]);
// Line 3 of the one-digit number
lcd.setCursor(0,3);
lcd.write(bn3[digit*3]);
lcd.write(bn3[digit*3+1]);
lcd.write(bn3[digit*3+2]);
}
void printTwoNumber(uint8_t number)
{
// Print position is hardcoded
int digit0; // To represent the ones
int digit1; // To represent the tens
digit0=number%10;
digit1=number/10;
// Line 1 of the two-digit number
lcd.setCursor(13,1);
lcd.write(bn1[digit1*3]);
lcd.write(bn1[digit1*3+1]);
lcd.write(bn1[digit1*3+2]);
lcd.write(A); // Blank
lcd.write(bn1[digit0*3]);
lcd.write(bn1[digit0*3+1]);
lcd.write(bn1[digit0*3+2]);
// Line 2 of the two-digit number
lcd.setCursor(13,2);
lcd.write(bn2[digit1*3]);
lcd.write(bn2[digit1*3+1]);
lcd.write(bn2[digit1*3+2]);
lcd.write(A); // Blank
lcd.write(bn2[digit0*3]);
lcd.write(bn2[digit0*3+1]);
lcd.write(bn2[digit0*3+2]);
// Line 3 of the two-digit number
lcd.setCursor(13,3);
lcd.write(bn3[digit1*3]);
lcd.write(bn3[digit1*3+1]);
lcd.write(bn3[digit1*3+2]);
lcd.write(A); // Blank
lcd.write(bn3[digit0*3]);
lcd.write(bn3[digit0*3+1]);
lcd.write(bn3[digit0*3+2]);
}
// The write to ESS9008 DAC routine
void bufwritereg(uint8_t regaddr,uint8_t regval)
{
Wire.beginTransmission(0x48);
Wire.send(regaddr);
Wire.send(regval);
Wire.endTransmission();
}
// Interrupt service routine for rotary encoder. Determines direction.
volatile byte volUp=0; // flags for the interrupt routine
volatile byte volDown=0;
void decoder()
{
if (digitalRead(2) == digitalRead(4))
{
volUp = 1; //if on interrupt the encoder channels are the same, direction is clockwise
}
else
{
volDown = 1; //if they are not the same, direction is ccw
}
}
// interrupt service routine for remote
volatile byte remoteOn = 0; // 1 means remote has been pressed
void remoting()
{
remoteOn=1;
}
// Declaring some more variables
int currVol=DEFAULTVOL; // this needs to be at least 10 bits
byte regval=0; // variable for volume lower bits
int irCode=0; // The code returned by the remote IR pulses
// This is the main decoding code for the remote.
int getIRKey() {
int duration=1;
int result=0;
while((duration=pulseIn(IRPIN, LOW, 50000)) < 2200 && duration!=0)
{
//do nothing waiting for start pulse
}
int mask = 1; // set mask to bit 0
for (int idx = 0; idx < 12; idx++) // get all 12 bits
{
duration = pulseIn(IRPIN, LOW, 2000); // measure the bit pulse
if (duration > ONEPULSE) // 1 bit?
result |= mask; // yes, update ir code
mask <<= 1; // shift mask to next bit
}
return result;
}
void setup() {
lcd.begin(20, 4);
lcd.clear();
DefineLargeChar(); // Define large characters
Wire.begin(); // Joining the I2C bus as master
pinMode(VOLUPPIN, INPUT); // Button or Encoder pin for volume up
digitalWrite(VOLUPPIN, HIGH); // Enable pull-up resistor
pinMode(VOLDOWNPIN, INPUT); // Button or Encoder pin for volume down
digitalWrite(VOLDOWNPIN, HIGH); // Enable pull-down resistor
pinMode(IRPIN, INPUT); // Pin for IR Receiver
digitalWrite(IRPIN, HIGH); // Enable high as specified by datasheet
delay(3000);
// The following lines is to set up the default volume
// To set up the volume you need to write to at least 8 registers
regval=DEFAULTVOL;
bufwritereg(REG0,regval);
bufwritereg(REG1,regval);
bufwritereg(REG2,regval);
bufwritereg(REG3,regval);
bufwritereg(REG4,regval);
bufwritereg(REG5,regval);
bufwritereg(REG6,regval);
bufwritereg(REG7,regval);
attachInterrupt(0, decoder, CHANGE); // ISR for rotary encoder
attachInterrupt(1, remoting, RISING); // ISR for remote IR sensor
lcd.setCursor(0,0);
// print header for current input
printOneNumber(1);
// print header for volume
lcd.setCursor(13,0);
lcd.print("-dB VOL");
printTwoNumber(currVol/2);
// Print the rest of the display
lcd.setCursor(4,2);
lcd.print("INPT");
lcd.write(0xA5);
lcd.print("PCM");
lcd.setCursor(4,1);
lcd.print("RATE");
lcd.write(0xA5);
lcd.print("192");
}
void loop()
{
// The following is to adjust the volume down (larger number)
while(volUp==1) // While there is CW motion in the rotary encoder
{
volUp=0; // Reset the flag
if (currVol<MINVOL)// Check if already at min numerical Volume
{
currVol=currVol+1; // Increase 0.5 dB
regval=currVol;
bufwritereg(REG0,regval); // Writing to reg 0
bufwritereg(REG1,regval);
bufwritereg(REG2,regval);
bufwritereg(REG3,regval);
bufwritereg(REG4,regval);
bufwritereg(REG5,regval);
bufwritereg(REG6,regval);
bufwritereg(REG7,regval);
printTwoNumber(currVol/2);
}
}
// The following is to adjust the volume up (smaller numbers)
while(volDown==1) // While there is ccw motion in rotary encoder
{
volDown=0; // clear the flag
if (currVol>MAXVOL) // Check if already at max Volume
{
currVol=currVol-1; // Decrease 0.5 dB
regval=currVol; // Calculate value for reg0
bufwritereg(REG0,regval); // Writing to reg 0
bufwritereg(REG1,regval);
bufwritereg(REG2,regval);
bufwritereg(REG3,regval);
bufwritereg(REG4,regval);
bufwritereg(REG5,regval);
bufwritereg(REG6,regval);
bufwritereg(REG7,regval);
printTwoNumber(currVol/2);
}
}
// The following code is for the remote.
while (remoteOn==1)
{
irCode = getIRKey(); //Fetch the key
//lcd.setCursor(4,3); // Used to find out remote keys value
//lcd.print(" ");
//lcd.setCursor(4,3); // Used to find out remote keys value
//lcd.print(irCode);
switch(irCode){
case KEY1:
printOneNumber(1);
break;
case KEY2:
printOneNumber(2);
break;
// The following for volume
case KEYVOLUP:
if (currVol<MINVOL)// Check if already at min numerical Volume
{
currVol=currVol+1; // Increase 0.5 dB
regval=currVol; // Calculate value for reg0
bufwritereg(REG0,regval); // Writing to reg 0
bufwritereg(REG1,regval);
bufwritereg(REG2,regval);
bufwritereg(REG3,regval);
bufwritereg(REG4,regval);
bufwritereg(REG5,regval);
bufwritereg(REG6,regval);
bufwritereg(REG7,regval);
printTwoNumber(currVol/2);
}
break;
case KEYVOLDOWN:
if (currVol>MAXVOL) // Check if already at max Volume
{
currVol=currVol-1; // Decrease 0.5 dB
regval=currVol;
bufwritereg(REG0,regval); // Writing to reg 0
bufwritereg(REG1,regval);
bufwritereg(REG2,regval);
bufwritereg(REG3,regval);
bufwritereg(REG4,regval);
bufwritereg(REG5,regval);
bufwritereg(REG6,regval);
bufwritereg(REG7,regval);
printTwoNumber(currVol/2);
}
break;
}
remoteOn=0; //reset flag
}
}
Κυριακή 6 Δεκεμβρίου 2009
The Buffalo Code so far....
Here is the latest code. Most sections were derived from HIFIDUINO- glt's work - appropriate thanks are due!
Εγγραφή σε:
Σχόλια ανάρτησης (Atom)
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου