Files
smartweatherstation_v2.0/lib/Adafruit MLX90614 Library/Adafruit_MLX90614.cpp
2025-07-08 08:54:35 +08:00

179 lines
4.6 KiB
C++

/***************************************************
This is a library for the MLX90614 Temp Sensor
Designed specifically to work with the MLX90614 sensors in the
adafruit shop
----> https://www.adafruit.com/products/1747 (3V)
----> https://www.adafruit.com/products/1748 (5V)
These sensors use I2C to communicate, 2 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include "Adafruit_MLX90614.h"
Adafruit_MLX90614::~Adafruit_MLX90614() {
if (i2c_dev)
delete i2c_dev;
}
/**
* @brief Begin the I2C connection
* @param addr I2C address for the device.
* @param wire Pointer to Wire instance
* @return True if the device was successfully initialized, otherwise false.
*/
bool Adafruit_MLX90614::begin(uint8_t addr, TwoWire *wire) {
_addr = addr; // needed for CRC
if (i2c_dev)
delete i2c_dev;
i2c_dev = new Adafruit_I2CDevice(addr, wire);
return i2c_dev->begin();
}
/**
* @brief Read the raw value from the emissivity register
*
* @return uint16_t The unscaled emissivity value or '0' if reading failed
*/
uint16_t Adafruit_MLX90614::readEmissivityReg(void) {
return read16(MLX90614_EMISS);
}
/**
* @brief Write the raw unscaled emissivity value to the emissivity register
*
* @param ereg The unscaled emissivity value
*/
void Adafruit_MLX90614::writeEmissivityReg(uint16_t ereg) {
write16(MLX90614_EMISS, 0); // erase
vTaskDelay(10);
write16(MLX90614_EMISS, ereg);
vTaskDelay(10);
}
/**
* @brief Read the emissivity value from the sensor's register and scale
*
* @return double The emissivity value, ranging from 0.1 - 1.0 or NAN if reading
* failed
*/
double Adafruit_MLX90614::readEmissivity(void) {
uint16_t ereg = read16(MLX90614_EMISS);
if (ereg == 0)
return NAN;
return ((double)ereg) / 65535.0;
}
/**
* @brief Set the emissivity value
*
* @param emissivity The emissivity value to use, between 0.1 and 1.0
*/
void Adafruit_MLX90614::writeEmissivity(double emissivity) {
uint16_t ereg = (uint16_t)(0xffff * emissivity);
writeEmissivityReg(ereg);
}
/**
* @brief Get the current temperature of an object in degrees Farenheit
*
* @return double The temperature in degrees Farenheit or NAN if reading failed
*/
double Adafruit_MLX90614::readObjectTempF(void) {
return (readTemp(MLX90614_TOBJ1) * 9 / 5) + 32;
}
/**
* @brief Get the current ambient temperature in degrees Farenheit
*
* @return double The temperature in degrees Farenheit or NAN if reading failed
*/
double Adafruit_MLX90614::readAmbientTempF(void) {
return (readTemp(MLX90614_TA) * 9 / 5) + 32;
}
/**
* @brief Get the current temperature of an object in degrees Celcius
*
* @return double The temperature in degrees Celcius or NAN if reading failed
*/
double Adafruit_MLX90614::readObjectTempC(void) {
return readTemp(MLX90614_TOBJ1);
}
/**
* @brief Get the current ambient temperature in degrees Celcius
*
* @return double The temperature in degrees Celcius or NAN if reading failed
*/
double Adafruit_MLX90614::readAmbientTempC(void) {
return readTemp(MLX90614_TA);
}
float Adafruit_MLX90614::readTemp(uint8_t reg) {
float temp;
temp = read16(reg);
if (temp == 0)
return NAN;
temp *= .02;
temp -= 273.15;
return temp;
}
/*********************************************************************/
uint16_t Adafruit_MLX90614::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);
}
byte Adafruit_MLX90614::crc8(byte *addr, byte len)
// The PEC calculation includes all bits except the START, REPEATED START, STOP,
// ACK, and NACK bits. The PEC is a CRC-8 with polynomial X8+X2+X1+1.
{
byte crc = 0;
while (len--) {
byte inbyte = *addr++;
for (byte i = 8; i; i--) {
byte carry = (crc ^ inbyte) & 0x80;
crc <<= 1;
if (carry)
crc ^= 0x7;
inbyte <<= 1;
}
}
return crc;
}
void Adafruit_MLX90614::write16(uint8_t a, uint16_t v) {
uint8_t buffer[4];
buffer[0] = _addr << 1;
buffer[1] = a;
buffer[2] = v & 0xff;
buffer[3] = v >> 8;
uint8_t pec = crc8(buffer, 4);
buffer[0] = buffer[1];
buffer[1] = buffer[2];
buffer[2] = buffer[3];
buffer[3] = pec;
i2c_dev->write(buffer, 4);
}