Using pointers within a library

Hi!
I'm trying to read the data from a MPU-6050 sensor (I2C). I have managed to get the raw data, but I would also like to create a function which formats the data to "correct" units, g's and deg/s. So I figured I could create another function which calls the "raw data function" and then it formats the read, raw data.

I'm very new to pointers so that's why I can't get this to work, I guess...

Anyway, I've created a library called IMUlib, and the code looks like this:

Main sketch

#include <Wire.h>
#include "IMUlib.h"
IMUlib IMU;
const uint8_t MPU6050 = 0x68; // I2C address to Acc/gyro
int16_t aX, aY, aZ, gX, gY, gZ;

void setup(){
  // Initialize serial monitor at 9600 baud
  Serial.begin(9600);
  // Initialize Wire object
  Wire.begin();
  
  // Wake the IMU sensor and set the sensor range
  IMU.initializeIMU(MPU6050_ACCEL_FS_2, MPU6050_GYRO_FS_250);
  // Test IMU connection
  IMU.testConnection();
}
void loop(){
  IMU.readIMUForm(&aX, &aY, &aZ, &gX, &gY, &gZ);
}

IMUlib.cpp (relevant functions):

void IMUlib::readIMU(int16_t *aX, int16_t *aY, int16_t *aZ, int16_t *gX, int16_t *gY, int16_t *gZ){
  I2Cdev::readBytes(devAddress, MPU6050_RA_ACCEL_XOUT_H, 14, data);
  *aX = (((int16_t)data[0]) << 8) | data[1];
  *aY = (((int16_t)data[2]) << 8) | data[3];
  *aZ = (((int16_t)data[4]) << 8) | data[5];
  // data[6:7] contains temperature
  *gX = (((int16_t)data[8]) << 8) | data[9];
  *gY = (((int16_t)data[10]) << 8) | data[11];
  *gZ = (((int16_t)data[12]) << 8) | data[13];
}
// Function which errors...
void IMUlib::readIMUForm(int16_t *aX, int16_t *aY, int16_t *aZ, int16_t *gX, int16_t *gY, int16_t *gZ){
  readIMU(&aX, &aY, &aZ, &gX, &gY, &gZ);
  *aX = *aX/16384;
}

Error:

IMUlib.cpp: In member function 'void IMUlib::readIMUForm(int16_t*, int16_t*, int16_t*, int16_t*, int16_t*, int16_t*)':
IMUlib.cpp:48: error: invalid conversion from 'int' to 'int16_t*'
IMUlib.cpp:48: error: initializing argument 1 of 'void IMUlib::readIMU(int16_t*, int16_t*, int16_t*, int16_t*, int16_t*, int16_t*)'
IMUlib.cpp:48: error: invalid conversion from 'int' to 'int16_t*'
IMUlib.cpp:48: error: initializing argument 2 of 'void IMUlib::readIMU(int16_t*, int16_t*, int16_t*, int16_t*, int16_t*, int16_t*)'
IMUlib.cpp:48: error: invalid conversion from 'int' to 'int16_t*'
IMUlib.cpp:48: error: initializing argument 3 of 'void IMUlib::readIMU(int16_t*, int16_t*, int16_t*, int16_t*, int16_t*, int16_t*)'
IMUlib.cpp:48: error: invalid conversion from 'int' to 'int16_t*'
IMUlib.cpp:48: error: initializing argument 4 of 'void IMUlib::readIMU(int16_t*, int16_t*, int16_t*, int16_t*, int16_t*, int16_t*)'
IMUlib.cpp:48: error: invalid conversion from 'int' to 'int16_t*'
IMUlib.cpp:48: error: initializing argument 5 of 'void IMUlib::readIMU(int16_t*, int16_t*, int16_t*, int16_t*, int16_t*, int16_t*)'
IMUlib.cpp:48: error: invalid conversion from 'int' to 'int16_t*'
IMUlib.cpp:48: error: initializing argument 6 of 'void IMUlib::readIMU(int16_t*, int16_t*, int16_t*, int16_t*, int16_t*, int16_t*)'

As you might see I want to be able to call two different functions depending on if I want the raw data or the formatted. How should I write this ?

I really hate when people use pointers where references are more appropriate. The existing function should have been written:

void IMUlib::readIMU(int16_t &aX, int16_t &aY, int16_t &aZ, int16_t &gX, int16_t &gY, int16_t &gZ)
{

Then, it would be trivial to clone it.

But, given that, in your copy, aX is a pointer to an int, and the original expects a pointer to an int, I don't understand why you are calling it with the address of aX and expecting that to work.

Cottus:

void IMUlib::readIMU(int16_t *aX, int16_t *aY, int16_t *aZ, int16_t *gX, int16_t *gY, int16_t *gZ){

void IMUlib::readIMUForm(int16_t *aX, int16_t *aY, int16_t *aZ, int16_t *gX, int16_t *gY, int16_t *gZ){
  readIMU(&aX, &aY, &aZ, &gX, &gY, &gZ);

In readIMUForm() aX, xY etc are pointers to int already. There is no need to take THEIR addresses when passing to readIMU().

You probably want:

void IMUlib::readIMUForm(int16_t *aX, int16_t *aY, int16_t *aZ, int16_t *gX, int16_t *gY, int16_t *gZ){
  readIMU(aX, aY, aZ, gX, gY, gZ);
  *aX = *aX/16384;
}

PaulS:
I really hate when people use pointers where references are more appropriate. The existing function should have been written:

void IMUlib::readIMU(int16_t &aX, int16_t &aY, int16_t &aZ, int16_t &gX, int16_t &gY, int16_t &gZ)

{




Then, it would be trivial to clone it.

But, given that, in your copy, aX is a pointer to an int, and the original expects a pointer to an int, I don't understand why you are calling it with the address of aX and expecting that to work.

Relax, I've only been programming this thing for a couple of weeks. As I said, I only started (read: today) with pointers and wanted to try it out.

But thanks for the heads up. Can you recommend any good resource on pointers and references? I've read a few, but I really don't get it yet.

gardner:

Cottus:

void IMUlib::readIMU(int16_t *aX, int16_t *aY, int16_t *aZ, int16_t *gX, int16_t *gY, int16_t *gZ){

void IMUlib::readIMUForm(int16_t *aX, int16_t *aY, int16_t *aZ, int16_t *gX, int16_t *gY, int16_t *gZ){
  readIMU(&aX, &aY, &aZ, &gX, &gY, &gZ);

In readIMUForm() aX, xY etc are pointers to int already. There is no need to take THEIR addresses when passing to readIMU().

You probably want:

void IMUlib::readIMUForm(int16_t *aX, int16_t *aY, int16_t *aZ, int16_t *gX, int16_t *gY, int16_t *gZ){

readIMU(aX, aY, aZ, gX, gY, gZ);
  *aX = *aX/16384;
}

Thank you! Now it works. Now I just need to figure out exactly what PaulS meant :wink:

EDIT: Now I get what PaulS meant..

http://www.learncpp.com/cpp-tutorial/67-introduction-to-pointers/

http://www.learncpp.com/cpp-tutorial/611-references/

Hackscribble:
http://www.learncpp.com/cpp-tutorial/67-introduction-to-pointers/

http://www.learncpp.com/cpp-tutorial/611-references/

Thanks! I have not read those pages earlier.

EDIT: I can really recommend those two guides linked by Hackscribble. Now I almost understand :wink:

While we're at it - are there any general recommendations when pointers/references should be used instead of just returning a variable/array from the function?