Open asfarley opened 12 months ago
The code in getTemp() uses a slightly different method for getting the MSB/LSB values from the device, I'm not sure why.
The code only refers to the MSB register:
float TMAG5273::getTemp()
{
// Variable to store full temperature value
int16_t temp = 0;
uint8_t databuffer[2];
// Read in the MSB and LSB registers
readRegisters(TMAG5273_REG_T_MSB_RESULT, databuffer, 2);
// Combines the two in one register where the MSB is shifted to the correct location
temp = (databuffer[0] << 8) | (databuffer[1]);
// Formula for correct output value
float tempOut = TMAG5273_TSENSE_T0 + (((float)temp - TMAG5273_TADC_T0) / (TMAG5273_TADC_RES));
return tempOut;
}
Whereas the code for e.g. GetZData reads MSB and LSB explicitly:
float TMAG5273::getZData()
{
int8_t zLSB = 0;
int8_t zMSB = 0;
zLSB = readRegister(TMAG5273_REG_Z_LSB_RESULT);
zMSB = readRegister(TMAG5273_REG_Z_MSB_RESULT);
// Variable to store full X data
int16_t zData = 0;
// Combines the two in one register where the MSB is shifted to the correct location
zData = zLSB + (zMSB << 8);
// Reads to see if the range is set to 40mT or 80mT
uint8_t rangeValZ = getZAxisRange();
uint8_t range = 0;
if (rangeValZ == 0)
{
range = 40;
}
else if (rangeValZ == 1)
{
range = 80;
}
// div = (2^16) / 2 (as per the datasheet equation 10)
// 16-bit data format equation
float div = 32768;
float zOut = (range * zData) / div;
return zOut;
}
I tried modifying getTemp to use the same approach, and now I'm getting a more sensible value (33C) although this is quite a bit higher than I expected unless the IC is self-heating by 13C.
The values I'm seeing for MSB and LSB are around 70 and 64 respectively. The LSB is moving around the amount I would expect (by the lower 1-2 bits) so it looks believable.
Here's the exact Arduino sketch code I'm using for completeness:
//#include <SoftwareWire.h>
#include <Wire.h> // Used to establish serial communication on the I2C bus
#include "SparkFun_TMAG5273_Arduino_Library.h" // Used to send and recieve specific information from our sensor
// I2C default address
#define TMAG5273_I2C_ADDRESS_INITIAL 0X35 // I2C ADDRESS (7 MBS BITS - TMAG5273A1)
#define TMAG5273_I2C_ADDRESS_WRITE 0X6A // I2C WRITE ADDRESS (8-bit)
#define TMAG5273_I2C_ADDRESS_READ 0X6B // I2C READ ADDRESS (8-bit)
TMAG5273 sensor; // Initialize hall-effect sensor
// I2C default address
uint8_t i2cAddress = TMAG5273_I2C_ADDRESS_INITIAL;
void setup() {
//myWire.begin();
Wire.begin();
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(A0, OUTPUT);
pinMode(6, INPUT);
pinMode(12, INPUT);
delay(1000);
// If begin is successful (0), then start example
if(sensor.begin(i2cAddress, Wire) == 1)
{
Serial.println("Begin");
}
else // Otherwise, infinite loop
{
Serial.println("Device failed to setup - Freezing code.");
while(1); // Runs forever
}
}
void loop() {
ReadMagnetometer();
// put your main code here, to run repeatedly:
// int j3 = digitalRead(6);
// int j4 = digitalRead(12);
// Serial.print("J3:");
// Serial.println(j3);
// Serial.print("J4:");
// Serial.println(j4);
//Serial.println("PF7:ON");
digitalWrite(A0, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
//Serial.println("PF7:OFF");
digitalWrite(A0, LOW); // turn the LED off by making the voltage LOW
delay(1000);
//Serial.println("Hello from ThrottleController");
}
void ReadMagnetometer()
{
// Checks if mag channels are on - turns on in setup
if(sensor.getMagneticChannel() != 0)
{
sensor.setTemperatureEn(true);
float magX = sensor.getXData();
float magY = sensor.getYData();
float magZ = sensor.getZData();
float temp = sensor.getTemp();
Serial.print("(");
Serial.print(magX);
Serial.print(", ");
Serial.print(magY);
Serial.print(", ");
Serial.print(magZ);
Serial.println(") mT");
Serial.print(temp);
Serial.println(" C");
}
else
{
// If there is an issue, stop the magnetic readings and restart sensor/example
Serial.println("Mag Channels disabled, stopping..");
}
}
Here's a schematic of my circuit, although (since the IC seems to be responding) I think this is probably a software issue rather than hardware.
I noticed a couple of things I don't understand:
I'm reading through the data sheet to check the code against the specs. The device returns 2s-complement values, so the final result interpreted as one 16-bit number should be interpreted as signed. According to the Arduino website, the Atmega-based devices use 16-bit 2s complement for integers.
It doesn't seem correct to me to sum together 2 signed values which each are one byte of a 2s-complement value. I also can't see anything in the datasheet indicating why the x-channel would need to be reversed.
I had success modifying the 2s-complement conversion routine in the library. It's interesting to me that there was another report of a similar issue, and it seemed to be fixed then. Is there some MCU dependency here? The other user was using an ESP8266.
Hi @asfarley ,
As for the X-Channel sign, it should be a negative number. If you look at Equation 10 on page 22 of the datasheet, all of the signs need to be flipped to be multiplied by (-1). The Y and Z channels will be corrected to match in the next release of this library.
For the temperature function confusion, this uses the readRegisters() function, not readRegister(). This function reads both the MSB and the LSB registers by reading one register, and then the next, combining them.
As for the issues that you are seeing with inconsistent readings of the temperature functionality, that issue was fixed in the previous update as you had mentioned. I have been testing with your code trying to recreate the issue that you have been seeing, but been having no luck. I'm going to continue with this throughout the day but wanted to give an update for the time being. I do not believe that it is an MCU dependency, but that will also be taken into consideration when testing. Thanks!
@MadisonC-SparkFun Thanks for following up. Are there any differences between my hardware/software setup and yours?
As for my testing environment, I have been using the following:
My temperature readings with each device are consistently reading around 24-25C in my environment (which is reading a tad high, but I do keep my office quite warm with a heater so it would make sense for my case).
Is the interrupt pin tied to ground on your TMAG?
Are you able to test with a Leonardo/ Atmega32u4?
Interesting re: temperature readings. 24-25C seems more believable than 30C.
I've been getting sensible/apparently correct magnetic readings after locally makes some changes to this library. My changes required a different method of 2s-complement conversion compared to what is in 1.0.3.
I'll post back here after doing some detailed testing on the changes I introduced.
The interrupt is tied high to 3.3V
As for the other boards, I will get my hands on those and report back with how those test 👍
Hi @asfarley , after doing some more testing, I have been unable to recreate the issue that you have been seeing. Since this is not being tested on a SparkFun product, there are a lot of variables that could be playing into this issue. At this point, I'm going to refer you to the SparkFun Forums for further questions and technical help. I am going to keep this issue open to see if any other users have come across this. https://forum.sparkfun.com/
I have the same results on a Sparkfun Pro Micro C https://www.sparkfun.com/products/15795 and Sparkfun 3D Linear Hall Effect Sensor https://www.sparkfun.com/products/23880 . I read -266C. I'll tinker around and see if I can help.
-Joe
Hi @joemcmanus, after some testing on my end with the Pro Micro C I am unable to recreate this result. I'm going to point you in the direction of our forums for further questions and technical help. https://forum.sparkfun.com/
I am using
After running the Example 1. Basic Reading from TMAG5273 Library. I got the results shown in the following figure.
I felt like all three-axis magnetic readings didn't make sense. I also tested with some PM, the reading will never be larger than 1mT.
For more information, I also attached my PCB board.
I would appreciate it very much if someone could give me some hints on how to debug this project. Thanks!
I'm also having this issue with the Pro Micro C Qwiic and the TMAG5273 sensor. Exactly the same boards as Joe in #issuecomment-1991918332
Oscilloscope shows that the data from the mag sensor looks correct, I suspect there is an issue with the conversion to floating point on the ATMEGA32U4 chip.
Yep, returning the values directly as int16 solves the problem. Not familiar with using floating point on ATMega chips (not am I interested in doing so), so I don't have a real "fix" for this, but you can use this patch to test. int16.patch
The change to uint8_t came from PR #8 which should also be merged, since it doesn't make sense to store multibyte I2C data in an int8_t.
I was able to get it working for myself on the ATMega, here's my fork:
https://github.com/asfarley/SparkFun_TMAG5273_Arduino_Library.git
@WenjingLi2036 Hi May I know if you solve this problem? I met the same problem recently.
I am using:
Steps to reproduce
Run BasicReadings code. Observe that Z-axis readings are consistent/make sense based on magnet presence, but X/Y axis readings seem to just be jumping around without any relationship to field strength.
Also, the temperature reading is indicating -266C. It's about 21C here.
Expected behavior
I expect a close-to-0 reading on magnetic axes when they're not exposed to a magnet. I expect a temperature reading around 21C.
Here's what I'm seeing from the Serial Monitor:
-266.31 C (0.94, -0.47, -0.03) mT -266.31 C (0.94, -0.66, -0.03) mT -266.31 C (0.51, -0.70, -0.02) mT -266.31 C (0.70, -0.66, -0.02) mT -266.31 C (0.94, -0.35, -0.02) mT -266.31 C (0.27, -0.82, -0.02) mT -266.31 C (0.86, -0.39, 0.00) mT -266.31 C (0.86, -0.86, -0.03) mT -266.31 C (0.43, -0.35, -0.03) mT -266.31 C (0.94, -0.47, -0.02) mT -266.31 C
I'll do some lower-level debugging and post the results here.