GY-63_MS5611/libraries/AGS02MA/AGS02MA.cpp

373 lines
6.9 KiB
C++
Raw Normal View History

2021-08-13 07:08:52 -04:00
//
// FILE: AGS02MA.cpp
2022-04-25 08:17:43 -04:00
// AUTHOR: Rob Tillaart, Viktor Balint, Beanow
2021-08-13 07:08:52 -04:00
// DATE: 2021-08-12
2022-05-02 07:50:27 -04:00
// VERSION: 0.3.0
2021-08-13 07:08:52 -04:00
// PURPOSE: Arduino library for AGS02MA TVOC
// URL: https://github.com/RobTillaart/AGS02MA
#include "AGS02MA.h"
// REGISTERS
#define AGS02MA_DATA 0x00
#define AGS02MA_CALIBRATION 0x01
#define AGS02MA_VERSION 0x11
#define AGS02MA_SLAVE_ADDRESS 0x21
AGS02MA::AGS02MA(const uint8_t deviceAddress, TwoWire *wire)
{
2021-09-24 06:31:48 -04:00
_address = deviceAddress;
_wire = wire;
reset();
2021-08-13 07:08:52 -04:00
}
#if defined (ESP8266) || defined(ESP32)
bool AGS02MA::begin(uint8_t dataPin, uint8_t clockPin)
{
_startTime = millis(); // PREHEAT
_wire = &Wire;
if ((dataPin < 255) && (clockPin < 255))
{
_wire->begin(dataPin, clockPin);
} else {
_wire->begin();
}
return isConnected();
}
#endif
bool AGS02MA::begin()
{
_startTime = millis(); // PREHEAT TIMING
_wire->begin();
return isConnected();
}
bool AGS02MA::isConnected()
{
#if defined (__AVR__)
2021-08-15 13:35:40 -04:00
TWBR = 255;
2021-08-13 07:08:52 -04:00
#else
_wire->setClock(AGS02MA_I2C_CLOCK);
#endif
_wire->beginTransmission(_address);
2021-08-15 13:35:40 -04:00
bool rv = ( _wire->endTransmission(true) == 0);
_wire->setClock(_I2CResetSpeed);
2021-08-13 07:08:52 -04:00
return rv;
}
2021-09-24 06:31:48 -04:00
void AGS02MA::reset()
{
_I2CResetSpeed = 100000;
_startTime = millis();
_lastRead = 0;
_lastPPB = 0;
_mode = 255;
_status = AGS02MA_OK;
_error = AGS02MA_OK;
}
2021-08-13 07:08:52 -04:00
bool AGS02MA::setAddress(const uint8_t deviceAddress)
{
2021-09-24 06:31:48 -04:00
if ((deviceAddress < 10) or (deviceAddress > 119)) return false;
2021-08-13 07:08:52 -04:00
_buffer[2] = _buffer[0] = deviceAddress;
_buffer[3] = _buffer[1] = 0xFF ^ deviceAddress;
_buffer[4] = _CRC8(_buffer, 4);
if (_writeRegister(AGS02MA_SLAVE_ADDRESS))
{
_address = deviceAddress;
}
return isConnected();
}
uint8_t AGS02MA::getSensorVersion()
{
uint8_t version = 0xFF;
if (_readRegister(AGS02MA_VERSION))
{
2021-09-24 06:31:48 -04:00
// for (int i = 0; i < 5; i++)
// {
// Serial.print(_buffer[i]);
// Serial.print('\t');
// }
// Serial.println();
// unclear what the other bytes have for information.
// datasheet names these 3 bytes as KEEP.
// BUFFER VALUE MEANING
// buffer [0] == 20 year ?
// buffer [1] == 07 month ?
// buffer [2] == 28 day ?
// buffer [3] == 117 VERSION
// buffer [4] == CRC
2021-08-13 07:08:52 -04:00
version = _buffer[3];
if (_CRC8(_buffer, 5) != 0)
{
2021-09-24 06:31:48 -04:00
_error = AGS02MA_ERROR_CRC;
2021-08-13 07:08:52 -04:00
}
}
return version;
}
2022-01-22 04:17:50 -05:00
uint32_t AGS02MA::getSensorDate()
{
uint32_t date = 0xFFFFFFFF;
if (_readRegister(AGS02MA_VERSION))
{
date = 0x20;
date <<= 8;
date += _bin2bcd(_buffer[0]);
date <<= 8;
date += _bin2bcd(_buffer[1]);
date <<= 8;
date += _bin2bcd(_buffer[2]);
// version = _buffer[3];
if (_CRC8(_buffer, 5) != 0)
{
_error = AGS02MA_ERROR_CRC;
}
}
return date;
}
2021-08-13 07:08:52 -04:00
bool AGS02MA::setPPBMode()
{
_buffer[0] = 0x00;
_buffer[1] = 0xFF;
_buffer[2] = 0x00;
_buffer[3] = 0xFF;
_buffer[4] = 0x30;
if (_writeRegister(AGS02MA_DATA))
{
_mode = 0;
return true;
}
return false;
}
bool AGS02MA::setUGM3Mode()
{
_buffer[0] = 0x02;
_buffer[1] = 0xFD;
_buffer[2] = 0x02;
_buffer[3] = 0xFD;
_buffer[4] = 0x00;
if (_writeRegister(AGS02MA_DATA))
{
_mode = 1;
return true;
}
return false;
}
uint32_t AGS02MA::readPPB()
{
2021-09-24 06:31:48 -04:00
uint32_t val = _readSensor();
if (_error == AGS02MA_OK)
2021-08-13 07:08:52 -04:00
{
2021-09-24 06:31:48 -04:00
_lastRead = millis();
_lastPPB = val;
}
else
{
val = _lastPPB;
2021-08-13 07:08:52 -04:00
}
return val;
}
uint32_t AGS02MA::readUGM3()
{
2021-09-24 06:31:48 -04:00
uint32_t val = _readSensor();
if (_error == AGS02MA_OK)
2021-08-13 07:08:52 -04:00
{
2021-09-24 06:31:48 -04:00
_lastRead = millis();
_lastUGM3 = val;
}
else
{
val = _lastUGM3;
2021-08-13 07:08:52 -04:00
}
return val;
}
2022-04-25 08:17:43 -04:00
bool AGS02MA::manualZeroCalibration(uint16_t value)
2021-08-13 07:08:52 -04:00
{
_buffer[0] = 0x00;
_buffer[1] = 0x0C;
2022-04-25 08:17:43 -04:00
_buffer[2] = (uint8_t) (value >> 8);
_buffer[3] = (uint8_t) (value & 0x00FF);
_buffer[4] = _CRC8(_buffer, 4);
2021-08-13 07:08:52 -04:00
return _writeRegister(AGS02MA_CALIBRATION);
}
2022-04-25 08:17:43 -04:00
bool AGS02MA::getZeroCalibrationData(AGS02MA::ZeroCalibrationData &data) {
if (!_readRegister(AGS02MA_CALIBRATION))
{
return false;
}
if (_CRC8(_buffer, 5) != 0)
{
_error = AGS02MA_ERROR_CRC;
return false;
}
_error = AGS02MA_OK;
// Don't pollute the struct given to us, until we've handled all error cases.
data.status = _getDataMSB();
data.value = _getDataLSB();
return true;
}
2021-08-13 07:08:52 -04:00
int AGS02MA::lastError()
{
int e = _error;
_error = AGS02MA_OK; // reset error after read
return e;
}
2022-05-02 07:50:27 -04:00
bool AGS02MA::readRegister(uint8_t address, AGS02MA::RegisterData &reg) {
if (!_readRegister(address))
{
return false;
}
_error = AGS02MA_OK;
// Don't pollute the struct given to us, until we've handled all error cases.
reg.data[0] = _buffer[0];
reg.data[1] = _buffer[1];
reg.data[2] = _buffer[2];
reg.data[3] = _buffer[3];
reg.crc = _buffer[4];
reg.crcValid = _CRC8(_buffer, 5) == 0;
return true;
}
2021-08-13 07:08:52 -04:00
/////////////////////////////////////////////////////////
//
// PRIVATE
//
2021-09-24 06:31:48 -04:00
uint32_t AGS02MA::_readSensor()
{
_error = AGS02MA_ERROR_READ;
2022-01-22 04:17:50 -05:00
uint32_t value = 0;
2021-09-24 06:31:48 -04:00
if (_readRegister(AGS02MA_DATA))
{
_error = AGS02MA_OK;
_status = _buffer[0];
2022-01-22 04:17:50 -05:00
if (_status & 0x01)
{
_error = AGS02MA_ERROR_NOT_READY;
}
value = _buffer[1] * 65536UL;
value += _buffer[2] * 256;
value += _buffer[3];
2021-09-24 06:31:48 -04:00
if (_CRC8(_buffer, 5) != 0)
{
_error = AGS02MA_ERROR_CRC;
}
}
2022-01-22 04:17:50 -05:00
return value;
2021-09-24 06:31:48 -04:00
}
2022-04-25 08:17:43 -04:00
2021-09-24 06:31:48 -04:00
2021-08-13 07:08:52 -04:00
bool AGS02MA::_readRegister(uint8_t reg)
{
2021-09-24 06:31:48 -04:00
while (millis() - _lastRegTime < 30) yield();
2021-08-13 07:08:52 -04:00
#if defined (__AVR__)
2021-08-15 13:35:40 -04:00
TWBR = 255;
2021-08-13 07:08:52 -04:00
#else
_wire->setClock(AGS02MA_I2C_CLOCK);
#endif
_wire->beginTransmission(_address);
_wire->write(reg);
2021-08-15 13:35:40 -04:00
_error = _wire->endTransmission(true);
delay(30);
2021-08-13 07:08:52 -04:00
if (_wire->requestFrom(_address, (uint8_t)5) != 5)
{
2021-09-24 06:31:48 -04:00
_error = AGS02MA_ERROR_READ;
2021-08-15 13:35:40 -04:00
_wire->setClock(_I2CResetSpeed);
2021-08-13 07:08:52 -04:00
return false;
}
2021-09-24 06:31:48 -04:00
for (uint8_t i = 0; i < 5; i++)
2021-08-13 07:08:52 -04:00
{
_buffer[i] = _wire->read();
}
2021-08-15 13:35:40 -04:00
_wire->setClock(_I2CResetSpeed);
2021-08-13 07:08:52 -04:00
return true;
}
bool AGS02MA::_writeRegister(uint8_t reg)
{
2021-09-24 06:31:48 -04:00
while (millis() - _lastRegTime < 30) yield();
_lastRegTime = millis();
2021-08-13 07:08:52 -04:00
#if defined (__AVR__)
2021-08-15 13:35:40 -04:00
TWBR = 255;
2021-08-13 07:08:52 -04:00
#else
_wire->setClock(AGS02MA_I2C_CLOCK);
#endif
_wire->beginTransmission(_address);
_wire->write(reg);
2021-09-24 06:31:48 -04:00
for (uint8_t i = 0; i < 5; i++)
2021-08-13 07:08:52 -04:00
{
_wire->write(_buffer[i]);
}
2021-08-15 13:35:40 -04:00
_error = _wire->endTransmission(true);
_wire->setClock(_I2CResetSpeed);
2021-08-13 07:08:52 -04:00
return (_error == 0);
}
2022-04-25 08:17:43 -04:00
uint16_t AGS02MA::_getDataMSB()
{
return (_buffer[0] << 8) + _buffer[1];
}
uint16_t AGS02MA::_getDataLSB()
{
return (_buffer[2] << 8) + _buffer[3];
}
2021-08-13 07:08:52 -04:00
uint8_t AGS02MA::_CRC8(uint8_t * buf, uint8_t size)
{
uint8_t crc = 0xFF; // start value
for (uint8_t b = 0; b < size; b++)
{
crc ^= buf[b];
for (uint8_t i = 0; i < 8; i++)
{
if (crc & 0x80) crc = (crc << 1) ^ 0x31;
else crc = (crc << 1);
}
}
return crc;
}
2022-01-22 04:17:50 -05:00
uint8_t AGS02MA::_bin2bcd (uint8_t value)
{
return value + 6 * (value / 10);
}
2021-08-13 07:08:52 -04:00
// -- END OF FILE --