├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── githubci.yml ├── Adafruit_MLX90393.cpp ├── Adafruit_MLX90393.h ├── LICENSE ├── README.md ├── examples ├── basicdemo │ └── basicdemo.ino ├── compass_calibrated │ └── compass_calibrated.ino ├── magcal_nosave │ └── magcal_nosave.ino └── oled_demo │ └── oled_demo.ino └── library.properties /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /.github/workflows/githubci.yml: -------------------------------------------------------------------------------- 1 | name: Arduino Library CI 2 | 3 | on: [pull_request, push, repository_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/setup-python@v4 11 | with: 12 | python-version: '3.x' 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: adafruit/ci-arduino 17 | path: ci 18 | 19 | - name: pre-install 20 | run: bash ci/actions_install.sh 21 | 22 | - name: test platforms 23 | run: python3 ci/build_platform.py main_platforms 24 | 25 | - name: clang 26 | run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 27 | 28 | - name: doxygen 29 | env: 30 | GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} 31 | PRETTYNAME : "Adafruit MLX90393 Library" 32 | run: bash ci/doxy_gen_and_deploy.sh 33 | -------------------------------------------------------------------------------- /Adafruit_MLX90393.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This is a library for the MLX90393 magnetometer. 3 | 4 | Designed specifically to work with the MLX90393 breakout from Adafruit: 5 | 6 | ----> https://www.adafruit.com/products/4022 7 | 8 | These sensors use I2C to communicate, 2 pins are required to interface. 9 | 10 | Adafruit invests time and resources providing this open source code, please 11 | support Adafruit and open-source hardware by purchasing products from 12 | Adafruit! 13 | 14 | Written by Kevin Townsend/ktown for Adafruit Industries. 15 | 16 | MIT license, all text above must be included in any redistribution 17 | *****************************************************************************/ 18 | #include "Adafruit_MLX90393.h" 19 | 20 | /** 21 | * Instantiates a new Adafruit_MLX90393 class instance 22 | */ 23 | Adafruit_MLX90393::Adafruit_MLX90393(void) {} 24 | 25 | /*! 26 | * @brief Sets up the hardware and initializes I2C 27 | * @param i2c_addr 28 | * The I2C address to be used. 29 | * @param wire 30 | * The Wire object to be used for I2C connections. 31 | * @return True if initialization was successful, otherwise false. 32 | */ 33 | bool Adafruit_MLX90393::begin_I2C(uint8_t i2c_addr, TwoWire *wire) { 34 | if (i2c_dev) { 35 | delete i2c_dev; 36 | } 37 | 38 | if (!i2c_dev) { 39 | i2c_dev = new Adafruit_I2CDevice(i2c_addr, wire); 40 | } 41 | spi_dev = NULL; 42 | 43 | if (!i2c_dev->begin()) { 44 | return false; 45 | } 46 | 47 | return _init(); 48 | } 49 | 50 | /*! 51 | * @brief Sets up the hardware and initializes hardware SPI 52 | * @param cs_pin The arduino pin # connected to chip select 53 | * @param theSPI The SPI object to be used for SPI connections. 54 | * @return True if initialization was successful, otherwise false. 55 | */ 56 | boolean Adafruit_MLX90393::begin_SPI(uint8_t cs_pin, SPIClass *theSPI) { 57 | i2c_dev = NULL; 58 | if (!spi_dev) { 59 | _cspin = cs_pin; 60 | spi_dev = new Adafruit_SPIDevice(cs_pin, 61 | 1000000, // frequency 62 | SPI_BITORDER_MSBFIRST, // bit order 63 | SPI_MODE3, // data mode 64 | theSPI); 65 | } 66 | if (!spi_dev->begin()) { 67 | return false; 68 | } 69 | return _init(); 70 | } 71 | 72 | bool Adafruit_MLX90393::_init(void) { 73 | 74 | if (!exitMode()) 75 | return false; 76 | 77 | if (!reset()) 78 | return false; 79 | 80 | /* Set gain and sensor config. */ 81 | if (!setGain(MLX90393_GAIN_1X)) { 82 | return false; 83 | } 84 | 85 | /* Set resolution. */ 86 | if (!setResolution(MLX90393_X, MLX90393_RES_16)) 87 | return false; 88 | if (!setResolution(MLX90393_Y, MLX90393_RES_16)) 89 | return false; 90 | if (!setResolution(MLX90393_Z, MLX90393_RES_16)) 91 | return false; 92 | 93 | /* Set oversampling. */ 94 | if (!setOversampling(MLX90393_OSR_3)) 95 | return false; 96 | 97 | /* Set digital filtering. */ 98 | if (!setFilter(MLX90393_FILTER_7)) 99 | return false; 100 | 101 | /* set INT pin to output interrupt */ 102 | if (!setTrigInt(false)) { 103 | return false; 104 | } 105 | 106 | return true; 107 | } 108 | 109 | /** 110 | * Perform a mode exit 111 | * @return True if the operation succeeded, otherwise false. 112 | */ 113 | bool Adafruit_MLX90393::exitMode(void) { 114 | uint8_t tx[1] = {MLX90393_REG_EX}; 115 | 116 | /* Perform the transaction. */ 117 | return (transceive(tx, sizeof(tx), NULL, 0, 0) == MLX90393_STATUS_OK); 118 | } 119 | 120 | /** 121 | * Perform a soft reset 122 | * @return True if the operation succeeded, otherwise false. 123 | */ 124 | bool Adafruit_MLX90393::reset(void) { 125 | uint8_t tx[1] = {MLX90393_REG_RT}; 126 | 127 | /* Perform the transaction. */ 128 | if (transceive(tx, sizeof(tx), NULL, 0, 5) != MLX90393_STATUS_RESET) { 129 | return false; 130 | } 131 | return true; 132 | } 133 | 134 | /** 135 | * Sets the sensor gain to the specified level. 136 | * @param gain The gain level to set. 137 | * @return True if the operation succeeded, otherwise false. 138 | */ 139 | bool Adafruit_MLX90393::setGain(mlx90393_gain_t gain) { 140 | _gain = gain; 141 | 142 | uint16_t data; 143 | readRegister(MLX90393_CONF1, &data); 144 | 145 | // mask off gain bits 146 | data &= ~0x0070; 147 | // set gain bits 148 | data |= gain << MLX90393_GAIN_SHIFT; 149 | 150 | return writeRegister(MLX90393_CONF1, data); 151 | } 152 | 153 | /** 154 | * Gets the current sensor gain. 155 | * 156 | * @return An enum containing the current gain level. 157 | */ 158 | mlx90393_gain_t Adafruit_MLX90393::getGain(void) { 159 | uint16_t data; 160 | readRegister(MLX90393_CONF1, &data); 161 | 162 | // mask off gain bits 163 | data &= 0x0070; 164 | 165 | return (mlx90393_gain_t)(data >> 4); 166 | } 167 | 168 | /** 169 | * Sets the sensor resolution to the specified level. 170 | * @param axis The axis to set. 171 | * @param resolution The resolution level to set. 172 | * @return True if the operation succeeded, otherwise false. 173 | */ 174 | bool Adafruit_MLX90393::setResolution(enum mlx90393_axis axis, 175 | enum mlx90393_resolution resolution) { 176 | 177 | uint16_t data; 178 | readRegister(MLX90393_CONF3, &data); 179 | 180 | switch (axis) { 181 | case MLX90393_X: 182 | _res_x = resolution; 183 | data &= ~0x0060; 184 | data |= resolution << 5; 185 | break; 186 | case MLX90393_Y: 187 | _res_y = resolution; 188 | data &= ~0x0180; 189 | data |= resolution << 7; 190 | break; 191 | case MLX90393_Z: 192 | _res_z = resolution; 193 | data &= ~0x0600; 194 | data |= resolution << 9; 195 | break; 196 | } 197 | 198 | return writeRegister(MLX90393_CONF3, data); 199 | } 200 | 201 | /** 202 | * Gets the current sensor resolution. 203 | * @param axis The axis to get. 204 | * @return An enum containing the current resolution. 205 | */ 206 | enum mlx90393_resolution 207 | Adafruit_MLX90393::getResolution(enum mlx90393_axis axis) { 208 | switch (axis) { 209 | case MLX90393_X: 210 | return _res_x; 211 | case MLX90393_Y: 212 | return _res_y; 213 | case MLX90393_Z: 214 | return _res_z; 215 | } 216 | // shouldn't get here, but to make compiler happy... 217 | return _res_x; 218 | } 219 | 220 | /** 221 | * Sets the digital filter. 222 | * @param filter The digital filter setting. 223 | * @return True if the operation succeeded, otherwise false. 224 | */ 225 | bool Adafruit_MLX90393::setFilter(enum mlx90393_filter filter) { 226 | _dig_filt = filter; 227 | 228 | uint16_t data; 229 | readRegister(MLX90393_CONF3, &data); 230 | 231 | data &= ~0x1C; 232 | data |= filter << 2; 233 | 234 | return writeRegister(MLX90393_CONF3, data); 235 | } 236 | 237 | /** 238 | * Gets the current digital filter setting. 239 | * @return An enum containing the current digital filter setting. 240 | */ 241 | enum mlx90393_filter Adafruit_MLX90393::getFilter(void) { return _dig_filt; } 242 | 243 | /** 244 | * Sets the oversampling. 245 | * @param oversampling The oversampling value to use. 246 | * @return True if the operation succeeded, otherwise false. 247 | */ 248 | bool Adafruit_MLX90393::setOversampling( 249 | enum mlx90393_oversampling oversampling) { 250 | _osr = oversampling; 251 | 252 | uint16_t data; 253 | readRegister(MLX90393_CONF3, &data); 254 | 255 | data &= ~0x03; 256 | data |= oversampling; 257 | 258 | return writeRegister(MLX90393_CONF3, data); 259 | } 260 | 261 | /** 262 | * Gets the current oversampling setting. 263 | * @return An enum containing the current oversampling setting. 264 | */ 265 | enum mlx90393_oversampling Adafruit_MLX90393::getOversampling(void) { 266 | return _osr; 267 | } 268 | 269 | /** 270 | * Sets the TRIG_INT pin to the specified function. 271 | * 272 | * @param state 'true/1' sets the pin to INT, 'false/0' to TRIG. 273 | * 274 | * @return True if the operation succeeded, otherwise false. 275 | */ 276 | bool Adafruit_MLX90393::setTrigInt(bool state) { 277 | uint16_t data; 278 | readRegister(MLX90393_CONF2, &data); 279 | 280 | // mask off trigint bit 281 | data &= ~0x8000; 282 | 283 | // set trigint bit if desired 284 | if (state) { 285 | /* Set the INT, highest bit */ 286 | data |= 0x8000; 287 | } 288 | 289 | return writeRegister(MLX90393_CONF2, data); 290 | } 291 | 292 | /** 293 | * Begin a single measurement on all axes 294 | * 295 | * @return True on command success 296 | */ 297 | bool Adafruit_MLX90393::startSingleMeasurement(void) { 298 | uint8_t tx[1] = {MLX90393_REG_SM | MLX90393_AXIS_ALL}; 299 | 300 | /* Set the device to single measurement mode */ 301 | uint8_t stat = transceive(tx, sizeof(tx), NULL, 0, 0); 302 | if ((stat == MLX90393_STATUS_OK) || (stat == MLX90393_STATUS_SMMODE)) { 303 | return true; 304 | } 305 | return false; 306 | } 307 | 308 | /** 309 | * Reads data from data register & returns the results. 310 | * 311 | * @param x Pointer to where the 'x' value should be stored. 312 | * @param y Pointer to where the 'y' value should be stored. 313 | * @param z Pointer to where the 'z' value should be stored. 314 | * 315 | * @return True on command success 316 | */ 317 | bool Adafruit_MLX90393::readMeasurement(float *x, float *y, float *z) { 318 | uint8_t tx[1] = {MLX90393_REG_RM | MLX90393_AXIS_ALL}; 319 | uint8_t rx[6] = {0}; 320 | 321 | /* Read a single data sample. */ 322 | if (transceive(tx, sizeof(tx), rx, sizeof(rx), 0) != MLX90393_STATUS_OK) { 323 | return false; 324 | } 325 | 326 | int16_t xi, yi, zi; 327 | 328 | /* Convert data to uT and float. */ 329 | xi = (rx[0] << 8) | rx[1]; 330 | yi = (rx[2] << 8) | rx[3]; 331 | zi = (rx[4] << 8) | rx[5]; 332 | 333 | if (_res_x == MLX90393_RES_18) 334 | xi -= 0x8000; 335 | if (_res_x == MLX90393_RES_19) 336 | xi -= 0x4000; 337 | if (_res_y == MLX90393_RES_18) 338 | yi -= 0x8000; 339 | if (_res_y == MLX90393_RES_19) 340 | yi -= 0x4000; 341 | if (_res_z == MLX90393_RES_18) 342 | zi -= 0x8000; 343 | if (_res_z == MLX90393_RES_19) 344 | zi -= 0x4000; 345 | 346 | *x = (float)xi * mlx90393_lsb_lookup[0][_gain][_res_x][0]; 347 | *y = (float)yi * mlx90393_lsb_lookup[0][_gain][_res_y][0]; 348 | *z = (float)zi * mlx90393_lsb_lookup[0][_gain][_res_z][1]; 349 | 350 | return true; 351 | } 352 | 353 | /** 354 | * Performs a single X/Y/Z conversion and returns the results. 355 | * 356 | * @param x Pointer to where the 'x' value should be stored. 357 | * @param y Pointer to where the 'y' value should be stored. 358 | * @param z Pointer to where the 'z' value should be stored. 359 | * 360 | * @return True if the operation succeeded, otherwise false. 361 | */ 362 | bool Adafruit_MLX90393::readData(float *x, float *y, float *z) { 363 | if (!startSingleMeasurement()) 364 | return false; 365 | // See MLX90393 Getting Started Guide for fancy formula 366 | // tconv = f(OSR, DIG_FILT, OSR2, ZYXT) 367 | // For now, using Table 18 from datasheet 368 | // Without +10ms delay measurement doesn't always seem to work 369 | delay(mlx90393_tconv[_dig_filt][_osr] + 10); 370 | return readMeasurement(x, y, z); 371 | } 372 | 373 | bool Adafruit_MLX90393::writeRegister(uint8_t reg, uint16_t data) { 374 | uint8_t tx[4] = { 375 | MLX90393_REG_WR, 376 | (uint8_t)(data >> 8), // high byte 377 | (uint8_t)(data & 0xFF), // low byte 378 | (uint8_t)(reg << 2)}; // the register itself, shift up by 2 bits! 379 | 380 | /* Perform the transaction. */ 381 | return (transceive(tx, sizeof(tx), NULL, 0, 0) == MLX90393_STATUS_OK); 382 | } 383 | 384 | bool Adafruit_MLX90393::readRegister(uint8_t reg, uint16_t *data) { 385 | uint8_t tx[2] = { 386 | MLX90393_REG_RR, 387 | (uint8_t)(reg << 2)}; // the register itself, shift up by 2 bits! 388 | 389 | uint8_t rx[2]; 390 | 391 | /* Perform the transaction. */ 392 | if (transceive(tx, sizeof(tx), rx, sizeof(rx), 0) != MLX90393_STATUS_OK) { 393 | return false; 394 | } 395 | 396 | *data = ((uint16_t)rx[0] << 8) | rx[1]; 397 | 398 | return true; 399 | } 400 | 401 | /**************************************************************************/ 402 | /*! 403 | @brief Gets the most recent sensor event, Adafruit Unified Sensor format 404 | @param event Pointer to an Adafruit Unified sensor_event_t object that 405 | we'll fill in 406 | @returns True on successful read 407 | */ 408 | /**************************************************************************/ 409 | bool Adafruit_MLX90393::getEvent(sensors_event_t *event) { 410 | /* Clear the event */ 411 | memset(event, 0, sizeof(sensors_event_t)); 412 | 413 | event->version = 1; 414 | event->sensor_id = _sensorID; 415 | event->type = SENSOR_TYPE_MAGNETIC_FIELD; 416 | event->timestamp = millis(); 417 | 418 | return readData(&event->magnetic.x, &event->magnetic.y, &event->magnetic.z); 419 | } 420 | 421 | /** 422 | * Performs a full read/write transaction with the sensor. 423 | * 424 | * @param txbuf Pointer the the buffer containing the data to write. 425 | * @param txlen The number of bytes to write. 426 | * @param rxbuf Pointer to an appropriately large buffer where data read 427 | * back will be written. 428 | * @param rxlen The number of bytes to read back (not including the 429 | * mandatory status byte that is always returned). 430 | * 431 | * @return The status byte from the IC. 432 | */ 433 | uint8_t Adafruit_MLX90393::transceive(uint8_t *txbuf, uint8_t txlen, 434 | uint8_t *rxbuf, uint8_t rxlen, 435 | uint8_t interdelay) { 436 | uint8_t status = 0; 437 | uint8_t i; 438 | uint8_t rxbuf2[rxlen + 2]; 439 | 440 | if (i2c_dev) { 441 | /* Write stage */ 442 | if (!i2c_dev->write(txbuf, txlen)) { 443 | return MLX90393_STATUS_ERROR; 444 | } 445 | delay(interdelay); 446 | 447 | /* Read status byte plus any others */ 448 | if (!i2c_dev->read(rxbuf2, rxlen + 1)) { 449 | return MLX90393_STATUS_ERROR; 450 | } 451 | status = rxbuf2[0]; 452 | for (i = 0; i < rxlen; i++) { 453 | rxbuf[i] = rxbuf2[i + 1]; 454 | } 455 | } 456 | 457 | if (spi_dev) { 458 | spi_dev->write_then_read(txbuf, txlen, rxbuf2, rxlen + 1, 0x00); 459 | status = rxbuf2[0]; 460 | for (i = 0; i < rxlen; i++) { 461 | rxbuf[i] = rxbuf2[i + 1]; 462 | } 463 | delay(interdelay); 464 | } 465 | 466 | /* Mask out bytes available in the status response. */ 467 | return (status >> 2); 468 | } 469 | 470 | /**************************************************************************/ 471 | /*! 472 | @brief Gets the sensor_t device data, Adafruit Unified Sensor format 473 | @param sensor Pointer to an Adafruit Unified sensor_t object that we'll 474 | fill in 475 | */ 476 | /**************************************************************************/ 477 | void Adafruit_MLX90393::getSensor(sensor_t *sensor) { 478 | /* Clear the sensor_t object */ 479 | memset(sensor, 0, sizeof(sensor_t)); 480 | 481 | /* Insert the sensor name in the fixed length char array */ 482 | strncpy(sensor->name, "MLX90393", sizeof(sensor->name) - 1); 483 | sensor->name[sizeof(sensor->name) - 1] = 0; 484 | sensor->version = 1; 485 | sensor->sensor_id = _sensorID; 486 | sensor->type = SENSOR_TYPE_MAGNETIC_FIELD; 487 | sensor->min_delay = 0; 488 | sensor->min_value = -50000; // -50 gauss in uTesla 489 | sensor->max_value = 50000; // +50 gauss in uTesla 490 | sensor->resolution = 0.15; // 100/16-bit uTesla per LSB 491 | } 492 | -------------------------------------------------------------------------------- /Adafruit_MLX90393.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | This is a library for the MLX90393 magnetometer. 3 | 4 | Designed specifically to work with the MLX90393 breakout from Adafruit: 5 | 6 | ----> https://www.adafruit.com/products/4022 7 | 8 | These sensors use I2C to communicate, 2 pins are required to interface. 9 | 10 | Adafruit invests time and resources providing this open source code, please 11 | support Adafruit and open-source hardware by purchasing products from 12 | Adafruit! 13 | 14 | Written by Kevin Townsend/ktown for Adafruit Industries. 15 | 16 | MIT license, all text above must be included in any redistribution 17 | *****************************************************************************/ 18 | #ifndef ADAFRUIT_MLX90393_H 19 | #define ADAFRUIT_MLX90393_H 20 | 21 | #include "Arduino.h" 22 | #include 23 | #include 24 | #include 25 | 26 | #define MLX90393_DEFAULT_ADDR (0x0C) /* Can also be 0x18, depending on IC */ 27 | 28 | #define MLX90393_AXIS_ALL (0x0E) /**< X+Y+Z axis bits for commands. */ 29 | #define MLX90393_CONF1 (0x00) /**< Gain */ 30 | #define MLX90393_CONF2 (0x01) /**< Burst, comm mode */ 31 | #define MLX90393_CONF3 (0x02) /**< Oversampling, filter, res. */ 32 | #define MLX90393_CONF4 (0x03) /**< Sensitivty drift. */ 33 | #define MLX90393_GAIN_SHIFT (4) /**< Left-shift for gain bits. */ 34 | #define MLX90393_HALL_CONF (0x0C) /**< Hall plate spinning rate adj. */ 35 | #define MLX90393_STATUS_OK (0x00) /**< OK value for status response. */ 36 | #define MLX90393_STATUS_SMMODE (0x08) /**< SM Mode status response. */ 37 | #define MLX90393_STATUS_RESET (0x01) /**< Reset value for status response. */ 38 | #define MLX90393_STATUS_ERROR (0xFF) /**< OK value for status response. */ 39 | #define MLX90393_STATUS_MASK (0xFC) /**< Mask for status OK checks. */ 40 | 41 | /** Register map. */ 42 | enum { 43 | MLX90393_REG_SB = (0x10), /**< Start burst mode. */ 44 | MLX90393_REG_SW = (0x20), /**< Start wakeup on change mode. */ 45 | MLX90393_REG_SM = (0x30), /**> Start single-meas mode. */ 46 | MLX90393_REG_RM = (0x40), /**> Read measurement. */ 47 | MLX90393_REG_RR = (0x50), /**< Read register. */ 48 | MLX90393_REG_WR = (0x60), /**< Write register. */ 49 | MLX90393_REG_EX = (0x80), /**> Exit moode. */ 50 | MLX90393_REG_HR = (0xD0), /**< Memory recall. */ 51 | MLX90393_REG_HS = (0x70), /**< Memory store. */ 52 | MLX90393_REG_RT = (0xF0), /**< Reset. */ 53 | MLX90393_REG_NOP = (0x00), /**< NOP. */ 54 | }; 55 | 56 | /** Gain settings for CONF1 register. */ 57 | typedef enum mlx90393_gain { 58 | MLX90393_GAIN_5X = (0x00), 59 | MLX90393_GAIN_4X, 60 | MLX90393_GAIN_3X, 61 | MLX90393_GAIN_2_5X, 62 | MLX90393_GAIN_2X, 63 | MLX90393_GAIN_1_67X, 64 | MLX90393_GAIN_1_33X, 65 | MLX90393_GAIN_1X 66 | } mlx90393_gain_t; 67 | 68 | /** Resolution settings for CONF3 register. */ 69 | typedef enum mlx90393_resolution { 70 | MLX90393_RES_16, 71 | MLX90393_RES_17, 72 | MLX90393_RES_18, 73 | MLX90393_RES_19, 74 | } mlx90393_resolution_t; 75 | 76 | /** Axis designator. */ 77 | typedef enum mlx90393_axis { 78 | MLX90393_X, 79 | MLX90393_Y, 80 | MLX90393_Z 81 | } mlx90393_axis_t; 82 | 83 | /** Digital filter settings for CONF3 register. */ 84 | typedef enum mlx90393_filter { 85 | MLX90393_FILTER_0, 86 | MLX90393_FILTER_1, 87 | MLX90393_FILTER_2, 88 | MLX90393_FILTER_3, 89 | MLX90393_FILTER_4, 90 | MLX90393_FILTER_5, 91 | MLX90393_FILTER_6, 92 | MLX90393_FILTER_7, 93 | } mlx90393_filter_t; 94 | 95 | /** Oversampling settings for CONF3 register. */ 96 | typedef enum mlx90393_oversampling { 97 | MLX90393_OSR_0, 98 | MLX90393_OSR_1, 99 | MLX90393_OSR_2, 100 | MLX90393_OSR_3, 101 | } mlx90393_oversampling_t; 102 | 103 | /** Lookup table to convert raw values to uT based on [HALLCONF][GAIN_SEL][RES]. 104 | */ 105 | const float mlx90393_lsb_lookup[2][8][4][2] = { 106 | 107 | /* HALLCONF = 0xC (default) */ 108 | { 109 | /* GAIN_SEL = 0, 5x gain */ 110 | {{0.751, 1.210}, {1.502, 2.420}, {3.004, 4.840}, {6.009, 9.680}}, 111 | /* GAIN_SEL = 1, 4x gain */ 112 | {{0.601, 0.968}, {1.202, 1.936}, {2.403, 3.872}, {4.840, 7.744}}, 113 | /* GAIN_SEL = 2, 3x gain */ 114 | {{0.451, 0.726}, {0.901, 1.452}, {1.803, 2.904}, {3.605, 5.808}}, 115 | /* GAIN_SEL = 3, 2.5x gain */ 116 | {{0.376, 0.605}, {0.751, 1.210}, {1.502, 2.420}, {3.004, 4.840}}, 117 | /* GAIN_SEL = 4, 2x gain */ 118 | {{0.300, 0.484}, {0.601, 0.968}, {1.202, 1.936}, {2.403, 3.872}}, 119 | /* GAIN_SEL = 5, 1.667x gain */ 120 | {{0.250, 0.403}, {0.501, 0.807}, {1.001, 1.613}, {2.003, 3.227}}, 121 | /* GAIN_SEL = 6, 1.333x gain */ 122 | {{0.200, 0.323}, {0.401, 0.645}, {0.801, 1.291}, {1.602, 2.581}}, 123 | /* GAIN_SEL = 7, 1x gain */ 124 | {{0.150, 0.242}, {0.300, 0.484}, {0.601, 0.968}, {1.202, 1.936}}, 125 | }, 126 | 127 | /* HALLCONF = 0x0 */ 128 | { 129 | /* GAIN_SEL = 0, 5x gain */ 130 | {{0.787, 1.267}, {1.573, 2.534}, {3.146, 5.068}, {6.292, 10.137}}, 131 | /* GAIN_SEL = 1, 4x gain */ 132 | {{0.629, 1.014}, {1.258, 2.027}, {2.517, 4.055}, {5.034, 8.109}}, 133 | /* GAIN_SEL = 2, 3x gain */ 134 | {{0.472, 0.760}, {0.944, 1.521}, {1.888, 3.041}, {3.775, 6.082}}, 135 | /* GAIN_SEL = 3, 2.5x gain */ 136 | {{0.393, 0.634}, {0.787, 1.267}, {1.573, 2.534}, {3.146, 5.068}}, 137 | /* GAIN_SEL = 4, 2x gain */ 138 | {{0.315, 0.507}, {0.629, 1.014}, {1.258, 2.027}, {2.517, 4.055}}, 139 | /* GAIN_SEL = 5, 1.667x gain */ 140 | {{0.262, 0.422}, {0.524, 0.845}, {1.049, 1.689}, {2.097, 3.379}}, 141 | /* GAIN_SEL = 6, 1.333x gain */ 142 | {{0.210, 0.338}, {0.419, 0.676}, {0.839, 1.352}, {1.678, 2.703}}, 143 | /* GAIN_SEL = 7, 1x gain */ 144 | {{0.157, 0.253}, {0.315, 0.507}, {0.629, 1.014}, {1.258, 2.027}}, 145 | }}; 146 | 147 | /** Lookup table for conversion time based on [DIF_FILT][OSR]. 148 | */ 149 | const float mlx90393_tconv[8][4] = { 150 | /* DIG_FILT = 0 */ 151 | {1.27, 1.84, 3.00, 5.30}, 152 | /* DIG_FILT = 1 */ 153 | {1.46, 2.23, 3.76, 6.84}, 154 | /* DIG_FILT = 2 */ 155 | {1.84, 3.00, 5.30, 9.91}, 156 | /* DIG_FILT = 3 */ 157 | {2.61, 4.53, 8.37, 16.05}, 158 | /* DIG_FILT = 4 */ 159 | {4.15, 7.60, 14.52, 28.34}, 160 | /* DIG_FILT = 5 */ 161 | {7.22, 13.75, 26.80, 52.92}, 162 | /* DIG_FILT = 6 */ 163 | {13.36, 26.04, 51.38, 102.07}, 164 | /* DIG_FILT = 7 */ 165 | {25.65, 50.61, 100.53, 200.37}, 166 | }; 167 | 168 | /** 169 | * Driver for the Adafruit MLX90393 magnetometer breakout board. 170 | */ 171 | class Adafruit_MLX90393 : public Adafruit_Sensor { 172 | public: 173 | Adafruit_MLX90393(); 174 | bool begin_I2C(uint8_t i2c_addr = MLX90393_DEFAULT_ADDR, 175 | TwoWire *wire = &Wire); 176 | bool begin_SPI(uint8_t cs_pin, SPIClass *theSPI = &SPI); 177 | 178 | bool reset(void); 179 | bool exitMode(void); 180 | 181 | bool readMeasurement(float *x, float *y, float *z); 182 | bool startSingleMeasurement(void); 183 | 184 | bool setGain(enum mlx90393_gain gain); 185 | enum mlx90393_gain getGain(void); 186 | 187 | bool setResolution(enum mlx90393_axis, enum mlx90393_resolution resolution); 188 | enum mlx90393_resolution getResolution(enum mlx90393_axis); 189 | 190 | bool setFilter(enum mlx90393_filter filter); 191 | enum mlx90393_filter getFilter(void); 192 | 193 | bool setOversampling(enum mlx90393_oversampling oversampling); 194 | enum mlx90393_oversampling getOversampling(void); 195 | 196 | bool setTrigInt(bool state); 197 | bool readData(float *x, float *y, float *z); 198 | 199 | bool getEvent(sensors_event_t *event); 200 | void getSensor(sensor_t *sensor); 201 | 202 | private: 203 | Adafruit_I2CDevice *i2c_dev = NULL; 204 | Adafruit_SPIDevice *spi_dev = NULL; 205 | 206 | bool readRegister(uint8_t reg, uint16_t *data); 207 | bool writeRegister(uint8_t reg, uint16_t data); 208 | bool _init(void); 209 | uint8_t transceive(uint8_t *txbuf, uint8_t txlen, uint8_t *rxbuf = NULL, 210 | uint8_t rxlen = 0, uint8_t interdelay = 10); 211 | 212 | enum mlx90393_gain _gain; 213 | enum mlx90393_resolution _res_x, _res_y, _res_z; 214 | enum mlx90393_filter _dig_filt; 215 | enum mlx90393_oversampling _osr; 216 | 217 | int32_t _sensorID = 90393; 218 | int _cspin; 219 | }; 220 | 221 | #endif /* ADAFRUIT_MLX90393_H */ 222 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Adafruit Industries 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adafruit MLX90393 Magnetic Field Sensor Driver [![Build Status](https://github.com/adafruit/Adafruit_MLX90393_Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_MLX90393_Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_MLX90393_Library/html/index.html) 2 | 3 | This driver is for use with the Adafruit MLX90393 Breakout, and has been 4 | designed specifically for these boards: 5 | 6 | ----> https://www.adafruit.com/product/4022 7 | 8 | Adafruit invests time and resources providing this open source code, 9 | please support Adafruit and open-source hardware by purchasing 10 | products from Adafruit! 11 | 12 | ## About this Driver 13 | 14 | Written by Kevin Townsend for Adafruit Industries. 15 | MIT license, all text above must be included in any redistribution 16 | -------------------------------------------------------------------------------- /examples/basicdemo/basicdemo.ino: -------------------------------------------------------------------------------- 1 | #include "Adafruit_MLX90393.h" 2 | 3 | Adafruit_MLX90393 sensor = Adafruit_MLX90393(); 4 | #define MLX90393_CS 10 5 | 6 | void setup(void) 7 | { 8 | Serial.begin(115200); 9 | 10 | /* Wait for serial on USB platforms. */ 11 | while (!Serial) { 12 | delay(10); 13 | } 14 | 15 | Serial.println("Starting Adafruit MLX90393 Demo"); 16 | 17 | if (! sensor.begin_I2C()) { // hardware I2C mode, can pass in address & alt Wire 18 | //if (! sensor.begin_SPI(MLX90393_CS)) { // hardware SPI mode 19 | Serial.println("No sensor found ... check your wiring?"); 20 | while (1) { delay(10); } 21 | } 22 | Serial.println("Found a MLX90393 sensor"); 23 | 24 | sensor.setGain(MLX90393_GAIN_1X); 25 | // You can check the gain too 26 | Serial.print("Gain set to: "); 27 | switch (sensor.getGain()) { 28 | case MLX90393_GAIN_1X: Serial.println("1 x"); break; 29 | case MLX90393_GAIN_1_33X: Serial.println("1.33 x"); break; 30 | case MLX90393_GAIN_1_67X: Serial.println("1.67 x"); break; 31 | case MLX90393_GAIN_2X: Serial.println("2 x"); break; 32 | case MLX90393_GAIN_2_5X: Serial.println("2.5 x"); break; 33 | case MLX90393_GAIN_3X: Serial.println("3 x"); break; 34 | case MLX90393_GAIN_4X: Serial.println("4 x"); break; 35 | case MLX90393_GAIN_5X: Serial.println("5 x"); break; 36 | } 37 | 38 | // Set resolution, per axis. Aim for sensitivity of ~0.3 for all axes. 39 | sensor.setResolution(MLX90393_X, MLX90393_RES_17); 40 | sensor.setResolution(MLX90393_Y, MLX90393_RES_17); 41 | sensor.setResolution(MLX90393_Z, MLX90393_RES_16); 42 | 43 | // Set oversampling 44 | sensor.setOversampling(MLX90393_OSR_3); 45 | 46 | // Set digital filtering 47 | sensor.setFilter(MLX90393_FILTER_5); 48 | } 49 | 50 | void loop(void) { 51 | float x, y, z; 52 | 53 | // get X Y and Z data at once 54 | if (sensor.readData(&x, &y, &z)) { 55 | Serial.print("X: "); Serial.print(x, 4); Serial.println(" uT"); 56 | Serial.print("Y: "); Serial.print(y, 4); Serial.println(" uT"); 57 | Serial.print("Z: "); Serial.print(z, 4); Serial.println(" uT"); 58 | } else { 59 | Serial.println("Unable to read XYZ data from the sensor."); 60 | } 61 | 62 | delay(500); 63 | 64 | /* Or....get a new sensor event, normalized to uTesla */ 65 | sensors_event_t event; 66 | sensor.getEvent(&event); 67 | /* Display the results (magnetic field is measured in uTesla) */ 68 | Serial.print("X: "); Serial.print(event.magnetic.x); 69 | Serial.print(" \tY: "); Serial.print(event.magnetic.y); 70 | Serial.print(" \tZ: "); Serial.print(event.magnetic.z); 71 | Serial.println(" uTesla "); 72 | 73 | delay(500); 74 | } -------------------------------------------------------------------------------- /examples/compass_calibrated/compass_calibrated.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Demo of computing the heading (of the +X axis) from magnetometer data 3 | * obtained from an MLX90393. Hard-iron and soft-iron calibration offsets 4 | * and scaling are applied to account for such distortions. Additionally, 5 | * the magnetic declination can be applied to convert magnetic heading to 6 | * geographic heading. 7 | * 8 | * Leave everything as default to apply no calibration data or declination. 9 | * 10 | * Run magcal_nosave.ino example to send raw data to MotionCal, following 11 | * this tutorial: 12 | * https://learn.adafruit.com/adafruit-sensorlab-magnetometer-calibration/ 13 | * 14 | * Copy the hard-iron and soft-iron calibration data to hard_iron[] and 15 | * soft_iron[][] arrays. Find your location from 16 | * https://www.magnetic-declination.com/. Copy the "Magnetic Declination" 17 | * angle value to mag_decl if you want to convert magnetic heading to 18 | * geographic heading. 19 | * 20 | * Author: Shawn Hymel 21 | * Date: February 20, 2022 22 | * 23 | * Based on the Adafruit_LIS2MDL compass demo by Limor Fried 24 | ***************************************************************************/ 25 | 26 | #include "Adafruit_MLX90393.h" 27 | 28 | // Hard-iron calibration settings 29 | // Set to {0, 0, 0} for no hard-iron offset 30 | const float hard_iron[3] = { 31 | 0.0, 0.0, 0.0 32 | }; 33 | 34 | // Soft-iron calibration settings 35 | // Set to identity matrix for no soft-iron scaling 36 | const float soft_iron[3][3] = { 37 | { 1.0, 0.0, 0.0 }, 38 | { 0.0, 1.0, 0.0 }, 39 | { 0.0, 0.0, 1.0 } 40 | }; 41 | 42 | // Magnetic declination from magnetic-declination.com 43 | // East is positive (+), west is negative (-) 44 | // mag_decl = (+/-)(deg + min/60 + sec/3600) 45 | // Set to 0 to get magnetic heading instead of geographic heading 46 | const float mag_decl = 0.0; 47 | 48 | // Sensor object 49 | Adafruit_MLX90393 mlx = Adafruit_MLX90393(); 50 | 51 | void setup() { 52 | 53 | // Start serial 54 | Serial.begin(115200); 55 | while (!Serial) { 56 | delay(10); 57 | } 58 | 59 | // Say hello 60 | Serial.println("Starting Adafruit MLX90393 Calibrated Compass"); 61 | 62 | // Connect to sensor 63 | if (!mlx.begin_I2C()) { 64 | Serial.println("ERROR: Could not connect to magnetometer"); 65 | while(1); 66 | } 67 | 68 | // Configure MLX90393 69 | mlx.setGain(MLX90393_GAIN_1X); 70 | mlx.setResolution(MLX90393_X, MLX90393_RES_17); 71 | mlx.setResolution(MLX90393_Y, MLX90393_RES_17); 72 | mlx.setResolution(MLX90393_Z, MLX90393_RES_16); 73 | mlx.setOversampling(MLX90393_OSR_3); 74 | mlx.setFilter(MLX90393_FILTER_5); 75 | } 76 | 77 | void loop() { 78 | 79 | // Raw magnetometer data stored as {x, y, z} 80 | static float mag_data[3] = {0.0, 0.0, 0.0}; 81 | 82 | static float hi_cal[3]; 83 | static float heading; 84 | 85 | // Sample and compensate with hard/soft-iron calibration data 86 | if (mlx.readData(&mag_data[0], &mag_data[1], &mag_data[2])) { 87 | 88 | // Apply hard-iron offsets 89 | for (uint8_t i = 0; i < 3; i++) { 90 | hi_cal[i] = mag_data[i] - hard_iron[i]; 91 | } 92 | 93 | // Apply soft-iron scaling 94 | for (uint8_t i = 0; i < 3; i++) { 95 | mag_data[i] = (soft_iron[i][0] * hi_cal[0]) + 96 | (soft_iron[i][1] * hi_cal[1]) + 97 | (soft_iron[i][2] * hi_cal[2]); 98 | } 99 | 100 | // Calculate angle for heading, assuming board is parallel to 101 | // the ground and +X points toward heading. 102 | // WARNING: X and Y silkscreen marketings are backward on v1 of board 103 | heading = (atan2(mag_data[1], mag_data[0]) * 180) / M_PI; 104 | 105 | // Apply magnetic declination to convert magnetic heading 106 | // to geographic heading 107 | heading += mag_decl; 108 | 109 | // Normalize to 0..360 110 | if (heading < 0) { 111 | heading += 360; 112 | } 113 | 114 | // Print raw readings and heading 115 | Serial.print("X: "); 116 | Serial.print(mag_data[0], 2); 117 | Serial.print("\tY: "); 118 | Serial.print(mag_data[1], 2); 119 | Serial.print("\tZ: "); 120 | Serial.print(mag_data[2], 2); 121 | Serial.print("\tHeading: "); 122 | Serial.println(heading, 2); 123 | 124 | } else { 125 | Serial.println("Unable to read XYZ data from the sensor."); 126 | } 127 | 128 | // Wait some 129 | delay(10); 130 | } -------------------------------------------------------------------------------- /examples/magcal_nosave/magcal_nosave.ino: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Demo of sending magnetometer sensor data to a calibration software. To be 3 | * used with MotionCal and Jupyter Notebook examples found in this tutorial: 4 | * https://learn.adafruit.com/adafruit-sensorlab-magnetometer-calibration/ 5 | * 6 | * Note that this demo does not include accelerometer or gyroscope data. It 7 | * is just for sending raw magnetometer data to be used in the calibration 8 | * process. 9 | * 10 | * An example of using calibrated magnetometer data can be found in 11 | * compass_calibrated.ino. 12 | * 13 | * Author: Shawn Hymel 14 | * Date: February 20, 2022 15 | * 16 | * Based on imucal by PJRC and adapted by Limor Fried for Adafruit Industries 17 | ***************************************************************************/ 18 | 19 | #include "Adafruit_MLX90393.h" 20 | 21 | // Sensor object 22 | Adafruit_MLX90393 mlx = Adafruit_MLX90393(); 23 | 24 | void setup() { 25 | 26 | // Start serial 27 | Serial.begin(115200); 28 | while (!Serial) { 29 | delay(10); 30 | } 31 | 32 | // Say hello 33 | Serial.println("MLX90393 Calibration"); 34 | 35 | // Connect to sensor 36 | if (!mlx.begin_I2C()) { 37 | Serial.println("ERROR: Could not connect to magnetometer"); 38 | while(1); 39 | } 40 | 41 | // Configure MLX90393 42 | mlx.setGain(MLX90393_GAIN_1X); 43 | mlx.setResolution(MLX90393_X, MLX90393_RES_17); 44 | mlx.setResolution(MLX90393_Y, MLX90393_RES_17); 45 | mlx.setResolution(MLX90393_Z, MLX90393_RES_16); 46 | mlx.setOversampling(MLX90393_OSR_3); 47 | mlx.setFilter(MLX90393_FILTER_5); 48 | } 49 | 50 | void loop() { 51 | 52 | static float x, y, z; 53 | 54 | // Sample data from magnetometer 55 | if (mlx.readData(&x, &y, &z)) { 56 | 57 | // Print raw data out for MotionCal (no accel or gyro data) 58 | Serial.print("Raw:"); 59 | Serial.print(0); Serial.print(","); 60 | Serial.print(0); Serial.print(","); 61 | Serial.print(0); Serial.print(","); 62 | Serial.print(0); Serial.print(","); 63 | Serial.print(0); Serial.print(","); 64 | Serial.print(0); Serial.print(","); 65 | Serial.print(int(x*10)); Serial.print(","); 66 | Serial.print(int(y*10)); Serial.print(","); 67 | Serial.print(int(z*10)); Serial.println(""); 68 | 69 | // Unified data (no accel or gyro data) 70 | Serial.print("Uni:"); 71 | Serial.print(0); Serial.print(","); 72 | Serial.print(0); Serial.print(","); 73 | Serial.print(0); Serial.print(","); 74 | Serial.print(0); Serial.print(","); 75 | Serial.print(0); Serial.print(","); 76 | Serial.print(0); Serial.print(","); 77 | Serial.print(int(x)); Serial.print(","); 78 | Serial.print(int(y)); Serial.print(","); 79 | Serial.print(int(z)); Serial.println(""); 80 | 81 | } else { 82 | Serial.println("Unable to read XYZ data from the sensor."); 83 | } 84 | 85 | // Wait some 86 | delay(10); 87 | } -------------------------------------------------------------------------------- /examples/oled_demo/oled_demo.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Adafruit_MLX90393.h" 3 | 4 | Adafruit_MLX90393 sensor = Adafruit_MLX90393(); 5 | Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire); 6 | 7 | void setup() { 8 | Serial.begin(115200); 9 | //while (!Serial); 10 | Serial.println("MLX demo"); 11 | 12 | if (sensor.begin_I2C()) { 13 | Serial.println("Found a MLX90393 sensor"); 14 | } else { 15 | Serial.println("No sensor found ... check your wiring?"); 16 | while (1); 17 | } 18 | 19 | // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally 20 | if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 21 | Serial.println(F("SSD1306 allocation failed")); 22 | for(;;); // Don't proceed, loop forever 23 | } 24 | display.display(); 25 | delay(500); // Pause for 2 seconds 26 | display.setTextSize(1); 27 | display.setTextColor(WHITE); 28 | } 29 | 30 | 31 | void loop() { 32 | float x, y, z; 33 | 34 | display.clearDisplay(); 35 | if(sensor.readData(&x, &y, &z)) { 36 | Serial.print("X: "); Serial.print(x, 4); Serial.println(" uT"); 37 | Serial.print("Y: "); Serial.print(y, 4); Serial.println(" uT"); 38 | Serial.print("Z: "); Serial.print(z, 4); Serial.println(" uT"); 39 | 40 | display.setCursor(0,0); 41 | display.println("- Adafruit MLX90393 -"); 42 | display.print("X:"); display.print(x, 1); display.println(" uT"); 43 | display.print("Y:"); display.print(y, 1); display.println(" uT"); 44 | display.print("Z:"); display.print(z, 1); display.println(" uT"); 45 | } else { 46 | Serial.println("Unable to read XYZ data from the sensor."); 47 | } 48 | display.display(); 49 | delay(50); 50 | } 51 | 52 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit MLX90393 2 | version=2.0.5 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Driver for the MLX90393 magenetic field sensor 6 | paragraph=Driver for the MLX90393 magenetic field sensor 7 | category=Sensors 8 | url=https://github.com/adafruit/Adafruit_MLX90393_Library 9 | architectures=* 10 | depends=Adafruit BusIO, Adafruit Unified Sensor, Adafruit SSD1306 11 | --------------------------------------------------------------------------------