add LTC2991 0.1.0

This commit is contained in:
rob tillaart 2021-05-16 13:21:38 +02:00
parent 8f47b63d70
commit e5488450a3
16 changed files with 1294 additions and 0 deletions

View File

@ -0,0 +1,7 @@
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
- uno
- leonardo
- due
- zero

View File

@ -0,0 +1,13 @@
---
name: Arduino CI
on: [push, pull_request]
jobs:
arduino_ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: Arduino-CI/action@master
# Arduino-CI/action@v0.1.1

View File

@ -0,0 +1,18 @@
name: JSON check
on:
push:
paths:
- '**.json'
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:
pattern: "\\.json$"

21
libraries/LTC2991/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-2021 Rob Tillaart
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,554 @@
//
// FILE: LTC2991.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// DATE: 2021-05-10
// PURPOSE: Library for LTC2991 temperature and voltage control IC
// URL: https://github.com/RobTillaart/LTC2991
//
// HISTORY:
// 0.1.0 2021-05-10 initial version
//
#include "LTC2991.h"
/////////////////////////////////////////////////////
//
// REGISTERS
//
#define STATUS_LOW 0x00
#define STATUS_HIGH 0x01
// 0x02..0x05 reserved
#define CONTROL_V1_V4 0x06
#define CONTROL_V5_V8 0x07
#define PWM_THRESHOLD_LSB 0x08
#define PWM_THRESHOLD_MSB 0x09
#define V_BASE 0x0A
#define V1_MSB 0x0A
#define V1_LSB 0x0B
#define V2_MSB 0x0C
#define V2_LSB 0x0D
#define V3_MSB 0x0E
#define V3_LSB 0x0F
#define V4_MSB 0x10
#define V4_LSB 0x11
#define V5_MSB 0x12
#define V5_LSB 0x13
#define V6_MSB 0x14
#define V6_LSB 0x15
#define V7_MSB 0x16
#define V7_LSB 0x17
#define V8_MSB 0x18
#define V8_lSB 0x19
#define T_INTERNAL_MSB 0x1A
#define T_INTERNAL_LSB 0x1B
#define VCC_MSB 0x1C
#define VCC_LSB 0x1D
/////////////////////////////////////////////////////
//
// MAGIC NUMBERS
//
// PAGE 21
const float SINGLE_ENDED_FACTOR = 2.5 / 8192; // 2^13
const float DIFFERENTIAL_FACTOR = 2.5 / 131072; // 2^17
const float VCC_FACTOR = 2.5 / 8192; // 2^13
const float TEMPERATURE_FACTOR = 1.0 / 16;
const float DIODE_VOLTAGE_FACTOR = 2.5 / 65536; // 2^16
/////////////////////////////////////////////////////
//
// CONSTRUCTORS
//
LTC2991::LTC2991(const int8_t address, TwoWire *wire)
{
_address = address;
_wire = wire;
}
#if defined (ESP8266) || defined(ESP32)
bool LTC2991::begin(uint8_t sda, uint8_t scl)
{
_wire = &Wire;
_wire->begin(sda, scl);
if (! isConnected()) return false;
return true;
}
#endif
bool LTC2991::begin()
{
_wire->begin();
if (! isConnected()) return false;
return true;
}
bool LTC2991::isConnected()
{
_wire->beginTransmission(_address);
return ( _wire->endTransmission() == 0);
}
//
// Core functions
//
bool LTC2991::new_data(uint8_t channel)
{
uint8_t x = _readRegister(STATUS_LOW);
return (x & (1 << (channel - 1))) > 0;
}
bool LTC2991::new_temperature()
{
uint8_t x = _readRegister(STATUS_HIGH);
return (x & 0x02) > 0;
}
bool LTC2991::new_voltage()
{
uint8_t x = _readRegister(STATUS_HIGH);
return (x & 0x01) > 0;
}
bool LTC2991::is_busy()
{
uint8_t x = _readRegister(STATUS_HIGH);
return (x & 0x04) > 0;
}
//////////////////////////////////////////////////////////////////
//
// EXTERNAL CHANNELS (8 voltage or 4 temperature)
//
void LTC2991::enable(uint8_t n, bool enable)
{
if (enable) _setRegisterMask(STATUS_HIGH, (0x08 << n));
else _clrRegisterMask(STATUS_HIGH, (0x08 << n));
}
bool LTC2991::is_enabled(uint8_t n)
{
uint8_t x = _readRegister(STATUS_HIGH);
return (x & (0x08 << n)) > 0;
}
void LTC2991::enable_filter(uint8_t n, bool enable)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x08;
if (n > 1) mask = 0x80;
if (enable) _setRegisterMask(reg, mask);
else _clrRegisterMask(reg, mask);
}
bool LTC2991::is_enabled_filter(uint8_t n)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x08;
if (n > 1) mask = 0x80;
return _getRegisterMask(reg, mask) > 0;
}
// can be more efficient in one register addressing.
void LTC2991::set_Kelvin(uint8_t n)
{
set_temp_scale(n, true);
set_mode_temperature(n);
};
// can be more efficient in one register addressing.
void LTC2991::set_Celsius(uint8_t n)
{
set_temp_scale(n, false);
set_mode_temperature(n);
};
void LTC2991::set_temp_scale(uint8_t n, bool Kelvin)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x04;
if (n > 1) mask = 0x40;
if (Kelvin) _setRegisterMask(reg, mask);
else _clrRegisterMask(reg, mask);
}
char LTC2991::get_temp_scale(uint8_t n)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x04;
if (n > 1) mask = 0x40;
if (_getRegisterMask(reg, mask) > 0)
{
return 'K';
}
return 'C';
}
void LTC2991::set_mode_temperature(uint8_t n)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x02;
if (n > 1) mask = 0x20;
_setRegisterMask(reg, mask);
}
void LTC2991::set_mode_voltage_differential(uint8_t n)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x02; // 3 == voltage | differential
if (n > 1) mask = 0x20;
_clrRegisterMask(reg, mask);
mask >>= 1;
_setRegisterMask(reg, mask);
}
void LTC2991::set_mode_voltage_normal(uint8_t n)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x02;
if (n > 1) mask = 0x20;
_clrRegisterMask(reg, mask);
mask >>= 1;
_clrRegisterMask(reg, mask);
}
uint8_t LTC2991::get_operational_mode(uint8_t n)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x02;
if (n > 1) mask = 0x20;
if (_getRegisterMask(reg, mask) > 0) return 1;
return 0;
}
uint8_t LTC2991::get_differential_mode(uint8_t n)
{
uint8_t reg = CONTROL_V1_V4;
if (n > 2)
{
reg++;
n -= 2;
}
uint8_t mask = 0x01;
if (n > 1) mask = 0x10;
if (_getRegisterMask(reg, mask) > 0) return 1;
return 0;
}
float LTC2991::get_value(uint8_t channel)
{
uint8_t chan = channel - 1;
uint8_t pair = (channel + 1)/2;
int16_t v = _readRegister16(V_BASE + chan * 2);
if (get_operational_mode(pair) > 0) // temperature
{
if (get_temp_scale(pair) == 'K') // KELVIN
{
return TEMPERATURE_FACTOR * (float)v;
}
// CELSIUS positive
if ((v & 0x1000) == 0)
{
return TEMPERATURE_FACTOR * (float)v;
}
// CELSIUS neg two complements (page 13, 2nd colom.)
v = (v^0x1FFF) + 1;
return TEMPERATURE_FACTOR * (float)v * -1.0;
}
if (get_differential_mode(pair) == 0) // SINGLE ENDED
{
if ((v & 0x4000) == 0)
{
return SINGLE_ENDED_FACTOR * (float)v;
}
v = (v^0x7FFFF) + 1;
return SINGLE_ENDED_FACTOR * (float)v * -1.0;
}
// DIFFERENTIAL
if ((v & 0x4000) == 0)
{
return DIFFERENTIAL_FACTOR * (float)v;
}
v = (v^0x7FFFF) + 1;
return DIFFERENTIAL_FACTOR * (float)v * -1.0;
}
//////////////////////////////////////////////////////////////////
//
// PWM functions
//
void LTC2991::set_PWM(uint16_t value)
{
if (value > 511) value = 511;
_writeRegister(PWM_THRESHOLD_MSB, value >> 1);
if (value & 0x01) _setRegisterMask(PWM_THRESHOLD_LSB, 0x80);
else _clrRegisterMask(PWM_THRESHOLD_LSB, 0x80);
}
uint16_t LTC2991::get_PWM()
{
uint16_t pwm = _readRegister(PWM_THRESHOLD_MSB);
pwm <<= 1;
if (_readRegister(PWM_THRESHOLD_LSB) > 0 ) pwm |= 0x01;
return pwm;
}
void LTC2991::invert_PWM(bool invert)
{
if (invert) _setRegisterMask(PWM_THRESHOLD_LSB, 0x40);
else _clrRegisterMask(PWM_THRESHOLD_LSB, 0x40);
}
bool LTC2991::is_inverted_PWM()
{
return _getRegisterMask(PWM_THRESHOLD_LSB, 0x40) > 0;
}
void LTC2991::enable_PWM(bool enable)
{
if (enable) _setRegisterMask(PWM_THRESHOLD_LSB, 0x20);
else _clrRegisterMask(PWM_THRESHOLD_LSB, 0x20);
}
bool LTC2991::is_enabled_PWM()
{
return _getRegisterMask(PWM_THRESHOLD_LSB, 0x20) > 0;
}
//////////////////////////////////////////////////////////////////
//
// CONFIGURATION
//
void LTC2991::set_acquisition_repeat()
{
_setRegisterMask(PWM_THRESHOLD_LSB, 0x10);
}
void LTC2991::set_acquisition_single()
{
_clrRegisterMask(PWM_THRESHOLD_LSB, 0x10);
}
uint8_t LTC2991::get_acquisition_mode()
{
if (_getRegisterMask(PWM_THRESHOLD_LSB, 0x10) > 0) return 1;
return 0;
}
//////////////////////////////////////////////////////////////////
//
// INTERNAL SENSORS
//
void LTC2991::enable_Tintern_Vcc(bool enable)
{
if (enable) _setRegisterMask(STATUS_HIGH, 0x08);
else _clrRegisterMask(STATUS_HIGH, 0x08);
}
bool LTC2991::is_enabled_Tintern_Vcc()
{
uint8_t x = _readRegister(STATUS_HIGH);
return ((x & 0x08) > 0);
}
void LTC2991::enable_filter_Tintern(bool enable)
{
if (enable) _setRegisterMask(PWM_THRESHOLD_LSB, 0x08);
else _clrRegisterMask(PWM_THRESHOLD_LSB, 0x08);
}
bool LTC2991::is_enabled_filter_Tintern()
{
return _getRegisterMask(PWM_THRESHOLD_LSB, 0x08) > 0;
}
// true = Kelvin, false = Celsius
void LTC2991::set_temp_scale_Tintern(bool Kelvin)
{
if (Kelvin) _setRegisterMask(PWM_THRESHOLD_LSB, 0x04);
else _clrRegisterMask(PWM_THRESHOLD_LSB, 0x04);
}
char LTC2991::get_temp_scale_Tintern()
{
if (_getRegisterMask(PWM_THRESHOLD_LSB, 0x04) > 0)
{
return 'K';
}
return 'C';
}
float LTC2991::get_Tintern()
{
int16_t v = _readRegister16(T_INTERNAL_MSB);
if (get_temp_scale_Tintern() == 'K')
{
return TEMPERATURE_FACTOR * (float)v;
}
// CELSIUS positive value
if ((v & 0x1000) == 0)
{
return TEMPERATURE_FACTOR * (float)v;
}
// CELSIUS neg two complements (page 13, 2nd colom.)
v = (v^0x1FFF) + 1;
return TEMPERATURE_FACTOR * (float)v * -1.0;
}
float LTC2991::get_VCC()
{
int16_t v = _readRegister16(VCC_MSB);
if ((v & 0x4000) == 0)
{
return VCC_FACTOR * (float)v + 2.5;
}
// can Vcc be negative?
v = (v^0x7FFFF) + 1;
return VCC_FACTOR * (float)v * -1.0 + 2.5;
}
//////////////////////////////////////////////////////////////////
//
// private functions
//
uint8_t LTC2991::_writeRegister(const uint8_t reg, const uint8_t value)
{
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->write(value);
return _wire->endTransmission();
}
uint8_t LTC2991::_readRegister(const uint8_t reg)
{
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->endTransmission();
_wire->requestFrom(_address, (uint8_t)1);
return _wire->read();
}
uint16_t LTC2991::_readRegister16(const uint8_t reg)
{
uint16_t x = _readRegister(reg) << 8;
x |= _readRegister(reg + 1);
bool dataValid = (x & 0x8000) > 0; // do nothing for now...
x &= 0x7FFF;
return x;
}
void LTC2991::_setRegisterMask(const uint8_t reg, uint8_t mask)
{
uint8_t x = _readRegister(reg);
x |= mask;
_writeRegister(reg, x);
}
void LTC2991::_clrRegisterMask(const uint8_t reg, uint8_t mask)
{
uint8_t x = _readRegister(reg);
x &= ~mask;
_writeRegister(reg, x);
}
uint8_t LTC2991::_getRegisterMask(const uint8_t reg, uint8_t mask)
{
uint8_t x = _readRegister(reg);
return x & mask;
}
// -- END OF FILE --

122
libraries/LTC2991/LTC2991.h Normal file
View File

@ -0,0 +1,122 @@
#pragma once
//
// FILE: LTC2991.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// DATE: 2021-05-10
// PURPOSE: Library for LTC2991 temperature and voltage control IC
// URL: https://github.com/RobTillaart/LTC2991
#include "Arduino.h"
#include "Wire.h"
#define LTC2991_LIB_VERSION (F("0.1.0"))
class LTC2991
{
public:
explicit LTC2991(const int8_t address, TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
bool begin(uint8_t sda, uint8_t scl);
#endif
bool begin();
bool isConnected();
// REGISTER 0x00 .. 0x01
// channel = 1..8
bool new_data(uint8_t channel); // external
bool new_temperature(); // internal
bool new_voltage(); // VCC
bool is_busy();
//
// EXTERNAL CHANNELS (8 voltage or 4 temperature)
//
// n = 1 ==> V1 V2 T1
// n = 2 ==> V3 V4 T2
// n = 3 ==> V5 V6 T3
// n = 4 ==> V7 V8 T4
void enable(uint8_t n, bool enable);
bool is_enabled(uint8_t n);
// REGISTER 0x06 .. 0x07
// n: 1..4
void enable_filter(uint8_t n, bool enable);
bool is_enabled_filter(uint8_t n);
void set_Kelvin(uint8_t n); // implicit set_mode_temperature
void set_Celsius(uint8_t n); // implicit set_mode_temperature
void set_temp_scale(uint8_t n, bool Kelvin = true); // MIGHT BECOME OBSOLETE ?
// returns 'C' or 'K'
char get_temp_scale(uint8_t n);
void set_mode_temperature(uint8_t n);
void set_mode_voltage_differential(uint8_t n);
void set_mode_voltage_normal(uint8_t n);
uint8_t get_operational_mode(uint8_t n);
uint8_t get_differential_mode(uint8_t n);
// REGISTER 0x0A .. 0x19
float get_value(uint8_t channel); // chan = 1..8
//
// PWM
//
// REGISTER 0x08 .. 0x09
// value = 0..511
void set_PWM(uint16_t value);
uint16_t get_PWM();
void invert_PWM(bool invert);
bool is_inverted_PWM();
void enable_PWM(bool enable);
bool is_enabled_PWM();
//
// CONFIGURATION
//
void set_acquisition_repeat();
void set_acquisition_single();
uint8_t get_acquisition_mode();
//
// INTERNAL SENSORS
//
void enable_Tintern_Vcc(bool enable);
bool is_enabled_Tintern_Vcc();
void enable_filter_Tintern(bool enable);
bool is_enabled_filter_Tintern();
void set_Kelvin_Tintern() { set_temp_scale_Tintern(true); };
void set_Celsius_Tintern() { set_temp_scale_Tintern(false); };
void set_temp_scale_Tintern(bool Kelvin = true);
// returns 'C' or 'K'
char get_temp_scale_Tintern();
// REGISTER 0x1A .. 0x1B
float get_Tintern();
// REGISTER 0x1C .. 0x1D
float get_VCC();
private:
uint8_t _writeRegister(const uint8_t reg, const uint8_t value);
uint8_t _readRegister(const uint8_t reg);
uint16_t _readRegister16(const uint8_t reg);
void _setRegisterMask(const uint8_t reg, uint8_t mask);
void _clrRegisterMask(const uint8_t reg, uint8_t mask);
uint8_t _getRegisterMask(const uint8_t reg, uint8_t mask);
uint8_t _address;
TwoWire * _wire;
};
// -- END OF FILE --

129
libraries/LTC2991/README.md Normal file
View File

@ -0,0 +1,129 @@
[![Arduino CI](https://github.com/RobTillaart/LTC2991/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/LTC2991/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/LTC2991.svg?maxAge=3600)](https://github.com/RobTillaart/LTC2991/releases)
# LTC2991
Arduino library for an LTC2991 temperature and voltage control IC
## Description
Experimental - not tested yet
LTC2991 is an experimental library for the LTC2991 IC which is typically used to control temperature and voltage lines.
The IC supports normal voltage measurement (8 lines), differential voltage measurements (4 pairs) and temperature measurements (4 pairs). These can be combined in a mix. As the IC has only 8 inputs available one has to choose what.
Read the datasheet for the details.
## Interface
### Constructor and setup
- **LTC2991(const int8_t address, TwoWire \*wire = Wire);**
- **bool begin(uint8_t sda, uint8_t scl)** ESP32 ea initializes the class.
sets I2C pins.
returns true if the LTC2991 is on the I2C bus.
- **bool begin()** UNO ea. initializes the class.
returns true if the LTC2991 is on the I2C bus.
- **bool isConnected()** returns true if the LTC2991 is on the I2C bus.
### Status functions
- **bool new_data(uint8_t channel)** true if there is a new **external** measurement (temperature or voltage) available.
- **new_temperature()** true if there is a new **internal** temperature measurement available.
- **new_voltage()** true, if ther is a new **internal** voltage measurement available.
- **is_busy()** true if converting...
### External measurements
The following functions work on pairs
| n | selected |
|:----:|:---------:|
| 1 | V1 V2 T1 |
| 2 | V3 V4 T2 |
| 3 | V5 V6 T3 |
| 4 | V7 V8 T4 |
- **void enable(uint8_t n, bool enable)** enable or disable an external line.
- **bool is_enabled(uint8_t n)** idem
- **void enable_filter(uint8_t n, bool enable)** not investigated
- **bool is_enabled_filter(uint8_t n)** idem
- **void set_Kelvin(uint8_t n)** sets temperature mode to Kelvin,
implicit set_mode_temperature(),
- **void set_Celsius(uint8_t n)** sets temperature mode to Celsius,
implicit set_mode_temperature
- **void set_temp_scale(uint8_t n, bool Kelvin = true)** obsolete?
- **char get_temp_scale(uint8_t n)** returns 'K' or 'C'
- **void set_mode_temperature(uint8_t n)** sets operational mode
- **void set_mode_voltage_differential(uint8_t n)** sets operational mode
- **void set_mode_voltage_normal(uint8_t n)** sets operational mode
- **uint8_t get_operational_mode(uint8_t n)** returns operational mode
- **uint8_t get_differential_mode(uint8_t n)** returns differential flag
- **float get_value(uint8_t channel)** channel = 1..8;
depending on the operational mode it returns the temperature or the
(differential) voltage.
### Internal measurements
- **void enable_Tintern_Vcc(bool enable)** enable internal temperature sensor
- **bool is_enabled_Tintern_Vcc()** idem
- **void enable_filter_Tintern(bool enable)** enable filter - not investigated
- **bool is_enabled_filter_Tintern()**
- **void set_Kelvin_Tintern()** use Kelvin
- **void set_Celsius_Tintern()** use Celsius
- **void set_temp_scale_Tintern(bool Kelvin = true)** Obsolete?
- **char get_temp_scale_Tintern()** returns 'K' or 'C'
- **float get_Tintern()** returns internal temperature
- **float get_VCC()** returns the internal voltage.
### Configuration
- **void set_acquisition_repeat()** set continuous measurement mode
- **void set_acquisition_single()** set single shot mode
- **uint8_t get_acquisition_mode()** return mode set (0,1)
### PWM functions
- **void set_PWM(uint16_t value)** value is 0..511
- **uint16_t get_PWM()** idem
- **void invert_PWM(bool invert)** idem
- **bool is_inverted_PWM()** idem
- **void enable_PWM(bool enable)** idem
- **bool is_enabled_PWM()** idem
### Performance
No data available yet.
To be measured when hardware is available...
## Operational
See examples..
### TODO
- get hardware to
- test test test
- elaborate on the documentation
- more examples
COULD
- cache all registers or
- cache a number of flags to speed up retrieving data
- optimize multibyte read / write
- look for code optimizations
-

View File

@ -0,0 +1,59 @@
//
// FILE: LTC2991_PWM.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-05-13
// PUPROSE: demo
#include "Wire.h"
#include "LTC2991.h"
LTC2991 LTC(0x20);
int speed = 10;
int incr = 1;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("LTC2991_LIB_VERSION:\t");
Serial.println(LTC2991_LIB_VERSION);
Wire.begin();
Wire.setClock(100000);
LTC.begin();
while (!LTC.isConnected())
{
Serial.println("Could not connect to device");
delay(2000);
}
LTC.enable_PWM(true);
}
void loop()
{
static uint32_t lastTime = 0;
if ((millis() - lastTime) >= 100)
{
lastTime = millis();
LTC.set_PWM(speed);
if (speed == 511) incr = -1; // reverse speed
if (speed == 0) incr = 1; // reverse speed
speed += incr;
Serial.print(lastTime);
Serial.print("\t");
Serial.print(LTC.get_PWM());
Serial.println();
}
}
// -- END OF FILE --

View File

@ -0,0 +1,36 @@
//
// FILE: LTC2991_demo.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-05-10
// PUPROSE: detect device on I2C bus
#include "Wire.h"
#include "LTC2991.h"
LTC2991 LTC(0x20);
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("LTC2991_LIB_VERSION:\t");
Serial.println(LTC2991_LIB_VERSION);
Wire.begin();
Wire.setClock(100000);
LTC.begin();
while (!LTC.isConnected())
{
Serial.println("Could not connect to device");
delay(2000);
}
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,65 @@
//
// FILE: LTC2991_internal_temp_volt.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-05-13
// PUPROSE: demo monitoring Tinternal and VCC
#include "Wire.h"
#include "LTC2991.h"
LTC2991 LTC(0x20);
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("LTC2991_LIB_VERSION:\t");
Serial.println(LTC2991_LIB_VERSION);
Wire.begin();
Wire.setClock(100000);
LTC.begin();
while (!LTC.isConnected())
{
Serial.println("Could not connect to device");
delay(2000);
}
LTC.enable_Tintern_Vcc(true);
LTC.set_Kelvin_Tintern();
// to get multiple readings in loop()
LTC.set_acquisition_repeat();
}
void loop()
{
static uint32_t lastTime = 0;
if ((millis() - lastTime) >= 2000)
{
lastTime = millis();
if (LTC.new_temperature())
{
float temp = LTC.get_Tintern();
Serial.print(lastTime);
Serial.print("\tTinternal: \t");
Serial.println(temp);
}
if (LTC.new_voltage())
{
float vcc = LTC.get_VCC();
Serial.print(lastTime);
Serial.print("\tVCC: \t");
Serial.println(vcc);
}
}
}
// -- END OF FILE --

View File

@ -0,0 +1,60 @@
//
// FILE: LTC2991_read_temperature.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-05-13
// PUPROSE: demo
#include "Wire.h"
#include "LTC2991.h"
LTC2991 LTC(0x20);
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("LTC2991_LIB_VERSION:\t");
Serial.println(LTC2991_LIB_VERSION);
Wire.begin();
Wire.setClock(100000);
LTC.begin();
while (!LTC.isConnected())
{
Serial.println("Could not connect to device");
delay(2000);
}
for (uint8_t channel = 1; channel <= 4; channel++)
{
// enable all 4 temp sensors
LTC.enable(channel, true);
LTC.enable_filter(channel, false);
LTC.set_Celsius(channel);
}
// to get multiple readings in loop()
LTC.set_acquisition_repeat();
}
void loop()
{
static uint32_t lastTime = 0;
if ((millis() - lastTime) >= 2000)
{
lastTime = millis();
Serial.print(lastTime);
for (uint8_t channel = 1; channel <= 4; channel++)
{
Serial.print("\t");
Serial.print(LTC.get_value(channel));
}
Serial.println();
}
}
// -- END OF FILE --

View File

@ -0,0 +1,60 @@
//
// FILE: LTC2991_read_voltage.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-05-13
// PUPROSE: demo
#include "Wire.h"
#include "LTC2991.h"
LTC2991 LTC(0x20);
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("LTC2991_LIB_VERSION:\t");
Serial.println(LTC2991_LIB_VERSION);
Wire.begin();
Wire.setClock(100000);
LTC.begin();
while (!LTC.isConnected())
{
Serial.println("Could not connect to device");
delay(2000);
}
for (uint8_t channel = 1; channel <= 4; channel++)
{
// enable all channels ==> are enabled in pairs! )
LTC.enable(channel, true);
LTC.enable_filter(channel, false);
LTC.set_mode_voltage_normal(channel);
}
// to get multiple readings in loop()
LTC.set_acquisition_repeat();
}
void loop()
{
static uint32_t lastTime = 0;
if ((millis() - lastTime) >= 2000)
{
lastTime = millis();
Serial.print(lastTime);
for (uint8_t channel = 1; channel <= 8; channel++)
{
Serial.print("\t");
Serial.print(LTC.get_value(channel));
}
Serial.println();
}
}
// -- END OF FILE --

View File

@ -0,0 +1,57 @@
# Syntax Coloring Map For LTC2991
# Datatypes (KEYWORD1)
LTC2991 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
new_data KEYWORD2
new_temperature KEYWORD2
new_voltage KEYWORD2
is_busy KEYWORD2
enable KEYWORD2
is_enabled KEYWORD2
enable_filter KEYWORD2
is_enabled_filter KEYWORD2
set_Kelvin KEYWORD2
set_Celsius KEYWORD2
get_temp_scale KEYWORD2
set_mode_temperature KEYWORD2
set_mode_voltage_differential KEYWORD2
set_mode_voltage_normal KEYWORD2
get_operational_mode KEYWORD2
get_differential_mode KEYWORD2
get_value KEYWORD2
set_PWM KEYWORD2
get_PWM KEYWORD2
invert_PWM KEYWORD2
is_inverted_PWM KEYWORD2
enable_PWM KEYWORD2
is_enabled_PWM KEYWORD2
set_acquisition_repeat KEYWORD2
set_acquisition_single KEYWORD2
get_acquisition_mode KEYWORD2
enable_Tintern_Vcc KEYWORD2
is_enabled_Tintern_Vcc KEYWORD2
enable_filter_Tintern KEYWORD2
is_enabled_filter_Tintern KEYWORD2
set_Kelvin_Tintern KEYWORD2
set_Celsius_Tintern KEYWORD2
set_temp_scale_Tintern KEYWORD2
get_temp_scale_Tintern KEYWORD2
get_Tintern KEYWORD2
get_VCC KEYWORD2
# Constants (LITERAL1)
LTC2991_LIB_VERSION LITERAL1

View File

@ -0,0 +1,22 @@
{
"name": "LTC2991",
"keywords": "voltage temperature differential PWM",
"description": "Arduino library for a LTC2991",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/LTC2991.git"
},
"version": "0.1.0",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -0,0 +1,11 @@
name=LTC2991
version=0.1.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for LTC2991
paragraph=
category=Data Processing
url=https://github.com/RobTillaart/LTC2991
architectures=*
includes=LTC2991.h
depends=

View File

@ -0,0 +1,60 @@
//
// FILE: unit_test_001.cpp
// AUTHOR: Rob Tillaart
// DATE: 2021-01-07
// PURPOSE: unit tests for the SET library
// https://github.com/RobTillaart/SET
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
//
// supported assertions
// ----------------------------
// assertEqual(expected, actual); // a == b
// assertNotEqual(unwanted, actual); // a != b
// assertComparativeEquivalent(expected, actual); // abs(a - b) == 0 or (!(a > b) && !(a < b))
// assertComparativeNotEquivalent(unwanted, actual); // abs(a - b) > 0 or ((a > b) || (a < b))
// assertLess(upperBound, actual); // a < b
// assertMore(lowerBound, actual); // a > b
// assertLessOrEqual(upperBound, actual); // a <= b
// assertMoreOrEqual(lowerBound, actual); // a >= b
// assertTrue(actual);
// assertFalse(actual);
// assertNull(actual);
// // special cases for floats
// assertEqualFloat(expected, actual, epsilon); // fabs(a - b) <= epsilon
// assertNotEqualFloat(unwanted, actual, epsilon); // fabs(a - b) >= epsilon
// assertInfinity(actual); // isinf(a)
// assertNotInfinity(actual); // !isinf(a)
// assertNAN(arg); // isnan(a)
// assertNotNAN(arg); // !isnan(a)
#include <ArduinoUnitTests.h>
#include "LTC2991.h"
unittest_setup()
{
}
unittest_teardown()
{
}
unittest(test_constructor)
{
fprintf(stderr, "VERSION: %s\n", LTC2991_LIB_VERSION);
LTC2991(0x20);
fprintf(stderr, "no tests yet");
}
unittest_main()
// --------