Magnetometer Data to SD Card

Hey guys, hope you can help! (I am really still learning Arduino so I’ll try my best)

Hardware
Arduino Uno
Arduino Wireless SD Shield
MicroMag Magentomater (https://www.sparkfun.com/products/244)

Problem
I have successfully managed to get the readings from the magnetometer to the Serial of the Arduino COM port (i.e. to the computer screen).
However, when I try to send this data to a file on the SD card in the shield (like I have previously done with my GPS module), it seems that it doesn’t open the file in the code below (FILE ERROR is printed in the Serial below), which also corrupts the data output by the magnetometer. Is there an issue with more than 1 thing moving data through the same pin etc.?

Sorry I can’t give more information, but I have no idea what it could be!

Thanks, hope you can help. GGA.

Code

//Original Arduino code for controlling a MicroMag3 magnetometer through SPI
//by Che-Wei Wang
//edited by Gareth
//tested on MICROMAG 3-AXIS
//clockwise rotation is positive
//14/01/2013
#define SCLK 8 //the clock to pulse (#1 on breakout)
#define SSNOT 7 //when low, the device is enabled (#4 on breakout)
#define DRDY 6 //this is low after a reset, high when data is ready (#5 on breakout)
#define RESET 5
#include <SoftwareSerial.h>
#include <math.h>
#include <SD.h>
File fout;
int x = 0;
int y = 0;
int z = 0;
int total = 1;
void setup(){
  Serial.begin(9600);
  pinMode(SSNOT, OUTPUT);
  pinMode(RESET, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(MISO, INPUT);
  pinMode(DRDY, INPUT);
  pinMode(SCLK, OUTPUT);
  pinMode(10, OUTPUT);
  digitalWrite(SSNOT, LOW);
  Serial.println("#\tx\ty\tz\t|B|");
  fout = SD.open("110313.txt", FILE_WRITE);
  if (fout) {
    fout.println("#\tx\ty\tz\t|B|");
  } 
  else {
    Serial.println("FILE ERROR");                    // THIS IS PRINTED!
  }
  fout.close();
}
void loop(){
  Serial.print(int(total));
  Serial.print("\t");
  x=readaxis(0);
  y=readaxis(1);
  z=readaxis(2);
  getMag(x,y,z);
  total++;
}
void send_bit(int _high){
  digitalWrite(MOSI, _high);
  delayMicroseconds(300);
  digitalWrite(SCLK, HIGH);
  delayMicroseconds(300);
  digitalWrite(SCLK, LOW);
  delayMicroseconds(300);
}
int receive_bit(){
  digitalWrite(SCLK, HIGH);
  delayMicroseconds(300);
  int bit = digitalRead(MISO);
  delayMicroseconds(300);
  digitalWrite(SCLK, LOW);
  delayMicroseconds(300);
  return bit;
}
float readaxis(int _axis){
  digitalWrite(RESET, LOW);
  delayMicroseconds(300);
  digitalWrite(RESET, HIGH);
  delayMicroseconds(300);
  digitalWrite(RESET, LOW);
  delayMicroseconds(300);
  send_bit(LOW);
  send_bit(HIGH);
  send_bit(HIGH);
  send_bit(LOW);
  send_bit(LOW);
  send_bit(LOW);
  if (_axis == 0){ //x axis
    send_bit(LOW);
    send_bit(HIGH);
  }
  else if (_axis == 1){ //y axis
    send_bit(HIGH);
    send_bit(LOW);
  }
  else{ //z axis
    send_bit(HIGH);
    send_bit(HIGH);
  }
  while (digitalRead(DRDY) == LOW){  
  }
  long runningtotal = 0;
  long sign = receive_bit();
  for (int i = 14; i >= 0; i = i - 1){
    long thisbit = receive_bit();
    thisbit = thisbit << i;
    runningtotal = runningtotal | thisbit;
  }
  if (sign == 1){
    runningtotal = runningtotal - 32768;
  }
  if (_axis == 0){
    x = runningtotal;
    Serial.print(x,DEC);
    Serial.print("\t");
  }
  else if (_axis == 1){
    y = runningtotal;
    Serial.print(y,DEC);
    Serial.print("\t");
  }
  else{
    z = runningtotal;
    Serial.print(z,DEC);
    Serial.print("\t"); 
  } 
  return runningtotal;
}
int getMag(float x, float y, float z){
  long mag = 0;
  //  int perc = 0;
  mag = sqrt((x*x)+(y*y)+(z*z));
  Serial.println(int(mag));
  fout = SD.open("110313.txt", FILE_WRITE);
  fout.print(x, DEC);
  fout.print('\t');
  fout.print(y, DEC);
  fout.print('\t');
  fout.print(z, DEC);
  fout.print('\t');
  fout.println(mag, DEC);
  fout.close();
  return mag;
}

Where do you call SD.begin()? Nowhere that I can see.

Why are you including SoftwareSerial.h?

PaulS: Where do you call SD.begin()? Nowhere that I can see.

Why are you including SoftwareSerial.h?

I have taken out SoftwareSerial.h in an older version, shouldn't be there! :astonished: In previous attempts at fixing, SD.begin() doesn't appear to help the cause (fixes the magnetometer, and "FILE ERROR" still occurs). :~ Is it essential?

Is it essential?

Only if you want to write to the SD card.

int getMag(float x, float y, float z){
  long mag = 0;
  mag = sqrt((x*x)+(y*y)+(z*z));
  Serial.println(int(mag));

  return mag;

Why does a function defined to return an int actually return a long?

PaulS:
Only if you want to write to the SD card.

Oh. Well, when I put it in in the past, it has only caused further errors*. Should I just place empty brackets or define a select line?

PaulS:
Why does a function defined to return an int actually return a long?

Thanks for that. Fixed to return long.

*Having placed it in, it stops any transmission of data from the magnetometer.

Having placed it in, it stops any transmission of data from the magnetometer.

We will need you to lean over a bit, so we can see.

PaulS: We will need you to lean over a bit, so we can see.

I'm gonna take a guess at what you mean there!

With the original (plus removing SoftwareSerial.h and changing int(mag) to long(mag), my Serial is:

#.x.y.z.|B|
FILE ERROR
1.-228.592.1280.1428
2.-246.585.1298.1444
3.-268.579.1273.1423
4.-278.591.1272.1429
5.-278.579.1295.1445
6.-313.583.1263.1425
7.-336.597.1278.1450
8.-329.591.1284.1451
9.-313.592.1262.1428
10.-302.587.1282.1441
...

With the SD.begin() placed in void setup{}, it gives:

#.x.y.z.|B|
FILE ERROR
1.

Something breaks with that line in.

I'm gonna take a guess at what you mean there!

Want to guess again? It's the code we need to see.

PaulS:
Want to guess again? It’s the code we need to see.

Oh. :cold_sweat:

//Original Arduino code for controlling a MicroMag3 magnetometer through SPI
//by Che-Wei Wang
//edited by Gareth
//tested on MICROMAG 3-AXIS
//clockwise rotation is positive
//14/01/2013
#define SCLK 8 //the clock to pulse (#1 on breakout)
#define SSNOT 7 //when low, the device is enabled (#4 on breakout)
#define DRDY 6 //this is low after a reset, high when data is ready (#5 on breakout)
#define RESET 5
#include <math.h>
#include <SD.h>
File fout;
int x = 0;
int y = 0;
int z = 0;
int total = 1;
void setup(){
  Serial.begin(9600);
  SD.begin();
  pinMode(SSNOT, OUTPUT);
  pinMode(RESET, OUTPUT);
  pinMode(MOSI, OUTPUT);
  pinMode(MISO, INPUT);
  pinMode(DRDY, INPUT);
  pinMode(SCLK, OUTPUT);
  pinMode(10, OUTPUT);
  digitalWrite(SSNOT, LOW);
  Serial.print("#\tx\ty\tz\t|B|\n");
  fout = SD.open("110313.txt", FILE_WRITE);
  if (fout) {
    fout.println("#\tx\ty\tz\t|B|");
  } 
  else {
    Serial.println("FILE ERROR");
  }
  fout.close();
}
void loop(){
  Serial.print(int(total));
  Serial.print("\t");
  x=readaxis(0);
  y=readaxis(1);
  z=readaxis(2);
  getMag(x,y,z);
  total++;
}
void send_bit(int _high){
  digitalWrite(MOSI, _high);
  delayMicroseconds(300);
  digitalWrite(SCLK, HIGH);
  delayMicroseconds(300);
  digitalWrite(SCLK, LOW);
  delayMicroseconds(300);
}
int receive_bit(){
  digitalWrite(SCLK, HIGH);
  delayMicroseconds(300);
  int bit = digitalRead(MISO);
  delayMicroseconds(300);
  digitalWrite(SCLK, LOW);
  delayMicroseconds(300);
  return bit;
}
float readaxis(int _axis){
  digitalWrite(RESET, LOW);
  delayMicroseconds(300);
  digitalWrite(RESET, HIGH);
  delayMicroseconds(300);
  digitalWrite(RESET, LOW);
  delayMicroseconds(300);
  send_bit(LOW);
  send_bit(HIGH);
  send_bit(HIGH);
  send_bit(LOW);
  send_bit(LOW);
  send_bit(LOW);
  if (_axis == 0){ //x axis
    send_bit(LOW);
    send_bit(HIGH);
  }
  else if (_axis == 1){ //y axis
    send_bit(HIGH);
    send_bit(LOW);
  }
  else{ //z axis
    send_bit(HIGH);
    send_bit(HIGH);
  }
  while (digitalRead(DRDY) == LOW){  
  }
  long runningtotal = 0;
  long sign = receive_bit();
  for (int i = 14; i >= 0; i = i - 1){
    long thisbit = receive_bit();
    thisbit = thisbit << i;
    runningtotal = runningtotal | thisbit;
  }
  if (sign == 1){
    runningtotal = runningtotal - 32768;
  }
  if (_axis == 0){
    x = runningtotal;
    Serial.print(x,DEC);
    Serial.print("\t");
  }
  else if (_axis == 1){
    y = runningtotal;
    Serial.print(y,DEC);
    Serial.print("\t");
  }
  else{
    z = runningtotal;
    Serial.print(z,DEC);
    Serial.print("\t"); 
  } 
  return runningtotal;
}
int getMag(float x, float y, float z){
  long mag = 0;
  mag = sqrt((x*x)+(y*y)+(z*z));
  Serial.println(long(mag));
  fout.print(x, DEC);
  fout.print('\t');
  fout.print(y, DEC);
  fout.print('\t');
  fout.print(z, DEC);
  fout.print('\t');
  fout.println(mag, DEC);
  return mag;
}