As3935 calibration (#5366)

This commit is contained in:
Mark Veinot 2023-10-11 22:27:36 -03:00 committed by GitHub
parent e35de626a4
commit 853d81c6dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 110 additions and 0 deletions

View file

@ -8,6 +8,8 @@ from esphome.const import (
CONF_IRQ_PIN, CONF_IRQ_PIN,
CONF_LIGHTNING_THRESHOLD, CONF_LIGHTNING_THRESHOLD,
CONF_MASK_DISTURBER, CONF_MASK_DISTURBER,
CONF_CALIBRATION,
CONF_TUNE_ANTENNA,
CONF_NOISE_LEVEL, CONF_NOISE_LEVEL,
CONF_SPIKE_REJECTION, CONF_SPIKE_REJECTION,
CONF_WATCHDOG_THRESHOLD, CONF_WATCHDOG_THRESHOLD,
@ -34,6 +36,8 @@ AS3935_SCHEMA = cv.Schema(
cv.Optional(CONF_MASK_DISTURBER, default=False): cv.boolean, cv.Optional(CONF_MASK_DISTURBER, default=False): cv.boolean,
cv.Optional(CONF_DIV_RATIO, default=0): cv.one_of(0, 16, 32, 64, 128, int=True), cv.Optional(CONF_DIV_RATIO, default=0): cv.one_of(0, 16, 32, 64, 128, int=True),
cv.Optional(CONF_CAPACITANCE, default=0): cv.int_range(min=0, max=15), cv.Optional(CONF_CAPACITANCE, default=0): cv.int_range(min=0, max=15),
cv.Optional(CONF_TUNE_ANTENNA, default=False): cv.boolean,
cv.Optional(CONF_CALIBRATION, default=True): cv.boolean,
} }
) )
@ -51,3 +55,5 @@ async def setup_as3935(var, config):
cg.add(var.set_mask_disturber(config[CONF_MASK_DISTURBER])) cg.add(var.set_mask_disturber(config[CONF_MASK_DISTURBER]))
cg.add(var.set_div_ratio(config[CONF_DIV_RATIO])) cg.add(var.set_div_ratio(config[CONF_DIV_RATIO]))
cg.add(var.set_capacitance(config[CONF_CAPACITANCE])) cg.add(var.set_capacitance(config[CONF_CAPACITANCE]))
cg.add(var.set_tune_antenna(config[CONF_TUNE_ANTENNA]))
cg.add(var.set_calibration(config[CONF_CALIBRATION]))

View file

@ -21,6 +21,14 @@ void AS3935Component::setup() {
this->write_mask_disturber(this->mask_disturber_); this->write_mask_disturber(this->mask_disturber_);
this->write_div_ratio(this->div_ratio_); this->write_div_ratio(this->div_ratio_);
this->write_capacitance(this->capacitance_); this->write_capacitance(this->capacitance_);
// Handle setting up tuning or auto-calibration
if (this->tune_antenna_) {
ESP_LOGCONFIG(TAG, " Antenna tuning: ENABLED - lightning detection will not function in this mode");
this->tune_antenna();
} else if (this->calibration_) {
this->calibrate_oscillator();
}
} }
void AS3935Component::dump_config() { void AS3935Component::dump_config() {
@ -227,6 +235,87 @@ uint32_t AS3935Component::get_lightning_energy_() {
return pure_light; return pure_light;
} }
// REG0x03, bit [7:6], manufacturer default: 0 (16 division ratio).
// This function returns the current division ratio of the resonance frequency.
// The antenna resonance frequency should be within 3.5 percent of 500kHz, and
// so when modifying the resonance frequency with the internal capacitors
// (tuneCap()) it's important to keep in mind that the displayed frequency on
// the IRQ pin is divided by this number.
uint8_t AS3935Component::read_div_ratio() {
ESP_LOGV(TAG, "Calling read_div_ratio");
uint8_t reg_val = this->read_register_(INT_MASK_ANT, DIV_MASK);
reg_val >>= 6; // Front of the line.
if (reg_val == 0) {
return 16;
} else if (reg_val == 1) {
return 32;
} else if (reg_val == 2) {
return 64;
} else if (reg_val == 3) {
return 128;
}
ESP_LOGW(TAG, "Unknown response received for div_ratio");
return 0;
}
uint8_t AS3935Component::read_capacitance() {
ESP_LOGV(TAG, "Calling read_capacitance");
uint8_t reg_val = this->read_register_(FREQ_DISP_IRQ, CAP_MASK) * 8;
return (reg_val);
}
// REG0x08, bits [5,6,7], manufacturer default: 0.
// This will send the frequency of the oscillators to the IRQ pin.
// _osc 1, bit[5] = TRCO - System RCO at 32.768kHz
// _osc 2, bit[6] = SRCO - Timer RCO Oscillators 1.1MHz
// _osc 3, bit[7] = LCO - Frequency of the Antenna
void AS3935Component::display_oscillator(bool state, uint8_t osc) {
if ((osc < 1) || (osc > 3))
return;
this->write_register(FREQ_DISP_IRQ, OSC_MASK, state, 4 + osc);
}
// REG0x3D, bits[7:0]
// This function calibrates both internal oscillators The oscillators are tuned
// based on the resonance frequency of the antenna and so it should be trimmed
// before the calibration is done.
bool AS3935Component::calibrate_oscillator() {
ESP_LOGI(TAG, "Starting oscillators calibration...");
this->write_register(CALIB_RCO, WIPE_ALL, DIRECT_COMMAND, 0); // Send command to calibrate the oscillators
this->display_oscillator(true, 2);
delay(2); // Give time for the internal oscillators to start up.
this->display_oscillator(false, 2);
// Check it they were calibrated successfully.
uint8_t reg_val_srco = this->read_register_(CALIB_SRCO, CALIB_MASK_NOK);
uint8_t reg_val_trco = this->read_register_(CALIB_TRCO, CALIB_MASK_NOK);
// reg_val_srco &= CALIB_MASK;
// reg_val_srco >>= 6;
// reg_val_trco &= CALIB_MASK;
// reg_val_trco >>= 6;
if (!reg_val_srco && !reg_val_trco) { // Zero upon success
ESP_LOGI(TAG, "Calibration was succesful");
return true;
} else {
ESP_LOGW(TAG, "Calibration was NOT succesful");
return false;
}
}
void AS3935Component::tune_antenna() {
ESP_LOGI(TAG, "Starting antenna tuning...");
uint8_t div_ratio = this->read_div_ratio();
uint8_t tune_val = this->read_capacitance();
ESP_LOGI(TAG, "Division Ratio is set to: %d", div_ratio);
ESP_LOGI(TAG, "Internal Capacitor is set to: %d", tune_val);
ESP_LOGI(TAG, "Displaying oscillator on INT pin. Measure its frequency - multiply value by Division Ratio");
this->display_oscillator(true, ANTFREQ);
}
uint8_t AS3935Component::read_register_(uint8_t reg, uint8_t mask) { uint8_t AS3935Component::read_register_(uint8_t reg, uint8_t mask) {
uint8_t value = this->read_register(reg); uint8_t value = this->read_register(reg);
value &= (~mask); value &= (~mask);

View file

@ -13,6 +13,9 @@
namespace esphome { namespace esphome {
namespace as3935 { namespace as3935 {
static const uint8_t DIRECT_COMMAND = 0x96;
static const uint8_t ANTFREQ = 3;
enum AS3935RegisterNames { enum AS3935RegisterNames {
AFE_GAIN = 0x00, AFE_GAIN = 0x00,
THRESHOLD, THRESHOLD,
@ -30,6 +33,7 @@ enum AS3935RegisterNames {
}; };
enum AS3935RegisterMasks { enum AS3935RegisterMasks {
WIPE_ALL = 0x0,
GAIN_MASK = 0x3E, GAIN_MASK = 0x3E,
SPIKE_MASK = 0xF, SPIKE_MASK = 0xF,
IO_MASK = 0xC1, IO_MASK = 0xC1,
@ -44,6 +48,7 @@ enum AS3935RegisterMasks {
NOISE_FLOOR_MASK = 0x70, NOISE_FLOOR_MASK = 0x70,
OSC_MASK = 0xE0, OSC_MASK = 0xE0,
CALIB_MASK = 0x7F, CALIB_MASK = 0x7F,
CALIB_MASK_NOK = 0xBF,
DIV_MASK = 0x3F DIV_MASK = 0x3F
}; };
@ -90,6 +95,13 @@ class AS3935Component : public Component {
void write_div_ratio(uint8_t div_ratio); void write_div_ratio(uint8_t div_ratio);
void set_capacitance(uint8_t capacitance) { capacitance_ = capacitance; } void set_capacitance(uint8_t capacitance) { capacitance_ = capacitance; }
void write_capacitance(uint8_t capacitance); void write_capacitance(uint8_t capacitance);
uint8_t read_div_ratio();
uint8_t read_capacitance();
bool calibrate_oscillator();
void display_oscillator(bool state, uint8_t osc);
void tune_antenna();
void set_tune_antenna(bool tune_antenna) { tune_antenna_ = tune_antenna; }
void set_calibration(bool calibration) { calibration_ = calibration; }
protected: protected:
uint8_t read_interrupt_register_(); uint8_t read_interrupt_register_();
@ -112,6 +124,8 @@ class AS3935Component : public Component {
bool mask_disturber_; bool mask_disturber_;
uint8_t div_ratio_; uint8_t div_ratio_;
uint8_t capacitance_; uint8_t capacitance_;
bool tune_antenna_;
bool calibration_;
}; };
} // namespace as3935 } // namespace as3935

View file

@ -783,6 +783,7 @@ CONF_TRACES = "traces"
CONF_TRANSITION_LENGTH = "transition_length" CONF_TRANSITION_LENGTH = "transition_length"
CONF_TRIGGER_ID = "trigger_id" CONF_TRIGGER_ID = "trigger_id"
CONF_TRIGGER_PIN = "trigger_pin" CONF_TRIGGER_PIN = "trigger_pin"
CONF_TUNE_ANTENNA = "tune_antenna"
CONF_TURN_OFF_ACTION = "turn_off_action" CONF_TURN_OFF_ACTION = "turn_off_action"
CONF_TURN_ON_ACTION = "turn_on_action" CONF_TURN_ON_ACTION = "turn_on_action"
CONF_TVOC = "tvoc" CONF_TVOC = "tvoc"