- Support for 4x20 LCD Display and large number display
- Brightness and contrast adjustment with remote
- (OPUS/Wolfson WM8741) DAC volume control: remote and rotary encoder
- (OPUS/Wolfson WM8741) DAC random filter selection 1 to 5 with remote
- (OPUS/Wolfson WM8741) DAC upsampling selection (L, M, H -this is the OSR setting)
- I2C level shifting (5V to 3.3V)
- Optimized power-up sequence

Saturday, February 27, 2010

Programming Buffalo DAC: Review of Arduino I2C

Is is fairly simple to use Arduino to program a DAC such as the ESS Sabre32. After you connect the appropriate signals (wires) from Arduino to the Buffalo board, you follow the tutorial sketches (in Arduino the programs are called sketches) to set up the main code and use the Arduino I2C functions to write values into the registers of the DAC.

In Arduino, the I2C protocol is supported by the "Wire library" and the functions are the following:
  • begin() - Join the I2C bus as a masterdevice
  • begin(address) - Join the I2C bus as a slave device
  • requestFrom(address, count) - Tell device that a request will follow
  • beginTransmission(address) - Tell device as address that data transmission will start
  • endTransmission()- Tell device that transmission is ended
  • send() - Send data (one byte at a time)
  • byte available() - Queries number of bytes available for retrieval
  • byte receive() - Retrieve (read) bytes from device
  • onReceive(handler) - The function to perform when slave receive a transmission
  • onRequest(handler) - The function to perform when slave receives a request
Before you do anything, Arduino joins the I2C bus as a master device with
The following code will write one value into one register:

beginTransmission(0x80); // Address of DAC is hex 80
  send(0x01); // Address of register is hex 1
  send(0x00); // Value into register is hex 0

Hex is hexadecimal notation. It is more convenient to write in hex notation rather than binary notation. Most data sheets give you register address value in hex and register value in binary. You can use any notation in your code but you have to indicate which notation.

You can convert binary to hex with one of many online tools such as this.

The following code sends one value to 4 registers. This example is typical for setting volume. The same value is assigned to all the internal DACs. Say for example the volume control of the DAC is 1/4 db and you want to set a -10 db volume. The value to use is -40 (you don't have to specify which notation because the default is decimal notation), and assume the registers to control the volume are registers 1 through 4

beginTransmission(0x80); // Address of DAC is hex 80
  send(0x01); // Address of register 1 is hex 1
  send(40); // Value into register 40
  send(0x02); // Address of register 2 is hex 2
  send(40); // Value into register 40
  send(0x03); // Address of register 3 is hex 3
  send(40); // Value into register 40
  send(0x04); // Address of register 4 is hex4
  send(40); // Value into register 40

That's it.

Update (October, 12, 2010): I just implemented and tested the basic code to control the Buffalo II DAC's volume. However, I couldn't program multiple registers within a single beginTransmission and endTransmission pair as shown above. I had to program each register with beginTransmission...endTransmission separately. You can see the code here.

    1 comment:

    Russ said...

    You should not have to use hex at all. The compiler understands base 10 decimals just fine. :)