mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	As3935 calibration (#5366)
This commit is contained in:
		| @@ -8,6 +8,8 @@ from esphome.const import ( | ||||
|     CONF_IRQ_PIN, | ||||
|     CONF_LIGHTNING_THRESHOLD, | ||||
|     CONF_MASK_DISTURBER, | ||||
|     CONF_CALIBRATION, | ||||
|     CONF_TUNE_ANTENNA, | ||||
|     CONF_NOISE_LEVEL, | ||||
|     CONF_SPIKE_REJECTION, | ||||
|     CONF_WATCHDOG_THRESHOLD, | ||||
| @@ -34,6 +36,8 @@ AS3935_SCHEMA = cv.Schema( | ||||
|         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_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_div_ratio(config[CONF_DIV_RATIO])) | ||||
|     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_div_ratio(this->div_ratio_); | ||||
|   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() { | ||||
| @@ -227,6 +235,87 @@ uint32_t AS3935Component::get_lightning_energy_() { | ||||
|   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 value = this->read_register(reg); | ||||
|   value &= (~mask); | ||||
|   | ||||
| @@ -13,6 +13,9 @@ | ||||
| namespace esphome { | ||||
| namespace as3935 { | ||||
|  | ||||
| static const uint8_t DIRECT_COMMAND = 0x96; | ||||
| static const uint8_t ANTFREQ = 3; | ||||
|  | ||||
| enum AS3935RegisterNames { | ||||
|   AFE_GAIN = 0x00, | ||||
|   THRESHOLD, | ||||
| @@ -30,6 +33,7 @@ enum AS3935RegisterNames { | ||||
| }; | ||||
|  | ||||
| enum AS3935RegisterMasks { | ||||
|   WIPE_ALL = 0x0, | ||||
|   GAIN_MASK = 0x3E, | ||||
|   SPIKE_MASK = 0xF, | ||||
|   IO_MASK = 0xC1, | ||||
| @@ -44,6 +48,7 @@ enum AS3935RegisterMasks { | ||||
|   NOISE_FLOOR_MASK = 0x70, | ||||
|   OSC_MASK = 0xE0, | ||||
|   CALIB_MASK = 0x7F, | ||||
|   CALIB_MASK_NOK = 0xBF, | ||||
|   DIV_MASK = 0x3F | ||||
| }; | ||||
|  | ||||
| @@ -90,6 +95,13 @@ class AS3935Component : public Component { | ||||
|   void write_div_ratio(uint8_t div_ratio); | ||||
|   void set_capacitance(uint8_t capacitance) { capacitance_ = 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: | ||||
|   uint8_t read_interrupt_register_(); | ||||
| @@ -112,6 +124,8 @@ class AS3935Component : public Component { | ||||
|   bool mask_disturber_; | ||||
|   uint8_t div_ratio_; | ||||
|   uint8_t capacitance_; | ||||
|   bool tune_antenna_; | ||||
|   bool calibration_; | ||||
| }; | ||||
|  | ||||
| }  // namespace as3935 | ||||
|   | ||||
| @@ -783,6 +783,7 @@ CONF_TRACES = "traces" | ||||
| CONF_TRANSITION_LENGTH = "transition_length" | ||||
| CONF_TRIGGER_ID = "trigger_id" | ||||
| CONF_TRIGGER_PIN = "trigger_pin" | ||||
| CONF_TUNE_ANTENNA = "tune_antenna" | ||||
| CONF_TURN_OFF_ACTION = "turn_off_action" | ||||
| CONF_TURN_ON_ACTION = "turn_on_action" | ||||
| CONF_TVOC = "tvoc" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user