H I F I D U I N O

Arduino code for HIFIDUINO project

Code v 0.7

Posted by downloadcode on June 22, 2009

/*
Hifiduino v 0.7
June 21, 2009
In this release:
- Support for Web4robot LCD
- Large number display for filter selection and volume
- Digital Filter Selection: Filter 1 to Filter 5.
- Rotary encoder.
- Volume Control. Now -99 db to 0db in 1db increment.
- Volume "dimmer". Volume dims to -60 dB when pushing rotary encoder
- Changed the default delay in the LCD library to (0,0) See below note.
- Select input sample rate (low, med, high) for future use.
- Adjust brightness and contrast of display with remote
- Remember brightness and contrast settings in eeprom
- New fonts for large number display
*/

/*
Additional notes:
- The default delay for the web4robot LCD is (50,4)
  It can be changed with setDelay(Cmd,Char).
  In fact setDelay(0,0) works with the web4robot display
  at least in this code, making it fairly fast
*/

#include <Wire.h>
#include "macros.h" // Used for defining custom characters
#include
LCDi2cW lcd = LCDi2cW(4,20,0x4C,0);

// We will use the eeprom to store values
#include <EEPROM.h>
#define BRIADDR 0  // The address to store brightness value
#define CONADDR 1  // The address to store contrast value

// 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 REG9 0x12     // Register 9 address (Reset)
#define RESET 0x00    // Write anything to reset the DAC

#define REG7 0x0E     // Register 7 address (PCM vs DSD)
#define PCMHIGH 0x40  // Value for reg7 for PCM, High Sample rate for filter
#define PCMMED 0x20  // Value for reg7 for PCM, Medium Sample rate for filter
#define PCMLOW 0x00  // Value for reg7 for PCM, Low Sample rate for filter

#define REG6 0x0C     // Register 6 address (filters)
#define FILTER1 0x00  // PCM Filter response 1
#define FILTER2 0x01  // PCM Filter response 2
#define FILTER3 0x02  // PCM Filter response 3
#define FILTER4 0x03  // PCM Filter response 4
#define FILTER5 0x04  // PCM Filter response 5

#define REG0 0x00     // Register 0 address (Volume Adjustment)
#define REG1 0x02     // Register 1 address (Volume Adjustment)
#define REG2 0x04     // Register 2 address (Volume Adjustment)
#define REG3 0x06     // Register 3 address (Volume Adjustment)
#define REG4 0x08     // Register 4 address (Volume Control)

// The following to be used in Reg4
//#define VOLCNTR 0x07  // VolRight=VolLeft, AntiClip, Vol Ramping is on (a)
#define VOLCNTR 0x05  // VolRight=VolLeft, No AntiClip, Vol Ramping is on (b)
//#define MUTE 0x0F     // Mute and (a) above
#define MUTE 0x0D     // Mute and (b) above

#define DEFAULTVOL 0x190 //-50 dB this is 50x8=400
#define MINVOL 0x318    //-99dB this is 99X8=792. -Dac adjustment is .125 db
#define MAXVOL 0x00     //-0 dB
#define DIMVOL 0x1E0    //-60dB The volume level when dimming the volume

#define FILTERPIN 6     // Button to select Filter
#define VOLDIMPIN 5     // Button for volume dimming feature
#define VOLUPPIN 4      // Button to increase  volume
#define VOLDOWNPIN 2    // Button to decrease volume

#define IRPIN 3         // The pin for the remote sensor

#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 147       // The value when pressing volume up key in remote
#define KEYVOLDOWN 146     // 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 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

  uint8_t cc1[8] = {     // Custom Character 1
    B8(11100),
    B8(11110),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111)
  };

  uint8_t cc2[8] = {    // Custom Character 2
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(00000),
    B8(00000),
    B8(00000)
  };

  uint8_t cc3[8] = {    // Custom Character 3
    B8(00000),
    B8(00000),
    B8(00000),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111)
  };

  uint8_t cc4[8] = {   // Custom Character 4
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(01111),
    B8(00111)
  };

  uint8_t cc5[8] = {    // Custom Character 5
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(00000),
    B8(00000)
  };

  uint8_t cc6[8] = {    // Custom Character 6
    B8(00000),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(00000),
    B8(00000)
  };

  uint8_t cc7[8] = {     // Custom Character 7
    B8(00000),
    B8(11100),
    B8(11110),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111)
  };

  // send custom characters to the display
  lcd.load_custom_character(1,cc1);
  lcd.load_custom_character(2,cc2);
  lcd.load_custom_character(3,cc3);
  lcd.load_custom_character(4,cc4);
  lcd.load_custom_character(5,cc5);
  lcd.load_custom_character(6,cc6);
  lcd.load_custom_character(7,cc7);

}

// 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(1,0);
  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(2,0);
  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(3,0);
  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(1,13);
  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(2,13);
  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(3,13);
  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 WM8741 DAC routine
void opuswritereg(uint8_t regaddr,uint8_t regval)
{
  Wire.beginTransmission(0x1B);
  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;
}

// Routines for LCD Adjustment

// For LCD backlight adjustment
void BackLight(uint8_t bright)
{
  Wire.beginTransmission(0x4C);
  Wire.send(0xFE);
  Wire.send(0x03);
  Wire.send(bright);
  Wire.endTransmission();
  delay(25);
}

// For LCD contrast adjustment
void Contrast(uint8_t cont)
{
  Wire.beginTransmission(0x4C);
  Wire.send(0xFE);
  Wire.send(0x04);
  Wire.send(cont);
  Wire.endTransmission();
  delay(25);
}

// Declaring some more variables

int currVol=DEFAULTVOL; // this needs to be at least 10 bits
byte filter=0;          // variable for current filter
byte reg0val=0;         // variable for volume lower bits
byte reg1val=0;         // variable for volume upper bits
byte volDimState=0;     // State for volume dimmer. =1 is dimmed
byte BC=0;              // State for selecting contrast or brightness
                        // BC=0, no adjustment, BC=1" Brighness
                        // BC=2: contrast
int brightness=0;
int contrast=0;

int irCode=0;           // The code returned by the remote IR pulses

void setup() {
  lcd.init();     // Initializing the LCD, clears the display
  lcd.setDelay(0,0); // Change de delay in the LCD library 
  DefineLargeChar();  // Define large characters

  Wire.begin();   // Joining the I2C bus as master

  pinMode(FILTERPIN, INPUT);      // Button to select Input fiter
  digitalWrite(FILTERPIN, HIGH);  // Enable pull-up resistor

  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(VOLDIMPIN, INPUT);      // Button or switch for volume dimmer
  digitalWrite(VOLDIMPIN, HIGH);  // Enable pull-up resistor

  pinMode(IRPIN, INPUT);          // Pin for IR Receiver
  digitalWrite(IRPIN, HIGH);      // Enable high as specified by datasheet

  for(int i=0;i<4;i++)  // Wait for DAC to power up, just in case
    {
      lcd.setCursor(i,1);
      lcd.print("H I F I D U I N O");
      delay(800);
    }
  for(int i=0;i<4;i++)  // Wait a bit more
    {
      lcd.setCursor(i,1);
      lcd.print("                 ");
      delay(800);
    }

  opuswritereg(REG9,RESET);   // Resetting the DAC just in case
  opuswritereg(REG4,MUTE);    // MUTE (and vol setup) 

  // The following 4 lines is to set up the default volume
  // To set up the volume you need to write to at least 2 registers

  reg0val=(DEFAULTVOL & 0x1F);     // The lower 5 bits goes to reg 0
  opuswritereg(REG0,reg0val);      // Writing to reg 0
  reg1val=((DEFAULTVOL>>5)| 0x20); // The upper 5 bits goes to reg 1
  opuswritereg(REG1,reg1val);      // Writing to reg 1

  opuswritereg(REG6,FILTER1);  // I'm setting the default filter at power on
  opuswritereg(REG7,PCMHIGH);  // Setting up for PCM and high sampling rate because I have 
                               // a reclocker and the output is 192K to the DAC                            
  opuswritereg(REG4,VOLCNTR);  // Setting up volume control. Unmute

  attachInterrupt(0, decoder, CHANGE);  // ISR for rotary encoder
  attachInterrupt(1, remoting, RISING); // ISR for remote IR sensor

  lcd.setCursor(0,0);
  // print header for digital filter and current filter 
  lcd.print("LnS");
  printOneNumber(1);

  // print header for volume and volume
  lcd.setCursor(0,13);
  lcd.print("-dB VOL");
  printTwoNumber(currVol/8);

  // Print the rest of the display
  lcd.setCursor(2 ,4);
  lcd.print("INPT");
  lcd.write(0xA5);
  lcd.print("PCM");
  lcd.setCursor(1,4);
  lcd.print("RATE");
  lcd.write(0xA5);
  lcd.print("192");

}

void loop()
{
  // The following code will select the next filter if the button is pushed
  // and it is repeated for the remote because I'm lazy :-) 

  if (digitalRead(FILTERPIN)==0)  // When the filter button is pushed
  {
    filter++;
    filter=filter%5;
    lcd.setCursor(0,8);
    switch(filter){
      case 0:
      opuswritereg(REG6,FILTER1);
      lcd.print("RESPONSE #1");
      break;
      case 1:
      opuswritereg(REG6,FILTER2);
      lcd.print("RESPONSE #2");
      break;
      case 2:
      opuswritereg(REG6,FILTER3);
      lcd.print("RESPONSE #3");
      break;
      case 3:
      opuswritereg(REG6,FILTER4);
      lcd.print("RESPONSE #4");
      break;
      case 4:
      opuswritereg(REG6,FILTER5);
      lcd.print("RESPONSE #5");
      break;
    }
    delay(300);  // Used to avoid reading the button more than one during the click
  }

  // 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// Check if already at min numerical Volume
    {
      currVol=currVol+8;                    // Increase 1 dB
      reg0val=(((byte)currVol) & 0x1F);     // Calculate value for reg0
      opuswritereg(REG0,reg0val);           // Write to reg0
      reg1val=(((byte)(currVol>>5))| 0x20); // Calculate value for reg1
      opuswritereg(REG1,reg1val);           // Write to reg1

      printTwoNumber(currVol/8);

      if (volDimState==1)                // If in dim state, undim
      {
        volDimState=0;
        lcd.setCursor(0,17);
        lcd.print("VOL");
      }
    }
  }

  // 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-8;                // Decrease 1 dB
      reg0val=(((byte)currVol) & 0x1F); // Calculate value for reg0
      opuswritereg(REG0,reg0val);       // Write to reg0
      reg1val=((currVol>>5)| 0x20);     // Calculate value for reg1
      opuswritereg(REG1,reg1val);       // Write to reg1

      printTwoNumber(currVol/8);

      if (volDimState==1)               // If in dim state, undim
      {
        volDimState=0;
        lcd.setCursor(0,17);
        lcd.print("VOL");
      }
    }
  }

  // The following is for the volume dimming feature

  if (digitalRead(VOLDIMPIN)==0) // When pressing the volume dim button
  {
    if (volDimState==0)  //if not dimmed, then dim the volume to min vol
    {
      reg0val=(((byte)DIMVOL) & 0x1F);
      opuswritereg(REG0,reg0val);
      reg1val=(((byte)(DIMVOL>>5))| 0x20);
      opuswritereg(REG1,reg1val);
      printTwoNumber(DIMVOL/8);
      volDimState=1;     // set state to dimmed
      lcd.setCursor(0,17);
      lcd.print("DIM");
    }
    else                 // if dimmed, then return to current volume
    {
      reg0val=(((byte)currVol) & 0x1F);
      opuswritereg(REG0,reg0val);
      reg1val=(((byte)(currVol>>5))| 0x20); // Calculate value for reg1
      opuswritereg(REG1,reg1val);
      printTwoNumber(currVol/8);
      volDimState=0;    // set state to undimmed.
      lcd.setCursor(0,17);
      lcd.print("VOL");
    }
    delay(300); // Used to avoid reading the button more than one during the click
  }

  // The following code is for the remote.

  while (remoteOn==1)
  {
    irCode = getIRKey();		    //Fetch the key
    //lcd.setCursor(0,4);                   // Used to find out remote keys value
    //lcd.print(irCode);

    switch(irCode){
      // The following for filter sel ection
      case KEY1:
      lcd.setCursor(0,0);
      lcd.print("LnS");
      opuswritereg(REG6,FILTER1);
      printOneNumber(1);
      delay(IRFILSELDELAY);
      break;
      case KEY2:
      lcd.setCursor(0,0);
      lcd.print("MnS");
      opuswritereg(REG6,FILTER2);
      printOneNumber(2);
      delay(IRFILSELDELAY);
      break;
      case KEY3:
      lcd.setCursor(0,0);
      lcd.print("BrK");
      opuswritereg(REG6,FILTER3);
      printOneNumber(3);
      delay(IRFILSELDELAY);
      break;
      case KEY4:
      lcd.setCursor(0,0);
      lcd.print("MnA");
      opuswritereg(REG6,FILTER4);
      printOneNumber(4);
      delay(IRFILSELDELAY);
      break;
      case KEY5:
      lcd.setCursor(0,0);
      lcd.print("LnA");
      opuswritereg(REG6,FILTER5);
      printOneNumber(5);
      delay(IRFILSELDELAY);
      break;

      // The following is for the input sample rate
      case KEY7:
      opuswritereg(REG7,PCMLOW);
      lcd.setCursor(1,9);
      lcd.print("48K");
      delay(IRFILSELDELAY);
      break;
      case KEY8:
      opuswritereg(REG7,PCMMED);
      lcd.setCursor(1,9);
      lcd.print("96K");
      delay(IRFILSELDELAY);
      break;
      case KEY9:
      opuswritereg(REG7,PCMHIGH);
      lcd.setCursor(1,9);
      lcd.print("192");
      delay(IRFILSELDELAY);
      break;

      // The following for volume
      case KEYVOLUP:
      if (currVol// Check if already at min numerical Volume
      {
        currVol=currVol+8;                    // Increase 1 dB
        reg0val=(((byte)currVol) & 0x1F);     // Calculate value for reg0
        opuswritereg(REG0,reg0val);           // Write to reg0
        reg1val=(((byte)(currVol>>5))| 0x20); // Calculate value for reg1
        opuswritereg(REG1,reg1val);           // Write to reg1

        printTwoNumber(currVol/8);

        if (volDimState==1)                // If in dim state, undim
        {
          volDimState=0;
          lcd.setCursor(0,17);
          lcd.print("VOL");
        }
      }
      break;

      case KEYVOLDOWN:
      if (currVol>MAXVOL)   // Check if already at max Volume
      {
        currVol=currVol-8;                // Decrease 1 dB
        reg0val=(((byte)currVol) & 0x1F); // Calculate value for reg0
        opuswritereg(REG0,reg0val);       // Write to reg0
        reg1val=((currVol>>5)| 0x20);     // Calculate value for reg1
        opuswritereg(REG1,reg1val);       // Write to reg1

        printTwoNumber(currVol/8);

        if (volDimState==1)               // If in dim state, undim
        {
          volDimState=0;
          lcd.setCursor(0,17);
          lcd.print("VOL");
        }
      }
      break;

      // The following is for brightness and constrast control

      case KEYDISPLAY:
      BC++;
      if (BC%3==0){
        lcd.setCursor(0,4);
        lcd.print("       ");
        EEPROM.write(BRIADDR,brightness); // Save value
        EEPROM.write(CONADDR,contrast);  // Save Value
      }
      if (BC%3==1){
        lcd.setCursor(0,4);
        lcd.print("BRI ");
        brightness=EEPROM.read(BRIADDR); // Read value
        lcd.print(brightness);
      }
      if (BC%3==2 ){
        lcd.setCursor(0,4);
        lcd.print("CON    ");
        contrast=EEPROM.read(CONADDR);  // Read value
        lcd.setCursor(8,0);
        lcd.print(contrast);
      }
      delay(IRFILSELDELAY);
      break;

      case KEYPICTUREUP:
      if (BC==1){
        brightness++;
        BackLight(brightness);
        lcd.setCursor(0,8);
        lcd.print(brightness);
        //lcd.print(" ");
      }
      if (BC==2){
        contrast++;
        Contrast(contrast);
        lcd.setCursor(0,8);
        lcd.print(contrast);
        //lcd.print(" ");
      }

      // delay(IRFILSELDELAY);
      break;

      case KEYPICTUREDOWN:
      if (BC==1){
        brightness--;
        BackLight(brightness);
        lcd.setCursor(0,8);
        lcd.print(brightness);
        lcd.print(" ");
      }
      if (BC==2){
        contrast--;
        Contrast(contrast);
        lcd.setCursor(0,8);
        lcd.print(contrast);
        lcd.print(" ");
      }

      // delay(IRFILSELDELAY);
      break;

    }

    remoteOn=0;  //reset flag
  }

}  

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

Posted in Uncategorized | Leave a Comment »

Code for Large Numbers

Posted by downloadcode on May 25, 2009

// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
// []
// []       Large number example
// []	    May 24, 2009
// []       Fof HIFIDUINO
// []       www.hifiduino.blogspot.com
// []
// [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]

#include <Wire.h>
#include "macros.h" // Used for defining custom characters
#include
LCDi2cW lcd = LCDi2cW(4,20,0x4C,0);

// 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

  uint8_t cc1[8] = {     // Custom Character 1
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111)
  };

  uint8_t cc2[8] = {    // Custom Character 2
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(00000),
    B8(00000),
    B8(00000)
  };

  uint8_t cc3[8] = {    // Custom Character 3
    B8(00000),
    B8(00000),
    B8(00000),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111)
  };

  uint8_t cc4[8] = {   // Custom Character 4
    B8(00000),
    B8(00000),
    B8(00000),
    B8(00000),
    B8(00000),
    B8(00000),
    B8(00000),
    B8(00000)
  };

  uint8_t cc5[8] = {    // Custom Character 5
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(00000),
    B8(00000)
  };

  uint8_t cc6[8] = {    // Custom Character 6
    B8(00000),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(00000),
    B8(00000)
  };

  uint8_t cc7[8] = {     // Custom Character 7
    B8(00000),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111),
    B8(11111)
  };

  // send custom characters to the display
  lcd.load_custom_character(1,cc1);
  lcd.load_custom_character(2,cc2);
  lcd.load_custom_character(3,cc3);
  lcd.load_custom_character(4,cc4);
  lcd.load_custom_character(5,cc5);
  lcd.load_custom_character(6,cc6);
  lcd.load_custom_character(7,cc7);

}

// 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[]={1,2,1, 3,1,4, 2,2,1, 2,2,1, 1,4,1, 1,2,2, 1,2,2, 2,2,1, 1,2,1, 1,2,1};
char bn2[]={1,4,1, 4,1,4, 7,6,5, 6,6,1, 5,6,1, 5,6,7, 1,6,7, 4,4,1, 1,6,1, 5,6,1};
char bn3[]={1,3,1, 3,1,3, 1,3,3, 3,3,1, 4,4,1, 3,3,1, 1,3,1, 4,4,1, 1,3,1, 3,3,1};

void printOneNumber(uint8_t digit)
{
  // Print position is hardcoded

  // Line 1 of the one digit number
  lcd.setCursor(1,0);
  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(2,0);
  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(3,0);
  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(1,13);
  lcd.write(bn1[digit1*3]);
  lcd.write(bn1[digit1*3+1]);
  lcd.write(bn1[digit1*3+2]);
  lcd.write(0x04); // 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(2,13);
  lcd.write(bn2[digit1*3]);
  lcd.write(bn2[digit1*3+1]);
  lcd.write(bn2[digit1*3+2]);
  lcd.write(0x04); // 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(3,13);
  lcd.write(bn3[digit1*3]);
  lcd.write(bn3[digit1*3+1]);
  lcd.write(bn3[digit1*3+2]);
  lcd.write(0x04); // Blank
  lcd.write(bn3[digit0*3]);
  lcd.write(bn3[digit0*3+1]);
  lcd.write(bn3[digit0*3+2]);
}

void setup()
{

  lcd.init(); // Init the display
  lcd.setDelay(0,0); // Change the delay in the LCD library
                     // We need some delays elsewhere like after lcd.clear 
  DefineLargeChar(); // Create the custom characters

  int filter=1;
  int volume=0;

  lcd.clear();
  delay(20); // After lcd.clear we seem to need a small delay

  // Lets print the filter header text
  lcd.print("FLT");

  // Print large number
  filter=5;
  printOneNumber(filter);

  // Print other text
  lcd.setCursor(1,4);
  lcd.print("INPT:PCM");
  lcd.setCursor(3,4);
  lcd.print("ASRC:192");

  // print header for volume
  lcd.setCursor(0,13);
  lcd.print("-dB VOL");

  delay(1000);

  // Print volume value in large numbers
  for(volume=0; volume<99 ; volume++)
  {
  printTwoNumber(volume);
  delay(500);
  }

}

void loop()
{
}

Posted in Uncategorized | Leave a Comment »

Code for HIFIDUINO v 05

Posted by downloadcode on April 26, 2009

Posted in Uncategorized | Leave a Comment »

Code to adjust LCD

Posted by downloadcode on April 19, 2009

Posted in Uncategorized | Leave a Comment »

Code for HIFIDUINO v 0.4

Posted by downloadcode on April 18, 2009

Posted in Uncategorized | Leave a Comment »

Code for HIFIDUINO v 0.3

Posted by downloadcode on April 13, 2009

Here is the code version 0.3

hifiduino v 03

Posted in Uncategorized | Leave a Comment »

CODE for HIFIDUINO v 0.2

Posted by downloadcode on April 8, 2009

Posted in Uncategorized | Leave a Comment »

CODE for HIFIDUINO v 0.1

Posted by downloadcode on April 6, 2009

Here is the version 0.1 of the code

hifiduinov01

Posted in Uncategorized | Leave a Comment »