ESPHome  2024.4.2
fs3000.cpp
Go to the documentation of this file.
1 #include "fs3000.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace fs3000 {
6 
7 static const char *const TAG = "fs3000";
8 
10  ESP_LOGCONFIG(TAG, "Setting up FS3000...");
11 
12  if (model_ == FIVE) {
13  // datasheet gives 9 points to interpolate from for the 1005 model
14  static const uint16_t RAW_DATA_POINTS_1005[9] = {409, 915, 1522, 2066, 2523, 2908, 3256, 3572, 3686};
15  static const float MPS_DATA_POINTS_1005[9] = {0.0, 1.07, 2.01, 3.0, 3.97, 4.96, 5.98, 6.99, 7.23};
16 
17  std::copy(RAW_DATA_POINTS_1005, RAW_DATA_POINTS_1005 + 9, this->raw_data_points_);
18  std::copy(MPS_DATA_POINTS_1005, MPS_DATA_POINTS_1005 + 9, this->mps_data_points_);
19  } else if (model_ == FIFTEEN) {
20  // datasheet gives 13 points to extrapolate from for the 1015 model
21  static const uint16_t RAW_DATA_POINTS_1015[13] = {409, 1203, 1597, 1908, 2187, 2400, 2629,
22  2801, 3006, 3178, 3309, 3563, 3686};
23  static const float MPS_DATA_POINTS_1015[13] = {0.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 13.0, 15.0};
24 
25  std::copy(RAW_DATA_POINTS_1015, RAW_DATA_POINTS_1015 + 13, this->raw_data_points_);
26  std::copy(MPS_DATA_POINTS_1015, MPS_DATA_POINTS_1015 + 13, this->mps_data_points_);
27  }
28 }
29 
31  // 5 bytes of data read from fs3000 sensor
32  // byte 1 - checksum
33  // byte 2 - (lower 4 bits) high byte of sensor reading
34  // byte 3 - (8 bits) low byte of sensor reading
35  // byte 4 - generic checksum data
36  // byte 5 - generic checksum data
37 
38  uint8_t data[5];
39 
40  if (!this->read_bytes_raw(data, 5)) {
41  this->status_set_warning();
42  ESP_LOGW(TAG, "Error reading data from FS3000");
43  this->publish_state(NAN);
44  return;
45  }
46 
47  // checksum passes if the modulo 256 sum of the five bytes is 0
48  uint8_t checksum = 0;
49  for (uint8_t i : data) {
50  checksum += i;
51  }
52 
53  if (checksum != 0) {
54  this->status_set_warning();
55  ESP_LOGW(TAG, "Checksum failure when reading from FS3000");
56  return;
57  }
58 
59  // raw value information is 12 bits
60  uint16_t raw_value = (data[1] << 8) | data[2];
61  ESP_LOGV(TAG, "Got raw reading=%i", raw_value);
62 
63  // convert and publish the raw value into m/s using the table of data points in the datasheet
64  this->publish_state(fit_raw_(raw_value));
65 
66  this->status_clear_warning();
67 }
68 
70  ESP_LOGCONFIG(TAG, "FS3000:");
71  LOG_I2C_DEVICE(this);
72  LOG_UPDATE_INTERVAL(this);
73  LOG_SENSOR(" ", "Air Velocity", this);
74 }
75 
76 float FS3000Component::fit_raw_(uint16_t raw_value) {
77  // converts a raw value read from the FS3000 into a speed in m/s based on the
78  // reference data points given in the datasheet
79  // fits raw reading using a linear interpolation between each data point
80 
81  uint8_t end = 8; // assume model 1005, which has 9 data points
82  if (this->model_ == FIFTEEN)
83  end = 12; // model 1015 has 13 data points
84 
85  if (raw_value <= this->raw_data_points_[0]) { // less than smallest data point returns first data point
86  return this->mps_data_points_[0];
87  } else if (raw_value >= this->raw_data_points_[end]) { // greater than largest data point returns max speed
88  return this->mps_data_points_[end];
89  } else {
90  uint8_t i = 0;
91 
92  // determine between which data points does the reading fall, i-1 and i
93  while (raw_value > this->raw_data_points_[i]) {
94  ++i;
95  }
96 
97  // calculate the slope of the secant line between the two data points that surrounds the reading
98  float slope = (this->mps_data_points_[i] - this->mps_data_points_[i - 1]) /
99  (this->raw_data_points_[i] - this->raw_data_points_[i - 1]);
100 
101  // return the interpolated value for the reading
102  return (float(raw_value - this->raw_data_points_[i - 1])) * slope + this->mps_data_points_[i - 1];
103  }
104 }
105 
106 } // namespace fs3000
107 } // namespace esphome
uint16_t raw_data_points_[13]
Definition: fs3000.h:28
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
optional< std::array< uint8_t, N > > read_bytes_raw()
Definition: i2c.h:225
float fit_raw_(uint16_t raw_value)
Definition: fs3000.cpp:76
void status_clear_warning()
Definition: component.cpp:166
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
void dump_config() override
Definition: fs3000.cpp:69
uint8_t checksum
Definition: bl0939.h:35
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
uint8_t end[39]
Definition: sun_gtil2.cpp:31