Infineon / TLV493D-A1B6-3DMagnetic-Sensor

Library for the TLV493D-A1B6 3D magnetic sensor for Arduino.
MIT License
39 stars 27 forks source link

Data "freezes" after some time, reseting gets back to work #24

Closed luizenger closed 1 year ago

luizenger commented 1 year ago

Hello there,

I am using a Python script with PySerial module to communicate with TLV493D-A1B6 MS2Go V3.2 kit.

With Arduino IDE, I programmed the sensor in MASTER CONTROLLED MODE based on the Cartesian_Fast example. In the loop function I read serial and if there is an specific character, I write to serial the magnetic field values. I am using the latest release of the Arduino library.

The Python script writes to serial that specific character when field values are wanted, and then reads serial.

The thing is, in the Python script I am reading in a loop because I want to sample X times the field values. I send the command, read serial to get the message, do a 2 ms sleep and then send the command again.

It works, but sometimes I start to get the exact same field values even when I am sure they must be different. If I reset the sensor (re-uploading the Arduino sketch or simply unplugging and plugging back the USB cable), it gets back to work as it should. The number of readings I can perform before this "freezing" is not fixed. Once I could do up to 26 k readings, once less than 5 k.

My guess is that somehow the sensor itself "dies" and register values are not longer updated. So the XMC uC puts into serial the latest value before the crash.

Any ideas on why this happens? And how could I avoid it? I could add another function to the Arduino sketch to force a reset of the sensor if another specific command is received in serial, and periodically send that command in my Python script. But initially I would like to avoid that,

The sleep of 2 ms in the Python script was chosen after checking how long it took for new data to be available: I timed the updateData() method using micros() in the Arduino sketch, and it yielded on average 1800 us. I had to use two updateData() in a row because new data wasn't showing up properly with only one function call. This comes to a second question: how to properly set the sampling frequency in MASTER CONTROLLED MODE without losing bits of resolution? I would like to sample as fast as possible while keeping the 12 bits. But this can be done later.

Thank you!

9Volts9er commented 1 year ago

Hi,

this sounds like the "ADC hang up" described in chapter 5.6 of the User Manual. Unfortunately this can not be avoided and can happen at any time during sensor operation.

The sensors VDD on the MS2Go kit is connected to P1.0 of the XMC1100, so you can easily reset the sensor by setting this pin to LOW and after a short amount of time to HIGH again. Another possibility would be to send the general address 0x00 via I2C. This also triggers a sensor reset. After the reset, the sensor needs to be reconfigured to the desired mode again.

With the 2nd generation 3D sensor this ADC hang up problem has been solved. (Link to the 2Go Kit: TLE493D-W2B6 MS2Go Kit)

luizenger commented 1 year ago

Thank you for the fast reply! I'll check on that. Do you know what causes the this "hang up"? Is there any way it can be avoided in MCM?

Also, any idea as to why one .updateData() is not enough to get the proper new values with .getX() when in MCM? If I configure sensor to low power I do not have this problem. The CartesianFast example constantly updates and prints values to serial monitor in the void loop{}, so I can't see if the very first value after changing the field is equal to the very last before the change. I would need to add more automation and control to the field itself to verify that.

I have something like:

void loop() { if (Serial.read == 'r') { Tlv493dMagnetic3DSensor.updateData(); Tlv493dMagnetic3DSensor.updateData(); // this is the second updateData() I need so getX prints the new values //delay () --> any value here makes no difference Serial.print(Tlv493dMagnetic3DSensor.getX()); } }

The Python script writes 'r' in serial, reads serial, waits 2 ms, writes 'r' again, etc until N samples are acquired. I believe it has to do with the fact that in MCM conversion is triggered by uC while in low power it does it at a fixed 100 Hz rate. But currently I don't have the knowledge to quickly understand all the .h and .cpp code in the repository + required timings presented in User Manual and datasheet.

Edit: added more info and remove code formatting using ` as it was completely messing up the formatting.

9Volts9er commented 1 year ago

I guess, this is a bug of the sensor, but I'm not sure what internal processes lead to this behavior. Anyhow, this cannot be avoided as long as you are using Master Controlled Mode or Fast Mode.

Yes, you are right with your assumption. In Low Power mode the sensor samples with 100Hz and when reading you will always get the last sampled value. You will get this value twice, if you read again before the next AD conversion of the sensor is finished. In Master Controlled Mode the AD conversion is triggerd by addressing the sensor via I2C. Therefore with the first updateData() you trigger a new AD conversion (and readout the values from the previous sampling), and with the second updateData() you then finally get the freshly sampled values. It would be enough to only write the address instead of the first updateData() and then wait a bit until the AD conversion is done, but I think the library does not support this. FYI: Figure 13 in chapter 5.5 of the User Manual shows how the AD conversion is triggered in Master Controlled Mode.

luizenger commented 1 year ago

Thanks a lot for the explanation! I could add a function to the library to check mExpectedFrameCount against the actual value and see if a hang up happened, and then reset the sensor. But then again this is just so I could do full 12 bits resolution readings faster than low power mode... Can this hang up problem be a timing issue? As I am not following an interrupt-based approach, I may be violating the specs... I added some delay between the two updateData() while running in MCM and could do 100 k readings without any problem...

Anyway, I will close the issue. Once more, thank you.

9Volts9er commented 1 year ago

I don't think you are violating any specs. Actually I just had a look into the datasheet, but MCM and Fast Mode are not mentioned there. Therefore I believe that this is really some kind of sensor bug. But it could be possible to avoid the problem by trimming the delays just right. However it is not guaranteed that this will work forever without reset...