Been held up trying to rebuild someones big usb enclosure, turns out it's a linux jbod......with t drives using non standard filessytems so .....
Link to site http://www.sureelectronics.net
module part numbers are so search
DC-SS503 i2c only
DC-SS504 i2c with uart can't talk to the uart yet, but I2C works
know there is both an Internet and eBay site(s), check out the overall cost inc shipping for the best deal.
http://www.sure-electronics.net/download/
select part number, wait for drop down list, they are down the very bottom, sometimes it will filter...
big zip file has memsic app notes as well
The I2C code is the easy bit, it's the calibration etc, I am writing some notes now, it's not a case of getting a direct bearing. Info is in the memsic app notes You also have to calibrate the compass and you need to obtain values for that, which go back ionto the maths.
I2C code is simple, not sure if Ihave used wiire.available() properly but it works.
There's afew more things , the modules have built in 4.7K pull-ups. they work fine with the twi.h internal pullup's on by default setting and 10-12 inches of hookup wire , I'm using a seeduino mega so no discrete pull ups on the controller board. I have not tested with other devices yet on the bus.
I had an issue with the first module, which is being replaced the straight I2C only model, but this works fine on the improved with uart (504). I do not expect there to be aproblem on the 503.
Sure were very quick to replace. they only wanted code and data.
The sample I wrote will test the compass out and will alow you to calibrate via dumping to serial console copy paste to spreadshhet. That worls well as it does not seem to need calibrating often, saves memory and code and allows you to chart the data .....which is useful when you have stray mag fields
// I left this is as LCD is easy
#include <LiquidCrystal.h>
// I2C example template I used, I also went to a 8 bit port expander to test out my I2C when I had issues so thanks helped me heaps!!!!
///Test program for PCF8574A I2C I/O expander from Futurlec
// - Blinks all pins low then high - 1 second cycle.
// by pclyne
//
#include <Wire.h>
// you need the maths library for arctan2
#include <math.h>
LiquidCrystal lcd(26, 27, 22, 23, 24, 25);
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// From the Memsic data sheet, def I2C address for compass chip is 60 as a 7 bit binary number, it is built in no physcial address can be set
// then write memory location which is 00Hex,
// then write 01 Hex for read,
// set and reset 04Hex or x02Hex need to be written to the single "status" register
//
// THIS IS A 7 BIT ADDRESS, I AM SHOUTING
#define CARD_ADR B0110000
int myADDR = CARD_ADR;
byte comp_reg_addr = B00000000;
byte read_comp = B00000001;
byte reset_comp = B00000100;
byte set_comp = B00000010;
// used to control the cardSet function, which I have commented out of loop but when in, you do n;t need to hammer the chip please read comments in the function
boolean compass_set = false;
// "p" should sets the size of an array which in this sample code , when a specifed number of data samples has been taken a dump occurs to the comsole
// copy the data by highlighting the values and controlc to copy and paste into a spreadsheet....quick and dirty more later on that
// and paste into a spreadsheet use that to do a quick calc for the calibration
// When you calibrate the compass, you turn it through 360 degrees and take the raw outputs of the sensor. You then take max and min values and then do a bit of calculation
// So you need an area which is easy to ove your test rig around 1.5 rev.s. you can vary delays etc after a bit of practice it's a second ot so and you can judge a turn to a few degrees which is accurate enough
// you need around 30 points per revolution of the compass I would alwayd do 1.5 revolutions so 45 is a good number, there's a potential array over run or pointer going out of bounds so you need to change an loop
// at the bottom of compassReader() if you decrease the value of "p". P should be a constant but I will you to change these values as you see fit
// As you turn the compass through the main north south east west points make very small changes, this is important in the calibration process
// store_x and store_y will contain the raw output of the sensor, WHY a big array we need some data points to calc the calibration, "p" sets the size for these arrays
// when not calibrating this can be changed
// need to work out how to do an arduino min and max on the arrays, at a later date when I add a calibration function,
//
// I am yet I am not sure how often calibration is required, I have seen some drift over the past few days around 5 degrees but that maybe because of a hspda modem not too far away
// now I have the lcd set up I've left the calls to the LCD in but commented out.
// setup arrays for raw sensor data
int p = 0;
// P is used as an index for store_x and y, dirty I've used the index in 2 functions sorry ba style but this is demo code for calibration
double store_x[55];
double store_y[55];
// IMPORTANT I've left a hard coded value in the very bottom of the compassReader() which is also set to 45 so if you change the value assigned to P change that also
// it will run the array put of bound s or you want a big sample spend hours slowly rotating the compass and only get 45 points....
//
void setup() {
Wire.begin(); // needed this sets the controller i2c as master () is empty
Serial.begin(9600);
// from liquid crystal
lcd.begin(20,4);
}
// I used a SEEED Mega, I2c @ default 100K, ardiono/seeduino internal pullups enabled by def by Wires Library
// amend this when I have tested at 400K and mixed in some other I2C devices
// by the way the compass modules have internal resistors on both SDA and SDL 4.7K
void loop() {
Serial.print("\n\n---------------------------------------------\n");
Serial.print("Lets talk to the compass, sample count = ");
Serial.print(p);
Serial.print("\n----------------------------------------------\n");
//Serial.println("!!!!!!!!!!Card set!!!!!!!!!!!!!!!!!!!");
// see cardSet() comments, disable if not required
// compassSet();
// delay(5);
// A delay for calibration gives you tme to move the compass and knock all the wires out......
// compass needs a few microseconds fro power on or set reset to recover
// Never moind the more you practice the better you get, after a few goes you can quite accurately rotate the comapss by 10 degrees and in 1 second
delay(2000);
// reads the compass sensor over I2c
lcd.clear();
compassReader();
}
void compassReader() {
// delay so when looping you give the compass time for a new measurement I think the delay is 5ms between samples
delay(6);
// the compass read should return 5 bytes with 4 bytes containing sensor values
byte comp_status = 0;
byte avail = 0;
byte x_msb = 0;
byte x_lsb = 0;
byte y_msb = 0;
byte y_lsb = 0;
// first byte is a status byte I'm currently using that to control the wires reads
// The i2c bus moves the remaining bytes according to the datasheets in order they are
// x msb
// x lsb
// y msb
// y lsb
// the msb seems to be 0000 XXXX in binary watch the order carefully if you have issues
// lsb XXXX XXXX in binary
//
// Next we need to do the read request there is alittle ambiguity over wording in a section of a datasheet so check the MEMSIC one it is crystal clear
// address of the compass module status register
Wire.beginTransmission(myADDR);
// command to address status register or memory location
Wire.send(B00000000);
// Wires will not write a command to compass status register to read compass sensor
Wire.send(B00000001);
// you must use the wires end transmission
Wire.endTransmission();
// sensor needs a bit of wake up time and take a fresh sample
delay(6);
// now read the data from the sensor, address and request or hope for 5 bytes
Wire.requestFrom(myADDR, 5);
// read status, seems to be 5 should put some handling on this for other status values.....
avail = Wire.available();
//avail = avail ;
Serial.print("Wire Available = ");
// just want to keep an eye on the status as not yet happy I understand what is being passed as a status value but it
// has worked well for 4 days
Serial.print(avail,BIN);
if ( avail == B00000101 ) {
Serial.print("\n");
avail = avail -1;
while( avail > 1 ) {
// comp_status = Wire.receive();
x_msb = Wire.receive();
//delay(1);
avail = avail -1;
x_lsb = Wire.receive();
//delay(1);
avail = avail -1;
y_msb = Wire.receive();
//delay(1);
avail = avail -1;
y_lsb = Wire.receive();
avail = avail -1;
// comp_status = Wire.receive();
// avail = avail -1;
}
}
else ( Serial.println )("compass sensor status not 5, probable I2C read error, or sensor recovering");
int x = (int) x_msb;
x = x_msb << 8;
int x_small = (int) x_lsb;
int x_big= x | x_small;
int y = (int) y_msb;
y = y_msb << 8;
int y_small = (int) y_lsb ;
int y_big= y | y_small;
Serial.print("Raw Sensor Values for x and raw_y");
Serial.print("\n");
Serial.print(x_big,BIN);
Serial.print("\t");
S