mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-03 12:20:43 +00:00
WIP Sen5X functions
This commit is contained in:
parent
94df0cb636
commit
d7bb0f7cdf
@ -200,5 +200,3 @@ lib_deps =
|
||||
sensirion/Sensirion Core@0.7.1
|
||||
# renovate: datasource=custom.pio depName=Sensirion I2C SCD4x packageName=sensirion/library/Sensirion I2C SCD4x
|
||||
sensirion/Sensirion I2C SCD4x@1.1.0
|
||||
# renovate: datasource=custom.pio depName=Sensirion I2C SEN5X packageName=sensirion/library/Sensirion I2C SEN5X
|
||||
sensirion/Sensirion I2C SEN5X
|
@ -9,10 +9,6 @@
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
#include "meshUtils.h" // vformat
|
||||
|
||||
#define SEN50_NAME 48
|
||||
#define SEN54_NAME 52
|
||||
#define SEN55_NAME 53
|
||||
|
||||
#endif
|
||||
|
||||
bool in_array(uint8_t *array, int size, uint8_t lookfor)
|
||||
@ -114,6 +110,58 @@ uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation
|
||||
return value;
|
||||
}
|
||||
|
||||
/// for SEN5X detection
|
||||
bool probeSEN5X(const ScanI2C::DeviceAddress& addr, TwoWire* i2cBus) {
|
||||
uint8_t cmd[] = { 0xD0, 0x33 }; // Read Serial Number command
|
||||
uint8_t rxBuf[9] = {0};
|
||||
|
||||
i2cBus->beginTransmission(addr.address);
|
||||
i2cBus->write(cmd, 2);
|
||||
if (i2cBus->endTransmission() != 0)
|
||||
return false;
|
||||
|
||||
delay(20); // wait for response
|
||||
|
||||
if (i2cBus->requestFrom(addr.address, (uint8_t)9) != 9)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 9 && i2cBus->available(); ++i)
|
||||
rxBuf[i] = i2cBus->read();
|
||||
|
||||
return true;
|
||||
}
|
||||
String readSEN5xProductName(TwoWire* i2cBus, uint8_t address) {
|
||||
uint8_t cmd[] = { 0xD0, 0x14 };
|
||||
uint8_t response[48] = {0};
|
||||
|
||||
i2cBus->beginTransmission(address);
|
||||
i2cBus->write(cmd, 2);
|
||||
if (i2cBus->endTransmission() != 0) return "";
|
||||
|
||||
delay(20);
|
||||
if (i2cBus->requestFrom(address, (uint8_t)48) != 48) return "";
|
||||
|
||||
for (int i = 0; i < 48 && i2cBus->available(); ++i) {
|
||||
response[i] = i2cBus->read();
|
||||
}
|
||||
|
||||
char productName[33] = {0};
|
||||
int j = 0;
|
||||
for (int i = 0; i < 48 && j < 32; i += 3) {
|
||||
if (response[i] >= 32 && response[i] <= 126)
|
||||
productName[j++] = response[i];
|
||||
else
|
||||
break;
|
||||
|
||||
if (response[i + 1] >= 32 && response[i + 1] <= 126)
|
||||
productName[j++] = response[i + 1];
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return String(productName);
|
||||
}
|
||||
|
||||
#define SCAN_SIMPLE_CASE(ADDR, T, ...) \
|
||||
case ADDR: \
|
||||
logFoundDevice(__VA_ARGS__); \
|
||||
@ -131,6 +179,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
DeviceAddress addr(port, 0x00);
|
||||
|
||||
uint16_t registerValue = 0x00;
|
||||
String prod = "";
|
||||
ScanI2C::DeviceType type;
|
||||
TwoWire *i2cBus;
|
||||
#ifdef RV3028_RTC
|
||||
@ -473,40 +522,25 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR
|
||||
// ICM20948 Register check
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
||||
prod = readSEN5xProductName(i2cBus, addr.address);
|
||||
if (registerValue == 0xEA) {
|
||||
type = ICM20948;
|
||||
logFoundDevice("ICM20948", (uint8_t)addr.address);
|
||||
break;
|
||||
} else {
|
||||
// TODO refurbish to find the model
|
||||
// Just a hack for the hackathon
|
||||
if (addr.address == SEN5X_ADDR) {
|
||||
if (prod.startsWith("SEN55")) {
|
||||
type = SEN5X;
|
||||
logFoundDevice("SEN5X", (uint8_t)addr.address);
|
||||
logFoundDevice("Sensirion SEN55", addr.address);
|
||||
break;
|
||||
} else if (prod.startsWith("SEN54")) {
|
||||
type = SEN5X;
|
||||
logFoundDevice("Sensirion SEN54", addr.address);
|
||||
break;
|
||||
} else if (prod.startsWith("SEN50")) {
|
||||
type = SEN5X;
|
||||
logFoundDevice("Sensirion SEN50", addr.address);
|
||||
break;
|
||||
}
|
||||
|
||||
// We can get the 0xD014 register to find the model. This is not a simple task
|
||||
// There is a buffer returned - getRegisterValue is not enough (maybe)
|
||||
// registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD014), 6);
|
||||
// Important to leave delay
|
||||
// delay(50);
|
||||
|
||||
// const uint8_t nameSize = 48;
|
||||
// uint8_t name[nameSize] = ®isterValue;
|
||||
|
||||
// switch(name[4]){
|
||||
// case SEN50_NAME:
|
||||
// type = SEN50;
|
||||
// break;
|
||||
// case SEN54_NAME:
|
||||
// type = SEN54;
|
||||
// break;
|
||||
// case SEN55_NAME:
|
||||
// type = SEN55;
|
||||
// break;
|
||||
// }
|
||||
|
||||
if (addr.address == BMX160_ADDR) {
|
||||
type = BMX160;
|
||||
logFoundDevice("BMX160", (uint8_t)addr.address);
|
||||
|
@ -24,7 +24,12 @@ PMSA003ISensor pmsa003iSensor;
|
||||
NullSensor pmsa003iSensor;
|
||||
#endif
|
||||
|
||||
#if __has_include(<SensirionI2CSen5x.h>)
|
||||
// Small hack
|
||||
#ifndef INCLUDE_SEN5X
|
||||
#define INCLUDE_SEN5X 1
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_SEN5X
|
||||
#include "Sensor/SEN5XSensor.h"
|
||||
SEN5XSensor sen5xSensor;
|
||||
#else
|
||||
|
@ -1,14 +1,169 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<SensirionI2CSen5x.h>)
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "SEN5XSensor.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include <SensirionI2CSen5x.h>
|
||||
|
||||
SEN5XSensor::SEN5XSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SEN5X, "SEN5X") {}
|
||||
|
||||
bool SEN5XSensor::getVersion()
|
||||
{
|
||||
if (!sendCommand(SEN5X_GET_FIRMWARE_VERSION)){
|
||||
LOG_ERROR("SEN5X: Error sending version command");
|
||||
return false;
|
||||
}
|
||||
delay(20); // From Sensirion Arduino library
|
||||
|
||||
uint8_t versionBuffer[12];
|
||||
size_t charNumber = readBuffer(&versionBuffer[0], 3);
|
||||
if (charNumber == 0) {
|
||||
LOG_ERROR("SEN5X: Error getting data ready flag value");
|
||||
return false;
|
||||
}
|
||||
|
||||
firmwareVer = versionBuffer[0] + (versionBuffer[1] / 10);
|
||||
hardwareVer = versionBuffer[3] + (versionBuffer[4] / 10);
|
||||
protocolVer = versionBuffer[5] + (versionBuffer[6] / 10);
|
||||
|
||||
LOG_INFO("SEN5X Firmware Version: %d", firmwareVer);
|
||||
LOG_INFO("SEN5X Hardware Version: %d", hardwareVer);
|
||||
LOG_INFO("SEN5X Protocol Version: %d", protocolVer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SEN5XSensor::findModel()
|
||||
{
|
||||
if (!sendCommand(SEN5X_GET_PRODUCT_NAME)) {
|
||||
LOG_ERROR("SEN5X: Error asking for product name");
|
||||
return false;
|
||||
}
|
||||
delay(50); // From Sensirion Arduino library
|
||||
|
||||
const uint8_t nameSize = 48;
|
||||
uint8_t name[nameSize];
|
||||
size_t charNumber = readBuffer(&name[0], nameSize);
|
||||
if (charNumber == 0) {
|
||||
LOG_ERROR("SEN5X: Error getting device name");
|
||||
return false;
|
||||
}
|
||||
|
||||
// We only check the last character that defines the model SEN5X
|
||||
switch(name[4])
|
||||
{
|
||||
case 48:
|
||||
model = SEN50;
|
||||
LOG_INFO("SEN5X: found sensor model SEN50");
|
||||
break;
|
||||
case 52:
|
||||
model = SEN54;
|
||||
LOG_INFO("SEN5X: found sensor model SEN54");
|
||||
break;
|
||||
case 53:
|
||||
model = SEN55;
|
||||
LOG_INFO("SEN5X: found sensor model SEN55");
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SEN5XSensor::sendCommand(uint16_t command)
|
||||
{
|
||||
uint8_t nothing;
|
||||
return sendCommand(command, ¬hing, 0);
|
||||
}
|
||||
|
||||
bool SEN5XSensor::sendCommand(uint16_t command, uint8_t* buffer, uint8_t byteNumber)
|
||||
{
|
||||
// At least we need two bytes for the command
|
||||
uint8_t bufferSize = 2;
|
||||
|
||||
// Add space for CRC bytes (one every two bytes)
|
||||
if (byteNumber > 0) bufferSize += byteNumber + (byteNumber / 2);
|
||||
|
||||
uint8_t toSend[bufferSize];
|
||||
uint8_t i = 0;
|
||||
toSend[i++] = static_cast<uint8_t>((command & 0xFF00) >> 8);
|
||||
toSend[i++] = static_cast<uint8_t>((command & 0x00FF) >> 0);
|
||||
|
||||
// Prepare buffer with CRC every third byte
|
||||
uint8_t bi = 0;
|
||||
if (byteNumber > 0) {
|
||||
while (bi < byteNumber) {
|
||||
toSend[i++] = buffer[bi++];
|
||||
toSend[i++] = buffer[bi++];
|
||||
uint8_t calcCRC = CRC(&buffer[bi - 2]);
|
||||
toSend[i++] = calcCRC;
|
||||
}
|
||||
}
|
||||
|
||||
// Transmit the data
|
||||
bus->beginTransmission(address);
|
||||
size_t writtenBytes = bus->write(toSend, bufferSize);
|
||||
uint8_t i2c_error = bus->endTransmission();
|
||||
|
||||
if (writtenBytes != bufferSize) {
|
||||
LOG_ERROR("SEN5X: Error writting on I2C bus");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i2c_error != 0) {
|
||||
LOG_ERROR("SEN5X: Error on I2c communication: %x", i2c_error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t SEN5XSensor::readBuffer(uint8_t* buffer, uint8_t byteNumber)
|
||||
{
|
||||
size_t readedBytes = bus->requestFrom(address, byteNumber);
|
||||
|
||||
if (readedBytes != byteNumber) {
|
||||
LOG_ERROR("SEN5X: Error reading I2C bus");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t i = 0;
|
||||
uint8_t receivedBytes = 0;
|
||||
while (readedBytes > 0) {
|
||||
buffer[i++] = bus->read(); // Just as a reminder: i++ returns i and after that increments.
|
||||
buffer[i++] = bus->read();
|
||||
uint8_t recvCRC = bus->read();
|
||||
uint8_t calcCRC = CRC(&buffer[i - 2]);
|
||||
if (recvCRC != calcCRC) {
|
||||
LOG_ERROR("SEN5X: Checksum error while receiving msg");
|
||||
return 0;
|
||||
}
|
||||
readedBytes -=3;
|
||||
receivedBytes += 2;
|
||||
}
|
||||
|
||||
return receivedBytes;
|
||||
}
|
||||
|
||||
uint8_t SEN5XSensor::CRC(uint8_t* buffer)
|
||||
{
|
||||
// This code is based on Sensirion's own implementation https://github.com/Sensirion/arduino-core/blob/41fd02cacf307ec4945955c58ae495e56809b96c/src/SensirionCrc.cpp
|
||||
uint8_t crc = 0xff;
|
||||
|
||||
for (uint8_t i=0; i<2; i++){
|
||||
|
||||
crc ^= buffer[i];
|
||||
|
||||
for (uint8_t bit=8; bit>0; bit--) {
|
||||
if (crc & 0x80)
|
||||
crc = (crc << 1) ^ 0x31;
|
||||
else
|
||||
crc = (crc << 1);
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
int32_t SEN5XSensor::runOnce()
|
||||
{
|
||||
LOG_INFO("Init sensor: %s", sensorName);
|
||||
@ -16,29 +171,53 @@ int32_t SEN5XSensor::runOnce()
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
|
||||
sen5x.begin(*nodeTelemetrySensorsMap[sensorType].second);
|
||||
bus = nodeTelemetrySensorsMap[sensorType].second;
|
||||
// sen5x.begin(*bus);
|
||||
|
||||
delay(25); // without this there is an error on the deviceReset function (NOT WORKING)
|
||||
delay(50); // without this there is an error on the deviceReset function
|
||||
|
||||
uint16_t error;
|
||||
char errorMessage[256];
|
||||
error = sen5x.deviceReset();
|
||||
if (error) {
|
||||
LOG_INFO("Error trying to execute deviceReset(): ");
|
||||
errorToString(error, errorMessage, 256);
|
||||
LOG_INFO(errorMessage);
|
||||
if (!sendCommand(SEN5X_RESET)) {
|
||||
LOG_ERROR("SEN5X: Error reseting device");
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
delay(200); // From Sensirion Arduino library
|
||||
|
||||
if (!findModel()) {
|
||||
LOG_ERROR("SEN5X: error finding sensor model");
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
}
|
||||
|
||||
error = sen5x.startMeasurement();
|
||||
if (error) {
|
||||
LOG_INFO("Error trying to execute startMeasurement(): ");
|
||||
errorToString(error, errorMessage, 256);
|
||||
LOG_INFO(errorMessage);
|
||||
// Check if firmware version allows The direct switch between Measurement and RHT/Gas-Only Measurement mode
|
||||
if (!getVersion()) return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
if (firmwareVer < 2) {
|
||||
LOG_ERROR("SEN5X: error firmware is too old and will not work with this implementation");
|
||||
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
} else {
|
||||
}
|
||||
|
||||
// Detection succeeded
|
||||
state = SEN5X_IDLE;
|
||||
status = 1;
|
||||
}
|
||||
LOG_INFO("SEN5X Enabled");
|
||||
|
||||
// uint16_t error;
|
||||
// char errorMessage[256];
|
||||
// error = sen5x.deviceReset();
|
||||
// if (error) {
|
||||
// LOG_INFO("Error trying to execute deviceReset(): ");
|
||||
// errorToString(error, errorMessage, 256);
|
||||
// LOG_INFO(errorMessage);
|
||||
// return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
// }
|
||||
|
||||
// error = sen5x.startMeasurement();
|
||||
// if (error) {
|
||||
// LOG_INFO("Error trying to execute startMeasurement(): ");
|
||||
// errorToString(error, errorMessage, 256);
|
||||
// LOG_INFO(errorMessage);
|
||||
// return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||
// } else {
|
||||
// status = 1;
|
||||
// }
|
||||
|
||||
return initI2CSensor();
|
||||
}
|
||||
@ -47,26 +226,24 @@ void SEN5XSensor::setup()
|
||||
{
|
||||
#ifdef SEN5X_ENABLE_PIN
|
||||
pinMode(SEN5X_ENABLE_PIN, OUTPUT);
|
||||
digitalWrite(SEN5X_ENABLE_PIN, HIGH);
|
||||
delay(25);
|
||||
#endif /* SEN5X_ENABLE_PIN */
|
||||
}
|
||||
|
||||
#ifdef SEN5X_ENABLE_PIN
|
||||
void SEN5XSensor::sleep() {
|
||||
digitalWrite(SEN5X_ENABLE_PIN, LOW);
|
||||
state = State::IDLE;
|
||||
}
|
||||
// void SEN5XSensor::sleep() {
|
||||
// digitalWrite(SEN5X_ENABLE_PIN, LOW);
|
||||
// state = SSEN5XState::SEN5X_OFF;
|
||||
// }
|
||||
|
||||
uint32_t SEN5XSensor::wakeUp() {
|
||||
digitalWrite(SEN5X_ENABLE_PIN, HIGH);
|
||||
state = State::ACTIVE;
|
||||
return SEN5X_WARMUP_MS;
|
||||
}
|
||||
// uint32_t SEN5XSensor::wakeUp() {
|
||||
// digitalWrite(SEN5X_ENABLE_PIN, HIGH);
|
||||
// state = SEN5XState::SEN5X_IDLE;
|
||||
// return SEN5X_WARMUP_MS;
|
||||
// }
|
||||
#endif /* SEN5X_ENABLE_PIN */
|
||||
|
||||
bool SEN5XSensor::isActive() {
|
||||
return state == State::ACTIVE;
|
||||
}
|
||||
|
||||
bool SEN5XSensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
uint16_t error;
|
||||
@ -82,24 +259,24 @@ bool SEN5XSensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
float vocIndex;
|
||||
float noxIndex;
|
||||
|
||||
error = sen5x.readMeasuredValues(
|
||||
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
||||
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
||||
noxIndex);
|
||||
// error = sen5x.readMeasuredValues(
|
||||
// massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
|
||||
// massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
|
||||
// noxIndex);
|
||||
|
||||
if (error) {
|
||||
LOG_INFO("Error trying to execute readMeasuredValues(): ");
|
||||
errorToString(error, errorMessage, 256);
|
||||
LOG_INFO(errorMessage);
|
||||
return false;
|
||||
}
|
||||
// if (error) {
|
||||
// LOG_INFO("Error trying to execute readMeasuredValues(): ");
|
||||
// errorToString(error, errorMessage, 256);
|
||||
// LOG_INFO(errorMessage);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
measurement->variant.air_quality_metrics.has_pm10_standard = true;
|
||||
measurement->variant.air_quality_metrics.pm10_standard = massConcentrationPm1p0;
|
||||
measurement->variant.air_quality_metrics.has_pm25_standard = true;
|
||||
measurement->variant.air_quality_metrics.pm25_standard = massConcentrationPm2p5;
|
||||
measurement->variant.air_quality_metrics.has_pm100_standard = true;
|
||||
measurement->variant.air_quality_metrics.pm100_standard = massConcentrationPm10p0;
|
||||
// measurement->variant.air_quality_metrics.has_pm10_standard = true;
|
||||
// measurement->variant.air_quality_metrics.pm10_standard = massConcentrationPm1p0;
|
||||
// measurement->variant.air_quality_metrics.has_pm25_standard = true;
|
||||
// measurement->variant.air_quality_metrics.pm25_standard = massConcentrationPm2p5;
|
||||
// measurement->variant.air_quality_metrics.has_pm100_standard = true;
|
||||
// measurement->variant.air_quality_metrics.pm100_standard = massConcentrationPm10p0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,38 +1,64 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<SensirionI2CSen5x.h>)
|
||||
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include <SensirionI2CSen5x.h>
|
||||
#include "Wire.h"
|
||||
// #include <SensirionI2CSen5x.h>
|
||||
|
||||
#ifndef SEN5X_WARMUP_MS
|
||||
// from the SEN5X datasheet
|
||||
#define SEN5X_WARMUP_MS_SMALL 30000
|
||||
#define SEN5X_WARMUP_MS 30000
|
||||
#endif
|
||||
|
||||
class SEN5XSensor : public TelemetrySensor
|
||||
{
|
||||
private:
|
||||
SensirionI2CSen5x sen5x;
|
||||
// PM25_AQI_Data pmsa003iData = {0};
|
||||
TwoWire * bus;
|
||||
uint8_t address;
|
||||
|
||||
bool getVersion();
|
||||
float firmwareVer = -1;
|
||||
float hardwareVer = -1;
|
||||
float protocolVer = -1;
|
||||
bool findModel();
|
||||
|
||||
// Commands
|
||||
#define SEN5X_RESET 0xD304
|
||||
#define SEN5X_GET_PRODUCT_NAME 0xD014
|
||||
#define SEN5X_GET_FIRMWARE_VERSION 0xD100
|
||||
#define SEN5X_START_MEASUREMENT 0x0021
|
||||
#define SEN5X_START_MEASUREMENT_RHT_GAS 0x0037
|
||||
#define SEN5X_STOP_MEASUREMENT 0x0104
|
||||
#define SEN5X_READ_DATA_READY 0x0202
|
||||
#define SEN5X_START_FAN_CLEANING 0x5607
|
||||
#define SEN5X_RW_VOCS_STATE 0x6181
|
||||
|
||||
#define SEN5X_READ_VALUES 0x03C4
|
||||
#define SEN5X_READ_RAW_VALUES 0x03D2
|
||||
#define SEN5X_READ_PM_VALUES 0x0413
|
||||
|
||||
enum SEN5Xmodel { SEN5X_UNKNOWN = 0, SEN50 = 0b001, SEN54 = 0b010, SEN55 = 0b100 };
|
||||
SEN5Xmodel model = SEN5X_UNKNOWN;
|
||||
|
||||
enum SEN5XState { SEN5X_OFF, SEN5X_IDLE, SEN5X_MEASUREMENT, SEN5X_MEASUREMENT_2, SEN5X_CLEANING, SEN5X_NOT_DETECTED };
|
||||
SEN5XState state = SEN5X_OFF;
|
||||
|
||||
bool sendCommand(uint16_t wichCommand);
|
||||
bool sendCommand(uint16_t wichCommand, uint8_t* buffer, uint8_t byteNumber=0);
|
||||
uint8_t readBuffer(uint8_t* buffer, uint8_t byteNumber); // Return number of bytes received
|
||||
uint8_t CRC(uint8_t* buffer);
|
||||
|
||||
protected:
|
||||
virtual void setup() override;
|
||||
|
||||
public:
|
||||
enum State {
|
||||
IDLE = 0,
|
||||
ACTIVE = 1,
|
||||
};
|
||||
|
||||
#ifdef SEN5X_ENABLE_PIN
|
||||
void sleep();
|
||||
uint32_t wakeUp();
|
||||
State state = State::IDLE;
|
||||
#else
|
||||
State state = State::ACTIVE;
|
||||
#endif
|
||||
// #ifdef SEN5X_ENABLE_PIN
|
||||
// void sleep();
|
||||
// uint32_t wakeUp();
|
||||
// #endif
|
||||
|
||||
SEN5XSensor();
|
||||
bool isActive();
|
||||
|
Loading…
Reference in New Issue
Block a user