Skip to content

Fixes #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 30, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions src/SparkFunMLX90614.cpp
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ IRTherm::IRTherm()
uint8_t IRTherm::begin(uint8_t address)
{
_deviceAddress = address; // Store the address in a private member

Wire.begin(); // Initialize I2C
//! TODO: read a register, return success only if the register
//! produced a known-good value.
@@ -104,7 +104,7 @@ uint8_t IRTherm::readObject()
_rawObject = rawObj;
return 1;
}
return 0;
return 0;
}

uint8_t IRTherm::readObject2()
@@ -122,7 +122,7 @@ uint8_t IRTherm::readObject2()
_rawObject2 = rawObj;
return 1;
}
return 0;
return 0;
}

uint8_t IRTherm::readAmbient()
@@ -174,7 +174,7 @@ uint8_t IRTherm::setMin(float minTemp)
{
// Convert the unit-ed value to a raw ADC value:
int16_t rawMin = calcRawTemp(minTemp);
// Write that value to the TOMIN EEPROM address:
// Write that value to the TOMIN EEPROM address:
return writeEEPROM(MLX90614_REGISTER_TOMIN, rawMin);
}

@@ -226,15 +226,15 @@ uint8_t IRTherm::setAddress(uint8_t newAdd)
{
tempAdd &= 0xFF00; // Mask out the address (MSB is junk?)
tempAdd |= newAdd; // Add the new address

// Write the new addres back to EEPROM:
return writeEEPROM(MLX90614_REGISTER_ADDRESS, tempAdd);
}
}
return 0;
}

uint8_t IRTherm::readID(void)
{
{
for (int i=0; i<4; i++)
{
int16_t temp = 0;
@@ -265,13 +265,13 @@ uint8_t IRTherm::sleep(void)
// Bits sent: _deviceAddress (shifted left 1) + 0xFF
uint8_t crc = crc8(0, (_deviceAddress << 1));
crc = crc8(crc, MLX90614_REGISTER_SLEEP);

// Manually send the sleep command:
Wire.beginTransmission(_deviceAddress);
Wire.write(MLX90614_REGISTER_SLEEP);
Wire.write(crc);
Wire.endTransmission(true);

// Set the SCL pin LOW, and SDA pin HIGH (should be pulled up)
pinMode(SCL, OUTPUT);
digitalWrite(SCL, LOW);
@@ -281,7 +281,7 @@ uint8_t IRTherm::sleep(void)
uint8_t IRTherm::wake(void)
{
// Wake operation from datasheet
Wire.end(); // stop i2c bus to send wake up request via digital pins
Wire.endTransmission(true); // stop i2c bus transmission BEFORE sending wake up request
pinMode(SCL, INPUT); // SCL high
pinMode(SDA, OUTPUT);
digitalWrite(SDA, LOW); // SDA low
@@ -293,13 +293,13 @@ uint8_t IRTherm::wake(void)
digitalWrite(SCL, LOW); // SCL low
delay(10); // Delay at least 1.44ms
pinMode(SCL, INPUT); // SCL high
Wire.begin();
Wire.beginTransmission(_deviceAddress); // reactivate i2c bus transmission AFTER sending wake up request
}

int16_t IRTherm::calcRawTemp(float calcTemp)
{
int16_t rawTemp; // Value to eventually be returned

if (_defaultUnit == TEMP_RAW)
{
// If unit is set to raw, just return that:
@@ -332,7 +332,7 @@ int16_t IRTherm::calcRawTemp(float calcTemp)
float IRTherm::calcTemperature(int16_t rawTemp)
{
float retTemp;

if (_defaultUnit == TEMP_RAW)
{
retTemp = (float) rawTemp;
@@ -349,28 +349,28 @@ float IRTherm::calcTemperature(int16_t rawTemp)
}
}
}

return retTemp;
}

uint8_t IRTherm::I2CReadWord(byte reg, int16_t * dest)
{
Wire.beginTransmission(_deviceAddress);
Wire.write(reg);

Wire.endTransmission(false); // Send restart
Wire.requestFrom(_deviceAddress, (uint8_t) 3);

uint8_t lsb = Wire.read();
uint8_t msb = Wire.read();
uint8_t pec = Wire.read();

uint8_t crc = crc8(0, (_deviceAddress << 1));
crc = crc8(crc, reg);
crc = crc8(crc, (_deviceAddress << 1) + 1);
crc = crc8(crc, lsb);
crc = crc8(crc, msb);

if (crc == pec)
{
*dest = (msb << 8) | lsb;
@@ -383,32 +383,32 @@ uint8_t IRTherm::I2CReadWord(byte reg, int16_t * dest)
}

uint8_t IRTherm::writeEEPROM(byte reg, int16_t data)
{
{
// Clear out EEPROM first:
if (I2CWriteWord(reg, 0) != 0)
return 0; // If the write failed, return 0
delay(5); // Delay tErase

uint8_t i2cRet = I2CWriteWord(reg, data);
delay(5); // Delay tWrite

if (i2cRet == 0)
return 1;
else
return 0;
return 0;
}

uint8_t IRTherm::I2CWriteWord(byte reg, int16_t data)
{
uint8_t crc;
uint8_t lsb = data & 0x00FF;
uint8_t msb = (data >> 8);

crc = crc8(0, (_deviceAddress << 1));
crc = crc8(crc, reg);
crc = crc8(crc, lsb);
crc = crc8(crc, msb);

Wire.beginTransmission(_deviceAddress);
Wire.write(reg);
Wire.write(lsb);
88 changes: 49 additions & 39 deletions src/SparkFunMLX90614.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/******************************************************************************
/******************************************************************************
SparkFunMLX90614.h
Header file for the SparkFun IR Thermometer Library
@@ -20,6 +20,16 @@ SparkFun IR Thermometer Evaluation Board - MLX90614
#include <Arduino.h>
#include <Wire.h>

///////////////////////////////////////////
// Default I2C PIN for non Atmega Boards //
///////////////////////////////////////////
#ifndef SDA
#define SDA (digitalPinToPinName(PIN_WIRE_SDA))
#endif
#ifndef SCL
#define SCL (digitalPinToPinName(PIN_WIRE_SCL))
#endif

//////////////////////////////////
// MLX90614 Default I2C Address //
//////////////////////////////////
@@ -53,134 +63,134 @@ typedef enum {
TEMP_F
} temperature_units;

class IRTherm
class IRTherm
{
public:
// Default constructor, does very little besides setting class variable
// initial values.
IRTherm();
// begin(<address>) initializes the Wire library, and prepares
// communication with an MLX90614 device at the specified 7-bit I2C

// begin(<address>) initializes the Wire library, and prepares
// communication with an MLX90614 device at the specified 7-bit I2C
// address.
// If no parameter is supplied, the default MLX90614 address is used.
uint8_t begin(uint8_t address = MLX90614_DEFAULT_ADDRESS);
// setUnit(<unit>) configures the units returned by the ambient(),
// object(), minimum() and maximum() functions, and it determines what

// setUnit(<unit>) configures the units returned by the ambient(),
// object(), minimum() and maximum() functions, and it determines what
// units the setMin() and setMax() functions should expect.
// <unit> can be either:
// - TEMP_RAW: No conversion, just the raw 12-bit ADC reading
// - TEMP_K: Kelvin
// - TEMP_C: Celsius
// - TEMP_F: Farenheit
void setUnit(temperature_units unit);
// read() pulls the latest ambient and object temperatures from the
// MLX90614. It will return either 1 on success or 0 on failure. (Failure

// read() pulls the latest ambient and object temperatures from the
// MLX90614. It will return either 1 on success or 0 on failure. (Failure
// can result from either a timed out I2C transmission, or an incorrect
// checksum value).
uint8_t read(void);
// object() returns the MLX90614's most recently read object temperature

// object() returns the MLX90614's most recently read object temperature
// after the read() function has returned successfully. The float value
// returned will be in the units specified by setUnit().
float object(void);
// ambient() returns the MLX90614's most recently read ambient temperature

// ambient() returns the MLX90614's most recently read ambient temperature
// after the read() function has returned successfully. The float value
// returned will be in the units specified by setUnit().
float ambient(void);
// readEmissivity() reads the MLX90614's emissivity setting. It will

// readEmissivity() reads the MLX90614's emissivity setting. It will
// return a value between 0.1 and 1.0.
float readEmissivity(void);
// setEmissivity(<emis>) can set the MLX90614's configured emissivity

// setEmissivity(<emis>) can set the MLX90614's configured emissivity
// EEPROM value.
// The <emis> parameter should be a value between 0.1 and 1.0.
// The function will return either 1 on success or 0 on failure.
uint8_t setEmissivity(float emis);

// readAddress() returns the MLX90614's configured 7-bit I2C bus address.
// A value between 0x01 and 0x7F should be returned.
uint8_t readAddress(void);

// setAddress(<newAdd>) can set the MLX90614's 7-bit I2C bus address.
// The <newAdd> parameter should be a value between 0x01 and 0x7F.
// The function returns 1 on success and 0 on failure.
// The new address won't take effect until the device is reset.
uint8_t setAddress(uint8_t newAdd);

// readID() reads the 64-bit ID of the MLX90614.
// Return value is either 1 on success or 0 on failure.
uint8_t readID(void);

// After calling readID() getIDH() and getIDL() can be called to read
// the upper 4 bytes and lower 4-bytes, respectively, of the MLX90614's
// identification registers.
uint32_t getIDH(void);
uint32_t getIDL(void);

// readRange() pulls the object maximum and minimum values stored in the
// MLX90614's EEPROM.
// It will return either 1 on success or 0 on failure.
uint8_t readRange(void);

// minimum() and maximum() return the MLX90614's minimum and maximum object
// sensor readings.
// The float values returned will be in the units specified by setUnit().
float minimum(void);
float maximum(void);
// setMax(<maxTemp>) and setMin(<minTemp>) configure the MLX90614's

// setMax(<maxTemp>) and setMin(<minTemp>) configure the MLX90614's
// maximum and minimum object sensor temperatures.
uint8_t setMax(float maxTemp);
uint8_t setMin(float minTemp);

// sleep() sets the MLX90614 into a low-power sleep mode.
uint8_t sleep(void);

// wake() should revive the MLX90614 from low-power sleep mode.
uint8_t wake(void);

private:
uint8_t _deviceAddress; // MLX90614's 7-bit I2C address
temperature_units _defaultUnit; // Keeps track of configured temperature unit

// These keep track of the raw temperature values read from the sensor:
int16_t _rawAmbient, _rawObject, _rawObject2, _rawMax, _rawMin;

uint16_t id[4]; // Keeps track of the 64-bit ID value

// These functions individually read the object, object2, and ambient
// temperature values from the MLX90614's RAM:
uint8_t readObject(void);
uint8_t readObject2(void);
uint8_t readAmbient(void);

// These functions individually read the min and mx temperatures in
// the MLX90614's EEPROM:
uint8_t readMax(void);
uint8_t readMin(void);

// calcTemperature converts a raw ADC temperature reading to the
// set unit.
float calcTemperature(int16_t rawTemp);

// calcRawTemperature converts a set unit temperature to a
// raw ADC value:
int16_t calcRawTemp(float calcTemp);

// Abstract function to write 16-bits to an address in the MLX90614's
// EEPROM
uint8_t writeEEPROM(byte reg, int16_t data);

// Abstract functions to read and write 16-bit values from a RAM
// or EEPROM address in the MLX90614
uint8_t I2CReadWord(byte reg, int16_t * dest);
uint8_t I2CWriteWord(byte reg, int16_t data);

// crc8 returns a calculated crc value given an initial value and
// input data.
// It's configured to calculate the CRC using a x^8+x^2+x^1+1 poly