+ refactor

+ added timing
+ fixed some bugs
This commit is contained in:
Rob Tillaart 2013-09-30 17:03:06 +02:00
parent 71447b5f3f
commit db6d3c636c
10 changed files with 771 additions and 98 deletions

View File

@ -0,0 +1,12 @@
This library is BETA, only tested partially and not thoroughly
No guarantees, use at own risk, all disclaimers apply
The example sketch can be used to config the compass.
For switching operational mode one must reboot the system.

View File

@ -0,0 +1,53 @@
//
// FILE: continuousDemo.pde
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: demo app HMC6352 library - continuous mode for Arduino
//
// HISTORY:
// 0.1.00 - 2011-04-12 initial version
//
// Released to the public domain
//
// All disclaimers apply use at own risk
//
#include <Wire.h>
#include <hmc6352.h>
hmc6352 Compass(0x21); // 0x21 <==> 33 <==> 66 >> 1
void setup()
{
Serial.begin(19200);
Serial.println("HMC6352: Version ");
Serial.println(HMC_LIB_VERSION);
Serial.print("current output modus");
Serial.println(Compass.getOutputModus());
x = Compass.askHeading();
//Serial.print("Ask returns: ");
//Serial.println(x);
}
int x;
void loop()
{
// in continuous mode it is not needed to ask for a new reading every time
// as it will do a new reading continuously even when not asked for
// Try making a fast turn and see the difference with the query mode
x = Compass.readHeading();
Serial.print("Degree : ");
Serial.println(x);
delay(1000);
}
// END OF FILE

View File

@ -0,0 +1,249 @@
//
// FILE: hmc6352Config.pde
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: test app HMC6352 library for Arduino
//
// Released to the public domain
//
#include <Wire.h>
#include <hmc6352.h>
hmc6352 Compass(33);
void setup()
{
Serial.begin(19200);
Serial.println("HMC6352: Config");
Serial.println(HMC_LIB_VERSION);
dumpEEPROM();
}
int x;
void loop()
{
// SHOWMENU
Serial.println("\n\n\t\tHMC6352 MENU\n");
Serial.println("F : Factory Reset");
Serial.println("E : Dump EEPROM & 2 RAM addresses");
Serial.println("R : Dump RAM");
Serial.println("A : ask sampling");
Serial.println("Q : read sample");
Serial.println("Z : continuous read (loop) - X to stop");
Serial.println("W : WakeUp");
Serial.println("S : Sleep");
Serial.println("O : Output Modus Menu");
Serial.println("7 : STANDBY MODE");
Serial.println("8 : QUERY MODE");
Serial.println("9 : CONTINUOUS MODE");
Serial.println("C : Callibration On (!!)");
Serial.println("X : Callibration Off (!!)");
Serial.println("I : set I2C address (!!)");
Serial.println("@ : reset (!!)");
Serial.println("Enter your choice ...");
// WAIT FOR COMMAND
while (Serial.available() == 0);
char cmd = Serial.read();
// EXECUTE COMMAND
switch(cmd)
{
case 'F':
factoryReset();
break;
case 'E':
dumpEEPROM();
break;
case 'R':
dumpRAM();
break;
case 'A':
askHeading();
break;
case 'Q':
readHeading();
break;
case 'W':
x = Compass.wakeUp();
Serial.println(x, DEC);
break;
case 'S':
x = Compass.sleep();
Serial.println(x, DEC);
break;
case 'O':
OutPutModusMenu();
break;
case '7':
// mode , freq , reset
Compass.setOperationalModus(STANDBY, 1, true); // 10 default val
Serial.println("Reboot Arduino");
break;
case '8':
Compass.setOperationalModus(QUERY, 1, true); // 10 default val
Serial.println("Reboot Arduino");
break;
case '9':
Compass.setOperationalModus(CONT, 20, true); // 10 default val
Serial.println("Reboot Arduino");
break;
case 'U':
Compass.callibrationOn();
break;
case 'X':
Compass.callibrationOff();
break;
case 'I':
setI2Caddress();
break;
case '@':
Compass.updateOffsets();
break;
case 'Z':
while (1)
{
readHeading();
if (Serial.available()>0)
{
Serial.read();
break;
}
delay(50); // 20 Hz
}
break;
default:
break;
}
}
void OutPutModusMenu()
{
Serial.println(Compass.getOutputModus());
Serial.println("output modus value :");
Serial.println("0 Heading (default)");
Serial.println("1 Raw Magnetometer X");
Serial.println("2 Raw Magnetometer Y");
Serial.println("3 Magnetometer X");
Serial.println("4 Magnetometer Y");
// WAIT FOR PARAM
while (Serial.available() == 0);
char cmd = Serial.read();
cmd -= '0'; // make a digit out of it
int x = Compass.setOutputModus(cmd);
Serial.print("Returns: ");
Serial.println(x);
}
void askHeading()
{
int x = Compass.askHeading();
Serial.print("Returns: ");
Serial.println(x);
}
void readHeading()
{
int x = Compass.readHeading();
Serial.print("DEGREE: ");
Serial.println(x);
}
void factoryReset()
{
Compass.factoryReset();
Serial.println("Reboot Arduino");
}
void dumpRAM()
{
Serial.println("\nDUMP RAM: (decimal values)");
Serial.println("Size 256 bytes (?) meaning mostly unknown");
for (int i = 0; i< 256; i++)
{
if (i % 16 == 0)
{
Serial.println();
Serial.print(i, HEX);
Serial.print(" : ");
}
Serial.print(Compass.readRAM(i), HEX);
Serial.print("\t ");
}
Serial.println();
}
void dumpEEPROM()
{
Serial.println("\nDUMP EEPROM: (decimal values)");
Serial.println("Read datasheet for meaning\n");
Serial.print(" I2C ADDRESS: 0x00 : ");
Serial.println(Compass.readEEPROM(0), DEC);
Serial.print("MAGN X OFFSET MSB: 0x01 : ");
Serial.println(Compass.readEEPROM(1), DEC);
Serial.print("MAGN X OFFSET LSB: 0x02 : ");
Serial.println(Compass.readEEPROM(2), DEC);
Serial.print("MAGN Y OFFSET MSB: 0x03 : ");
Serial.println(Compass.readEEPROM(3), DEC);
Serial.print("MAGN Y OFFSET LSB: 0x04 : ");
Serial.println(Compass.readEEPROM(4), DEC);
Serial.print(" Time Delay: 0x05 : ");
Serial.println(Compass.readEEPROM(5), DEC);
Serial.print(" Measurement Sum: 0x06 : ");
Serial.println(Compass.readEEPROM(6), DEC);
Serial.print(" Software Version: 0x07 : ");
Serial.println(Compass.readEEPROM(7), DEC);
Serial.print(" Operational Mode: 0x08 : ");
Serial.println(Compass.readEEPROM(8), DEC);
Serial.println("REGISTERS RAM");
Serial.print("Operational Mode Control Byte: 0x74 : ");
Serial.println(Compass.getOperationalModus(), BIN);
Serial.print("Output Data Mode: 0x4E : ");
Serial.println(Compass.getOutputModus(), BIN);
}
void setI2Caddress()
{
Serial.print("Current I2C address : ");
Serial.println(Compass.getI2CAddress());
Serial.println();
Serial.println("Give new value: (decimal, 2 digits)");
Serial.println("00 to escape");
while (Serial.available() < 2);
int v1 = Serial.read();
v1 -= '0';
v1 *= 10;
int v2 = Serial.read();
v2 -= '0';
v1 += v2;
if (v1 == 0) return;
Serial.println(v1);
int x = Compass.setI2CAddress(v1);
Serial.println(x);
Serial.print("Current I2C address : ");
Serial.println(Compass.getI2CAddress());
}
// END OF FILE

View File

@ -0,0 +1,54 @@
//
// FILE: queryDemo.pde
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: demo app HMC6352 library - query mode for Arduino
//
// HISTORY:
// 0.1.00 - 2011-04-12 initial version
//
// Released to the public domain
//
// All disclaimers apply use at own risk
//
#include <Wire.h>
#include <hmc6352.h>
hmc6352 Compass(0x21); // 0x21 <==> 33 <==> 66 >> 1
void setup()
{
Serial.begin(19200);
Serial.println("HMC6352: Version ");
Serial.println(HMC_LIB_VERSION);
Serial.print("current output modus");
Serial.println(Compass.getOutputModus());
x = Compass.askHeading();
//Serial.print("Ask returns: ");
//Serial.println(x);
}
int x;
void loop()
{
// in query mode it is not needed to ask for a new reading every time
// as it will do a new reading directly after the chip is read
// and waits until it is asked for.
// Try making a fast turn and smile ...
x = Compass.readHeading();
Serial.print("Degree : ");
Serial.println(x);
delay(1000);
}
// END OF FILE

View File

@ -0,0 +1,68 @@
//
// FILE: set2continuous.pde
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: Reset HMC6352 to continuous mode
//
// HISTORY:
// 0.1.00 - 2011-04-12 initial version
//
// Released to the public domain
//
// All disclaimers apply use at own risk
//
#include <Wire.h>
int HMC = 0x21;
int ledPin = 13;
boolean ledState = LOW;
byte value;
int x;
void setup()
{
Serial.begin(9600);
Serial.print("HMC6352 : start - ");
Serial.println(HMC, HEX);
pinMode(ledPin, OUTPUT);
Wire.begin();
delay(1000); // give all things time to start
}
void loop()
{
// flashing means not blocking
ledState = !ledState;
digitalWrite(ledPin, ledState);
// write continuous mode to RAM 0x74 and do an L command immediately after it
// pull out 5 volt if it reads back 0x72
Wire.beginTransmission(HMC);
Wire.send('G');
Wire.send(0x74);
Wire.send(0x72); // 20 Hz | Reset = True | CONT
Wire.send('L');
// Wire.send('O'); optional reset
x = Wire.endTransmission();
delay(10);
// Read the EEPROM value for feedback as this is the next startup value
Wire.beginTransmission(HMC);
Wire.send('r');
Wire.send(0x07);
x = Wire.endTransmission();
delay(10);
Wire.requestFrom(HMC, 1);
i = 0;
while(Wire.available() < 1);
value = Wire.receive();
Serial.print("Current Mode: ");
Serial.println((int)value, BIN);
}

View File

@ -0,0 +1,70 @@
//
// FILE: Set2query.pde
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: Reset HMC6352 to query mode
//
// HISTORY:
// 0.1.00 - 2011-04-12 initial version
//
// Released to the public domain
//
// All disclaimers apply use at own risk
//
#include <Wire.h>
int HMC = 0x21;
int ledPin = 13;
boolean ledState = LOW;
byte value;
int x;
void setup()
{
Serial.begin(9600);
Serial.print("HMC6352 : start - ");
Serial.println(HMC, HEX);
pinMode(ledPin, OUTPUT);
Wire.begin();
delay(1000); // give all things time to start
}
void loop()
{
// flashing means not blocking
ledState = !ledState;
digitalWrite(ledPin, ledState);
// write query mode to RAM 0x74 and do an L command immediately after it
// this is done to "break through" the continuous mode if needed
// pull out 5 volt if it reads back 0x50
Wire.beginTransmission(HMC);
Wire.send('G');
Wire.send(0x74);
Wire.send(0x51); // 10 Hz | Reset = True | QUERY
Wire.send('L');
// Wire.send('O'); optional reset
x = Wire.endTransmission();
delay(10);
// Read the EEPROM value for feedback as this is the next startup value
Wire.beginTransmission(HMC);
Wire.send('r');
Wire.send(0x07);
x = Wire.endTransmission();
delay(10);
Wire.requestFrom(HMC, 1);
i = 0;
while(Wire.available() < 1);
value = Wire.receive();
Serial.print("Current Mode: ");
Serial.println((int)value, BIN);
}

View File

@ -0,0 +1,70 @@
//
// FILE: set2standby.pde
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: Reset HMC6352 to standby mode (esp if it is struck in continuous mode - Arduino)
//
// HISTORY:
// 0.1.00 - 2011-04-12 initial version
//
// Released to the public domain
//
// All disclaimers apply use at own risk
//
#include <Wire.h>
int HMC = 0x21;
int ledPin = 13;
boolean ledState = LOW;
byte value;
int x;
void setup()
{
Serial.begin(9600);
Serial.print("HMC6352 : start - ");
Serial.println(HMC, HEX);
pinMode(ledPin, OUTPUT);
Wire.begin();
delay(1000); // give all things time to start
}
void loop()
{
// flashing means not blocking
ledState = !ledState;
digitalWrite(ledPin, ledState);
// write stdby mode to RAM 0x74 and do an L command immediately after it
// this is done to "break through" the continuous mode
// pull out 5 volt if it reads back 0x50
Wire.beginTransmission(HMC);
Wire.send('G');
Wire.send(0x74);
Wire.send(0x50);
Wire.send('L');
// Wire.send('O'); optional reset
x = Wire.endTransmission();
delay(10);
// Read the EEPROM value for feedback as this is the next startup value
Wire.beginTransmission(HMC);
Wire.send('r');
Wire.send(0x07);
x = Wire.endTransmission();
delay(10);
Wire.requestFrom(HMC, 1);
i = 0;
while(Wire.available() < 1);
value = Wire.receive();
Serial.print("Current Mode: ");
Serial.println((int)value, BIN);
}

View File

@ -0,0 +1,58 @@
//
// FILE: standbyDemo.pde
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// PURPOSE: demo app HMC6352 library - standby mode for Arduino
//
// HISTORY:
// 0.1.00 - 2011-04-12 initial version
//
// Released to the public domain
//
// All disclaimers apply use at own risk
//
#include <Wire.h>
#include <hmc6352.h>
hmc6352 Compass(0x21); // 0x21 <==> 33 <==> 66 >> 1
void setup()
{
Serial.begin(19200);
Serial.println("HMC6352: Version ");
Serial.println(HMC_LIB_VERSION);
Serial.print("current output modus");
Serial.println(Compass.getOutputModus());
}
int x;
void loop()
{
Compass.wakeup(); // decent wake up from sleep mode
// Note that reading a heading is requires two steps, ask() & read()
// this makes the query and continuous mode more efficient
// without impact on the footprint of the lib.
// a wrapper is an option.
x = Compass.askHeading();
//Serial.print("Ask returns: ");
//Serial.println(x);
x = Compass.readHeading();
Serial.print("Degree : ");
Serial.println(x);
Compass.sleep(); // low energy mode
delay(500);
}
// END OF FILE

View File

@ -1,11 +1,13 @@
//
// FILE: hmc6352.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// VERSION: 0.1.02
// PURPOSE: HMC6352 library for Arduino
//
// HISTORY:
// 0.1.00 - 2011-04-07 initial version
// 0.1.01 - 2011-04-09 quite a complete redo
// 0.1.02 - 2011-04-12 added timing, fixed a bug
//
// Released to the public domain
//
@ -14,70 +16,72 @@
#include <Wire.h>
#include "WProgram.h"
/* ERROR CODES ALL FUNCTIONS
// * twi_writeTo codes
//
// * twi_writeTo codes (== endTransmission commands)
// 0 .. OK
// -1 .. length to long for buffer
// -2 .. address send, NACK received
// -3 .. data send, NACK received
// -4 .. other twi error (lost bus arbitration, bus error, ..)
//
// * requestFrom
// -10 : not enough values returned
// -10 .. not enough values returned
//
// * function calls
// 0 .. OK
// -20 .. error param1
// -21 .. error param2
// -22 .. error param3
//
//
*/
// >=0 == direction
// < 0 error code
hmc6352::hmc6352(uint8_t device)
{
Wire.begin();
_device = constrain(device, 0x10, 0xF6);
}
/* RETURN VALUES
// >=0 == direction
// < 0 error code
*/
int hmc6352::direction()
// Ask the device to make a new reading
int hmc6352::askHeading()
{
int rv = cmd(HMC_GET_DATA);
if (rv != 0) return -rv; // problem with handshake
delay(6); // see datasheet, p8
// no need for wire.available()...
rv = Wire.requestFrom(_device, (uint8_t)2); // remove ambiguity
if (rv != 2) return -10;
rv = Wire.receive() * 256;
rv += Wire.receive();
return rv;
}
int hmc6352::qry()
// read the last value from the
int hmc6352::readHeading()
{
// no need for wire.available()...
int rv = Wire.requestFrom(_device, (uint8_t)2); // remove ambiguity
if (rv != 2) return -10;
rv = Wire.receive() * 256;
rv += Wire.receive();
rv = Wire.receive() * 256; // MSB
rv += Wire.receive(); // LSB
return rv;
}
// wake up from energy saving modus
int hmc6352::wakeUp()
{
return cmd(HMC_WAKE);
int rv = cmd(HMC_WAKE);
delayMicroseconds(100);
return rv;
}
// go into energy saving modus
int hmc6352::sleep()
{
return cmd(HMC_SLEEP);
int rv = cmd(HMC_SLEEP);
delayMicroseconds(10);
return rv;
}
// values obtained from dump
int hmc6352::factoryReset()
{
writeRAM(0x74, 0x50);
writeRAM(0x74, 0x50); // is needed !!
writeCmd(HMC_WRITE_EEPROM, 0, 66);
writeCmd(HMC_WRITE_EEPROM, 1, 0);
writeCmd(HMC_WRITE_EEPROM, 2, 0);
@ -86,20 +90,14 @@ int hmc6352::factoryReset()
writeCmd(HMC_WRITE_EEPROM, 5, 1);
writeCmd(HMC_WRITE_EEPROM, 6, 4);
writeCmd(HMC_WRITE_EEPROM, 7, 6);
writeCmd(HMC_WRITE_EEPROM, 8, 80);
cmd(HMC_SLEEP);
delay(1000);
cmd(HMC_WAKE);
writeCmd(HMC_WRITE_EEPROM, 8, 0x50);
cmd(HMC_SAVE_OP_MODE);
delayMicroseconds(125);
return 0;
}
// HANDLE WITH CARE - RESTART NECESSARY
/* RETURN VALUES
0 = OK
-20 = illegal param1
-21 = illegal param1
-22 = illegal param2
*/
// Returns Operational Mode Config Byte
int hmc6352::setOperationalModus(hmcMode m, uint8_t freq, bool periodicReset)
{
byte omcb = 0; // Operational Mode Control Byte
@ -124,56 +122,69 @@ int hmc6352::setOperationalModus(hmcMode m, uint8_t freq, bool periodicReset)
writeCmd(HMC_WRITE_RAM, 0x74, omcb);
cmd(HMC_SAVE_OP_MODE);
return 0;
}
int hmc6352::SaveOpMode()
{
return cmd(HMC_SAVE_OP_MODE);
delayMicroseconds(125);
return omcb;
}
// read the Operational Modus as byte from EEPROM
// TODO: split into 3 items
//
int hmc6352::getOperationalModus()
{
// readCmd(HMC_READ_RAM, 0x74);
return readCmd(HMC_READ_EEPROM, 0x08);
// datasheet state that at startup the OM is copied from EEPROM
// and that after writing to RAM a reboot is needed to enable new settings
// my interpretation ==> EEPROM is leading
return readCmd(HMC_READ_RAM, 0x74);
//return readCmd(HMC_READ_EEPROM, 0x08);
}
// WARNING DANGEROUS
//
/* RETURN VALUES
// 0 = OK
// -20 = illegal param1
*/
// Switch between normal heading and raw modes
// default = 0 ==> normal headings
// Note: after a reboot the output modus will be 0 again.
int hmc6352::setOutputModus(uint8_t om)
{
if (om > 4) return -20;
return writeCmd(HMC_WRITE_RAM, 0x4E, om);
}
// Read the output modus from RAM
int hmc6352::getOutputModus()
{
return readCmd(HMC_READ_RAM, 0x4E);
}
/* RETURN VALUES
// 0 = OK
// -20 = illegal param1
*/
int hmc6352::setI2Caddress(uint8_t address)
// NOT TESTED
int hmc6352::callibrationOn()
{
int rv = cmd(HMC_CALLIBRATE_ON);
delayMicroseconds(10);
return rv;
}
// NOT TESTED
int hmc6352::callibrationOff()
{
int rv = cmd(HMC_CALLIBRATE_OFF);
delay(15);
return rv;
}
// NOT TESTED
int hmc6352::setI2CAddress(uint8_t address)
{
if (address < 0x10 || address > 0xF6 ) return -20;
return writeCmd(HMC_WRITE_EEPROM, 0, address);
}
int hmc6352::getI2Caddress()
// returns current I2C address
int hmc6352::getI2CAddress()
{
return readCmd(HMC_READ_EEPROM, 0);
}
/* RETURN VALUES
// 0 = OK
// -20 = illegal param1
*/
// NOT TESTED
// meaning time delay unknown
// therefore removed from lib for now
int hmc6352::setTimeDelay(uint8_t msec)
{
return writeCmd(HMC_WRITE_EEPROM, 5, msec);
@ -184,6 +195,9 @@ int hmc6352::getTimeDelay()
return readCmd(HMC_READ_EEPROM, 5);
}
// NOT TESTED
// meaning measurement summing unknown
// therefore removed from lib for now
int hmc6352::setMeasurementSumming(uint8_t ms)
{
if (ms > 16 ) ms = 16;
@ -195,49 +209,63 @@ int hmc6352::getMeasurementSumming()
return readCmd(HMC_READ_EEPROM, 6);
}
int hmc6352::UserCallibrationOn()
// Makes only sense in setOperationalModus()
// therefore removed from lib for now
int hmc6352::saveOpMode()
{
return cmd(HMC_CALLIBRATE_ON);
int rv = cmd(HMC_SAVE_OP_MODE);
delayMicroseconds(125);
return rv;
}
int hmc6352::UserCallibrationOff()
// NOT TESTED
// meaning UpdateOffsets unknown
// therefore removed from lib for now
int hmc6352::updateOffsets()
{
return cmd(HMC_CALLIBRATE_OFF);
}
int hmc6352::UpdateOffsets()
{
return cmd(HMC_UPDATE_OFFSETS);
int rv = cmd(HMC_UPDATE_OFFSETS);
delay(6);
return rv;
}
// idem
// use at own risk ...
int hmc6352::writeEEPROM(uint8_t address, uint8_t data)
{
return writeCmd(HMC_WRITE_EEPROM, address, data);
}
// idem
int hmc6352::readEEPROM(uint8_t address)
{
return readCmd(HMC_READ_EEPROM, address);
}
// idem
// Most RAM locations have an unknown meaning
// use at own risk ...
int hmc6352::writeRAM(uint8_t address, uint8_t data)
{
return writeCmd(HMC_WRITE_RAM, address, data);
}
// idem
int hmc6352::readRAM(uint8_t address)
{
return readCmd(HMC_READ_RAM, address);
}
/* PRIVATE FUNCTIONS
mostly to remove redundancy in functions above
*/
int hmc6352::cmd(uint8_t c)
{
Wire.beginTransmission(_device);
Wire.send(c);
return Wire.endTransmission();
int rv = Wire.endTransmission();
delay(10);
return rv;
}
int hmc6352::readCmd(uint8_t c, uint8_t address)
@ -248,6 +276,8 @@ int hmc6352::readCmd(uint8_t c, uint8_t address)
int rv = Wire.endTransmission();
if (rv != 0) return -rv;
delayMicroseconds(70);
rv = Wire.requestFrom(_device, (uint8_t)1);
if (rv != 1) return -10;
rv = Wire.receive();
@ -260,5 +290,7 @@ int hmc6352::writeCmd(uint8_t c, uint8_t address, uint8_t data)
Wire.send(c);
Wire.send(address);
Wire.send(data);
return Wire.endTransmission();
int rv = Wire.endTransmission();
delayMicroseconds(70);
return rv;
}

View File

@ -1,7 +1,7 @@
//
// FILE: hmc6352.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.00
// VERSION: 0.1.02
// PURPOSE: HMC6352 library for Arduino
//
// DETAILS: see cpp file
@ -14,7 +14,7 @@
#include "Wprogram.h"
#define HMC_LIB_VERSION "0.1.00"
#define HMC_LIB_VERSION "0.1.01"
#define HMC_GET_DATA 0x41
#define HMC_WAKE 0x57
@ -35,38 +35,45 @@ class hmc6352
public:
hmc6352(uint8_t device);
int direction(void);
int qry(void);
// BASIC CALLS FOR STANDBY MODE
int askHeading(void);
int readHeading(void);
int wakeUp(void);
int sleep(void);
int UserCallibrationOn(void);
int UserCallibrationOff(void);
// REST
int factoryReset();
int setOperationalModus(hmcMode m, uint8_t freq, bool periodicReset);
int getOperationalModus();
int setOutputModus(uint8_t om);
int getOutputModus();
int setI2Caddress(uint8_t address);
int getI2Caddress();
int callibrationOn(void);
int callibrationOff(void);
int setTimeDelay(uint8_t msec);
int getTimeDelay();
int setMeasurementSumming(uint8_t ms);
int getMeasurementSumming();
int SaveOpMode(void);
int UpdateOffsets(void);
int setI2CAddress(uint8_t address);
int getI2CAddress();
int writeEEPROM(uint8_t address, uint8_t data);
int readEEPROM(uint8_t address);
int writeRAM(uint8_t address, uint8_t data);
int readRAM(uint8_t address);
// NOT TESTED / UNKNOWN
int setTimeDelay(uint8_t msec);
int getTimeDelay();
int setMeasurementSumming(uint8_t ms);
int getMeasurementSumming();
int saveOpMode(void);
int updateOffsets(void);
private:
int cmd(uint8_t c);
int readCmd(uint8_t c, uint8_t address);