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.

81 lines
1.8 KiB

  1. /*
  2. EmonLiteESP
  3. Energy Monitor Library for ESP8266 based on EmonLib
  4. Currently only support current sensing
  5. */
  6. #include "Arduino.h"
  7. #include "EmonLiteESP.h"
  8. void EnergyMonitor::initCurrent(current_c callback, double ref, double ratio) {
  9. _currentCallback = callback;
  10. _referenceVoltage = ref;
  11. _currentRatio = ratio;
  12. _currentMidPoint = (ADC_COUNTS>>1);
  13. calculatePrecision();
  14. };
  15. void EnergyMonitor::calculatePrecision() {
  16. _currentFactor = _currentRatio * _referenceVoltage / ADC_COUNTS;
  17. _precision = 0;
  18. _multiplier = 1;
  19. while (_multiplier * _currentFactor < 1) {
  20. _multiplier *= 10;
  21. ++_precision;
  22. }
  23. --_precision;
  24. _multiplier /= 10;
  25. }
  26. void EnergyMonitor::setReference(double ref) {
  27. _referenceVoltage = ref;
  28. }
  29. void EnergyMonitor::setCurrentRatio(double ratio) {
  30. _currentRatio = ratio;
  31. }
  32. byte EnergyMonitor::getPrecision() {
  33. return _precision;
  34. }
  35. void EnergyMonitor::setPrecision(byte precision) {
  36. _precision = precision;
  37. _multiplier = 1;
  38. for (byte i=0; i<_precision; i++) _multiplier *= 10;
  39. }
  40. double EnergyMonitor::getCurrent(unsigned int samples) {
  41. int sample;
  42. double filtered;
  43. double sum;
  44. for (unsigned int n = 0; n < samples; n++) {
  45. // Read analog value
  46. sample = _currentCallback();
  47. // Digital low pass filter extracts the VDC offset
  48. _currentMidPoint = (_currentMidPoint + (sample - _currentMidPoint) / 10.0);
  49. filtered = sample - _currentMidPoint;
  50. // Root-mean-square method
  51. sum += (filtered * filtered);
  52. }
  53. double rms = int(sqrt(sum / samples) - 0.5);
  54. double current = _currentFactor * rms;
  55. Serial.println(sum);
  56. Serial.println(rms);
  57. Serial.println(current);
  58. current = round(current * _multiplier) / _multiplier;
  59. Serial.println(current);
  60. return current;
  61. };