Add comprehensive MLX90632 control and status register functionality
- Add getProductCode() function with product code decoding - Add control register functions: startSingleMeasurement(), startFullMeasurement() - Add mode control: setMode(), getMode() with enum support - Add measurement select: setMeasurementSelect(), getMeasurementSelect() - Add status register functions: isBusy(), isEEPROMBusy(), reset() - Add data monitoring: readCyclePosition(), resetNewData(), isNewData() - Add measurement mode and type enums (HALT, STEP, CONTINUOUS, MEDICAL, EXTENDED_RANGE) - Update test sketch with full register testing and status monitoring - All functions use proper RegisterBits for clean bit manipulation - All setter functions return bool for I2C write verification 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
d38f88cb80
commit
dfa2379739
3 changed files with 293 additions and 0 deletions
|
|
@ -77,6 +77,178 @@ uint64_t Adafruit_MLX90632::getProductID() {
|
|||
return ((uint64_t)id2 << 32) | ((uint64_t)id1 << 16) | id0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read the product code
|
||||
* @return Product code (16-bit value)
|
||||
*/
|
||||
uint16_t Adafruit_MLX90632::getProductCode() {
|
||||
Adafruit_BusIO_Register product_code_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_EE_PRODUCT_CODE), 2, MSBFIRST, 2);
|
||||
return product_code_reg.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Start a single measurement (SOC)
|
||||
* @return True if write succeeded, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::startSingleMeasurement() {
|
||||
Adafruit_BusIO_Register control_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_CONTROL), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits soc_bit =
|
||||
Adafruit_BusIO_RegisterBits(&control_reg, 1, 3);
|
||||
|
||||
return soc_bit.write(1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Start a full measurement table (SOB)
|
||||
* @return True if write succeeded, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::startFullMeasurement() {
|
||||
Adafruit_BusIO_Register control_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_CONTROL), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits sob_bit =
|
||||
Adafruit_BusIO_RegisterBits(&control_reg, 1, 11);
|
||||
|
||||
return sob_bit.write(1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Set the measurement mode
|
||||
* @param mode The measurement mode to set
|
||||
* @return True if write succeeded, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::setMode(mlx90632_mode_t mode) {
|
||||
Adafruit_BusIO_Register control_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_CONTROL), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits mode_bits =
|
||||
Adafruit_BusIO_RegisterBits(&control_reg, 2, 1);
|
||||
|
||||
return mode_bits.write(mode);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the measurement mode
|
||||
* @return The current measurement mode
|
||||
*/
|
||||
mlx90632_mode_t Adafruit_MLX90632::getMode() {
|
||||
Adafruit_BusIO_Register control_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_CONTROL), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits mode_bits =
|
||||
Adafruit_BusIO_RegisterBits(&control_reg, 2, 1);
|
||||
|
||||
return (mlx90632_mode_t)mode_bits.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Set the measurement select type
|
||||
* @param meas_select The measurement select type to set
|
||||
* @return True if write succeeded, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::setMeasurementSelect(mlx90632_meas_select_t meas_select) {
|
||||
Adafruit_BusIO_Register control_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_CONTROL), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits meas_select_bits =
|
||||
Adafruit_BusIO_RegisterBits(&control_reg, 5, 4);
|
||||
|
||||
return meas_select_bits.write(meas_select);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the measurement select type
|
||||
* @return The current measurement select type
|
||||
*/
|
||||
mlx90632_meas_select_t Adafruit_MLX90632::getMeasurementSelect() {
|
||||
Adafruit_BusIO_Register control_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_CONTROL), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits meas_select_bits =
|
||||
Adafruit_BusIO_RegisterBits(&control_reg, 5, 4);
|
||||
|
||||
return (mlx90632_meas_select_t)meas_select_bits.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Check if device is busy with measurement
|
||||
* @return True if device is busy, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::isBusy() {
|
||||
Adafruit_BusIO_Register status_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_STATUS), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits device_busy_bit =
|
||||
Adafruit_BusIO_RegisterBits(&status_reg, 1, 10);
|
||||
|
||||
return device_busy_bit.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Check if EEPROM is busy
|
||||
* @return True if EEPROM is busy, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::isEEPROMBusy() {
|
||||
Adafruit_BusIO_Register status_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_STATUS), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits eeprom_busy_bit =
|
||||
Adafruit_BusIO_RegisterBits(&status_reg, 1, 9);
|
||||
|
||||
return eeprom_busy_bit.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reset device using addressed reset command
|
||||
* @return True if reset succeeded, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::reset() {
|
||||
// Send addressed reset command: 0x3005, 0x0006
|
||||
uint8_t reset_cmd[] = {0x30, 0x05, 0x00, 0x06};
|
||||
if (!i2c_dev->write(reset_cmd, 4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for reset to complete (at least 150us as per datasheet)
|
||||
delay(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read the cycle position
|
||||
* @return Current cycle position (0-31)
|
||||
*/
|
||||
uint8_t Adafruit_MLX90632::readCyclePosition() {
|
||||
Adafruit_BusIO_Register status_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_STATUS), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits cycle_position_bits =
|
||||
Adafruit_BusIO_RegisterBits(&status_reg, 5, 2);
|
||||
|
||||
return cycle_position_bits.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Reset the new data flag to 0
|
||||
* @return True if write succeeded, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::resetNewData() {
|
||||
Adafruit_BusIO_Register status_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_STATUS), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits new_data_bit =
|
||||
Adafruit_BusIO_RegisterBits(&status_reg, 1, 0);
|
||||
|
||||
return new_data_bit.write(0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Check if new data is available
|
||||
* @return True if new data is available, false otherwise
|
||||
*/
|
||||
bool Adafruit_MLX90632::isNewData() {
|
||||
Adafruit_BusIO_Register status_reg =
|
||||
Adafruit_BusIO_Register(i2c_dev, swapBytes(MLX90632_REG_STATUS), 2, MSBFIRST, 2);
|
||||
Adafruit_BusIO_RegisterBits new_data_bit =
|
||||
Adafruit_BusIO_RegisterBits(&status_reg, 1, 0);
|
||||
|
||||
return new_data_bit.read();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Byte swap helper for register addresses
|
||||
* @param value 16-bit value to swap
|
||||
|
|
|
|||
|
|
@ -121,6 +121,28 @@
|
|||
#define MLX90632_REG_RAM_60 0x403B ///< Raw data 60
|
||||
/*=========================================================================*/
|
||||
|
||||
/*=========================================================================
|
||||
CONTROL REGISTER ENUMS
|
||||
-----------------------------------------------------------------------*/
|
||||
/*!
|
||||
* @brief MLX90632 measurement modes
|
||||
*/
|
||||
typedef enum {
|
||||
MLX90632_MODE_HALT = 0x00, ///< Halt mode for EEPROM operations
|
||||
MLX90632_MODE_SLEEPING_STEP = 0x01, ///< Sleeping step mode
|
||||
MLX90632_MODE_STEP = 0x02, ///< Step mode
|
||||
MLX90632_MODE_CONTINUOUS = 0x03 ///< Continuous mode
|
||||
} mlx90632_mode_t;
|
||||
|
||||
/*!
|
||||
* @brief MLX90632 measurement types
|
||||
*/
|
||||
typedef enum {
|
||||
MLX90632_MEAS_MEDICAL = 0x00, ///< Medical measurement
|
||||
MLX90632_MEAS_EXTENDED_RANGE = 0x11 ///< Extended range measurement
|
||||
} mlx90632_meas_select_t;
|
||||
/*=========================================================================*/
|
||||
|
||||
/*!
|
||||
* @brief Class that stores state and functions for interacting with
|
||||
* MLX90632 Far Infrared Temperature Sensor
|
||||
|
|
@ -131,6 +153,19 @@ public:
|
|||
~Adafruit_MLX90632();
|
||||
bool begin(uint8_t i2c_addr = MLX90632_DEFAULT_ADDR, TwoWire *wire = &Wire);
|
||||
uint64_t getProductID();
|
||||
uint16_t getProductCode();
|
||||
bool startSingleMeasurement();
|
||||
bool startFullMeasurement();
|
||||
bool setMode(mlx90632_mode_t mode);
|
||||
mlx90632_mode_t getMode();
|
||||
bool setMeasurementSelect(mlx90632_meas_select_t meas_select);
|
||||
mlx90632_meas_select_t getMeasurementSelect();
|
||||
bool isBusy();
|
||||
bool isEEPROMBusy();
|
||||
bool reset();
|
||||
uint8_t readCyclePosition();
|
||||
bool resetNewData();
|
||||
bool isNewData();
|
||||
|
||||
private:
|
||||
Adafruit_I2CDevice *i2c_dev; ///< Pointer to I2C bus interface
|
||||
|
|
|
|||
|
|
@ -16,12 +16,98 @@ void setup() {
|
|||
}
|
||||
Serial.println("MLX90632 Found!");
|
||||
|
||||
// Reset the device
|
||||
if (!mlx.reset()) {
|
||||
Serial.println("Device reset failed");
|
||||
while (1) { delay(10); }
|
||||
}
|
||||
Serial.println("Device reset: SUCCESS");
|
||||
|
||||
uint64_t productID = mlx.getProductID();
|
||||
Serial.print("Product ID: 0x");
|
||||
Serial.print((uint32_t)(productID >> 32), HEX);
|
||||
Serial.println((uint32_t)(productID & 0xFFFFFFFF), HEX);
|
||||
|
||||
uint16_t productCode = mlx.getProductCode();
|
||||
Serial.print("Product Code: 0x");
|
||||
Serial.println(productCode, HEX);
|
||||
|
||||
// Decode product code bits
|
||||
uint8_t fov = (productCode >> 8) & 0x3;
|
||||
uint8_t package = (productCode >> 5) & 0x7;
|
||||
uint8_t accuracy = productCode & 0x1F;
|
||||
|
||||
Serial.print("FOV: ");
|
||||
Serial.println(fov == 0 ? "50°" : "Unknown");
|
||||
|
||||
Serial.print("Package: ");
|
||||
Serial.println(package == 1 ? "SFN 3x3" : "Unknown");
|
||||
|
||||
Serial.print("Accuracy: ");
|
||||
if (accuracy == 1) {
|
||||
Serial.println("Medical");
|
||||
} else if (accuracy == 2) {
|
||||
Serial.println("Standard");
|
||||
} else {
|
||||
Serial.println("Unknown");
|
||||
}
|
||||
|
||||
// Set and get mode (continuous)
|
||||
Serial.println("\n--- Mode Settings ---");
|
||||
if (!mlx.setMode(MLX90632_MODE_CONTINUOUS)) {
|
||||
Serial.println("Failed to set mode to Continuous");
|
||||
while (1) { delay(10); }
|
||||
}
|
||||
|
||||
mlx90632_mode_t currentMode = mlx.getMode();
|
||||
Serial.print("Current mode: ");
|
||||
switch (currentMode) {
|
||||
case MLX90632_MODE_HALT:
|
||||
Serial.println("Halt");
|
||||
break;
|
||||
case MLX90632_MODE_SLEEPING_STEP:
|
||||
Serial.println("Sleeping Step");
|
||||
break;
|
||||
case MLX90632_MODE_STEP:
|
||||
Serial.println("Step");
|
||||
break;
|
||||
case MLX90632_MODE_CONTINUOUS:
|
||||
Serial.println("Continuous");
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unknown");
|
||||
}
|
||||
|
||||
// Set and get measurement select (medical)
|
||||
Serial.println("\n--- Measurement Select Settings ---");
|
||||
if (!mlx.setMeasurementSelect(MLX90632_MEAS_MEDICAL)) {
|
||||
Serial.println("Failed to set measurement select to Medical");
|
||||
while (1) { delay(10); }
|
||||
}
|
||||
|
||||
mlx90632_meas_select_t currentMeasSelect = mlx.getMeasurementSelect();
|
||||
Serial.print("Current measurement select: ");
|
||||
switch (currentMeasSelect) {
|
||||
case MLX90632_MEAS_MEDICAL:
|
||||
Serial.println("Medical");
|
||||
break;
|
||||
case MLX90632_MEAS_EXTENDED_RANGE:
|
||||
Serial.println("Extended Range");
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print("Device Busy: ");
|
||||
Serial.print(mlx.isBusy() ? "YES" : "NO");
|
||||
Serial.print(" EEPROM Busy: ");
|
||||
Serial.print(mlx.isEEPROMBusy() ? "YES" : "NO");
|
||||
Serial.print(" New Data: ");
|
||||
Serial.print(mlx.isNewData() ? "YES" : "NO");
|
||||
Serial.print(" Cycle Position: ");
|
||||
Serial.println(mlx.readCyclePosition());
|
||||
|
||||
delay(500);
|
||||
}
|
||||
Loading…
Reference in a new issue