Closed TinManAkshay closed 3 years ago
Hi @TinManAkshay , are you using the LSM6DSR via I2C on your PCB? If so, it could be an issue due to I3C. In order to prevent the component to start in I3C mode, you should put a Pull-Down resistor on INT1 of LSM6DSR. If you cannot do it on your PCB, there is also a software workaround that consists of setting INT1 pin of LSM6DSR low before initializing the sensor; after the initialization of the sensor that disables I3C mode by software, you can configure INT1 as interrupt pin and using it as usual. If you cannot control INT1 in your PCB because you did not connect it to the MCU, it could be an issue because you cannot apply the workaround that I suggested. Best Regards, Carlo
Hi @cparata
Thank you for your quick response.
Yes we have been communicating with the IMU via I2C on our PCB. INT1 interrupt pin is not connected to the MCU, so I am afraid that we cannot do anything about the hardware now. If there is anything we can do on a software level to prevent I3C to happen, then it'd be awesome.
So how do you suggest here? Shall I just pull the INT1 pin low in an arduino code? I dont know how it is going to effect that since pin is not connected to the MCU?
Hi @TinManAkshay , you can try something like this before initializing the sensor in order to try to unblock the bus if the issue is really the I3C mode:
for (int i=0; i<2; i++)
{
dev_i2c->beginTransmission(((uint8_t)(((0xD7) >> 1) & 0x7F)));
dev_i2c->write(0x18);
dev_i2c->write(0xE2);
dev_i2c->endTransmission(true);
}
where dev_i2c is the I2C instance. Please check that the I2C address in the beginTransmission is effectively 0xD7 that means SA0 pin connected to Vdd. If SA0 pin is connected to GND, then you should use 0xD5 instead of 0xD7 I hope that this procedure can help. Best Regards, Carlo
Hi @cparata
I tried this but didnt work either. Its just stuck after print line "Initializing IMU...."
DEBUG_PRINTLN("Initializing IMU...");
for (int i = 0; i < 2; i++)
{
Wire.beginTransmission(((uint8_t)(((0xD7) >> 1) & 0x7F)));
Wire.write(0x18);
Wire.write(0xE2);
Wire.endTransmission(true);
}
We have connected SA0 pin to Vdd. Now I wonder what could be the reason now.
Hi @cparata ,
I have inserted debug statement in every function which we are using to get the raw data up and rolling, whenever initialization happens to be failed, I will know it failed from which "if" statement inside the initialization routine. Will let you know and if you have any suggestions in mind, please do let me know. I need to resolve this inconsistency thing while initialization issue.
/ Disable I3C / if (lsm6dsr_i3c_disable_set(®_ctx, LSM6DSR_I3C_DISABLE) != LSM6DSR_OK) { Serial.println("Disabling I3C failed"); return; }
We are getting stuck in this function...
Hi @TinManAkshay , could you try this other procedure always before the initialization of the sensor:
Wire.begin();
uint8_t value = 0;
do
{
Wire.beginTransmission(((uint8_t)(((0xD7) >> 1) & 0x7F)));
Wire.write(0x18);
Wire.write(0xE2);
Wire.endTransmission(true);
Wire.beginTransmission(((uint8_t)(((0xD7) >> 1) & 0x7F)));
Wire.write(0x18);
Wire.endTransmission(false);
Wire.requestFrom(((uint8_t)(((0xD7) >> 1) & 0x7F)), 1);
while(Wire.available())
{
value = Wire.read();
}
} while(value != 0xE2);
Let me know if it solves your issue. Best Regards, Carlo
Hi @cparata ,
Before I include the above logic, my IMU is up and running as I mentioned its every 1 or 2 out of 15 firmware updates. So I have included that logic before I call "AccGyr = new LSM6DSRSensor(&Wire, LSM6DSR_I2C_ADD_H);" and lets see if I still get the initialization issue.
Also, I have other components running on I2C. The logic which you suggested will not effect communication with other components on I2C right?
-Akshay
Hi @TinManAkshay , Yes, this routine acts only on LSM6DSR. It should not impact the other devices connected to the I2C bus. Best Regards, Carlo
Hi @cparata ,
My system just went into the hung (failed) IMU initialization state again.
So I inserted your latest code lines, just above the IMU initialize steps, and the PCB simply never returned from the while loop below.
Hi @TinManAkshay , No good. Unfortunately, if the issue is really I3C mode, the only safe procedure that I know is to put the INT1 low but it is not applicable to your PCB, because you did not connect INT1 to the MCU. It would be useful also to check the signals on the I2C pins with a logical analyzer when the firmware hangs, but I don't know if in your PCB you have the test points for these pins. I'm sorry for that but I do not have many other ideas to spend. Best Regards, Carlo
Hi @TinManAkshay , I realized that if you have other I2C devices in your PCB, so the issue can be due also to an I2C bus that is in an inconsistent state because some devices did not see the STOP sequence. So, I suggest also to try to bit-banging a STOP message before using the Wire library. So really at the beginning of your program you can try something like that:
pinMode(SCL_PIN, OUTPUT);
pinMode(SDA_PIN, OUTPUT);
for (int i = 0; i<10; i++){
digitalWrite(SDA_PIN, LOW);
delay(3);
digitalWrite(SCL_PIN, HIGH);
delay(3);
digitalWrite(SDA_PIN, HIGH);
delay(3);
digitalWrite(SCL_PIN, LOW);
delay(3);
}
pinMode(SDA_PIN, INPUT);
pinMode(SCL_PIN, INPUT);
Where SDA_PIN and SCL_PIN are the I2C pins of your PCB. Let me know if it helps. Best Regards, Carlo
Hi @cparata ,
I appreciate your another possible solution to my issue.
Another issue rises up like out of the blue. Sometimes when I upload the code, IMU gives status zeros values for all the 3 axis even though IMU in initialized successfully at the setup() routine. Because of that, we observed other device on I2C bus like AMG sensor (thermal) starts giving static zeros. So, we may be dealing with a full lockup of the I2C bus – not an isolated IMU problem? Perhaps the remedy angle here is something related to a brute force reset of the I2C bus if either condition occurs?
Is your latest solution could be the possible solution to prevent I2C bus from going to full lock-up?
Thanks, Akshay
Hi @TinManAkshay , it is not clear to me if this issue (other I2C components that do not work fine together with the LSM6DSR) rose after applying my last patch proposal or in general happens in any case. If the answer is the second one, then it means that you probably have some instability on the I2C bus. Is the issue happens also if you unplug and then plug the board? In theory my last patch is just a simulation of a STOP sequence (repeated 10 times) on the I2C bus in order to unblock the bus when it is stuck. So, I proposed it just to try to solve the issue that now you are experiencing. Best Regards, Carlo
Hi @cparata ,
We dont know yet what is the root cause of this issue and its very random also. So we are thinking to reproduce the same issue whatsoever, and then apply all our approaches to resolve it.
Do you have any ideas how to reproduce the issue when IMU stuck on static zeros? Is it a calibration issue at boot-up?
-Akshay
Hi @TinManAkshay , If you have enabled the sensor and you continue to get static values, I suspect that there is an issue on the I2C bus. But in order to understand if the issue is on the bus you should capture the I2C signals with a logical analyzer and I guess it is not possible on your PCB, correct? Best Regards, Carlo
Yes that is not possible. If I get static values per se, I would upload the firmware again, but that wont solve the issue. So I tried plugging out the USB cable and plugged back in, then everything went to normal state. I keep on getting normal values from the IMU. So that basically is hardware reset solution. But our project says to find the solution on a software level. We need to find the solution either to prevent this issue from happening or apply the recovery solution.
-Akshay
Hi @TinManAkshay , If you don't have any issue when you unplug/plug the board, I guess that the problem arises when you flash the firmware during an I2C transaction and so in this case the I2C bus remains in an unstable state. Unfortunately, I don't know very well the SAMD microcontroller, so I don't know if there exists any API to unblock the I2C bus. On STM32, the Wire.end() can help in this case, but I don't know if it works also on SAMD architecture. Best Regards, Carlo
Hi @cparata ,
Good news!! Actually I was about to tell you this morning!!
Last night we were able to reproduce the issue consistently, so we applied your logic of bit-banging at the very start of the setup() routine and it just worked. Woah!. Thanks a ton for the possible solutions in this issue and staying active. Appreciate it!! :)
-Akshay
Hi,
I have been using this library from a couple of months now and I am very pleased with the results. However, recently we are observing an IMU initialization issue in a void setup().
Every so often (about 1 out of 10-15 firmware updates) the PCB (having LSM6 on it) appears to not enable the accelerometer properly (i.e. the values read from the accel are static regardless of significant physical vibration). I also see that this usually is preceded by the system failing several times to even finish the setup routine where the IMU is initialized.
Perhaps I have a bad physical board with the chip not properly seated or connected to the appropriate pin. Not sure how to interpret inconsistent initialization with the same startup code…
Have you seen this behavior before when you were testing the IMU or have any clues behind this issue?
Hope to hear from you soon.
Thanks, Akshay