adafruit / Adafruit_MLX90393_Library

MIT License
14 stars 18 forks source link

Need to be able to read data without being in single measurement mode #13

Open j980m842 opened 3 years ago

j980m842 commented 3 years ago

The current library forces you into single measurement mode to do the readData command which slows the sampling rate down drastically. According to the data sheet I should be able to achieve ~500 Hz. However, I can only get 90~. After working on this for several days and chatting with a few people on the adafruit discord I believe we have arrived at this as the only problem. To double check I used Ted Yapo's MLX90393 library with identical settings and got ~500 Hz sampling rate because that library doesn't force you into single measurement mode. Could the library be modified to make it possible to read data without being in single measurement mode? I believe this causes the magnetometer to perpetually go to sleep and re-awaken each time data is supposed to be read and slows the sampling frequency down a lot. I have pasted my code below which is full of trouble shooting things like printing millis() frequently to show me what in the code is taking so long... Thanks!

/* SDA: A4 SCL: A5 3v3: 3v3 GND: GND DRDY (might be labeled Int): A3

*/

include

include

include "Adafruit_MLX90393.h"

include

define MAG_I2C_ADDRESS 0xC

Adafruit_MLX90393 mlx = Adafruit_MLX90393();

define MLX90393_CS 10

int i =0;

void setup() { Serial.begin(115200); Wire.begin(); Wire.setClock(1000000); M5.begin();

byte status = mlx.begin_I2C(); //iic jumpers set

mlx.setGain(MLX90393_GAIN_5X); mlx.setResolution(MLX90393_X, MLX90393_RES_16); mlx.setResolution(MLX90393_Y, MLX90393_RES_16); mlx.setResolution(MLX90393_Z, MLX90393_RES_16); mlx.setOversampling(MLX90393_OSR_0); mlx.setFilter(MLX90393_FILTER_2);

}

void loop() { Serial.print("1,"); Serial.println(millis()); float x, y, z; Serial.print("2,"); Serial.println(millis()); mlx.readData(&x, &y, &z); Serial.print("3,"); Serial.println(millis());

if(i>9){ Serial.print(millis()); Serial.print(", ");

Serial.print(x, 2); Serial.print(", "); Serial.print(y, 2); Serial.print(", "); Serial.print(z, 2); Serial.println(" ; "); Serial.print("4,"); Serial.println(millis()); i=0; }

//delay(500); i++; Serial.print("5,"); Serial.println(millis()); }

ladyada commented 3 years ago

hi what is the exact sensor you are using, can you provide a URL?

j980m842 commented 3 years ago

It’s the adafruit MLX90393 breakout board.

https://www.adafruit.com/product/4022?gclid=EAIaIQobChMIyLD88KLP7QIVQb2GCh3SagQNEAAYASAAEgJW2fD_BwE

ladyada commented 3 years ago

we dont have any plans for continuous mode, we'll leave this open in case someone wants to submit code for that. for now we recommend that other library if it works for you :)

SarwarN88 commented 3 years ago

I believe this causes the magnetometer to perpetually go to sleep and re-awaken each time data is supposed to be read and slows the sampling frequency down a lot.

Where did you get that information from? In the data sheet it doesn't describe that in SM mode exist and wake-up mode will be initiated. It only state that exit mode will be rejected. also by looking at your example you are running the chip on I2C protocol which the clock can run at maximum frequency of 400KHz (fast mode) but you are sitting the clock to 1MHz. In the SPI protocol you can reach max clock frequency of 10MHz.
Capture

Holdenpham commented 2 years ago

M5StickC I used the below code, but sampling rate achieves to 70 Hz. Could you tell me how to increase it to 500 Hz.

include "Adafruit_MLX90393.h"

Adafruit_MLX90393 sensor = Adafruit_MLX90393();

define MLX90393_CS 10

void setup(void) { Serial.begin(2000000);

/ Wait for serial on USB platforms. / while (!Serial) { delay(5); }

Serial.println("Starting Adafruit MLX90393 Demo");

if (! sensor.begin_I2C()) { // hardware I2C mode, can pass in address & alt Wire //if (! sensor.begin_SPI(MLX90393_CS)) { // hardware SPI mode Serial.println("No sensor found ... check your wiring?"); while (1) { delay(5); } } Serial.println("Found a MLX90393 sensor");

sensor.setGain(MLX90393_GAIN_5X); // You can check the gain too Serial.print("Gain set to: "); switch (sensor.getGain()) { case MLX90393_GAIN_1X: Serial.println("1 x"); break; case MLX90393_GAIN_1_33X: Serial.println("1.33 x"); break; case MLX90393_GAIN_1_67X: Serial.println("1.67 x"); break; case MLX90393_GAIN_2X: Serial.println("2 x"); break; case MLX90393_GAIN_2_5X: Serial.println("2.5 x"); break; case MLX90393_GAIN_3X: Serial.println("3 x"); break; case MLX90393_GAIN_4X: Serial.println("4 x"); break; case MLX90393_GAIN_5X: Serial.println("5 x"); break; }

// Set resolution, per axis sensor.setResolution(MLX90393_X, MLX90393_RES_16); sensor.setResolution(MLX90393_Y, MLX90393_RES_16); sensor.setResolution(MLX90393_Z, MLX90393_RES_16);

// Set oversampling sensor.setOversampling(MLX90393_OSR_0);

// Set digital filtering sensor.setFilter(MLX90393_FILTER_0); }

void loop(void) { float x, y, z;

// get X Y and Z data at once /*if (sensor.readData(&x, &y, &z)) { Serial.print("X: "); Serial.print(x, 4); Serial.println(" uT"); Serial.print("Y: "); Serial.print(y, 4); Serial.println(" uT"); Serial.print("Z: "); Serial.print(z, 4); Serial.println(" uT"); } else { Serial.println("Unable to read XYZ data from the sensor."); }

//delay(500);

/ Or....get a new sensor event, normalized to uTesla / sensors_event_t event; sensor.getEvent(&event); / Display the results (magnetic field is measured in uTesla) / Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print(" \tY: "); Serial.print(event.magnetic.y); Serial.print(" \tZ: "); Serial.print(event.magnetic.z); Serial.println(" uTesla ");

// delay(500); }

busload-pessimist-cornbread commented 9 months ago

This PR should get you to ~400Hz single axis, ~500Hz all axis.