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.

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