I have a LTC2487 ADC wired up using I2C.
Extract from the data sheet below
Have successfully used the wire library to convert a 24bit reading to the voltage.
Code is below
I feel like there should have been an easier way to convert the output without if statements etc
The chip programmers thought a 24 bit message with one status bit, 17 bits two's complement binary number and then 6 zeroes would be an easy convert?
I think the binary would convert to integer fine if it was a 16 bit two's complement number.
Just occurred to me - maybe I should just lose the least significant bit.
Any thoughts - please school me! I have long but very sporadic experience in various programming languages.
Thanks in advance!
// Wire Master Reader
// by devyte
// based on the example of the same name by Nicholas Zambetti <http://www.zambetti.com>
// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this
// This example code is in the public domain.
#include <Wire.h>
#include <PolledTimeout.h>
#define SDA_PIN 4
#define SCL_PIN 5
const int16_t I2C_MASTER = 0x42;
const int16_t I2C_SLAVE = 0x24; //ltc2487
void setup() {
Serial.begin(9600); // start serial for output
Wire.begin(SDA_PIN, SCL_PIN, I2C_MASTER); // join i2c bus (address optional for master)
}
void loop() {
using periodic = esp8266::polledTimeout::periodicMs;
static periodic nextPing(1000);
if (nextPing) {
Wire.requestFrom(I2C_SLAVE, 3); // request 6 bytes from slave device #8
int result = 0;
while (Wire.available()) { // slave may send less than requested
byte c = Wire.read(); // receive a byte
result = (result << 8) + c;
//Serial.print (c);
prntBits(c, 8); // print byte
Serial.print(" ");
}
Serial.println();
prntBits(result, 24);
Serial.print(" ");
bool neg = (result & 0b010000000000000000000000) >> 22 ; // bit 22
int binvalue = (result & 0b001111111111111111000000) >> 6; // bits 21-6
long attempt = (result & 0b011111111111111111000000) >> 6; // bits 22-6 - try to get signed int from 17 bit twos complement
Serial.print (attempt); //doesn't work as presumes it's 32 bit binary
Serial.print (" ");
float value;
Serial.print (neg);
Serial.print(" ");
prntBits(binvalue, 16);
Serial.print(" ");
Serial.print(binvalue);
Serial.print(" ");
if (neg == 1) {
binvalue = binvalue ^ 0xffff; //invert bits
value = binvalue / (float)0xffff * -1.0; // number between 0 and -1
}
else {
value = (binvalue / (float)0xffff); //number between 0 and 1
}
float voltage = (3.26 / 2) * value ; // ref = 3.26v
Serial.print(value, 5);
Serial.print(" ");
Serial.print(voltage, 5);
Serial.println();
Serial.println();
}
}
void prntBits(long b, byte length)
{
for (int i = length; i >= 1; i--)
Serial.print(bitRead(b, i - 1));
}
TYPICAL OUTPUT -
01010101 10100001 00000000
010101011010000100000000 87684 1 0101011010000100 22148 -0.66204 -1.07913
10101010 01011110 00000000
101010100101111000000000 43384 0 1010100101111000 43384 0.66200 1.07906
ltc2487 p16 (2).pdf (55.7 KB)