I would be surprised if writing to specific registers of I2C devices wasn't a very common requirement for people using the Wire library.
The Wire documentation could be expanded a thousand-fold, and still wouldn't cover half the devices that I2C can be used to communicate with.
I wouldn't expect the Wire doc to cover specific devices, but I would expect it to at least cover some of the most common functionality of the I2C paradigm.
Anyway, in case Googlers come across this thread, here's some example code that sets some registers to do useful things;
#include <Wire.h>
#define HMC6343_ADDRESS 0x19
//====================================================================================
void setup() {
Wire.begin();
Serial.begin(115200);
/*
* Set the 'variation angle correction' (magnetic declination), see p8 in datasheet.
* At the cathedral in St Andrews on 07/08/2012 this was 3 degrees 16 seconds West
* which is -3.2667 decimal degrees, or -33 tenths of a degree, so MSB/LSB in two's
* complement is 11111111/11011111. This is written to EEPROM so technically doesn't
* need to be done every time if the device isn't moving to a drastically new
* location inbetween use.
*/
byte deviationMSB = B11111111;
Wire.beginTransmission(HMC6343_ADDRESS);
Wire.write(0xF1); // 'Write to EEPROM' command
Wire.write(0x0D); // EEPROM address of deviation angle MSB
Wire.write(deviationMSB);
Wire.endTransmission();
byte deviationLSB = B11011111;
Wire.beginTransmission(HMC6343_ADDRESS);
Wire.write(0xF1);
Wire.write(0x0C); // EEPROM address of deviation angle LSB
Wire.write(deviationLSB);
Wire.endTransmission();
/*
* Set the measurement rate to 10Hz (0x02) from default of 5Hz (0x01).
* Again this is EEPROM so shouldn't need re-doing unless it is explicitly reset
* at some point.
*/
Wire.beginTransmission(HMC6343_ADDRESS);
Wire.write(0xF1);
Wire.write(0x05); // EEPROM address of Operational Mode Register 2
Wire.write(0x02); // (OM2_1 = 1 && OM2_0 = 0) == 10Hz operation
Wire.endTransmission();
/*
* Set the Heading Infinite Impulse Response (IIR) filter from its default of 0
* to something a bit more than 0. Again, this is EEPROM so shouldn't need re-doing
* unless it is explicitly reset at some point.
*/
Wire.beginTransmission(HMC6343_ADDRESS);
Wire.write(0xF1);
Wire.write(0x14); // EEPROM address of the Heading IIR filter LSB
Wire.write(0x00); // 0 is no filtering, 15 is filtered with 15 previous readings
Wire.endTransmission();
/*
* Set the HMC6343 to 'upright front' orientation. This is temporary, but can be
* written to an EEPROM register if required.
*/
Wire.beginTransmission(HMC6343_ADDRESS);
Wire.write(0x74);
Wire.endTransmission();
}
//====================================================================================
void loop() {
/*
* Set the HMC6343 to return the information that we want (HeadMSB, HeadLSB,
* PitchMSB, PitchLSB, RollMSB, RollLSB).
*/
Wire.beginTransmission(HMC6343_ADDRESS);
Wire.write(0x50); // Command to return the data we want
Wire.endTransmission();
byte MSByte, LSByte;
Wire.requestFrom(HMC6343_ADDRESS, 6); // request 6 bytes (see command 0x50)
while(Wire.available() < 1); // busy wait while no bytes to receive
MSByte = Wire.read();
LSByte = Wire.read();
float heading = ((MSByte << 8) + LSByte) / 10.0; // the heading in degrees
MSByte = Wire.read();
LSByte = Wire.read();
float pitch = ((MSByte << 8) + LSByte) / 10.0; // the pitch in degrees
MSByte = Wire.read();
LSByte = Wire.read();
float roll = ((MSByte << 8) + LSByte) / 10.0; // the roll in degrees
Serial.print(heading);
Serial.print(" ");
Serial.print(pitch);
Serial.print(" ");
Serial.println(roll);
delay(100);
}
//====================================================================================