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.

184 lines
4.8 KiB

  1. /*
  2. POWER EMON MODULE
  3. Copyright (C) 2016-2017 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #if (POWER_PROVIDER == POWER_PROVIDER_EMON_ANALOG) || (POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121)
  6. // -----------------------------------------------------------------------------
  7. // MODULE GLOBALS AND CACHE
  8. // -----------------------------------------------------------------------------
  9. #include <EmonLiteESP.h>
  10. EmonLiteESP _emon;
  11. #if POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
  12. #if I2C_USE_BRZO
  13. #include "brzo_i2c.h"
  14. #else
  15. #include "Wire.h"
  16. #endif
  17. // ADC121 Registers
  18. #define ADC121_REG_RESULT 0x00
  19. #define ADC121_REG_ALERT 0x01
  20. #define ADC121_REG_CONFIG 0x02
  21. #define ADC121_REG_LIMITL 0x03
  22. #define ADC121_REG_LIMITH 0x04
  23. #define ADC121_REG_HYST 0x05
  24. #define ADC121_REG_CONVL 0x06
  25. #define ADC121_REG_CONVH 0x07
  26. #endif // POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
  27. // -----------------------------------------------------------------------------
  28. // HAL
  29. // -----------------------------------------------------------------------------
  30. unsigned int currentCallback() {
  31. #if POWER_PROVIDER == POWER_PROVIDER_EMON_ANALOG
  32. return analogRead(A0);
  33. #endif // POWER_PROVIDER == POWER_PROVIDER_EMON_ANALOG
  34. #if POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
  35. unsigned int value;
  36. #if I2C_USE_BRZO
  37. uint8_t buffer[2];
  38. i2cStart(ADC121_I2C_ADDRESS);
  39. buffer[0] = ADC121_REG_RESULT;
  40. brzo_i2c_write(buffer, 1, false);
  41. brzo_i2c_read(buffer, 2, false);
  42. brzo_i2c_end_transaction();
  43. value = (buffer[0] & 0x0F) << 8;
  44. value |= buffer[1];
  45. #else
  46. Wire.beginTransmission(ADC121_I2C_ADDRESS);
  47. Wire.write(ADC121_REG_RESULT);
  48. Wire.endTransmission();
  49. Wire.requestFrom(ADC121_I2C_ADDRESS, 2);
  50. value = (Wire.read() & 0x0F) << 8;
  51. value = value + Wire.read();
  52. #endif
  53. return value;
  54. #endif // POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
  55. }
  56. // -----------------------------------------------------------------------------
  57. // POWER API
  58. // -----------------------------------------------------------------------------
  59. double _powerCurrent() {
  60. static unsigned long last = 0;
  61. static double current = 0;
  62. if (millis() - last > 1000) {
  63. last = millis();
  64. current = _emon.getCurrent(EMON_SAMPLES);
  65. current -= EMON_CURRENT_OFFSET;
  66. if (current < 0) current = 0;
  67. }
  68. return current;
  69. }
  70. double _powerVoltage() {
  71. return _power_voltage;
  72. }
  73. double _powerActivePower() {
  74. return 0;
  75. }
  76. double _powerApparentPower() {
  77. return _powerCurrent() * _powerVoltage();
  78. }
  79. double _powerReactivePower() {
  80. return 0;
  81. }
  82. double _powerPowerFactor() {
  83. return 1;
  84. }
  85. void _powerEnabledProvider() {
  86. // Nothing to do
  87. }
  88. void _powerCalibrateProvider(unsigned char magnitude, double value) {
  89. if (value <= 0) return;
  90. if (magnitude == POWER_MAGNITUDE_ACTIVE) {
  91. double power = _powerApparentPower();
  92. double ratio = getSetting("pwrRatioC", EMON_CURRENT_RATIO).toFloat();
  93. ratio = ratio * (value / power);
  94. _emon.setCurrentRatio(ratio);
  95. setSetting("pwrRatioC", ratio);
  96. saveSettings();
  97. }
  98. if (magnitude == POWER_MAGNITUDE_VOLTAGE) {
  99. _power_voltage = value;
  100. setSetting("pwrVoltage", value);
  101. saveSettings();
  102. }
  103. }
  104. void _powerResetCalibrationProvider() {
  105. delSetting("pwrRatioC");
  106. _powerConfigureProvider();
  107. saveSettings();
  108. }
  109. void _powerConfigureProvider() {
  110. _emon.setCurrentRatio(getSetting("pwrRatioC", EMON_CURRENT_RATIO).toFloat());
  111. _power_voltage = getSetting("pwrVoltage", POWER_VOLTAGE).toFloat();
  112. }
  113. void _powerSetupProvider() {
  114. _emon.initCurrent(currentCallback, EMON_ADC_BITS, EMON_REFERENCE_VOLTAGE, EMON_CURRENT_RATIO);
  115. #if POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121
  116. #if I2C_USE_BRZO
  117. uint8_t buffer[2];
  118. buffer[0] = ADC121_REG_CONFIG;
  119. buffer[1] = 0x00;
  120. brzo_i2c_start_transaction(ADC121_I2C_ADDRESS, I2C_SCL_FREQUENCY);
  121. brzo_i2c_write(buffer, 2, false);
  122. brzo_i2c_end_transaction();
  123. #else
  124. Wire.beginTransmission(ADC121_I2C_ADDRESS);
  125. Wire.write(ADC121_REG_CONFIG);
  126. Wire.write(0x00);
  127. Wire.endTransmission();
  128. #endif
  129. #endif
  130. _emon.warmup();
  131. }
  132. void _powerLoopProvider(bool before) {
  133. if (before) {
  134. static unsigned long last = 0;
  135. if (millis() - last > powerReadInterval()) {
  136. last = millis();
  137. _power_newdata = true;
  138. }
  139. }
  140. }
  141. #endif // (POWER_PROVIDER == POWER_PROVIDER_EMON_ANALOG) || (POWER_PROVIDER == POWER_PROVIDER_EMON_ADC121)