PlantCtrl/esp32test/Esp32DeepSleepTest/src/DS2438.cpp

287 lines
8.0 KiB
C++
Raw Normal View History

2021-01-30 23:28:15 +01:00
/*
* DS2438.cpp
*
* by Joe Bechter
*
* (C) 2012, bechter.com
*
* All files, software, schematics and designs are provided as-is with no warranty.
* All files, software, schematics and designs are for experimental/hobby use.
* Under no circumstances should any part be used for critical systems where safety,
* life or property depends upon it. You are responsible for all use.
* You are free to use, modify, derive or otherwise extend for your own non-commercial purposes provided
* 1. No part of this software or design may be used to cause injury or death to humans or animals.
* 2. Use is non-commercial.
* 3. Credit is given to the author (i.e. portions © bechter.com), and provide a link to the original source.
*
*/
#include "DS2438.h"
// DSROM FIELDS
#define DSROM_FAMILY 0
#define DSROM_CRC 7
#define DS2438MODEL 0x26
2021-01-31 00:14:15 +01:00
DS2438::DS2438(OneWire *ow, float currentShunt = 1.0f) {
2021-01-30 23:28:15 +01:00
_ow = ow;
2021-01-31 00:14:15 +01:00
_currentShunt = currentShunt;
2021-01-30 23:28:15 +01:00
};
void DS2438::begin(){
DeviceAddress searchDeviceAddress;
_ow->reset_search();
memset(searchDeviceAddress,0, 8);
_temperature = 0;
_voltageA = 0.0;
_voltageB = 0.0;
_error = true;
_mode = (DS2438_MODE_CHA | DS2438_MODE_CHB | DS2438_MODE_TEMPERATURE);
deviceFound = false; // Reset the number of devices when we enumerate wire devices
while (_ow->search(searchDeviceAddress)) {
if (validAddress(searchDeviceAddress)) {
if (validFamily(searchDeviceAddress)) {
memcpy(_address,searchDeviceAddress,8);
2021-02-16 21:35:46 +01:00
DEFAULT_PAGE0(defaultConfig);
writePage(0, defaultConfig);
2021-01-30 23:28:15 +01:00
deviceFound = true;
}
}
}
}
bool DS2438::isFound(){
return deviceFound;
}
bool DS2438::validAddress(const uint8_t* deviceAddress) {
return (_ow->crc8(deviceAddress, 7) == deviceAddress[DSROM_CRC]);
}
bool DS2438::validFamily(const uint8_t* deviceAddress) {
switch (deviceAddress[DSROM_FAMILY]) {
case DS2438MODEL:
return true;
default:
return false;
}
}
void DS2438::update() {
uint8_t data[9];
_error = true;
if(!isFound()){
return;
}
if (_mode & DS2438_MODE_CHA || _mode == DS2438_MODE_TEMPERATURE) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE;
if (!startConversion(DS2438_CHA, doTemperature)) {
Serial.println("Error starting temp conversion ds2438 channel a");
return;
}
if (!readPage(0, data)){
2021-02-04 23:52:54 +01:00
2021-01-30 23:28:15 +01:00
Serial.println("Error reading zero page ds2438 channel a");
return;
}
2021-02-04 23:52:54 +01:00
Serial.print(data[0],16);
Serial.print(" ");
Serial.print(data[1],16);
Serial.print(" ");
Serial.print(data[2],16);
Serial.print(" ");
Serial.print(data[3],16);
Serial.print(" ");
Serial.print(data[4],16);
Serial.print(" ");
Serial.print(data[5],16);
Serial.print(" ");
Serial.print(data[6],16);
Serial.print(" ");
Serial.println(data[7],16);
2021-01-30 23:28:15 +01:00
if (doTemperature) {
_temperature = (double)(((((int16_t)data[2]) << 8) | (data[1] & 0x0ff)) >> 3) * 0.03125;
}
if (_mode & DS2438_MODE_CHA) {
_voltageA = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
}
if (_mode & DS2438_MODE_CHB) {
boolean doTemperature = _mode & DS2438_MODE_TEMPERATURE && !(_mode & DS2438_MODE_CHA);
if (!startConversion(DS2438_CHB, doTemperature)) {
Serial.println("Error starting temp conversion channel b ds2438");
return;
}
if (!readPage(0, data)){
2021-01-30 23:28:15 +01:00
Serial.println("Error reading zero page ds2438 channel b");
return;
}
if (doTemperature) {
int16_t upperByte = ((int16_t)data[2]) << 8;
int16_t lowerByte = data[1] >> 3;
int16_t fullByte = (upperByte | lowerByte);
_temperature = ((double)fullByte) * 0.03125;
}
_voltageB = (((data[4] << 8) & 0x00300) | (data[3] & 0x0ff)) / 100.0;
}
2021-01-31 00:14:15 +01:00
int16_t upperByte = ((int16_t)data[6]) << 8;
int16_t lowerByte = data[5];
2021-02-04 23:52:54 +01:00
int16_t fullByte = (int16_t)(upperByte | lowerByte);
float fullByteb = fullByte;
_current = (fullByteb) / ((4096.0f * _currentShunt));
2021-01-30 23:28:15 +01:00
_error = false;
2021-02-04 23:52:54 +01:00
Serial.print(data[0],16);
Serial.print(" ");
Serial.print(data[1],16);
Serial.print(" ");
Serial.print(data[2],16);
Serial.print(" ");
Serial.print(data[3],16);
Serial.print(" ");
Serial.print(data[4],16);
Serial.print(" ");
Serial.print(data[5],16);
Serial.print(" ");
Serial.print(data[6],16);
Serial.print(" ");
Serial.println(data[7],16);
Serial.println("-");
2021-02-04 21:10:21 +01:00
2021-02-16 21:35:46 +01:00
uint16_t ICA = 0;
2021-02-04 23:52:54 +01:00
if (readPage(1, data)){
2021-02-16 21:35:46 +01:00
PageOne_t *pOne = (PageOne_t *) data;
Serial.println(pOne->ICA);
float Ah = pOne->ICA / (2048.0f * _currentShunt);
Serial.print("Ah=");
2021-02-04 23:52:54 +01:00
Serial.println(Ah);
2021-02-16 21:35:46 +01:00
ICA = pOne->ICA;
}
2021-02-04 23:52:54 +01:00
2021-02-16 21:35:46 +01:00
if (readPage(7, data)){
PageSeven_t *pSeven = (PageSeven_t *) data;
int16_t CCA = pSeven->CCA0 | ((int16_t) pSeven->CCA1) << 8;
int16_t DCA = pSeven->DCA0 | ((int16_t) pSeven->DCA1) << 8;
Serial.println("ICA, DCA, CCA");
Serial.print(ICA);
Serial.print(", ");
Serial.print(DCA);
Serial.print(", ");
Serial.println(CCA);
2021-02-04 23:52:54 +01:00
}
2021-01-30 23:28:15 +01:00
}
double DS2438::getTemperature() {
return _temperature;
}
float DS2438::getVoltage(int channel) {
if (channel == DS2438_CHA) {
return _voltageA;
} else if (channel == DS2438_CHB) {
return _voltageB;
} else {
return 0.0;
}
}
2021-01-31 00:14:15 +01:00
float DS2438::getCurrent() {
return _current;
}
2021-01-30 23:28:15 +01:00
boolean DS2438::isError() {
return _error;
}
boolean DS2438::startConversion(int channel, boolean doTemperature) {
if(!isFound()){
return false;
}
if (!selectChannel(channel)){
return false;
}
_ow->reset();
_ow->select(_address);
if (doTemperature) {
_ow->write(DS2438_TEMPERATURE_CONVERSION_COMMAND, 0);
delay(DS2438_TEMPERATURE_DELAY);
_ow->reset();
_ow->select(_address);
}
_ow->write(DS2438_VOLTAGE_CONVERSION_COMMAND, 0);
delay(DS2438_VOLTAGE_CONVERSION_DELAY);
return true;
}
boolean DS2438::selectChannel(int channel) {
if(!isFound()){
return false;
}
uint8_t data[9];
if (readPage(0, data)) {
2021-01-30 23:28:15 +01:00
if (channel == DS2438_CHB){
data[0] = data[0] | 0x08;
}
else {
data[0] = data[0] & 0xf7;
}
writePage(0, data);
2021-01-30 23:28:15 +01:00
return true;
}
Serial.println("Could not read page zero data");
return false;
}
void DS2438::writePage(int page, uint8_t *data) {
2021-01-30 23:28:15 +01:00
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_WRITE_SCRATCHPAD_COMMAND, 0);
if ((page >= PAGE_MIN) && (page <= PAGE_MAX)) {
_ow->write(page, 0);
} else {
return;
}
2021-01-30 23:28:15 +01:00
for (int i = 0; i < 8; i++){
_ow->write(data[i], 0);
}
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_COPY_SCRATCHPAD_COMMAND, 0);
_ow->write(page, 0);
2021-01-30 23:28:15 +01:00
}
boolean DS2438::readPage(int page, uint8_t *data) {
2021-02-16 21:45:13 +01:00
//TODO if all data is 0 0 is a valid crc, but most likly not as intended
2021-01-30 23:28:15 +01:00
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_RECALL_MEMORY_COMMAND, 0);
if ((page >= PAGE_MIN) && (page <= PAGE_MAX)) {
_ow->write(page, 0);
} else {
return false;
}
2021-01-30 23:28:15 +01:00
_ow->reset();
_ow->select(_address);
_ow->write(DS2438_READ_SCRATCHPAD_COMMAND, 0);
_ow->write(page, 0);
2021-01-30 23:28:15 +01:00
for (int i = 0; i < 9; i++){
data[i] = _ow->read();
}
return _ow->crc8(data, 8) == data[8];
}