Could i get some help. i just got this micromag 3-axis magnetic field sensor and i cant figure out why the code wont work. this code was provided as an example. i copied the wiring diagram and everything. im using an arduino uno. ive check the connections atleast 20 times. it wont print the data in the serial monitor. i wanted the data of x, y, z and the heading of the magnetic field to be shown in the serial monitor. Right now it does nothing.
int SCLKpin = 8; // magnetometer pin 1
int MISOpin = 9; // magnetometer pin 2
int MOSIpin = 10; // magnetometer pin 3
int SSNOTpin = 11; // magnetometer pin 4
int DRDYpin = 12; // magnetometer pin 5
int RESETpin = 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(LED_BUILTIN, OUTPUT); // turn ON the board LED for diagnostics only
digitalWrite(LED_BUILTIN, HIGH);
pinMode(SSNOTpin, OUTPUT);
pinMode(RESETpin, OUTPUT);
pinMode(MOSIpin, OUTPUT);
pinMode(SCLKpin, OUTPUT);
pinMode(MISOpin, INPUT);
pinMode(DRDYpin, INPUT);
digitalWrite(SSNOTpin, 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(MOSIpin, bit);
delay(2);
digitalWrite(SCLKpin, HIGH);
delay(2);
digitalWrite(SCLKpin, LOW);
delay(2);
}
int receiveBit()
{
// receive the data on the FALLING edge of the clock
digitalWrite(SCLKpin, HIGH);
delay(2);
int bit = digitalRead(MISOpin);
delay(2);
digitalWrite(SCLKpin, 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(RESETpin, LOW);
delay(2);
digitalWrite(RESETpin, HIGH);
delay(2);
digitalWrite(RESETpin, 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(DRDYpin) == 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));
}
oh sorry, it wont print the data in the serial monitor. i wanted the data of x, y, z and the heading of the magnet to be shown in the serial monitor. Right now it does nothing.
Do you have the correct baud rate setting in serial monitor to match your code?
Add some extra Serial.println() commands like Serial.println("Exiting setup()"), Serial.println("Entering loop()") and similar to your code to help diagnose what is going on.
yes i do have correct baud setting. its set to 9600.
#include <SPI.h>
int SCLKpin = 13; // SCK pin of Arduino Uno connected to magnetometer pin 1
int MISOpin = 12; // MISO pin of Arduino Uno connected to magnetometer pin 2
int MOSIpin = 11; // MOSI pin of Arduino Uno connected to magnetometer pin 3
int SSNOTpin = 10; // SS (Slave Select) pin of Arduino Uno connected to magnetometer pin 4
int DRDYpin = 9; // Data Ready pin of Arduino Uno connected to magnetometer pin 5
int RESETpin = 8; // Reset pin of Arduino Uno connected to 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(SSNOTpin, OUTPUT);
pinMode(RESETpin, OUTPUT);
pinMode(MOSIpin, OUTPUT);
pinMode(SCLKpin, OUTPUT);
pinMode(MISOpin, INPUT);
pinMode(DRDYpin, INPUT);
digitalWrite(SSNOTpin, HIGH); // Ensure SS is high initially (not selected)
digitalWrite(RESETpin, LOW); // Keep reset low initially
// Debug prints
Serial.println("Setup complete.");
}
void loop() {
digitalWrite(SSNOTpin, LOW); // Step 1: Bring SSNOT low
Serial.println("Step 1: SSNOT pin set LOW");
delayMicroseconds(10); // Ensure SSNOT is stable low
digitalWrite(RESETpin, HIGH); // Step 2: Pulse RESET high
Serial.println("Step 2: RESET pin set HIGH");
delayMicroseconds(10); // Pulse width minimum 5us
digitalWrite(RESETpin, LOW); // Reset to low state
Serial.println("Step 2: RESET pin set LOW");
delayMicroseconds(10); // Ensure RESET is stable low
// Step 3: Send command byte (000000) and axis selection
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); // Start SPI transaction
digitalWrite(SSNOTpin, LOW); // Select the MicroMag3
Serial.println("Step 3: MicroMag3 selected");
SPI.transfer(0b00110000); // Send command byte: 000000
Serial.println("Step 3: Command byte sent");
SPI.transfer(0b00000110); // Send axis selection byte (for example, X-axis)
Serial.println("Step 3: Axis selection sent");
digitalWrite(SSNOTpin, HIGH); // Deselect the MicroMag3
Serial.println("Step 3: MicroMag3 deselected");
SPI.endTransaction(); // End SPI transaction
// Small delay for stability
delay(10);
// Step 4: Wait for DRDY pin to go high indicating data is ready
unsigned long startTime = millis(); // Record start time for timeout
while (digitalRead(DRDYpin) == LOW) {
// Wait until DRDY line is high or timeout
if (millis() - startTime > 100) { // Timeout after 100ms (adjust as necessary)
Serial.println("Timeout waiting for DRDY to go HIGH");
break;
}
}
if (digitalRead(DRDYpin) == HIGH) {
Serial.println("Step 4: DRDY pin is HIGH, data ready");
// Step 5: Read data from MISO line
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0)); // Start SPI transaction
digitalWrite(SSNOTpin, LOW); // Select the MicroMag3
Serial.println("Step 5: MicroMag3 selected for data read");
// Shift out 16 bits of data from MicroMag3
int sign = SPI.transfer(0); // First bit is sign
Serial.println("Step 5: First bit (sign) read");
long total = 0;
for (int i = 14; i >= 0; i--) {
int thisbit = SPI.transfer(0);
thisbit = thisbit << i;
total = total | thisbit;
}
Serial.println("Step 5: 16 bits of data read");
digitalWrite(SSNOTpin, HIGH); // Deselect the MicroMag3
Serial.println("Step 5: MicroMag3 deselected");
SPI.endTransaction(); // End SPI transaction
// Interpret total as signed integer
if (sign == 1) {
total = total - 32768;
}
// Assign values based on axis
x = total; // Assuming axis is predefined or calculated earlier
y = total; // Replace with actual axis assignments
z = total; // Replace with actual axis assignments
// Calculate heading if needed
heading = getHeading(x, y, z);
// Print data or do further processing
Serial.print("x: ");
Serial.print(x);
Serial.print(" y: ");
Serial.print(y);
Serial.print(" z: ");
Serial.print(z);
Serial.print(" heading: ");
Serial.println(heading);
}
else {
Serial.println("Data not ready within timeout period");
}
delay(20000); // Next reading in 20 seconds
}
// Function to calculate heading
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));
}
Output for serial monitor:
Setthin timeout period
: Axis selection sent
Step 3: MicroMag3 deselected
Timeout waiting for DRDY to go HIGH
Data not ready within timeout period
: Axis selection sent
Step 3: MicroMag3 deselected
Timeout waiting for DRDY to go HIGH
Data not ready within timeout period
Setup complete.
Step 1: SSNOT pin set LOW
Step 2: RESET pin set HIGH
Step 2: RESET pin set LOW
Step 3: MicroMag3 selected
The first code didn't use SPI library all all. It bit-banged comms with the sensor. Like I said, it was very different code, not simply something missed or changed for debugging.
Before I or anyone else wastes time helping you with the second code, it is going to completely change again?