|
// micromag 3-axis magnetic field sensor
int SCLK = 8; // magnetometer pin 1
int MISO = 9; // magnetometer pin 2
int MOSI = 10; // magnetometer pin 3
int SSNOT = 11; // magnetometer pin 4
int DRDY = 12; // magnetometer pin 5
int RESET = 13; // magnetometer pin 6
int x = 0; // magnetic field x axis
int y = 0; // magnetic field y axis
int z = 0; // magnetic field z axis
int heading = 0; // magnetic field heading
void setup() {
Serial.begin(9600);
pinMode(48, OUTPUT); // turn ON the board LED for diagnostics only
digitalWrite(48, HIGH);
pinMode(SSNOT, OUTPUT);
pinMode(RESET, OUTPUT);
pinMode(MOSI, OUTPUT);
pinMode(SCLK, OUTPUT);
pinMode(MISO, INPUT);
pinMode(DRDY, INPUT);
digitalWrite(SSNOT, LOW);
}
void loop() {
x = readAxis(0); // read the x-axis magnetic field value
y = readAxis(1); // read the y-axis magnetic field value
z = readAxis(2); // read the z-axis magnetic field value
heading = getHeading(x, y, z); // calculates the magnetic field heading
Serial.print("x: ");
Serial.print(x, DEC);
Serial.print("y: ");
Serial.print(y, DEC);
Serial.print("z: ");
Serial.print(z, DEC);
Serial.print("heading: ");
Serial.print(heading, DEC);
delay(20000); // next reading in 20 seconds
}
// specific commands for the sensor
void sendBit(int bit){
// send the bit on the RISING edge of the clock
digitalWrite(MOSI, bit);
delay(2);
digitalWrite(SCLK, HIGH);
delay(2);
digitalWrite(SCLK, LOW);
delay(2);
}
int receiveBit(){
// receive the data on the FALLING edge of the clock
digitalWrite(SCLK, HIGH);
delay(2);
int bit = digitalRead(MISO);
delay(2);
digitalWrite(SCLK, LOW);
delay(2);
return bit;
}
float readAxis(int axis){
// send eight bits, wait until the data is ready then receive 16 bits
// pulse the reset
digitalWrite(RESET, LOW);
delay(2);
digitalWrite(RESET, HIGH);
delay(2);
digitalWrite(RESET, LOW);
delay(2);
// send the command byte
// set the time to read the magnetic sensors (ASIC period) as /2048
sendBit(LOW);
sendBit(HIGH);
sendBit(HIGH);
sendBit(LOW);
sendBit(LOW);
sendBit(LOW);
// the last two bits select the axis
if (axis == 0){ // x axis
sendBit(LOW);
sendBit(HIGH);
}
else if (axis == 1){ // y axis
sendBit(HIGH);
sendBit(LOW);
}
else{ // z axis
sendBit(HIGH);
sendBit(HIGH);
}
// wait until the DRDY line is high
while(digitalRead(DRDY) == LOW) {
}
long total = 0;
// receive result
// the leftmost bit mark the number as positive or negative
long sign = receiveBit();
// the remaining bits are converted to an integer
for (int i = 14; i >= 0; i = i - 1){
long thisbit = receiveBit();
thisbit = thisbit << i;
total = total | thisbit;
}
if(sign == 1) {
total = total - 32768;
}
// set and return the appropriate variable
if (axis == 0){
x = total;
}
else if (axis == 1){
y = total;
}
else{
z = total;
}
return total;
}
int getHeading(float x, float y, float z){
float heading=0;
if((x == 0)&&(y < 0))
heading= PI/2.0;
if((x == 0)&&(y > 0))
heading=3.0*PI/2.0;
if (x < 0)
heading = PI - atan(y/x);
if((x > 0)&&(y < 0))
heading = -atan(y/x);
if((x > 0)&&(y > 0))
heading = 2.0*PI - atan(y/x);
return int(degrees(heading));
}
|