ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
mmc5603.cpp
Go to the documentation of this file.
1#include "mmc5603.h"
2#include "esphome/core/log.h"
3
4#include <numbers>
5
6namespace esphome::mmc5603 {
7
8ESPHOME_LOG_TAG(TAG, "mmc5603");
9static const uint8_t MMC5603_ADDRESS = 0x30;
10static const uint8_t MMC56X3_PRODUCT_ID = 0x39;
11
12static const uint8_t MMC56X3_DEFAULT_ADDRESS = 0x30;
13static const uint8_t MMC56X3_CHIP_ID = 0x10;
14
15static const uint8_t MMC56X3_ADDR_XOUT0 = 0x00;
16static const uint8_t MMC56X3_ADDR_XOUT1 = 0x01;
17static const uint8_t MMC56X3_ADDR_XOUT2 = 0x06;
18
19static const uint8_t MMC56X3_ADDR_YOUT0 = 0x02;
20static const uint8_t MMC56X3_ADDR_YOUT1 = 0x03;
21static const uint8_t MMC56X3_ADDR_YOUT2 = 0x07;
22
23static const uint8_t MMC56X3_ADDR_ZOUT0 = 0x04;
24static const uint8_t MMC56X3_ADDR_ZOUT1 = 0x05;
25static const uint8_t MMC56X3_ADDR_ZOUT2 = 0x08;
26
27static const uint8_t MMC56X3_OUT_TEMP = 0x09;
28static const uint8_t MMC56X3_STATUS_REG = 0x18;
29static const uint8_t MMC56X3_CTRL0_REG = 0x1B;
30static const uint8_t MMC56X3_CTRL1_REG = 0x1C;
31static const uint8_t MMC56X3_CTRL2_REG = 0x1D;
32static const uint8_t MMC5603_ODR_REG = 0x1A;
33
35 // Some chips report 0 instead of MMC56X3_CHIP_ID (0x10), so bit 4 is ignored
36 if (!this->check_chip_id(this, MMC56X3_PRODUCT_ID, 0x00, static_cast<uint8_t>(~MMC56X3_CHIP_ID)))
37 return;
38
39 if (!this->write_byte(MMC56X3_CTRL1_REG, 0x80)) { // turn on set bit
40 this->mark_failed(LOG_STR("Control 1 failed for set bit"));
41 return;
42 }
43
44 if (!this->write_byte(MMC56X3_CTRL0_REG, 0x08)) { // turn on set bit
45 this->mark_failed(LOG_STR("Control 0 failed for set bit"));
46 return;
47 }
48
49 if (!this->write_byte(MMC56X3_CTRL0_REG, 0x10)) {
50 this->mark_failed(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
51 return;
52 }
53
54 uint8_t ctrl_2 = 0;
55
56 ctrl_2 &= ~0x10; // turn off cmm_en bit
57 if (!this->write_byte(MMC56X3_CTRL2_REG, ctrl_2)) {
58 this->mark_failed(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
59 return;
60 }
61}
63 ESP_LOGCONFIG(TAG, "MMC5603:");
64 LOG_I2C_DEVICE(this);
65 LOG_UPDATE_INTERVAL(this);
66 ESP_LOGCONFIG(TAG, " Auto set/reset: %s", ONOFF(this->auto_set_reset_));
67
68 LOG_SENSOR(" ", "X Axis", this->x_sensor_);
69 LOG_SENSOR(" ", "Y Axis", this->y_sensor_);
70 LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
71 LOG_SENSOR(" ", "Heading", this->heading_sensor_);
72}
73
75 uint8_t ctrl0 = (this->auto_set_reset_) ? 0x21 : 0x01;
76 if (!this->write_byte(MMC56X3_CTRL0_REG, ctrl0)) {
77 this->status_set_warning();
78 return;
79 }
80 uint8_t status = 0;
81 if (!this->read_byte(MMC56X3_STATUS_REG, &status)) {
82 this->status_set_warning();
83 return;
84 }
85
86 uint8_t buffer[9] = {0};
87
88 if (!this->read_byte(MMC56X3_ADDR_XOUT0, &buffer[0]) || !this->read_byte(MMC56X3_ADDR_XOUT1, &buffer[1]) ||
89 !this->read_byte(MMC56X3_ADDR_XOUT2, &buffer[2])) {
90 this->status_set_warning();
91 return;
92 }
93
94 if (!this->read_byte(MMC56X3_ADDR_YOUT0, &buffer[3]) || !this->read_byte(MMC56X3_ADDR_YOUT1, &buffer[4]) ||
95 !this->read_byte(MMC56X3_ADDR_YOUT2, &buffer[5])) {
96 this->status_set_warning();
97 return;
98 }
99
100 if (!this->read_byte(MMC56X3_ADDR_ZOUT0, &buffer[6]) || !this->read_byte(MMC56X3_ADDR_ZOUT1, &buffer[7]) ||
101 !this->read_byte(MMC56X3_ADDR_ZOUT2, &buffer[8])) {
102 this->status_set_warning();
103 return;
104 }
105
106 int32_t raw_x = 0;
107 raw_x |= buffer[0] << 12;
108 raw_x |= buffer[1] << 4;
109 raw_x |= buffer[2] & 0x0F;
110
111 const float x = 0.00625 * (raw_x - 524288);
112
113 int32_t raw_y = 0;
114 raw_y |= buffer[3] << 12;
115 raw_y |= buffer[4] << 4;
116 raw_y |= buffer[5] & 0x0F;
117
118 const float y = 0.00625 * (raw_y - 524288);
119
120 int32_t raw_z = 0;
121 raw_z |= buffer[6] << 12;
122 raw_z |= buffer[7] << 4;
123 raw_z |= buffer[8] & 0x0F;
124
125 const float z = 0.00625 * (raw_z - 524288);
126
127 const float heading = atan2f(0.0f - x, y) * 180.0f / std::numbers::pi_v<float>;
128 ESP_LOGD(TAG, "Got x=%0.02fµT y=%0.02fµT z=%0.02fµT heading=%0.01f°", x, y, z, heading);
129
130 if (this->x_sensor_ != nullptr)
131 this->x_sensor_->publish_state(x);
132 if (this->y_sensor_ != nullptr)
133 this->y_sensor_->publish_state(y);
134 if (this->z_sensor_ != nullptr)
135 this->z_sensor_->publish_state(z);
136 if (this->heading_sensor_ != nullptr)
137 this->heading_sensor_->publish_state(heading);
138}
139
140} // namespace esphome::mmc5603
uint8_t status
Definition bl0942.h:8
void mark_failed()
Mark this component as failed.
bool check_chip_id(Component *component, uint8_t a_register, uint8_t expected, uint8_t mask=0xFF)
Read the 8-bit ID at a_register and accept it when it matches expected in the bits set in mask.
Definition i2c.h:232
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:312
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:272
sensor::Sensor * heading_sensor_
Definition mmc5603.h:33
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
uint32_t buffer
Definition gif.cpp:50
bool z
Definition msa3xx.h:1
ESPHOME_LOG_TAG(TAG, "mmc5603")
uint16_t x
Definition tt21100.cpp:5
uint16_t y
Definition tt21100.cpp:6