My sketch steps both pots on the Maxim DS1882 down in volume incrementally, pauses 2 seconds when the chip reaches mute, and then starts down again from full volume. From the WiperSetValue output in the serial monitor (and from actually hearing the output) I can tell this part is working, but I'm also attempting to read back from the wiper memory on each pot, and it continues to print "0" for both pots for each read operation, regardless of the wiper setting.
From the datasheet, the LSB on the Slave Address Byte needs to be "1' to read, and that byte sent to the chip for it to respond to a read request. However, using the Wire library there's no option to set that bit...and I'm not even sure what the library does send when I call the Wire.requestFrom function.
Do I need to step outside of the the Wire library to execute a read? Or is something else faulty in either my bitmath or how I'm calling the request function?
Datasheet: Maxim DS1882 Datasheet
/*
DS1882 Test Sketch
---------------------------------
DS1882 I2C Command Byte Structure
---------------------------------
SLAVE ADDRESS BYTE
Base A2 A1 A0 ... R/W (LSB=1 for Read request)
Bin 0 1 0 1 0 0 0 ... 0
Bitval 64 32 16 8 4 2 1
Hex 0x28 (<-----This is the slave address base)
Dec 40
COMMAND BYTE
Bin 0 0 0 0 0 0 0 0
POT0 0 0 0 POT0WiperPos <---BIT6 toggles POT0 or POT1
POT1 0 1 0 POT1WiperPos <┘
CONFIG 1 0 X X X 0 0 0 <---BIT7 flags CONFIG register
| | |
| | POTConfig(BIT0): 0(0x0)=63 positions & mute, 1(0x1)=33 positions & mute(default)
| POTZeroCrossing(BIT1): 0=disabled, 1=enabled(default)
POTNVM Volatile/Nonvolatile(BIT2): 0=nonvolatile, 1=volatile(default, potentiometer powers up in mute pos.)
Read Protocol: Start SLAVEADDR POT0BYTE POT1BYTE CONFIG Stop
Write Protocol: Start SLAVEADDR (POT0BYTE, POT1BYTE, CONFIG can be sent in any order after SLAVEADDR) Stop
*/
#include <Wire.h>
byte CONFIG = B10000010; //set configuration byte for write
byte RDCONFIG = B10000011; //set configuration byte for read req.
byte POT0 = 00; //flag for pot 0
byte POT1 = 01; //flag for pot 1
int POT0SET = 1; //initialize pot 0 wiper set (63 = mute, 0 = no attenuation)
int POT1SET = 1; //initialize pot 1 wiper set
byte POT0CMD; //initialize pot 0 command byte
byte POT1CMD; //initialize pot 1 command byte
byte POT0RD; //initialize pot 0 read byte
byte POT1RD; //initialize pot 1 read byte
byte CONFIGRD; //initialize configuration byte read
unsigned char POT0GET; //initialize pot 0 wiper position reading
unsigned char POT1GET; //initialize pot 1 wiper position reading
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600);
}
void loop()
{
POT0SET++; // increase attenuation
POT1SET++;
POT0CMD = ((POT0 << 6) | (POT0SET >> 2)); //assemble pot 0 command byte
POT1CMD = ((POT1 << 6) | (POT1SET >> 2)); //assemble pot 1 command byte
Wire.beginTransmission(40); // transmit to device #40 (0x28)
Wire.write(POT0CMD); // sends pot 0 command byte
Wire.write(POT1CMD); // sends pot 1 command byte
Wire.write(CONFIG); // sends configuration byte
Wire.endTransmission(); // stop transmitting
Serial.print("Pot0 WiperSetValue = ");
Serial.println(POT0SET);
Serial.print("Pot1 WiperSetValue = ");
Serial.println(POT1SET);
// Not working yet - returns "0" on every POT#GET print
Wire.beginTransmission(40);
Wire.write(RDCONFIG);
Wire.endTransmission();
Wire.requestFrom(40, 3); //request 3 bytes from device #40
while (Wire.available()) {
POT0RD = Wire.read(); //read pot0 byte
POT1RD = Wire.read(); //read pot1 byte
CONFIGRD = Wire.read(); //read configuration register byte
}
delay(750);
POT0GET = POT0RD & B00111111; //mask pot0 flag and extract wiper value
POT1GET = POT1RD & B00111111; //mask pot1 flag and extract wiper value
Serial.print("Pot0 Position = ");
Serial.println(POT0GET);
Serial.print("Pot1 Position = ");
Serial.println(POT1GET);
Serial.println();
if(POT0SET == 255) // if reached position 63(???!) (mute)
{
delay(2000); // hold mute for 2 seconds
POT0SET = 0; // start over from full volume
POT1SET = 0;
}
delay(100);
}