// Last Update: 23-9-21
// Settinttg MAG3110: 0x01 0x80, LSB at High address !!!!!
// NOTE: The sensor axis x,y,z are NOT aligned with the axis X,Y,Z of the wooden cube.
// Note: Make sure the size of BitVal_Vec is within the Error-check range.
// Data recorder for Magnetometer calibration with N measurements
// Use for N: 6yaw x 6roll x 6pitch= 216 readings
// To record the data on txt-file, use the program coolterm.exe with
// the option => Connection=> Capture to Textfile.
// The file will be saved in C:\arduino-c-dev\coolterm-record-to-filev160\coolterm capture 20xx-yy-zz hr-min-sec.txt
// Copy the saved datafile to directory d:\Pelles C-SourceCode\sensordata\ and rename
// Finally copy the measurements to file recorded-sensordata.txt and reduce this file
// Further process the reduced datafile with application:
// PELLES-ST-ROTATED-ELLIPSOID-FITTING-FOR-SENSOR-CALIBRATION.C
// The Pelles-C application assumes a rotated 3D ellipsoid.
// Note: The orientation i.e. the signs of the sensor with respect to cube axis
// Note: All Results are Bit-Values and NOT Gauss or the like.!!!!
// plug the SPEAKER signal wire in digital pin 9
#include <Wire.h> // with DUE all Wire has to be replaced by Wire1
#define I2C Wire // Teensy
// mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
// The Magnetometer Sensor that will be used is MAG3110.
// mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
#define KOMPASS 0x0E // I2C 7bit address of MAG3110.
// mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
// mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
#define SPKR 9 // 9 is the digital pin that you plugged the speaker "red" wire into
int auto_switch=0; //switch for automatic (=>1)run, or user confirmed (=>0)
const int _row= 216; //Deze waarde aanpassen mbt het aantal 6yaw x 6roll x 6pitch=216 gewenste metingen.
int n, j;
int mag[3];
int magshift_x = 0;
int magshift_y = 0;
int magshift_z = 0;
char dest[20];
char desth[10];
const char str1[] = "D[";
const char str2[] = "][";
const char str3[] = "]=";
const char str4[] = ";";
int X[_row][3]; // X matrix m x p (m=_rows, p=columns=3)
// m rows is aantal metingen, bv 6x6x6 = 216
int BitVal_Vec;
// ===============================================================
void setup()
{
Serial.begin(9600); // start serial for output. Make sure you set your Serial Monitor to the same!
I2C.begin(); // join i2c bus (address optional for master)
delay(100);
pinMode(SPKR, OUTPUT); //set the speaker as output
delay(100);
// ++++++++++++ Configure KOMPASS Magnetometers +++++++++++++++
Serial.println("Note:A MAG3110 is the installed magnetometer.");
config_MAG3110(); //Puts the Mag-sensor in the correct operating mode
Serial.println();
Serial.print("Magnetometer Calibration measurements at ");
Serial.print (_row);
Serial.print (" arbitrary cube positions");
Serial.println();
Serial.println();
// ============= Start Sensor Reading Loop =====================
beep();
delay(50);
beep();
beep();
Serial.println("Press any key to start Sensor Reading Loop.");
while (!Serial.available()){} // wait for a character
for (n=0; n<_row; n++)
{
Serial.println(" ");
Serial.println(" ");
Serial.print ("Measurement ");
Serial.print(n+1);
Serial.print (" of ");
Serial.print (_row);
if (n>0)
{
Serial.print (" Put Cube in an arbitrary position.....");
}
Serial.println();
tone(9,800,300);
delay(30);
tone(9,400,300);
delay(10);
beep();
delay(10);
beep();
beep();
delay(10);
tone(9,200,300);
delay(1000); //Set cube in new position.
// Measurement will now be taken.
if (auto_switch==1) //switch for manual or auto measurements
{
while (!Serial.available()){} // wait for a character
{
Serial.read(); // clear the input buffer
}
}
Serial.println("Reading Sensor."); //Start of data measurement and recording
int xsum=0; //Bij DUE is int 4byte = 32 bit = 2.147.483.648
int ysum=0;
int zsum=0;
for (j=1 ; j<11 ; j++) //j<11 means j<11
{
read_MAG3110_MAGSENSOR(mag); // read x/y/z and store in global mag[3] van type integer
xsum += (mag[0] -magshift_x); // x-as raw-data.
ysum += (mag[1] -magshift_y); // y-as raw-data.
zsum += (mag[2] -magshift_z); // z-as raw-data.
}
j=j-1;
Serial.print("Number of samples taken for averaging the measurement is: ");
Serial.println( j);
X[n][0]=(int)(xsum/j); //average raw bitvalue as integer
X[n][1]=(int)(ysum/j); //average raw bitvalue as integer
X[n][2]=(int)(zsum/j); //average raw bitvalue as integer
BitVal_Vec = (int)sqrt( X[n][0] * X[n][0] + X[n][1] * X[n][1] + X[n][2] * X[n][2]); //integer
Serial.print("X= ");
Serial.print(X[n][0]);
Serial.print(" Y= ");
Serial.print(X[n][1]);
Serial.print(" Z= ");
Serial.print(X[n][2]);
Serial.print(" Vector= ");
Serial.println(BitVal_Vec);
Serial.println(" ");
if (BitVal_Vec>15000) //in case of error reading
{
beep();
beep();
beep();
beep();
beep();
beep();
break;
}
Serial.print("Measurement ");
Serial.print (n+1);
Serial.print (" of ");
Serial.print (_row);
Serial.print (" is written to file...");
Serial.println();
Serial.println();
} //end for-loop
//###############################################################
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//========== All N Cube positions have been recorded ============
// MatrixMathPrint((int*) X, _row ,3 , 0, "Recorded Data Matrix");
int i;
float vector;
for (i=0; i<_row; i++)
{
Serial.print("X= ");
Serial.print(X[i][0]);
Serial.print(" Y= ");
Serial.print(X[i][1]);
Serial.print(" Z= ");
Serial.print(X[i][2]);
vector=sqrt(X[i][0]*X[i][0] + X[i][1]*X[i][1] + X[i][2]*X[i][2]);
Serial.print(" Vector= ");
Serial.print(vector,0);
Serial.println(" ");
}
Serial.println();
Serial.println();
Serial.println("Save below data under file-name: recorded-sensordata.txt");
Serial.println("The raw sensor measurements x,y,z are integer bit-values. ");
for (int i=0;i<_row;i++)
{
for (int j=0;j<3;j++)
{
strcpy(dest, str1);
itoa(i,desth,10);
strcat(dest, desth);
strcat(dest, str2);
itoa(j,desth,10);
strcat(dest, desth);
strcat(dest, str3);
int val = X[i][j];
itoa(val,desth,10);
strcat(dest, desth);
strcat(dest, str4);
Serial.println(dest);
delay(10);
}
}
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void loop()
{
Serial.println("Data Recording Finished..........");
delay(3000);
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++ Start of (support) functions ++++++++++++++
// ***************** Matrix Printing Routine ****************
// Uses tabs to separate numbers under assumption printed float width won't cause problems
void MatrixMathPrint(int* A, int m, int n, int decimals, String label)
{
// A = input matrix (m x p)
// m = number of rows in A
// p = number of columns in A
int i,j;
Serial.println();
Serial.println(label);
for (i=0; i<m; i++)
{
for (j=0;j<n;j++)
{
// Serial.print(A[n*i+j],decimals);
Serial.print(A[n*i+j]);
// Serial.print("\t");
Serial.print(" ");
}
Serial.println();
}
}
//**************************************************************
//++++++++++++++ Configure MAG3110 KOMPASS +++++++++++++++++++++
void config_MAG3110(void)
{
I2C.beginTransmission(KOMPASS); // transmit to device 0x0E
I2C.write(0x10); // cntrl register1
I2C.write(0x01); // send 0x01, active mode
// 0x01 => 0b 000 00 0 0 1
// I2C.write(0b00000001);
I2C.endTransmission(); // stop transmitting
delay(10);
I2C.beginTransmission(KOMPASS); // transmit to device 0x0E
I2C.write(0x11); // cntrl register2
I2C.write(0x80); // send 0x80, enable auto resets
// 0x80 => 0b 1 0 0 0 0000
// I2C.write(0b10000000);
I2C.endTransmission(); // stop transmitting
}
//===============================================================
void read_MAG3110_MAGSENSOR(int * result)
{
int regAddress = 0x01; //first axis-Kompass-data register of the MAG3110
byte howManyBytesToRead = 6; //uint8_t means: give me an unsigned int of exactly 8 bits.
byte _buff[6];
short readings[3]; // short=2bytes
// Read the Mag-data from the MAG3110
// Each axis reading comes in 10 bit resolution, ie 2 bytes.
// Most Significat Byte first.
readFrom(KOMPASS, regAddress, howManyBytesToRead, _buff); //read the acceleration data from the ADXL345
// now we are merging both bytes into one 2byte short
readings[0] = (_buff[0] << 8) | _buff[1]; // X_H=0x01=buff[0] X_L=0x02=buff[1]
readings[1] = (_buff[2] << 8) | _buff[3]; // Y_H=0x03=buff[2] Y_L=0x04=buff[3]
readings[2] = (_buff[4] << 8) | _buff[5]; // Z_M=0x05=buff[4] Z_L=0x06=buff[5]
delay(5);
//NOTE: Do NOT align here the sensor axis x,y,z with the X,Y,Z axis of the wooden cube!!
//Do this in the calc_pitch_roll_yaw_4_pid.ino function of Kompass and Flight-Control applications.
result[0] = (int)readings[0]; //bit-values
result[1] = (int)readings[1];
result[2] = (int)readings[2];
/*
Serial.print("Magnetometer raw readings: ");
Serial.print(result[0]); //X
Serial.print(" ");
Serial.print(result[1]); //Y
Serial.print(" ");
Serial.println(result[2]); //Z
*/
}
//==============================================================
// Reads num bytes starting from address register of DEVICE into _buff array
void readFrom(int DEVICE, byte address, int num, byte _buff[])
{
I2C.beginTransmission(DEVICE); // start transmission to device
I2C.write(address); // sends address to read from
I2C.endTransmission(); // end transmission
delay(2);
I2C.beginTransmission(DEVICE); // start transmission to device
I2C.requestFrom(DEVICE, num); // request 6 bytes from device
int i = 0;
while (I2C.available()) // device may send less than requested (abnormal)
{
_buff[i] = I2C.read(); // receive a byte
delay(5);
i++;
}
I2C.endTransmission(); // end transmission
}
//===============================================================
void writeTo(int DEVICE, byte address, byte val)
{
I2C.beginTransmission(DEVICE); // start transmission to device
I2C.write(address); // send register address
I2C.write(val); // send value to write
I2C.endTransmission(); // end transmission
}
//==========================================================
void beep()
{
for (int i=0; i<500; i++) // generate a 1KHz tone for 1/2 second
{
digitalWrite(SPKR, HIGH);
delayMicroseconds(500);
digitalWrite(SPKR, LOW);
delayMicroseconds(500);
}
return;
}
//==========================================================
//==========================================================
//==========================================================