Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.3 KiB

  1. // -----------------------------------------------------------------------------
  2. // MICS-5525 (and MICS-4514) CO Analog Sensor
  3. // Copyright (C) 2019 by Xose Pérez <xose dot perez at gmail dot com>
  4. // -----------------------------------------------------------------------------
  5. #if SENSOR_SUPPORT && MICS5525_SUPPORT
  6. #pragma once
  7. #include "BaseAnalogSensor.h"
  8. extern "C" {
  9. #include "../libs/fs_math.h"
  10. }
  11. class MICS5525Sensor : public BaseAnalogSensor {
  12. public:
  13. // ---------------------------------------------------------------------
  14. // Public
  15. // ---------------------------------------------------------------------
  16. MICS5525Sensor() {
  17. _count = 2;
  18. _sensor_id = SENSOR_MICS5525_ID;
  19. }
  20. void calibrate() {
  21. setR0(_getResistance());
  22. }
  23. // ---------------------------------------------------------------------
  24. void setAnalogGPIO(unsigned char gpio) {
  25. _redGPIO = gpio;
  26. }
  27. unsigned char getAnalogGPIO() {
  28. return _redGPIO;
  29. }
  30. // ---------------------------------------------------------------------
  31. // Sensor API
  32. // ---------------------------------------------------------------------
  33. // Initialization method, must be idempotent
  34. void begin() {
  35. pinMode(_redGPIO, INPUT);
  36. _ready = true;
  37. }
  38. // Pre-read hook (usually to populate registers with up-to-date data)
  39. void pre() {
  40. _Rs = _getResistance();
  41. }
  42. // Descriptive name of the sensor
  43. String description() {
  44. return String("MICS-5525 @ TOUT");
  45. }
  46. // Descriptive name of the slot # index
  47. String description(unsigned char index) {
  48. return description();
  49. };
  50. // Address of the sensor (it could be the GPIO or I2C address)
  51. String address(unsigned char index) {
  52. return String("0");
  53. }
  54. // Type for slot # index
  55. unsigned char type(unsigned char index) {
  56. if (0 == index) return MAGNITUDE_RESISTANCE;
  57. if (1 == index) return MAGNITUDE_CO;
  58. return MAGNITUDE_NONE;
  59. }
  60. // Current value for slot # index
  61. double value(unsigned char index) {
  62. if (0 == index) return _Rs;
  63. if (1 == index) return _getPPM();
  64. return 0;
  65. }
  66. private:
  67. unsigned long _getReading() {
  68. return analogRead(_redGPIO);
  69. }
  70. double _getResistance() {
  71. // get voltage (1 == reference) from analog pin
  72. double voltage = (float) _getReading() / 1024.0;
  73. // schematic: 3v3 - Rs - P - Rl - GND
  74. // V(P) = 3v3 * Rl / (Rs + Rl)
  75. // Rs = 3v3 * Rl / V(P) - Rl = Rl * ( 3v3 / V(P) - 1)
  76. // 3V3 voltage is cancelled
  77. double resistance = (voltage > 0) ? _Rl * ( 1 / voltage - 1 ) : 0;
  78. return resistance;
  79. }
  80. double _getPPM() {
  81. // According to the datasheet (https://airqualityegg.wikispaces.com/file/view/mics-5525-CO.pdf)
  82. return 764.2976 * fs_pow(2.71828, -7.6389 * ((float) _Rs / _R0));
  83. }
  84. unsigned char _redGPIO = MICS5525_RED_PIN;
  85. };
  86. #endif // SENSOR_SUPPORT && MICS5525_SUPPORT