Last active
June 11, 2018 12:38
-
-
Save Ryotsuke/9100459 to your computer and use it in GitHub Desktop.
LTC2990 sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "LTC2990.h" | |
LTC2990::LTC2990() { | |
config((LTC2990_BASE_ADDRESS>>1) + 0, 0, 0, LTC2990_MEASURE_ALL, LTC2990_MEASURE_MODE_V1_V2_V3_V4); | |
} | |
LTC2990::LTC2990(uint8_t relative_address) { | |
config(((LTC2990_BASE_ADDRESS>>1) + relative_address), 0, 0, LTC2990_MEASURE_ALL, LTC2990_MEASURE_MODE_V1_V2_V3_V4); | |
} | |
LTC2990::LTC2990(uint8_t relative_address, uint8_t tempFormatIsCelsius, uint8_t single, uint8_t limit, uint8_t measureMode) { | |
config(((LTC2990_BASE_ADDRESS>>1) + relative_address), tempFormatIsCelsius, single, limit, measureMode); | |
} | |
bool LTC2990::initialized() { | |
return _initialised; | |
} | |
void LTC2990::begin() { | |
#ifdef LTC2990_DEBUG | |
Serial.begin(9600); | |
Serial.println("Init"); | |
#endif | |
Wire.begin(); | |
_initialised = true; | |
if(writeRegister(LTC2990_REGISTER_CONTROL, _mode) !=0 ) { | |
_initialised = false; | |
#ifdef LTC2990_DEBUG | |
Serial.println("Init failed"); | |
#endif | |
} | |
if(writeRegister(LTC2990_REGISTER_TRIGGER, 0x1)!=0 ) { | |
_initialised = false; | |
} | |
} | |
void LTC2990::config(uint8_t address, uint8_t tempFormatIsCelsius, uint8_t single, uint8_t limit, uint8_t measureMode) { | |
_shadow = 0x0; | |
_initialised = false; | |
_addr = address; | |
_mode = setMode(tempFormatIsCelsius, single, limit, measureMode); | |
#ifdef LTC2990_DEBUG | |
Serial.print("Addr "); | |
Serial.print(_addr, HEX); | |
Serial.println(); | |
Serial.print("Mode "); | |
Serial.print(_mode, BIN); | |
Serial.println(); | |
#endif | |
} | |
uint8_t LTC2990::setMode(uint8_t tempFormatIsCelsius = 0, uint8_t single = 0, uint8_t limit = LTC2990_MEASURE_ALL, uint8_t measureMode = LTC2990_MEASURE_MODE_V1_V2_V3_V4) { | |
return measureMode + (limit<<3) + (single<<LTC2990_REPEAT_BIT) + (tempFormatIsCelsius<<LTC2990_TEMPFORMAT_BIT); | |
} | |
uint8_t LTC2990::writeRegister(uint8_t r, uint8_t val) { | |
#ifdef LTC2990_DEBUG | |
Serial.print("Write "); | |
Serial.print(r, HEX); | |
Serial.print(val, HEX); | |
Serial.print(": "); | |
#endif | |
noInterrupts(); | |
Wire.beginTransmission(_addr); | |
Wire.write(r); | |
Wire.write(val); | |
uint8_t status = Wire.endTransmission(true); | |
if(status != 0) { | |
_lastErrorCode = LTC2990_ERROR_WRITE; | |
} else { | |
_lastErrorCode = LTC2990_SUCCESS; | |
} | |
delayMicroseconds(200); | |
interrupts(); | |
#ifdef LTC2990_DEBUG | |
Serial.println(status); | |
#endif | |
return status; | |
} | |
uint8_t LTC2990::readRegister(uint8_t r) { | |
#ifdef LTC2990_DEBUG | |
Serial.print("Read "); | |
Serial.print(r, HEX); | |
Serial.print(": "); | |
#endif | |
noInterrupts(); | |
Wire.beginTransmission(_addr); | |
Wire.write(r); | |
uint8_t status = Wire.endTransmission(true); | |
delayMicroseconds(200); | |
if(status == 0) { | |
if(Wire.requestFrom(_addr, 1, true) == 1) { | |
uint8_t result = Wire.read(); | |
#ifdef LTC2990_DEBUG | |
Serial.println(result, BIN); | |
#endif | |
interrupts(); | |
_lastErrorCode = LTC2990_SUCCESS; | |
return result; | |
} else { | |
_lastErrorCode = LTC2990_ERROR_READ; | |
} | |
#ifdef LTC2990_DEBUG | |
Serial.println(" NA"); | |
#endif | |
} else { | |
_lastErrorCode = LTC2990_ERROR_WRITE; | |
} | |
interrupts(); | |
return 0; | |
} | |
uint32_t LTC2990::getLastErrorCode() { | |
return _lastErrorCode; | |
} | |
uint32_t LTC2990::readVoltage(uint8_t m_register) { | |
uint8_t m = readRegister(m_register); | |
uint8_t l = 0; | |
uint8_t m_error = _lastErrorCode; | |
uint8_t l_error = LTC2990_SUCCESS; | |
#ifndef LTC2990_LOW_PRECISION | |
l = readRegister(m_register + 1); | |
uint8_t l_error = _lastErrorCode; | |
#endif | |
if((m&0x80) == 0 || m == 0) { | |
if(m!=0) { | |
_lastErrorCode = LTC2990_ERROR_NOT_READY; //No new value is available at this point | |
} | |
return 0; | |
} | |
if(l_error != LTC2990_SUCCESS) { | |
_lastErrorCode = l_error; | |
return 0; | |
} | |
if((m&0x40) == 0x40) { | |
#ifdef LTC2990_DEBUG | |
Serial.println(m, HEX); | |
Serial.println(m&0x3F, HEX); | |
Serial.println(m&0x40, HEX); | |
Serial.println("Neg"); | |
#endif | |
_lastErrorCode = LTC2990_ERROR_NEGATIVE; | |
return 0; //negative | |
} | |
m &= 0x3F; | |
#ifdef LTC2990_DEBUG | |
Serial.println(((m<<8)+l), BIN); | |
Serial.println(((m<<8)+l), HEX); | |
#endif | |
_lastErrorCode = LTC2990_SUCCESS; | |
return ((m<<8)+l) / 1000.0 * LTC2990_VOLTAGE_SINGLE_END_COEF; | |
} | |
uint32_t LTC2990::readVoltageDifferential(uint8_t m_register) { | |
uint8_t m = readRegister(m_register); | |
uint8_t l = 0; | |
uint8_t m_error = _lastErrorCode; | |
uint8_t l_error = LTC2990_SUCCESS; | |
#ifndef LTC2990_LOW_PRECISION | |
l = readRegister(m_register + 1); | |
uint8_t l_error = _lastErrorCode; | |
#endif | |
if((m&0x80) == 0 || m == 0) { | |
if(m!=0) { | |
_lastErrorCode = LTC2990_ERROR_NOT_READY; //No new value is available at this point | |
} | |
return 0; | |
} | |
if(l_error != LTC2990_SUCCESS) { | |
_lastErrorCode = l_error; | |
return 0; | |
} | |
if((m&0x40) == 0x40) { | |
#ifdef LTC2990_DEBUG | |
Serial.println(m, HEX); | |
Serial.println(m&0x3F, HEX); | |
Serial.println(m&0x40, HEX); | |
Serial.println("Neg"); | |
#endif | |
_lastErrorCode = LTC2990_ERROR_NEGATIVE; | |
return 0; //negative | |
} | |
m &= 0x3F; | |
#ifdef LTC2990_DEBUG | |
Serial.println(((m<<8)+l), BIN); | |
Serial.println(((m<<8)+l), HEX); | |
#endif | |
_lastErrorCode = LTC2990_SUCCESS; | |
return ((m<<8)+l) / 1000.0 * LTC2990_VOLTAGE_DIFFERENTIAL_COEF; | |
} | |
uint32_t LTC2990::readTemperature(uint8_t m_register) { | |
uint8_t m = readRegister(m_register); | |
uint8_t l = 0; | |
uint8_t m_error = _lastErrorCode; | |
uint8_t l_error = LTC2990_SUCCESS; | |
#ifndef LTC2990_LOW_PRECISION | |
l = readRegister(m_register + 1); | |
uint8_t l_error = _lastErrorCode; | |
#endif | |
if((m&0x80) == 0 || m == 0) { | |
if(m!=0) { | |
_lastErrorCode = LTC2990_ERROR_NOT_READY; //No new value is available at this point | |
} | |
return 0; | |
} | |
if(l_error != LTC2990_SUCCESS) { | |
_lastErrorCode = l_error; | |
return 0; | |
} | |
m &= 0x1F; | |
#ifdef LTC2990_DEBUG | |
Serial.println(((m<<8)+l), BIN); | |
Serial.println(((m<<8)+l), HEX); | |
#endif | |
_lastErrorCode = LTC2990_SUCCESS; | |
return ((m<<8) + l) * LTC2990_TEMP_COEF; | |
} | |
uint32_t LTC2990::readV1() { | |
return readVoltage(LTC2990_REGISTER_V1_M); | |
} | |
uint32_t LTC2990::readV2() { | |
return readVoltage(LTC2990_REGISTER_V2_M); | |
} | |
uint32_t LTC2990::readV3() { | |
return readVoltage(LTC2990_REGISTER_V3_M); | |
} | |
uint32_t LTC2990::readV4() { | |
return readVoltage(LTC2990_REGISTER_V4_M); | |
} | |
uint32_t LTC2990::readVCC() { | |
uint32_t v = readVoltage(LTC2990_REGISTER_VCC_M); | |
if(v!=0) { | |
return v+2500; | |
} | |
return 0; | |
} | |
uint32_t LTC2990::readV1V2() { | |
return readVoltageDifferential(LTC2990_REGISTER_V1_M); | |
} | |
uint32_t LTC2990::readV3V4() { | |
return readVoltageDifferential(LTC2990_REGISTER_V3_M); | |
} | |
uint32_t LTC2990::readTR1() { | |
return readTemperature(LTC2990_REGISTER_V1_M); | |
} | |
uint32_t LTC2990::readTR2() { | |
return readTemperature(LTC2990_REGISTER_V3_M); | |
} | |
uint32_t LTC2990::readTINT() { | |
return readTemperature(LTC2990_REGISTER_TINT_M); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef LTC2990_h | |
#define LTC2990_h | |
#include <inttypes.h> | |
/** | |
* Uncomment to enable serial debugging output. Serial starts on LTC2990 begin method with 9600 speed | |
* */ | |
//#define LTC2990_DEBUG | |
/** | |
* Uncomment to enable low precision mode which ignores lower byte. For voltage this drops precision to 0.077V steps | |
* */ | |
//#define LTC2990_LOW_PRECISION | |
#define LTC2990_MEASURE_MODE_V1_V2_TR2 0x0 | |
#define LTC2990_MEASURE_MODE_V1_MINUS_V2_TR2 0x1 | |
#define LTC2990_MEASURE_MODE_V1_MINUS_V2_V3_V4 0x2 | |
#define LTC2990_MEASURE_MODE_TR1_V3_V4 0x3 | |
#define LTC2990_MEASURE_MODE_TR1_V3_MINUS_V4 0x4 | |
#define LTC2990_MEASURE_MODE_TR1_TR2 0x5 | |
#define LTC2990_MEASURE_MODE_V1_MINUS_V2_V3_MINUS_V4 0x6 | |
#define LTC2990_MEASURE_MODE_V1_V2_V3_V4 0x7 | |
#define LTC2990_MEASURE_ONLY_INT 0x0 | |
#define LTC2990_MEASURE_ONLY_V1_TR1 0x1 | |
#define LTC2990_MEASURE_ONLY_V3_TR2 0x2 | |
#define LTC2990_MEASURE_ALL 0x3 | |
#define LTC2990_REPEAT_BIT 0x6 | |
#define LTC2990_TEMPFORMAT_BIT 0x7 | |
#define LTC2990_STATUS_BUSY_BIT 0x0 | |
#define LTC2990_STATUS_READY_TINT_BIT 0x1 | |
#define LTC2990_STATUS_READY_V1_TR1_BIT 0x2 | |
#define LTC2990_STATUS_READY_V2_BIT 0x3 | |
#define LTC2990_STATUS_READY_V3_TR2_BIT 0x4 | |
#define LTC2990_STATUS_READY_V4_BIT 0x5 | |
#define LTC2990_STATUS_READY_VCC_BIT 0x6 | |
#define LTC2990_STATUS_RESERVED_BIT 0x7 | |
#define LTC2990_REGISTER_STATUS 0x0 | |
#define LTC2990_REGISTER_CONTROL 0x1 | |
#define LTC2990_REGISTER_TRIGGER 0x2 | |
#define LTC2990_REGISTER_NA 0x3 | |
#define LTC2990_REGISTER_TINT_M 0x4 | |
#define LTC2990_REGISTER_TINT_L 0x5 | |
#define LTC2990_REGISTER_V1_M 0x6 | |
#define LTC2990_REGISTER_V1_L 0x7 | |
#define LTC2990_REGISTER_V2_M 0x8 | |
#define LTC2990_REGISTER_V2_L 0x9 | |
#define LTC2990_REGISTER_V3_M 0xA | |
#define LTC2990_REGISTER_V3_L 0xB | |
#define LTC2990_REGISTER_V4_M 0xC | |
#define LTC2990_REGISTER_V4_L 0xD | |
#define LTC2990_REGISTER_VCC_M 0xE | |
#define LTC2990_REGISTER_VCC_L 0xF | |
#define LTC2990_BASE_ADDRESS 0x98 | |
#define LTC2990_GLOBAL_SYNC_ADDRESS 0xEE | |
#define LTC2990_VOLTAGE_SINGLE_END_COEF 305.180 | |
#define LTC2990_VOLTAGE_DIFFERENTIAL_COEF 19.420 | |
#define LTC2990_TEMP_COEF 0.0625 | |
#define LTC2990_SUCCESS 0 | |
#define LTC2990_ERROR_WRITE 1 | |
#define LTC2990_ERROR_READ 2 | |
#define LTC2990_ERROR_NEGATIVE 3 | |
#define LTC2990_ERROR_NOT_READY 4 | |
#include <inttypes.h> | |
class LTC2990 { | |
public: | |
LTC2990(); | |
LTC2990(uint8_t relative_address); | |
LTC2990(uint8_t relative_address, uint8_t tempFormatIsCelsius, uint8_t single, uint8_t limit, uint8_t measureMode); | |
void begin(); | |
uint8_t setMode(uint8_t tempFormatIsCelsius, uint8_t single, uint8_t limit, uint8_t measureMode); | |
uint32_t readV1(); | |
uint32_t readV2(); | |
uint32_t readV3(); | |
uint32_t readV4(); | |
uint32_t readVCC(); | |
uint32_t readV1V2(); | |
uint32_t readV3V4(); | |
uint32_t readTR1(); | |
uint32_t readTR2(); | |
uint32_t readTINT(); | |
uint32_t getLastErrorCode(); | |
bool initialized(); | |
void triggerConvertion(); | |
uint8_t readRegister(uint8_t reg); | |
private: | |
void config(uint8_t relative_address, uint8_t tempFormatIsCelsius, uint8_t single, uint8_t limit, uint8_t measureMode); | |
uint8_t writeRegister(uint8_t reg, uint8_t value); | |
uint32_t readVoltage(uint8_t reg); | |
uint32_t readVoltageDifferential(uint8_t reg); | |
uint32_t readTemperature(uint8_t reg); | |
uint8_t _addr; | |
uint8_t _mode; | |
uint8_t _shadow; | |
uint8_t _initialised; | |
uint8_t _lastErrorCode; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "LTC2990.h" | |
LTC2990 voltageMonitor; | |
int voltage = 0; | |
bool monitor = false; | |
int oks = 1; | |
int errors = 0; | |
int successRatePercent = 100; | |
int vol(String args) { | |
if(args=="prev") { | |
monitor = !monitor; | |
return monitor; | |
} else { | |
if(voltageMonitor.initialized()) { | |
voltage = voltageMonitor.readVCC(); | |
return voltage; | |
} | |
} | |
return -1; | |
} | |
void setup() { | |
Spark.variable("voltage", &voltage, INT); | |
Spark.variable("stability", &successRatePercent, INT); | |
Spark.function("player", &vol); | |
voltageMonitor.begin(); | |
} | |
void loop() { | |
if(monitor) { | |
if(voltageMonitor.initialized()) { | |
voltage = voltageMonitor.readV1(); | |
if(voltage==0) { | |
errors++; | |
} else { | |
oks++; | |
} | |
} else { | |
voltage = 5; | |
} | |
successRatePercent = 100*oks/(errors+oks); | |
delay(100); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment