HMC6343 compass how to get heading to particle publish

Hello, I have a HMC6343 compass and trying to collect the heading data. Does anyone have experience with this. Any help how to get heading to particle publish would be greatly appreciated

Here is the arduino code

// Libraries for I2C and the HMC6343 sensor
#include <Wire.h>
#include "SFE_HMC6343.h"

SFE_HMC6343 compass; // Declare the sensor object

void setup()
{
  // Start serial communication at 115200 baud
  Serial.begin(115200);
  
  // Give the HMC6343 a half second to wake up
  delay(500); 
  
  // Initialize the HMC6343 and verify its physical presence
  if (!compass.init())
  {
    Serial.println("Sensor Initialization Failed\n\r"); // Report failure, is the sensor wiring correct?
  }
}

void loop()
{
  // Read, calculate, and print the heading, pitch, and roll from the sensor
  compass.readHeading();
  printHeadingData();
  
  // Read, calculate, and print the acceleration on the x, y, and z axis of the sensor
  compass.readAccel();
  printAccelData();
  
  // Wait for two seconds
  delay(2000); // Minimum delay of 200ms (HMC6343 has 5Hz sensor reads/calculations)
}

// Print both the raw values of the compass heading, pitch, and roll
// as well as calculate and print the compass values in degrees
// Sample Output:
// Heading Data (Raw value, in degrees):
// Heading: 3249  324.90°
// Pitch:   28    2.80°
// Roll:    24    2.40°
void printHeadingData()
{
  Serial.println("Heading Data (Raw value, in degrees):");
  Serial.print("Heading: ");
  Serial.print(compass.heading); Serial.print("  "); // Print raw heading value
  Serial.print((float) compass.heading/10.0);Serial.write(176);Serial.println(); // Print heading in degrees
  Serial.print("Pitch: ");
  Serial.print(compass.pitch); Serial.print("  ");
  Serial.print((float) compass.pitch/10.0);Serial.write(176);Serial.println();
  Serial.print("Roll: ");
  Serial.print(compass.roll); Serial.print("  ");
  Serial.print((float) compass.roll/10.0);Serial.write(176);Serial.println();
  Serial.println();
}

// Print both the raw values of the compass acceleration measured on each axis
// as well as calculate and print the accelerations in g forces
// Sample Output:
// Accelerometer Data (Raw value, in g forces):
// X: -52    -0.05g
// Y: -44    -0.04g
// Z: -1047  -1.02g
void printAccelData()
{
  Serial.println("Accelerometer Data (Raw value, in g forces):");
  Serial.print("X: ");
  Serial.print(compass.accelX); Serial.print("  "); // Print raw acceleration measurement on x axis
  Serial.print((float) compass.accelX/1024.0);Serial.println("g"); // Print x axis acceleration measurement in g forces
  Serial.print("Y: ");
  Serial.print(compass.accelY); Serial.print("  ");
  Serial.print((float) compass.accelY/1024.0);Serial.println("g");
  Serial.print("Z: ");
  Serial.print(compass.accelZ); Serial.print("  ");
  Serial.print((float) compass.accelZ/1024.0);Serial.println("g");
  Serial.println();
}

Here is the Particle io code from NCD

#include <application.h>
#include <spark_wiring_i2c.h>

// HMC6343A I2C address is 19(25)
#define Addr 0x19

int xAccl = 0, yAccl =  0, zAccl = 0, xMag = 0, yMag =  0, zMag = 0;
void setup() 
{
    // Set variable
    Particle.variable("i2cdevice", "HMC6343A");
    Particle.variable("xAccl", xAccl);
    Particle.variable("yAccl", yAccl);
    Particle.variable("zAccl", zAccl);
    Particle.variable("xMag", xMag);
    Particle.variable("yMag", yMag);
    Particle.variable("zMag", zMag);
    
    // Initialise I2C communication as MASTER
    Wire.begin();
    // Initialise Serial Communication, set baud rate = 9600
    Serial.begin(9600);
  
    // Start I2C Transmission
    Wire.beginTransmission(Addr);
    // Select Operational mode register 1
    Wire.write(0x04);
    // Set enable run mode and level orientation
    Wire.write(0x11);
    // Stop I2C Transmission
    Wire.endTransmission();
  
    // Start I2C Transmission
    Wire.beginTransmission(Addr);
    // Select Operational mode register 2
    Wire.write(0x05);
    // Set measuremnet rate 5 Hz
    Wire.write(0x01);
    // Stop I2C Transmission
    Wire.endTransmission();
    delay(300);
}

void loop()
{
    unsigned int data[6];
    for(int i = 0; i < 6; i++)
    {
        // Start I2C Transmission
        Wire.beginTransmission(Addr);
        // Select data register
        Wire.write((64+i));
        // Stop I2C Transmission
        Wire.endTransmission();
        
        // Request 1 byte of data
        Wire.requestFrom(Addr, 1);
        
        // Read 6 bytes of data
        // xAccl msb, xAccl lsb, yAccl msb, yAccl lsb, zAccl msb, zAccl lsb
        if(Wire.available() == 1)
        {
            data[i] = Wire.read();
        }
        delay(300);
    }
    

    // Convert the data
    xAccl = ((data[0] * 256) + data[1]);
    if(xAccl > 32767)
    {
        xAccl -= 65536;
    }
    yAccl = ((data[2] * 256) + data[3]);
    if(yAccl > 32767)
    {
        yAccl -= 65536;
    }
    zAccl = ((data[4] * 256) + data[5]);
    if(zAccl > 32767)
    {
        zAccl -= 65536;
    }

    for(int i = 0; i < 6; i++)
    {
        // Start I2C Transmission
        Wire.beginTransmission(Addr);
        // Select data register
        Wire.write((69+i));
        // Stop I2C Transmission
        Wire.endTransmission();
        
        // Request 1 byte of data
        Wire.requestFrom(Addr, 1);
        
        // Read 6 bytes of data
        // xMag msb, xMag lsb, yMag msb, yMag lsb, zMag msb, zMag lsb
        if(Wire.available() == 1)
        {
            data[i] = Wire.read();
        }
        delay(300);
    }
    

    // Convert the data
    xMag = ((data[0] * 256) + data[1]);
    if(xMag > 32767)
    {
        xMag -= 65536;
    }
    yMag = ((data[2] * 256) + data[3]);
    if(yMag > 32767)
    {
        yMag -= 65536;
    }
    zMag = ((data[4] * 256) + data[5]);
    if(zMag > 32767)
    {
        zMag -= 65536;
    }

    // Output data to dashboard
    Particle.publish("Acceleration in X-Axis : ", String(xAccl));
    delay(1000);
    Particle.publish("Acceleration in Y-Axis : ", String(yAccl));
    delay(1000);
    Particle.publish("Acceleration in Z-Axis : ", String(zAccl));
    delay(1000);
    Particle.publish("Magnetic field in X-Axis : ", String(xMag));
    delay(1000);
    Particle.publish("Magnetic field in Y-Axis : ", String(yMag));
    delay(1000);
    Particle.publish("Magnetic filed in Z-Axis : ", String(zMag));
    delay(1000);
}

Instead of multiple publishes you should put the data into one single string and publish that

  char data[64];
  snprintf(data, sizeof(data), "Acc: %d/%d%d, Mag: %d/%d/%d", xAccl, yAccl, zAccl, xMag, yMag, zMag);
  Particle.publish("hmcData", data, PRIVATE);

To know how the heading info is obtained, you may want to look at the implementation of the SFE_HMC6343 library used in your Arduino sketch.

1 Like

Thanks @ScruffR
Can you help me get the heading, im struggling to find how to obtain the heading. On an arduino with the arduino code i can read it though when i bring the sensor over to the photon… im not sure how to do it.

Here is the source code for that library.
This code should work without any (considerable) alterations on Particel devices too.

Hey @ScruffR

Thanks for the help, ill have a look into it. You have been on here for ages! always super helpful!

1 Like

Thanks! :+1:

If you get stuck with the library, just ping :wink: