calling function from tab

Dear Arduino Community,

i've a question about calling a function from a tab by another tab.

The HMC5883L compass module is used (library: GitHub - jarzebski/Arduino-HMC5883L: HMC5883L Triple Axis Digital Compass Arduino Library).
At startup (setup()) the init. is done an the sensor is recognised.
Calling the function getHeading() from main loop() is working (MainProject) and returning the heading
(serial output).

But trying to call the function getHeading() in another Tab-function (setupView.initView() -> display.viewDisplay()) crashes the ATmega. Am i missing a scope problem?

Thank you very much for your help!.

Regards,
Phi

p.s.: IDE 1.8.1 actual libs on macOS, ATmega 2650

  1. Tab: compass.ino
#include <Arduino.h>
#include <Wire.h>
#include <HMC5883L.h>

HMC5883L compassX; // static, volatile already tested

void init_compassX(){
  while (!compassX.begin())
  {
    Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
    delay(500);
  }
  debug("compassX initiated");

  // Set measurement range
  compassX.setRange(HMC5883L_RANGE_1_3GA);

  // Set measurement mode
  compassX.setMeasurementMode(HMC5883L_CONTINOUS);

  // Set data rate
  compassX.setDataRate(HMC5883L_DATARATE_30HZ);

  // Set number of samples averaged
  compassX.setSamples(HMC5883L_SAMPLES_8);

  // Set calibration offset. See HMC5883L_calibration.ino
  compassX.setOffset(0, 0);
}

void getHeading(){
  Vector norm = compassX.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;
  }

  // Convert to degrees
  float headingDegrees = heading * 180/M_PI; 

  debug("compass:");

  char headingstr[10];
  dtostrf(headingDegrees, 8, 4, headingstr);

  debug(headingstr);

  //return headingDegrees;
}
  1. Tab: MainProject.ino
void setup() {
  init_compassX();
  debug("finishedInit");
}

/*
   Main Loop
*/
void loop() {
  getHeading(); // working
  initView(); //error!
}
  1. Tab: display.ino
    calling: void viewDisplay() { getHeading(); //not working, crashes the ATmega 2560 }

  2. Tab: setupView.ino
    calling: void initView() { viewDisplay(); }

When you have several .ino files in your project (in different tabs) the compiler loads the extra files in the tabs in alphabetical order. That means a function in setupView.ino could call a function in display.ino but not vice versa. I believe you can get around that by including function prototypes in the principal file - mainProject.ino in your example.

...R

I suspect that the includes must be in the file with the name of the project.

Is your project called compas.ino?

Thank's for your fast reply!

as suggested i've added

void getHeading(void);

in the main Project file before any code (except include)

I've also removed all inside the getHeading() function an added a simple serial out "test" and it is working
also from another tab. But if i'm including the Vector norm = compassX.readNormalize(); line the crash appears, so maybe this is caused by compassX? is there a prototype for variables?

Regards,
Phi

sterretje:
I suspect that the includes must be in the file with the name of the project.

Is your project called compas.ino?

it's called: MainProject.ino

I'm new to the Arduino IDE an a bit confused about the tab thing...

Ok, i just figured out the error is only occurring if the function is called by the interrupt function defined - and only if using the variable compassX. Calling the function in another tab just at Start work's fine. So any changes have to be done using a global variable with an Interrupt?

The Problem seems to be the i2c sensor Request during the Interrupt... Is it possible to use i2c communication during an ISR?

Is it possible to use i2c communication during an ISR?

I rather expect that i2c uses interrupts and they are disabled when in an ISR.

I rather expect that i2c uses interrupts and they are disabled when in an ISR.

That would be correct.

The Arduino IDE does its best to automatically generates function prototypes and put them in the right place regardless of whether you have multiple .ino tabs or not. It just concatenates all the .ino files in alphabetical order after the one that matches the sketch folder at the start of the build prodess so tabs should have no effect on prototype generation. There are certain things rarely seen by the average Arduino user that the Arduino IDE isn't able to generate prototypes for but you can always declare them yourself if that happens.

I'm afraid that the first respondents (including me) did not notice that OP mentioned run-time problems and not compile problems