Use of MLX90614 without library

Hi everyone,
For a project in class, i need to use a MLX90614 infrared sensor with arduino without using the library that is associated, so i copied in my code the part of the two libraries (Adafruit_MLX90614.h and Adafruit_I2CDevice.h ) that are of interest and it returns that i2c_dev was not declared in this scope. So my question is : What is i2c_dev and how can i declare it ?

#ifndef Adafruit_I2CDevice_h
#define Adafruit_I2CDevice_h

#include <Arduino.h>
#include <Wire.h>

///< The class which defines how we will talk to this device over I2C
class Adafruit_I2CDevice {
public:
  Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire = &Wire);
  uint8_t address(void);
  bool begin(bool addr_detect = true);
  void end(void);
  bool detected(void);

  bool read(uint8_t *buffer, size_t len, bool stop = true);
  bool write(const uint8_t *buffer, size_t len, bool stop = true,
             const uint8_t *prefix_buffer = NULL, size_t prefix_len = 0);
  bool write_then_read(const uint8_t *write_buffer, size_t write_len,
                       uint8_t *read_buffer, size_t read_len,
                       bool stop = false);
  bool setSpeed(uint32_t desiredclk);

  /*!   @brief  How many bytes we can read in a transaction
   *    @return The size of the Wire receive/transmit buffer */
  size_t maxBufferSize() { return _maxBufferSize; }

private:
  uint8_t _addr;
  TwoWire *_wire;
  bool _begun;
  size_t _maxBufferSize;
  bool _read(uint8_t *buffer, size_t len, bool stop);
};

#endif // Adafruit_I2CDevice_h
////
uint8_t Adafruit_I2CDevice::address(void) { return _addr; }
////
Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
  
  _addr = addr;
  _wire = theWire;
  _begun = false;
#ifdef ARDUINO_ARCH_SAMD
  _maxBufferSize = 250; // as defined in Wire.h's RingBuffer
#else
  _maxBufferSize = 32;
#endif
}

/////
bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
                               const uint8_t *prefix_buffer,
                               size_t prefix_len) {
  if ((len + prefix_len) > maxBufferSize()) {
    // currently not guaranteed to work if more than 32 bytes!
    // we will need to find out if some platforms have larger
    // I2C buffer sizes :/
#ifdef DEBUG_SERIAL
    DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer"));
#endif
    return false;
  }

  _wire->beginTransmission(_addr);

  // Write the prefix data (usually an address)
  if ((prefix_len != 0) && (prefix_buffer != NULL)) {
    if (_wire->write(prefix_buffer, prefix_len) != prefix_len) {
#ifdef DEBUG_SERIAL
      DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
#endif
      return false;
    }
  }

  // Write the data itself
  if (_wire->write(buffer, len) != len) {
#ifdef DEBUG_SERIAL
    DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
#endif
    return false;
  }

#ifdef DEBUG_SERIAL
bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
  size_t pos = 0;
  while (pos < len) {
    size_t read_len =
        ((len - pos) > maxBufferSize()) ? maxBufferSize() : (len - pos);
    bool read_stop = (pos < (len - read_len)) ? false : stop;
    if (!_read(buffer + pos, read_len, read_stop))
      return false;
    pos += read_len;
  }
  return true;
}
//////

bool Adafruit_I2CDevice::_read(uint8_t *buffer, size_t len, bool stop) {
#if defined(TinyWireM_h)
  size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len);
#else
  size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
#endif

  if (recv != len) {
    // Not enough data available to fulfill our obligation!
#ifdef DEBUG_SERIAL
    DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: "));
    DEBUG_SERIAL.println(recv);
#endif
    return false;
  }

  for (uint16_t i = 0; i < len; i++) {
    buffer[i] = _wire->read();
  }

#ifdef DEBUG_SERIAL
  DEBUG_SERIAL.print(F("\tI2CREAD  @ 0x"));
  DEBUG_SERIAL.print(_addr, HEX);
  DEBUG_SERIAL.print(F(" :: "));
  for (uint16_t i = 0; i < len; i++) {
    DEBUG_SERIAL.print(F("0x"));
    DEBUG_SERIAL.print(buffer[i], HEX);
    DEBUG_SERIAL.print(F(", "));
    if (len % 32 == 31) {
      DEBUG_SERIAL.println();
    }
  }
  DEBUG_SERIAL.println();
#endif

  return true;
}

  DEBUG_SERIAL.print(F("\tI2CWRITE @ 0x"));
  DEBUG_SERIAL.print(_addr, HEX);
  DEBUG_SERIAL.print(F(" :: "));
  if ((prefix_len != 0) && (prefix_buffer != NULL)) {
    for (uint16_t i = 0; i < prefix_len; i++) {
      DEBUG_SERIAL.print(F("0x"));
      DEBUG_SERIAL.print(prefix_buffer[i], HEX);
      DEBUG_SERIAL.print(F(", "));
    }
  }
  for (uint16_t i = 0; i < len; i++) {
    DEBUG_SERIAL.print(F("0x"));
    DEBUG_SERIAL.print(buffer[i], HEX);
    DEBUG_SERIAL.print(F(", "));
    if (i % 32 == 31) {
      DEBUG_SERIAL.println();
    }
  }

  if (stop) {
    DEBUG_SERIAL.print("\tSTOP");
  }
#endif

  if (_wire->endTransmission(stop) == 0) {
#ifdef DEBUG_SERIAL
    DEBUG_SERIAL.println();
    // DEBUG_SERIAL.println("Sent!");
#endif
    return true;
  } else {
#ifdef DEBUG_SERIAL
    DEBUG_SERIAL.println("\tFailed to send!");
#endif
    return false;
  }
}
/////
bool begin(uint8_t addr, TwoWire *wire) 
{
  uint8_t _addr = addr; // needed for CRC
  if (i2c_dev)
    delete i2c_dev;
  i2c_dev = new Adafruit_I2CDevice(addr, wire);
  return i2c_dev->begin();
}
////
bool Adafruit_I2CDevice::write_then_read(const uint8_t *write_buffer,
                                         size_t write_len, uint8_t *read_buffer,
                                         size_t read_len, bool stop) {
  if (!write(write_buffer, write_len, stop)) {
    return false;
  }

  return read(read_buffer, read_len);
}

/////
uint16_t read16(uint8_t a) {
  uint8_t buffer[3];
  buffer[0] = a;
  // read two bytes of data + pec
  bool status =i2c_dev->write_then_read(buffer, 1, buffer, 3);
  if (!status)
    return 0;
  // return data, ignore pec
  return uint16_t(buffer[0]) | (uint16_t(buffer[1]) << 8);
}

///////
float readTemp(uint8_t reg) {
  float temp;

  temp = read16(reg);
  if (temp == 0)
    return NAN;
  temp *= .02;
  temp -= 273.15;
  return temp;
}

///////
double readObjectTempC(void) 
{
  #define MLX90614_TOBJ1 0x07
  return readTemp(MLX90614_TOBJ1);
}

///////
double readAmbientTempC(void) {
  #define MLX90614_TA 0x06
  return readTemp(MLX90614_TA);
}

///////
#define MLX90614_I2CADDR 0x5A

// RAM
#define MLX90614_RAWIR1 0x04
#define MLX90614_RAWIR2 0x05
#define MLX90614_TA 0x06
#define MLX90614_TOBJ1 0x07
#define MLX90614_TOBJ2 0x08
// EEPROM
#define MLX90614_TOMAX 0x20
#define MLX90614_TOMIN 0x21
#define MLX90614_PWMCTRL 0x22
#define MLX90614_TARANGE 0x23
#define MLX90614_EMISS 0x24
#define MLX90614_CONFIG 0x25
#define MLX90614_ADDR 0x2E
#define MLX90614_ID1 0x3C
#define MLX90614_ID2 0x3D
#define MLX90614_ID3 0x3E
#define MLX90614_ID4 0x3F

/**
 * @brief Class to read from and control a MLX90614 Temp Sensor
 *
 */
class Adafruit_MLX90614 {
public:
  ~Adafruit_MLX90614();
  bool begin(uint8_t addr = MLX90614_I2CADDR, TwoWire *wire = &Wire);
  double readObjectTempC(void);
  double readAmbientTempC(void);
  void writeEmissivityReg(uint16_t ereg);
  double readEmissivity(void);
  void writeEmissivity(double emissivity);

private:
  Adafruit_I2CDevice *i2c_dev = NULL; ///< Pointer to I2C bus interface
  float readTemp(uint8_t reg);
  uint16_t read16(uint8_t addr);
  void write16(uint8_t addr, uint16_t data);
  byte crc8(byte *addr, byte len);
  uint8_t _addr;
};
///////////notre code///////


float Text;
float Tpers;
float number = 2.0;

int loop_interval = 1000; //regarde la température toute les 1 secondes 
Adafruit_MLX90614 mlx = Adafruit_MLX90614(); //definie le mlx comme un objet pour qu'il puisse tourner dans arduino

void setup() {
  mlx.begin();
  Serial.begin(115200);
  delay(1000); // commence 1 seconde après 
}

void loop() {
  // lis la température ambiante/exterieure (Text) et la température de la personne (Tpers) en degrès Celcius
  Tpers = number + mlx.readObjectTempC();
  Text = mlx.readAmbientTempC();
  Serial.println("Personne:" + String(Tpers) + " °C" + " exterieure:" + String(Text) + " °C") ; // écrit dans le log les valeurs de la temperature de l'exterieur et de la personne puis change de ligne
  delay(loop_interval);
}

It's a private member of Adafruit_MLX90614

You could have used a simple text search to find it, as I did

Will your instructor agree that this falls under the definition of "not using the libraries"?

1 Like

yes if i can explain the code which are used

what do you mean i searched with ctrl+f for it but that didn t have a result in all .cpp and .h i searched

I mean, I searched this page, and found it.
Using text search.

i meant i know it s in the private of Adafruit_MLX90614 but i don't know what it does and why it show as an error that it is not declared

It's the means the library uses to access the sensor.
It's not in scope because it is private

How may i change that ? I need it to be in the scope, do i just need to put it in public ?

If you make it public, doesn't that break the rule of using a library?

The rule Is not realy to not use a library but to explain the part that i used so if i can explain it i am allowed to use it.
By making it public am i using the library ?(sorry i don’t understand the class in arduino)
How can i make it public ? (By just moving the part which is relevant into the public part ?)

Plenty of online resources to learn about C++ classes.

By making i2c_dev public, you're exposing the fact that it is an instance of an Adafruit class, and part of the Adafruit infrastructure/ecosystem.
Can you explain that to your tutor?

As of now, i am clearly not able to do that but i have to explain it in 5 month from now, do you think i can learn what the Adafruit infrastructure is about and then explain it in 5 month ?
I tried moving it and it didn't work, (i didn't change the code at all apart from the fact that the Adafruit_I2CDevice *i2c_dev = NULL; ///< Pointer to I2C bus interface is moved in the public part, it is still "not declared in this scope"

Certainly, if you work hard. Or, you could study the MLX90614 data sheet, and write your own code, which you should be able to understand very well.

i will try with the MLX datasheet, when i will have a semblance of code i will post other questions on the forum
Thank you very much everyone