ESPHome  2024.4.0
mmc5603.cpp
Go to the documentation of this file.
1 #include "mmc5603.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace mmc5603 {
6 
7 static const char *const TAG = "mmc5603";
8 static const uint8_t MMC5603_ADDRESS = 0x30;
9 static const uint8_t MMC56X3_PRODUCT_ID = 0x39;
10 
11 static const uint8_t MMC56X3_DEFAULT_ADDRESS = 0x30;
12 static const uint8_t MMC56X3_CHIP_ID = 0x10;
13 
14 static const uint8_t MMC56X3_ADDR_XOUT0 = 0x00;
15 static const uint8_t MMC56X3_ADDR_XOUT1 = 0x01;
16 static const uint8_t MMC56X3_ADDR_XOUT2 = 0x06;
17 
18 static const uint8_t MMC56X3_ADDR_YOUT0 = 0x02;
19 static const uint8_t MMC56X3_ADDR_YOUT1 = 0x03;
20 static const uint8_t MMC56X3_ADDR_YOUT2 = 0x07;
21 
22 static const uint8_t MMC56X3_ADDR_ZOUT0 = 0x04;
23 static const uint8_t MMC56X3_ADDR_ZOUT1 = 0x05;
24 static const uint8_t MMC56X3_ADDR_ZOUT2 = 0x08;
25 
26 static const uint8_t MMC56X3_OUT_TEMP = 0x09;
27 static const uint8_t MMC56X3_STATUS_REG = 0x18;
28 static const uint8_t MMC56X3_CTRL0_REG = 0x1B;
29 static const uint8_t MMC56X3_CTRL1_REG = 0x1C;
30 static const uint8_t MMC56X3_CTRL2_REG = 0x1D;
31 static const uint8_t MMC5603_ODR_REG = 0x1A;
32 
34  ESP_LOGCONFIG(TAG, "Setting up MMC5603...");
35  uint8_t id = 0;
36  if (!this->read_byte(MMC56X3_PRODUCT_ID, &id)) {
38  this->mark_failed();
39  return;
40  }
41 
42  if (id != MMC56X3_CHIP_ID) {
43  ESP_LOGCONFIG(TAG, "Chip Wrong");
44  this->error_code_ = ID_REGISTERS;
45  this->mark_failed();
46  return;
47  }
48 
49  if (!this->write_byte(MMC56X3_CTRL1_REG, 0x80)) { // turn on set bit
50  ESP_LOGCONFIG(TAG, "Control 1 Failed for set bit");
52  this->mark_failed();
53  return;
54  }
55 
56  if (!this->write_byte(MMC56X3_CTRL0_REG, 0x08)) { // turn on set bit
57  ESP_LOGCONFIG(TAG, "Control 0 Failed for set bit");
59  this->mark_failed();
60  return;
61  }
62 
63  if (!this->write_byte(MMC56X3_CTRL0_REG, 0x10)) {
65  this->mark_failed();
66  return;
67  }
68 
69  uint8_t ctrl_2 = 0;
70 
71  ctrl_2 &= ~0x10; // turn off cmm_en bit
72  if (!this->write_byte(MMC56X3_CTRL2_REG, ctrl_2)) {
74  this->mark_failed();
75  return;
76  }
77 }
79  ESP_LOGCONFIG(TAG, "MMC5603:");
80  LOG_I2C_DEVICE(this);
81  if (this->error_code_ == COMMUNICATION_FAILED) {
82  ESP_LOGE(TAG, "Communication with MMC5603 failed!");
83  } else if (this->error_code_ == ID_REGISTERS) {
84  ESP_LOGE(TAG, "The ID registers don't match - Is this really an MMC5603?");
85  }
86  LOG_UPDATE_INTERVAL(this);
87 
88  LOG_SENSOR(" ", "X Axis", this->x_sensor_);
89  LOG_SENSOR(" ", "Y Axis", this->y_sensor_);
90  LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
91  LOG_SENSOR(" ", "Heading", this->heading_sensor_);
92 }
93 
95 
97  if (!this->write_byte(MMC56X3_CTRL0_REG, 0x01)) {
98  this->status_set_warning();
99  return;
100  }
101  uint8_t status = 0;
102  if (!this->read_byte(MMC56X3_STATUS_REG, &status)) {
103  this->status_set_warning();
104  return;
105  }
106 
107  uint8_t buffer[9] = {0};
108 
109  if (!this->read_byte(MMC56X3_ADDR_XOUT0, &buffer[0]) || !this->read_byte(MMC56X3_ADDR_XOUT1, &buffer[1]) ||
110  !this->read_byte(MMC56X3_ADDR_XOUT2, &buffer[2])) {
111  this->status_set_warning();
112  return;
113  }
114 
115  if (!this->read_byte(MMC56X3_ADDR_YOUT0, &buffer[3]) || !this->read_byte(MMC56X3_ADDR_YOUT1, &buffer[4]) ||
116  !this->read_byte(MMC56X3_ADDR_YOUT2, &buffer[5])) {
117  this->status_set_warning();
118  return;
119  }
120 
121  if (!this->read_byte(MMC56X3_ADDR_ZOUT0, &buffer[6]) || !this->read_byte(MMC56X3_ADDR_ZOUT1, &buffer[7]) ||
122  !this->read_byte(MMC56X3_ADDR_ZOUT2, &buffer[8])) {
123  this->status_set_warning();
124  return;
125  }
126 
127  int32_t raw_x = 0;
128  raw_x |= buffer[0] << 12;
129  raw_x |= buffer[1] << 4;
130  raw_x |= buffer[2] << 0;
131 
132  const float x = 0.0625 * (raw_x - 524288);
133 
134  int32_t raw_y = 0;
135  raw_y |= buffer[3] << 12;
136  raw_y |= buffer[4] << 4;
137  raw_y |= buffer[5] << 0;
138 
139  const float y = 0.0625 * (raw_y - 524288);
140 
141  int32_t raw_z = 0;
142  raw_z |= buffer[6] << 12;
143  raw_z |= buffer[7] << 4;
144  raw_z |= buffer[8] << 0;
145 
146  const float z = 0.0625 * (raw_z - 524288);
147 
148  const float heading = atan2f(0.0f - x, y) * 180.0f / M_PI;
149  ESP_LOGD(TAG, "Got x=%0.02fµT y=%0.02fµT z=%0.02fµT heading=%0.01f°", x, y, z, heading);
150 
151  if (this->x_sensor_ != nullptr)
152  this->x_sensor_->publish_state(x);
153  if (this->y_sensor_ != nullptr)
154  this->y_sensor_->publish_state(y);
155  if (this->z_sensor_ != nullptr)
156  this->z_sensor_->publish_state(z);
157  if (this->heading_sensor_ != nullptr)
158  this->heading_sensor_->publish_state(heading);
159 }
160 
161 } // namespace mmc5603
162 } // namespace esphome
sensor::Sensor * y_sensor_
Definition: mmc5603.h:32
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:235
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:19
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
uint16_t x
Definition: tt21100.cpp:17
float get_setup_priority() const override
Definition: mmc5603.cpp:94
uint16_t y
Definition: tt21100.cpp:18
sensor::Sensor * x_sensor_
Definition: mmc5603.h:31
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
enum esphome::mmc5603::MMC5603Component::ErrorCode error_code_
uint8_t status
Definition: bl0942.h:23
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition: i2c.h:262
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
sensor::Sensor * z_sensor_
Definition: mmc5603.h:33
sensor::Sensor * heading_sensor_
Definition: mmc5603.h:34