mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
147 lines
4.6 KiB
C++
147 lines
4.6 KiB
C++
/*
|
|
|
|
BL0937
|
|
|
|
Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
#ifndef BL0937_h
|
|
#define BL0937_h
|
|
|
|
#include <Arduino.h>
|
|
|
|
// Internal voltage reference value
|
|
#define V_REF 1.218
|
|
|
|
// The factor of a 1mOhm resistor
|
|
// as per recomended circuit in datasheet
|
|
// A 1mOhm resistor allows a ~30A max measurement
|
|
#define R_CURRENT 0.001
|
|
|
|
// This is the factor of a voltage divider of 1MOhm upstream and 1kOhm downstream
|
|
// as per recomended circuit in datasheet
|
|
#define R_VOLTAGE 1000
|
|
|
|
// Frequency of the BL0937 internal clock
|
|
#define F_OSC 2000000
|
|
|
|
// Minimum delay between selecting a mode and reading a sample
|
|
#define READING_INTERVAL 3000
|
|
|
|
// Maximum pulse with in microseconds
|
|
// If longer than this pulse width is reset to 0
|
|
// This value is purely experimental.
|
|
// Higher values allow for a better precission but reduce sampling rate
|
|
// and response speed to change
|
|
// Lower values increase sampling rate but reduce precission
|
|
// Values below 0.5s are not recommended since current and voltage output
|
|
// will have no time to stabilise
|
|
#define PULSE_TIMEOUT 5000000
|
|
|
|
// Define ICACHE_RAM_ATTR for AVR platforms
|
|
#if defined(ARDUINO_ARCH_AVR)
|
|
#define ICACHE_RAM_ATTR
|
|
#endif
|
|
|
|
// CF1 mode
|
|
typedef enum {
|
|
MODE_CURRENT,
|
|
MODE_VOLTAGE
|
|
} bl0937_mode_t;
|
|
|
|
class BL0937 {
|
|
|
|
public:
|
|
|
|
void cf_interrupt();
|
|
void cf1_interrupt();
|
|
|
|
void begin(
|
|
unsigned char cf_pin,
|
|
unsigned char cf1_pin,
|
|
unsigned char sel_pin,
|
|
unsigned char currentWhen = HIGH,
|
|
bool use_interrupts = true,
|
|
unsigned long pulse_timeout = PULSE_TIMEOUT);
|
|
|
|
void setMode(bl0937_mode_t mode);
|
|
bl0937_mode_t getMode();
|
|
bl0937_mode_t toggleMode();
|
|
|
|
double getCurrent();
|
|
unsigned int getVoltage();
|
|
unsigned int getActivePower();
|
|
unsigned int getApparentPower();
|
|
double getPowerFactor();
|
|
unsigned int getReactivePower();
|
|
unsigned long getEnergy(); //in Ws
|
|
void resetEnergy();
|
|
|
|
void setResistors(double current, double voltage_upstream, double voltage_downstream);
|
|
|
|
void expectedCurrent(double current);
|
|
void expectedVoltage(unsigned int current);
|
|
void expectedActivePower(unsigned int power);
|
|
|
|
double getCurrentMultiplier() { return _current_multiplier; };
|
|
double getVoltageMultiplier() { return _voltage_multiplier; };
|
|
double getPowerMultiplier() { return _power_multiplier; };
|
|
|
|
void setCurrentMultiplier(double current_multiplier) { _current_multiplier = current_multiplier; };
|
|
void setVoltageMultiplier(double voltage_multiplier) { _voltage_multiplier = voltage_multiplier; };
|
|
void setPowerMultiplier(double power_multiplier) { _power_multiplier = power_multiplier; };
|
|
void resetMultipliers();
|
|
|
|
private:
|
|
|
|
unsigned char _cf_pin;
|
|
unsigned char _cf1_pin;
|
|
unsigned char _sel_pin;
|
|
|
|
double _current_resistor = R_CURRENT;
|
|
double _voltage_resistor = R_VOLTAGE;
|
|
|
|
double _current_multiplier; // Unit: us/A
|
|
double _voltage_multiplier; // Unit: us/V
|
|
double _power_multiplier; // Unit: us/W
|
|
|
|
unsigned long _pulse_timeout = PULSE_TIMEOUT; //Unit: us
|
|
volatile unsigned long _voltage_pulse_width = 0; //Unit: us
|
|
volatile unsigned long _current_pulse_width = 0; //Unit: us
|
|
volatile unsigned long _power_pulse_width = 0; //Unit: us
|
|
volatile unsigned long _pulse_count = 0;
|
|
|
|
double _current = 0;
|
|
unsigned int _voltage = 0;
|
|
unsigned int _power = 0;
|
|
|
|
unsigned char _current_mode = HIGH;
|
|
volatile unsigned char _mode;
|
|
|
|
bool _use_interrupts = true;
|
|
volatile unsigned long _last_cf_interrupt = 0;
|
|
volatile unsigned long _last_cf1_interrupt = 0;
|
|
volatile unsigned long _first_cf1_interrupt = 0;
|
|
|
|
void _checkCFSignal();
|
|
void _checkCF1Signal();
|
|
void _calculateDefaultMultipliers();
|
|
|
|
};
|
|
|
|
#endif
|