Skip to content

Commit

Permalink
Merge pull request #208 from kike-canaries/m5AirQS3
Browse files Browse the repository at this point in the history
M5AirQ S3 Support
  • Loading branch information
hpsaturn authored Mar 8, 2024
2 parents 711acff + 689712b commit b605255
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 17 deletions.
32 changes: 32 additions & 0 deletions examples/m5airq/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
src_dir = .
lib_dir = ../..
extra_configs = ../../unified-lib-deps.ini

[env]
framework = arduino
upload_speed = 1500000
monitor_speed = 115200
build_flags =
-D CORE_DEBUG_LEVEL=0
-D ARDUINO_USB_CDC_ON_BOOT=1
-D ARDUINO_ESP32_DEV=1
-D M5AIRQ=1 ; in your implementation you NEED it (it will improved in the future)
lib_deps =
${commonlibs.lib_deps}

[env:m5airq]
extends = env
platform = espressif32
board = esp32-s3-devkitc-1
board_build.filesystem = littlefs ; compatibility with original demo firmware
96 changes: 96 additions & 0 deletions examples/m5airq/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* @file main.cpp
* @author Antonio Vanegas @hpsaturn
* @date June 2018 - 2024
* @brief CanAirIO M5AirQ test
* @license GPL3
*
* Full documentation:
* https://github.com/kike-canaries/canairio_sensorlib#canairio-air-quality-sensors-library
*
* Full implementation for WiFi and Bluetooth Air Quality fixed and mobile station:
* https://github.com/kike-canaries/canairio_firmware#canairio-firmware
*
* CanAirIO project documentation:
* https://canair.io/docs
*/

#include <Arduino.h>

#include <Sensors.hpp>

#define POWER_HOLD 46 // M5AirQ main board
#define SEN55_POWER_EN 10

#define GROVE_SDA 13
#define GROVE_SCL 15

#define I2C1_SDA_PIN 11
#define I2C1_SCL_PIN 12

void printSensorsDetected() {
uint16_t sensors_count = sensors.getSensorsRegisteredCount();
uint16_t units_count = sensors.getUnitsRegisteredCount();
Serial.println("-->[MAIN] Sensors detected \t: " + String(sensors_count));
Serial.println("-->[MAIN] Sensors units count\t: " + String(units_count));
Serial.print("-->[MAIN] Sensors devices names\t: ");
int i = 0;
while (sensors.getSensorsRegistered()[i++] != 0) {
Serial.print(sensors.getSensorName((SENSORS)sensors.getSensorsRegistered()[i - 1]));
Serial.print(",");
}
Serial.println();
}

void printSensorsValues() {
Serial.println("-->[MAIN] Preview sensor values :");
UNIT unit = sensors.getNextUnit();
while (unit != UNIT::NUNIT) {
String uName = sensors.getUnitName(unit);
float uValue = sensors.getUnitValue(unit);
String uSymb = sensors.getUnitSymbol(unit);
Serial.printf("-->[MAIN] %6s:\t%02.1f\t%s\n", uName.c_str(), uValue, uSymb.c_str());
unit = sensors.getNextUnit();
}
}

void onSensorDataOk() {
Serial.println("======= E X A M P L E T E S T =========");
printSensorsDetected();
printSensorsValues();
}

void onSensorDataError(const char* msg) {}
/******************************************************************************
* M A I N
******************************************************************************/

void powerEnableSensors() {
Serial.println("-->[POWR] == enable sensors ==");
pinMode(POWER_HOLD, OUTPUT);
digitalWrite(POWER_HOLD, HIGH);
pinMode(SEN55_POWER_EN, OUTPUT);
digitalWrite(SEN55_POWER_EN, LOW);
}

void setup() {
Serial.begin(115200);
delay(2000); // Only for debugging
powerEnableSensors(); // M5AirQ enable sensors

delay(100);
Serial.println("\n== Sensor test setup ==\n");
Serial.println("-->[SETUP] Detecting sensors..");

sensors.setSampleTime(10); // config sensors sample time interval
sensors.setOnDataCallBack(&onSensorDataOk); // all data read callback
sensors.setDebugMode(false); // [optional] debug mode
sensors.detectI2COnly(true); // not force to only i2c sensors
sensors.setTemperatureUnit(TEMPUNIT::CELSIUS); // comment for Celsius or set Fahrenheit
sensors.init(); // Auto detection (UART and i2c sensors)
delay(1000);
}

void loop() {
sensors.loop(); // read sensor data and showed it
}
43 changes: 27 additions & 16 deletions src/Sensors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ bool Sensors::readAllSensors() {
}
enableWire1();

sen5xRead();
CO2scd30Read();
GCJA5Read();
sps30Read();
Expand Down Expand Up @@ -1068,12 +1067,17 @@ void Sensors::sen5xRead() {
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex, noxIndex);

if (error) return;
if (error) {
DEBUG("[E][SLIB] SEN5x read error!");
return;
}

pm1 = massConcentrationPm1p0;
pm25 = massConcentrationPm2p5;
pm4 = massConcentrationPm4p0;
pm10 = massConcentrationPm4p0;
pm1 = (u_int16_t)massConcentrationPm1p0;
pm25 = (u_int16_t)massConcentrationPm2p5;
pm4 = (u_int16_t)massConcentrationPm4p0;
pm10 = (u_int16_t)massConcentrationPm4p0;
voci = vocIndex;
noxi = noxIndex;
temp = ambientTemperature;
humi = ambientHumidity;
dataReady = true;
Expand All @@ -1084,6 +1088,8 @@ void Sensors::sen5xRead() {
unitRegister(UNIT::PM10);
unitRegister(UNIT::TEMP);
unitRegister(UNIT::HUM);
unitRegister(UNIT::VOCI);
unitRegister(UNIT::NOXI);
}

void Sensors::GCJA5Read() {
Expand Down Expand Up @@ -1738,21 +1744,22 @@ void Sensors::setSCD4xAltitudeOffset(float offset) {
/// Panasonic SEN5X sensor init
void Sensors::sen5xInit() {
sensorAnnounce(SENSORS::SSEN5X);
#ifndef Wire1
sen5x.begin(Wire);
#else
sen5x.begin(Wire1);
#endif
uint16_t error;
error = sen5x.deviceReset();
if (error) return;
float tempOffset = 0.0;
DEBUG("-->[SLIB] SEN5X Temp offset\t:",
String(sen5x.getTemperatureOffsetSimple(tempOffset)).c_str());
sen5x.getTemperatureOffsetSimple(tempOffset);
DEBUG("-->[SLIB] SEN5X Temp offset\t:", String(tempOffset).c_str());
if (uint16_t((tempOffset * 100)) != (uint16_t(toffset * 100))) {
sen5x.setTemperatureOffsetSimple(toffset);
delay(10);
}
error = sen5x.startMeasurement();
if (error) {
DEBUG("[E][SLIB] Error trying to execute startMeasurement():");
return;
}
sensorRegister(SENSORS::SSEN5X);
}

Expand Down Expand Up @@ -1956,13 +1963,13 @@ void Sensors::startI2C() {
#ifdef M5ATOM
enableWire1();
#endif
#if not defined(M5STICKCPLUS) && not defined(M5COREINK) && not defined(M5ATOM) && \
not defined(ESP32C3)
Wire.begin();
#endif
#ifdef ESP32C3
Wire.begin(19, 18);
#endif
#ifdef M5AIRQ
Wire.begin(I2C1_SDA_PIN, I2C1_SCL_PIN);
enableWire1();
#endif
}

void Sensors::enableWire1() {
Expand All @@ -1978,6 +1985,10 @@ void Sensors::enableWire1() {
Wire1.flush();
Wire1.begin(26, 32); // M5CoreInk Ext port (default for all sensors)
#endif
#ifdef M5AIRQ
Wire1.flush();
Wire1.begin(GROVE_SDA, GROVE_SCL);
#endif
}

void Sensors::disableWire1() {
Expand Down
13 changes: 12 additions & 1 deletion src/Sensors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@
#define EXT_I2C_SDA 32
#define EXT_I2C_SCL 33

#ifdef M5AIRQ
#define GROVE_SDA 13
#define GROVE_SCL 15
#define I2C1_SDA_PIN 11
#define I2C1_SCL_PIN 12
#endif

// Read UART sensor retry.
#define SENSOR_RETRY 1000 // Max Serial characters

Expand Down Expand Up @@ -111,6 +118,8 @@
X(NH3, "ppm", "NH3") \
X(CO, "ppm", "CO") \
X(NO2, "ppm", "NO2") \
X(NOXI, "noxi", "NOXI") \
X(VOCI, "voci", "VOCI") \
X(UCOUNT, "COUNT", "UCOUNT")

#define X(unit, symbol, name) unit,
Expand Down Expand Up @@ -391,7 +400,9 @@ class Sensors {
float temp = 0.0; // Temperature (°C)
float pres = 0.0; // Pressure
float alt = 0.0;
float gas = 0.0; //
float gas = 0.0;
float voci = 0.0;
float noxi = 0.0;

// temperature unit (C,K,F)
TEMPUNIT temp_unit = TEMPUNIT::CELSIUS;
Expand Down

0 comments on commit b605255

Please sign in to comment.