Skip to content

Instantly share code, notes, and snippets.

@Ryotsuke
Last active June 11, 2018 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Ryotsuke/9100459 to your computer and use it in GitHub Desktop.
Save Ryotsuke/9100459 to your computer and use it in GitHub Desktop.
LTC2990 sample
#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);
}
#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
#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