Again...Getting my data by sending "A" and then ask for the result works fine.
Now I just want to step it up a bit and let the compass sample so all I have to do is ask for the result.
The idea is to have a compass sending data via the Arduino 2560 board autonomously on Serial1 which goes to my PC. On the PC I run my robot SW which is done in C#.
(I know .... probably overkill to have the 2560 to do this simple task but thats how it is done today )
#include <avr/io.h>
#include <MsTimer2.h>
#include <Wire.h>
//General
#define __AVR_ATmega2560__
#define F_CPU 16000000UL
#define UBRR1H // Used for Serial1 routines
//COMPASS
#define COMPASS_1_WRITE_ADDRESS 0x21 // The addess is normally 0x42 but shifted >> 1 to get right format for wire lib
#define COMPASS_1_READ_ADDRESS 0x21 // The addess is normally 0x43 bin 0100 0011 but shifted >> 1 -> 0010 0001 also 0x21 ???? to get right format for wire lib
#define CMD_WRITE_TO_EEPROM 'w'
#define CMD_READ_FROM_EEPROM 'r'
#define CMD_WRITE_TO_RAM_REGISTER 'G'
#define CMD_READ_FROM_RAM_REGISTER 'g'
#define CMD_ENTER_SLEEP_MODE 'S'
#define CMD_EXIT_SLEEP_MODE 'W'
#define CMD_UPDATE_BRIDGE_OFFSETS 'O'
#define CMD_ENTER_USER_CALIBRATION_MODE 'C'
#define CMD_EXIT_USER_CALIBRATION_MODE 'E'
#define CMD_SAVE_OP_MODE_TO_EEPROM 'L'
#define CMD_GET_DATA_COMPENSATE_AND_CALCULATE_NEW_HEADING 'A'
#define CMD_CONTINOUS_20HZ 0x72
#define CMD_CONTINOUS_10HZ 0x52
#define CMD_CONTINOUS_10HZ_NORES 0x42
#define RAM_ADRESS_OPERATIONAL_MODE 0x7F //0x74
#define RAM_ADRESS_OUTPUT_MODE 0x4E
//OPERATIONAL_MODE = MEASUREMENT_RATE || OP_MODE
const byte MEASUREMENT_RATE_1HZ = 0x00;
const byte MEASUREMENT_RATE_5HZ = 0x20;
const byte MEASUREMENT_RATE_10HZ = 0x40;
const byte MEASUREMENT_RATE_20HZ = 0x60;
const byte PERIOD_RESET_SET_ON = 0x10;
const byte PERIOD_RESET_SET_OFF = 0x00;
const byte OP_MODE_STANDBY = 0x00;
const byte OP_MODE_QUERY = 0x01;
const byte OP_MODE_CONTINUOUS = 0x02;
const byte OP_MODE_NOT_ALLOWED = 0x03;
#define MAX_NO_OF_READINGS_IN_FILTER 50
// GLOBAL VARIABLES
static boolean COMPASSTIME,COMPASSDATAVALID;
unsigned int GlobCompassData[4]={0x55,00,00,00}; //Startbyte always 55 , 2 data bytes and a checksum is added when data is read.
// Init Compass1 to a mode where it sends data at TBDHz
void InitCompass1()
{
Wire.beginTransmission(COMPASS_1_WRITE_ADDRESS);
Wire.send(CMD_WRITE_TO_RAM_REGISTER);
Wire.send(RAM_ADRESS_OPERATIONAL_MODE);
//Only one of the two below is used
Wire.send(CMD_CONTINOUS_10HZ_NORES);
// Wire.send(MEASUREMENT_RATE_1HZ || PERIOD_RESET_SET_ON || OP_MODE_CONTINUOUS);
Wire.endTransmission();
}
void GetCompass1Dir()
{
byte val = 0;
byte data[2];
int deg, j, frac, compassdatavalid, checksum;
//Wire.beginTransmission(COMPASS_1_WRITE_ADDRESS);
//Wire.send(CMD_GET_DATA_COMPENSATE_AND_CALCULATE_NEW_HEADING);
//Wire.endTransmission();
//delay(70);
Wire.requestFrom(COMPASS_1_READ_ADDRESS, 2);
j = 0;
COMPASSDATAVALID=false;
while(Wire.available())
{
char c = Wire.receive();
Serial.println(c,HEX);
data[j] = c;
GlobCompassData[j+1]=c;
j++;
COMPASSDATAVALID=true;
}
Wire.endTransmission();
Serial.print("Total Byte count");
Serial.println(j,HEX);
// ADD checksum at the end
checksum = GlobCompassData[0];
for(j = 1; j < 3; j++){
checksum ^= GlobCompassData[j];
}
GlobCompassData[3]=checksum;
if (COMPASSDATAVALID)
{
Serial.print(" DataByte One: ");
Serial.print(GlobCompassData[1], HEX);
Serial.print(" DataByte two: ");
Serial.println(GlobCompassData[2], HEX);
Serial.print(" heading = ");
frac = data[0]*256 + data[1];
deg = frac / 10;
frac = frac - deg * 10;
Serial.print(deg);
Serial.print(".");
Serial.println(frac);
}
else
{
Serial.println("NO DATA RECIEVED");
}
}
// Timer2int called at 10HZ
void Timer2interrupt()
{
static boolean output = HIGH;
digitalWrite(13, output);
output = !output;
COMPASSTIME=true;
}
void setup()
{
pinMode(13, OUTPUT);
MsTimer2::set(500,Timer2interrupt); // 200ms period gives a call at 2Hz to get the compass direction. The compass is internally sampled at 10Hz and average
MsTimer2::start();
Serial.begin(19200);
Serial1.begin(19200);
Wire.begin();
delay(100);
InitCompass1; // Set up the compass for automode
}
void loop()
{
if (COMPASSTIME)
{
GetCompass1Dir();
Serial1.print("Compass data: Command Byte:");
Serial1.print(GlobCompassData[0], HEX);
Serial1.print(" First Byte: ");
Serial1.print(GlobCompassData[1], HEX);
Serial1.print(" Second Byte: ");
Serial1.print(GlobCompassData[2], HEX);
Serial1.print(" Checksum:");
Serial1.println(GlobCompassData[3], HEX);
COMPASSTIME=false;
}
}
Last Edit ..jus removed some swedish out of the code...
Well... I just gave up on this.
I have looked at the oscillsocope screen over and over and cannot figure out why I cant read out the values after initiating the compass.
I am starting to believe that I must write som more commands when initating the compass.....but I have no idea which...
Instead I am now using my oscilloscope to trim and run the Command "A" and read data at 20Hz.
Then I will do the Low Pass filtering on my PC instead.....
Well... I just gave up on this.
I have looked at the oscillsocope screen over and over and cannot figure out why I cant read out the values after initiating the compass.
Did you read robtillart's comment about the compass not being intialised?
I think your test program is too complicated - I'd simplify, forget the timer.
This is how I got mine to work when I first got it.
#include <Wire.h>
int HMC6352Address = 0x42;
// This is calculated in the setup() function
int slaveAddress;
int ledPin = 13;
boolean ledState = false;
byte headingData[2];
int i, headingValue;
void setup()
{
// Shift the device's documented slave address (0x42) 1 bit right
// This compensates for how the TWI library only wants the
// 7 most significant bits (with the high bit padded with 0)
slaveAddress = HMC6352Address >> 1; // This results in 0x21 as the address to pass to TWI
Serial.begin(57600);
pinMode(ledPin, OUTPUT); // Set the LED pin as output
Wire.begin();
}
void loop()
{
// Flash the LED on pin 13 just to show that something is happening
// Also serves as an indication that we're not "stuck" waiting for TWI data
ledState = !ledState;
if (ledState) {
digitalWrite(ledPin,HIGH);
}
else
{
digitalWrite(ledPin,LOW);
}
// Send a "A" command to the HMC6352
// This requests the current heading data
Wire.beginTransmission(slaveAddress);
Wire.send("A"); // The "Get Data" command
Wire.endTransmission();
delay(10); // The HMC6352 needs at least a 70us (microsecond) delay
// after this command. Using 10ms just makes it safe
// Read the 2 heading bytes, MSB first
// The resulting 16bit word is the compass heading in 10th's of a degree
// For example: a heading of 1345 would be 134.5 degrees
Wire.requestFrom(slaveAddress, 2); // Request the 2 byte heading (MSB comes first)
i = 0;
while(Wire.available() && i < 2)
{
headingData[i] = Wire.receive();
i++;
}
headingValue = headingData[0]*256 + headingData[1]; // Put the MSB and LSB together
Serial.print("Current heading: ");
Serial.print(int (headingValue / 10)); // The whole number part of the heading
Serial.print(".");
Serial.print(int (headingValue % 10)); // The fractional part of the heading
Serial.println(" degrees");
delay(500);
}
Basically it's just the example code modified to work on a mega.
Then I got my RTC, MPL115A1, SparkFun huge LCD with serial back pack.
I added a keypad as well, but the finished unit probably wont use it.
It works but the big LCD is proving to be a hassle to house/mount.
If you have a look at the LCD closely you can see the barometer output is bogus! It wasn't hooked up.
How the hell do I put photo's here or circuits or drawings?
@Fred
Got my hmc6352 sensor last week, wrote a library for it which is still in Beta. Also made a simple config sketch to set modes and do a EEPROM dump etc. However when put the hmc in continuous mode it "got mad" values in EEPROM and RAM completely made no sense anymore and I could not reset it for two days. It was working in continuous mode as I could get (uncallibrated) readings at 20 times per second.
I finally got it back to standby mode by a separate sketch that kept on writing to EEPROM the right value and then I pulled the 5V plug.
If you are interested in a "continuous" experiment please send me a PM than I will mail the BETA version. I have to do more tests before publishing the library (but some other projects scream for attention Let me know.