mirror of
https://github.com/esphome/esphome.git
synced 2024-12-23 05:54:56 +01:00
As3935 calibration (#5366)
This commit is contained in:
parent
e35de626a4
commit
853d81c6dd
4 changed files with 110 additions and 0 deletions
|
@ -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]))
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue