Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mgrouch committed Dec 12, 2024
1 parent cb9e788 commit 5997fbc
Show file tree
Hide file tree
Showing 3 changed files with 287 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
arduino-board-fqbn: esp32:esp32:m5stack-atoms3:CDCOnBoot=cdc
arduino-platform: esp32:[email protected]
platform-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
required-libraries: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],Adafruit SGP30 [email protected],Adafruit BME680 [email protected],Adafruit VEML7700 [email protected],SparkFun AS7331 Arduino [email protected],SparkFun AS3935 Lightning Detector Arduino [email protected],[email protected],[email protected],[email protected],[email protected],[email protected]
required-libraries: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],Adafruit SGP30 [email protected],Adafruit BME680 [email protected],Adafruit VEML7700 [email protected],SparkFun AS7331 Arduino [email protected],SparkFun AS3935 Lightning Detector Arduino [email protected],[email protected],[email protected],[email protected],[email protected],[email protected]
sketch-names: "*.ino"
sketch-names-find-start: bbn_*
extra-arduino-cli-args: "--warnings default"
Expand Down
3 changes: 1 addition & 2 deletions i2c_ads1115.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#ifndef i2c_ads1115_h
#define i2c_ads1115_h

#include <M5_ADS1115.h>

#include "m5_ads1115.h"
#include "NmeaXDR.h"
#include "Nmea0183Msg.h"

Expand Down
285 changes: 285 additions & 0 deletions m5_ads1115.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
#ifndef m5_ads1115_h
#define m5_ads1115_h

#include <Arduino.h>
#include <Wire.h>
#include <I2C_Class.h>

#define ADS1115_REG_CONVERSION 0x00
#define ADS1115_REG_CONFIG 0x01
#define ADS1115_I2C_ADDR_0 0x48
#define ADS1115_I2C_ADDR_1 0x49

#define ADS1115_MV_6144 0.187500F
#define ADS1115_MV_4096 0.125000F
#define ADS1115_MV_2048 0.062500F // default
#define ADS1115_MV_1024 0.031250F
#define ADS1115_MV_512 0.015625F
#define ADS1115_MV_256 0.007813F

#define MEASURING_DIRECTION -1

typedef enum {
ADS1115_PGA_6144 = 0,
ADS1115_PGA_4096,
ADS1115_PGA_2048, // default
ADS1115_PGA_1024,
ADS1115_PGA_512,
ADS1115_PGA_256,
} ads1115_gain_t;

typedef enum {
ADS1115_RATE_8 = 0,
ADS1115_RATE_16,
ADS1115_RATE_32,
ADS1115_RATE_64,
ADS1115_RATE_128, // default
ADS1115_RATE_250,
ADS1115_RATE_475,
ADS1115_RATE_860,
} ads1115_rate_t;

typedef enum {
ADS1115_MODE_CONTINUOUS = 0,
ADS1115_MODE_SINGLESHOT, // default
} ads1115_mode_t;

class ADS1115 {
private:
I2C_Class _i2c;
uint8_t _addr;
uint8_t _epprom_addr;
float _coefficient;

public:
ads1115_gain_t _gain;
ads1115_rate_t _rate;
ads1115_mode_t _mode;

uint16_t cover_time;
int16_t adc_raw;
float _calibration_factor;

public:
bool begin(TwoWire* wire = &Wire, uint8_t addr = ADS1115_I2C_ADDR_0,
uint8_t sda = 21, uint8_t scl = 22, long freq = 400000U);

void setGain(ads1115_gain_t gain);
void setRate(ads1115_rate_t rate);
void setMode(ads1115_mode_t mode);

float getCoefficient();

float getFactoryCalibration();

int16_t getSingleConversion(uint16_t timeout = 125);
int16_t getAdcRaw();

bool isInConversion();
void startSingleConversion();

void setEEPROMAddr(uint8_t addr);

void setCalibration(int8_t voltage, uint16_t actual);
bool saveCalibration(ads1115_gain_t gain, int16_t hope, int16_t actual);
bool readCalibration(ads1115_gain_t gain, int16_t* hope, int16_t* actual);
};

bool ADS1115::begin(TwoWire* wire, uint8_t addr, uint8_t sda, uint8_t scl,
long freq) {
_i2c.begin(wire, sda, scl, freq);
_addr = addr;
_coefficient = 0.0;
_calibration_factor = 0.0;
return _i2c.exist(_addr);
}

void ADS1115::setEEPROMAddr(uint8_t addr) {
_epprom_addr = addr;
}

float ADS1115::getCoefficient() {
return _coefficient;
}

float ADS1115::getFactoryCalibration() {
return _calibration_factor;
}

void ADS1115::setGain(ads1115_gain_t gain) {
uint16_t reg_value = 0;
bool result = _i2c.readU16(_addr, ADS1115_REG_CONFIG, &reg_value);

if (result == false) {
return;
}

reg_value &= ~(0b0111 << 9);
reg_value |= gain << 9;

result = _i2c.writeU16(_addr, ADS1115_REG_CONFIG, reg_value);

if (result) {
_gain = gain;
int16_t hope = 1;
int16_t actual = 1;
if (readCalibration(gain, &hope, &actual)) {
_calibration_factor = fabs((double)hope / actual);
}

switch (_gain) {
case ADS1115_PGA_6144:
_coefficient = ADS1115_MV_6144;
break;
case ADS1115_PGA_4096:
_coefficient = ADS1115_MV_4096;
break;
case ADS1115_PGA_2048:
_coefficient = ADS1115_MV_2048;
break;
case ADS1115_PGA_1024:
_coefficient = ADS1115_MV_1024;
break;
case ADS1115_PGA_512:
_coefficient = ADS1115_MV_512;
break;
case ADS1115_PGA_256:
_coefficient = ADS1115_MV_256;
break;
default:
break;
}
}
}

void ADS1115::setRate(ads1115_rate_t rate) {
uint16_t reg_value = 0;
bool result = _i2c.readU16(_addr, ADS1115_REG_CONFIG, &reg_value);
if (result == false) {
return;
}

reg_value &= ~(0b0111 << 5);
reg_value |= rate << 5;

result = _i2c.writeU16(_addr, ADS1115_REG_CONFIG, reg_value);

if (result) {
_rate = rate;
}

return;
}

/*! @brief Set read continuous read/single read data */
void ADS1115::setMode(ads1115_mode_t mode) {
uint16_t reg_value = 0;
bool result = _i2c.readU16(_addr, ADS1115_REG_CONFIG, &reg_value);
if (result == false) {
return;
}

reg_value &= ~(0b0001 << 8);
reg_value |= mode << 8;

result = _i2c.writeU16(_addr, ADS1115_REG_CONFIG, reg_value);
if (result) {
_mode = mode;
}

return;
}

/*! @brief Determine if data is being converted
@return Data being converted returns 1, otherwise 0.. */
bool ADS1115::isInConversion() {
uint16_t value = 0x00;
_i2c.readU16(_addr, ADS1115_REG_CONFIG, &value);

return (value & (1 << 15)) ? false : true;
}

/*! @brief Turn on single data conversion */
void ADS1115::startSingleConversion() {
uint16_t reg_value = 0;
bool result = _i2c.readU16(_addr, ADS1115_REG_CONFIG, &reg_value);

if (result == false) {
return;
}

reg_value &= ~(0b0001 << 15);
reg_value |= 0x01 << 15;

_i2c.writeU16(_addr, ADS1115_REG_CONFIG, reg_value);
}

int16_t ADS1115::getAdcRaw() {
uint16_t value = 0x00;
_i2c.readU16(_addr, ADS1115_REG_CONVERSION, &value);
adc_raw = value;
return value;
}

int16_t ADS1115::getSingleConversion(uint16_t timeout) {
if (_mode == ADS1115_MODE_SINGLESHOT) {
startSingleConversion();
delay(cover_time);
uint64_t time = millis() + timeout;
while (time > millis() && isInConversion())
;
}

return getAdcRaw() * MEASURING_DIRECTION;
}

bool ADS1115::saveCalibration(ads1115_gain_t gain, int16_t hope,
int16_t actual) {
if (hope == 0 || actual == 0) {
return false;
}

uint8_t buff[8];
memset(buff, 0, 8);
buff[0] = gain;
buff[1] = hope >> 8;
buff[2] = hope & 0xFF;

buff[3] = actual >> 8;
buff[4] = actual & 0xFF;

for (uint8_t i = 0; i < 5; i++) {
buff[5] ^= buff[i];
}

uint8_t reg = 0xd0 + gain * 8;
return _i2c.writeBytes(_epprom_addr, reg, buff, 8);
}

bool ADS1115::readCalibration(ads1115_gain_t gain, int16_t* hope,
int16_t* actual) {
uint8_t reg = 0xd0 + gain * 8;
uint8_t buff[8];
memset(buff, 0, 8);

bool result = _i2c.readBytes(_epprom_addr, reg, buff, 8);

if (result == false) {
return false;
}

uint8_t xor_result = 0x00;
for (uint8_t i = 0; i < 5; i++) {
xor_result ^= buff[i];
}

if (xor_result != buff[5]) {
return false;
}

*hope = (buff[1] << 8) | buff[2];
*actual = (buff[3] << 8) | buff[4];
return true;
}

#endif

0 comments on commit 5997fbc

Please sign in to comment.