HMC5883l compass code stops execution

Hello,

I am working on a project that has a Heltec esp32 v2 with a compass point to another at a separate location. The receiving end has a compass because often times when this is in use the person will not be moving but it is still necessary to know the heading of the device. Without the compass code, The Loop section will run. Once I add in the code for the compass, it will run until it hits that portion of the code and then stop. If I remove all the other code and just run the code from the compass, It will run as well. Any insight as to what is freezing up?

#include <TinyGPS.h>
#include <Wire.h>
#include <HMC5883L.h>
#include "heltec.h"
#define BAND 433E6 //you can set band here directly,e.g. 868E6,915E6
String rssi = "RSSI --";
String packSize = "--";
String packet, slat, slon;
String pkt2;
int pksize;
float tlati, tlon;
float clat, clon, cbearing, bearing;
int comma1 = 0, comma2 = 0, salti = 0;
HMC5883L compass;
TinyGPS gps;
float flat, flon;
unsigned long age, date, chars;
int year;
byte month, day, hour, minute, second, hundredths;
char sz[32];
bool newData= false;
HardwareSerial GPS_Serial(2);
void cbk(int packetSize) {
packet ="";
pkt2 = "";
packSize = String(packetSize,DEC);
pksize = packetSize;
for (int i = 0; i < packetSize; i++) { packet += (char) LoRa.read();

delay(100);
}
pkt2 = packet;
Serial.println(pkt2);
parsedata();
}
void parsedata(){
comma1 = 0;
comma2 = 0;
slat="";
slon = "";
for (int x = 0; pkt2[x]!=','; x++){
slat+=pkt2[x];
comma1 = x;
}
for (int i = ((comma1)+2); pkt2[i]!=','; i++){
slon += pkt2[i];
comma2 = i;
}
tlon = (slon.toFloat());
tlati = (slat.toFloat());
Serial.println(tlon,6);
Serial.println(tlati,6);
}

void setup() {
Serial.println("Initialize HMC5883L");
while (!compass.begin())
{
Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
delay(500);
}
// Set measurement range
compass.setRange(HMC5883L_RANGE_1_3GA);
// Set measurement mode
compass.setMeasurementMode(HMC5883L_CONTINOUS);
// Set data rate
compass.setDataRate(HMC5883L_DATARATE_30HZ);
// Set number of samples averaged
compass.setSamples(HMC5883L_SAMPLES_8);
// Set calibration offset. See HMC5883L_calibration.ino
compass.setOffset(0, 0);
Heltec.begin(true /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);

Heltec.display->init();
Heltec.display->flipScreenVertically();
Heltec.display->setFont(ArialMT_Plain_10);
Heltec.display->clear();
Heltec.display->drawString(0 , 15 , "Initialization Success");
Heltec.display->display();
Heltec.display->clear();
//LoRa.onReceive(cbk);
LoRa.receive();
}
void loop() {
String bstr = "";
float thisway = 0;




//This is the compass code where it stops

Vector norm = compass.readNormalize();
// Calculate heading
float heading = atan2(norm.YAxis, norm.XAxis);
// Set declination angle on your location and fix heading
// You can find your declination on: http://magnetic-declination.com/
// (+) Positive or (-) for negative
// For Bytom / Poland declination angle is 4'26E (positive)
// Formula: (deg + (min / 60.0)) / (180 / M_PI);
float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI);
heading += declinationAngle;
// Correct for heading < 0deg and heading > 360deg
if (heading < 0)
{
heading += 2 * PI;
}
if (heading > 2 * PI)
{
heading -= 2 * PI;
}
float headingDegrees = heading * 180/M_PI;

//end of compass code




int packetSize = LoRa.parsePacket();
if (packetSize) { cbk(packetSize);}
getgps();
bearing = getbearing(clat, clon, tlati, tlon);
thisway = ((headingDegrees)+bearing);
bstr = String(thisway);
Heltec.display->clear();
Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
Heltec.display->setFont(ArialMT_Plain_10);
Serial.println (thisway);
Heltec.display->drawString(0, 15, bstr);
Heltec.display->display();
Heltec.display->clear();
}

void getgps(){

gps.f_get_position(&flat, &flon, &age);
gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
sprintf(sz, "%02d/%02d/%02d, %02d:%02d:%02d", month, day, year, hour - 4, minute, second);
while (GPS_Serial.available())
{
char c = GPS_Serial.read();
//Serial.write(c); // uncomment this line if you want to see the GPS data flowing
if (gps.encode(c)) // Did a new valid sentence come in?
newData = true;
}
clat = (flat);
clon = (flon);
Serial.println (clat);
Serial.println (clon);
}
float getbearing(float lat1,float lon1,float lat2,float lon2){
float teta1 = radians(lat1);
float teta2 = radians(lat2);
float delta1 = radians(lat2-lat1);
float delta2 = radians(lon2-lon1);
//==================Heading Formula Calculation================//
float y = sin(delta2) * cos(teta2);
float x = cos(teta1)*sin(teta2) - sin(teta1)*cos(teta2)*cos(delta2);
float brng = atan2(y,x);
brng = degrees(brng);// radians to degrees
brng = ( ((int)brng + 360) % 360 );
Serial.print("Heading GPS: ");
Serial.println(brng);

return brng;
}

So that snippet of compass code is right out of the example and will run on its own. The compass is on I2C.

Thank you

it will run until it hits that portion of the code and then stop

What, exactly, does that mean?

Does the program print "Could not find a valid HMC5883L sensor, check wiring!"?

If not, what happens instead? How do you know it stops, and where?

Just here to follow; Mine stops working as well after a few minutes.

jremington:
What, exactly, does that mean?

Does the program print "Could not find a valid HMC5883L sensor, check wiring!"?

If not, what happens instead? How do you know it stops, and where?

Thanks for the response. The Compass is found and it is initiated (along with the gps, lora, screen etc.). I have tried moving the code for the compass below the getgps() function, and below the parse() function. It will run any functions above it in the loop and then stop once it gets to where the compass should be getting the current bearing.

Sorry, not a very helpful answer.

Put in Serial.print() statements to determine the exact program line at which failure occurs.

jremington:
Put in Serial.print() statements to determine the exact program line at which failure occurs.

The code is stopping at:

Vector norm = compass.readNormalize();

It will not print the serial statement after this.

void loop() {
String bstr = "";
float thisway = 0;



int packetSize = LoRa.parsePacket();
if (packetSize) { cbk(packetSize);}
getgps();

Vector norm = compass.readNormalize();
Serial.print("This is where it is stopping");
// Calculate heading
float heading = atan2(norm.YAxis, norm.XAxis);

Serial.print(heading);
// Set declination angle on your location and fix heading
// You can find your declination on: http://magnetic-declination.com/
// (+) Positive or (-) for negative
// For Bytom / Poland declination angle is 4'26E (positive)
// Formula: (deg + (min / 60.0)) / (180 / M_PI);
float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI);
heading += declinationAngle;
// Correct for heading < 0deg and heading > 360deg
if (heading < 0)
{
heading += 2 * PI;
}
if (heading > 2 * PI)
{
heading -= 2 * PI;
}
float headingDegrees = heading * 180/M_PI;

//end of compass code




bearing = getbearing(clat, clon, tlati, tlon);
thisway = ((headingDegrees)+bearing);
bstr = String(thisway);
Heltec.display->clear();
Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
Heltec.display->setFont(ArialMT_Plain_10);
Serial.println (thisway);
Heltec.display->drawString(0, 15, bstr);
Heltec.display->display();
Heltec.display->clear();

It looks like either a communications failure, or the compass is not working properly.

If you disconnect the compass, do you get the message "Could not find a valid HMC5883L sensor, check wiring!"?

What else do you have on the I2C bus? Perhaps another module is interfering, or the pullup resistors are wrong, etc.

jremington:
If you disconnect the compass, do you get the message "Could not find a valid HMC5883L sensor, check wiring!"?

What else do you have on the I2C bus? Perhaps another module is interfering, or the pullup resistors are wrong, etc.

Yes, When the compass is disconnected I do get the error message. The display is also on i2c. One of the examples is an I2C scanner. The Scanner Picks up Both the Screen and the Compass address. The address of the screen is 0x3C and the address of the Compass Is 0x1E.

Try removing the screen and see if the compass starts working. If so, it may be a problem with bus loading (pullup resistors incorrect, etc.).

I have the same problem, managed to solve?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.