I2C timeout for STM32F103C8

Post here all questions related to LibMaple core if you can't find a relevant section!
Blosso
Posts: 8
Joined: Mon Feb 15, 2021 4:11 pm

I2C timeout for STM32F103C8

Post by Blosso »

Hi there,

I'm working on a project with a connection with an IMU through I2C (25Hz, Wire set to 100000), it however, always hangs. The stays stable longer if I lower the speed. The reason I suspend it is the IMU is that whenever I unplug it, the rest of it works without a problem (together with a Bluetooth module HC05). I use the Wire library within the package http://dan.drown.org/stm32duino/package ... index.json

Is there a way to workaround, like setting a timeout in the library?

Also, here is the measurement with the oscilloscope, (it is a random waveform collected when data is sent through Bluetooth without a problem. I couldn't catch the waveform right at the moment when the program stop, because my oscilloscope doesn't come with a or it would be great if someone could suggest how.) From the measurement, I see spikes when clock signal is low https://drive.google.com/file/d/13QnP_t ... sp=sharing
Would that be a problem in a long run?
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: I2C timeout for STM32F103C8

Post by stevestrong »

How old is your package? There was some activity lately around the Wire lib.
What IMU chip?
And what supply voltage you use? Hopefully the signals have same high levels (which cannot be derived form the scope plot).
A simple example sketch which shows the problem would be useful.

Those spikes are normal, due to the external circuitry which pulls the line low after the 9th clock pulse (ACK).
Blosso
Posts: 8
Joined: Mon Feb 15, 2021 4:11 pm

Re: I2C timeout for STM32F103C8

Post by Blosso »

Hi Steve,
Do you mean the boards manager? it is STM32F1xx/GD32F1xx board by stm32duino, version 2020.12.26.
I'm using STM32F103C8
I have tested out with solely the IMU and displaying in the serial monitor, the same happens.
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: I2C timeout for STM32F103C8

Post by mrburnette »

Blosso wrote: Thu Feb 25, 2021 1:02 pm ...
I use the Wire library within the package http://dan.drown.org/stm32duino/package ... index.json
See #1 & #3 here:
viewtopic.php?f=2&t=301

Dan's core is not currently recommended (for this forum.) Dan sources from
http://dan.drown.org/stm32duino/STM32F1-2020.1.17.zip
and not from his github at
https://github.com/ddrown/Arduino_STM32

Thus, without taking my time to fully review the Zip, I cannot comment on how closely he follows Roger's or Steve's cores. Dan's github however is 5 years out-of-sync :o

I recommend the Official core if you are doing anything serious or Roger's core if you are doing "hobby" Arduino projects. Steve is updating Roger's core as critical issues are found (and a few non-critical.) All hail Steve's community effort.


Ray
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: I2C timeout for STM32F103C8

Post by stevestrong »

Blosso wrote: Thu Feb 25, 2021 1:21 pm I have tested out with solely the IMU and displaying in the serial monitor, the same happens.
Again, I need a simple sketch in order to reproduce the problem.
Try to write one.
In my experience, the issue gets understood by simplifying the software, or by using a simple working version and trying to add more and more features step by step.
Blosso
Posts: 8
Joined: Mon Feb 15, 2021 4:11 pm

Re: I2C timeout for STM32F103C8

Post by Blosso »

Thank you, I'm using Roger's core now, and tried to separate the problem. It looks like that the problem comes from the bluetooth HC05 module, (not quite sure if that's the only problem though :shock: )
I tried on the same I2C connection and displaying data to the serial monitor instead of transmitting through bluetooth to mobile, and it looks good to me.
There is something wrong on the bluetooth side. As the whole string could be 100 to 144 bytes, I
1) changed the USART_TX_BUF_SIZE and USART_RX_BUF_SIZE to 256 for the usart.h under (C:\Users\I\Documents\Arduino\hardware\Arduino_STM32\STM32F1\system\libmaple\include\libmaple).
2) used serial.flush(); at the beginning of every loop. (the code loops every 18 ms).
The bluetooth transmission still freezes after working for awhile, (according to the HC05 led indicator, it is still connecting to the phone).

Also, testing with just printing a fixed string without reading sensor data also produce the same result...for transmission at a baud rate of 115200, 230400, 460800.
However, when shortening the string to be sent (to 55 bytes), the connection and transmission still hold.
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: I2C timeout for STM32F103C8

Post by stevestrong »

I do not know any parts of your code, so I cannot tell you what might be the problem.
But I own some BT HC05 modules, so if you write a simple sketch I could eventually try to reproduce your problem.
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: I2C timeout for STM32F103C8

Post by mrburnette »

Blosso wrote: Thu Mar 18, 2021 12:59 pm ...
There is something wrong on the bluetooth side. As the whole string could be 100 to 144 bytes, I
1) changed the USART_TX_BUF_SIZE and USART_RX_BUF_SIZE to 256 for the usart.h under (C:\Users\I\Documents\Arduino\hardware\Arduino_STM32\STM32F1\system\libmaple\include\libmaple).
2) used serial.flush(); at the beginning of every loop. (the code loops every 18 ms).
The bluetooth transmission still freezes after working for awhile, (according to the HC05 led indicator, it is still connecting to the phone).

Also, testing with just printing a fixed string without reading sensor data also produce the same result...for transmission at a baud rate of 115200, 230400, 460800.
However, when shortening the string to be sent (to 55 bytes), the connection and transmission still hold.
I do not think you have isolated software from hardware. For example, you did not switch out the HC05 which is the ultimate validation. I always preach to buy two of anything affordable and keep 1 for situations such as yours.
From datasheet:
Default Baud rate: 38400, Data bits:8, Stop bit:1,Parity:No parity, Data control: has.
Supported baud rate: 9600,19200,38400,57600,115200,230400,460800.
Try configuring Arduino to the default BAUD rate parameters but return all of those header file buffer mods to original values. I do not know if LeafLabs/Roger implemented Serial.availableForWrite() but I do not think they did, which is unfortunate.
Blosso
Posts: 8
Joined: Mon Feb 15, 2021 4:11 pm

Re: I2C timeout for STM32F103C8

Post by Blosso »

@stevestrong Thanks, here is the code I used to test with. Buffer sizes for RX and TX for USART are set to 256, and fixed values are printed to Serial3 (no analog read or I2C request are performed). I tested with both 115200 and 460800 baud rate for HC05, but transmission freezes within 20 seconds. If I just comment out IMU();, it gets smoother, at least no noticeable problems within 30 minutes.

I will also try out mrburnette suggestion, to disconnect hc05 from the stm32, see if I2C is still stable when displaying data to the serial monitor.

Code: Select all

// for STM32
//USART_TX_BUF_SIZE               256
//USART_RX_BUF_SIZE               256

int fsrA,fsrB,fsrC,fsrD,fsrE,fsrF,fsrG; 
int printDelay = 20;

void setup() {
//  disableDebugPorts();
  Serial.begin(500000);
  Serial3.begin(460800); //for bluetooth
  delay(500);
}

void loop() {
  int startL = millis();
    Serial3.flush();
    //time
    Serial3.print("T=");
    Serial3.print(startL);
    Serial3.print(";");
    
    FSR();
    IMU();
    battery();
    Serial3.println("#");
    
  if ((millis()-startL) < printDelay){
      delay((printDelay - (millis() - startL)));
    }
}

void battery(){
      Serial3.print("B=");
      Serial3.print("1000");
      Serial3.print(";");
}

void FSR(){
  fsrA = 7000;
  fsrB = 7000;
  fsrC = 7000;
  fsrD = 7000;
  fsrE = 7000;
  fsrF = 7000;
  fsrG = 7000;
  
  Serial3.print("F="); Serial3.print(fsrA);
  Serial3.print(","); Serial3.print(fsrB);
  Serial3.print(","); Serial3.print(fsrC);
  Serial3.print(","); Serial3.print(fsrD);
  Serial3.print(","); Serial3.print(fsrE);
  Serial3.print(","); Serial3.print(fsrF);
  Serial3.print(","); Serial3.print(fsrG);
  Serial3.print(";");
}
void IMU(){
  Serial3.print("I=");
  for(int i = 0 ; i < 8; ++i){
    Serial3.print("-100.00");
    Serial3.print(",");
      }
  Serial3.print("-100.00");
  Serial3.print(";");
 
}
stevestrong
Posts: 502
Joined: Fri Dec 27, 2019 4:53 pm
Answers: 8
Location: Munich, Germany
Contact:

Re: I2C timeout for STM32F103C8

Post by stevestrong »

This sequence
Blosso wrote: Fri Mar 19, 2021 5:24 am

Code: Select all

  if ((millis()-startL) < printDelay){
      delay((printDelay - (millis() - startL)));
    }
looks very dubious.

I do not know what you wanted to achieve with that, but I se a big problem when (millis() - startL) becomes greater then printDelay.
This can happen when the serial interface cannot send the amount of data within a predetermined time, due to its blocking strategy, independent of the size of the Tx buffer.
For example, 500000 Bauds = 62.5kBytes per second = 1250 bytes per 20 milliseconds.
If you go above this, you would delay with a huge amount of time - which looks like a hangup.

If you want to send the data periodically in specific time intervals then you should try something like this:

Code: Select all

const uint32_t printDelay = 20; // time in ms 
uint32_t lastTime = 0;
...
void loop()
{
  if ( (millis()-lastTime) < printDelay )
    return;

  lastTime = millis();

  ... // do your periodic stuff here

  // optional: monitor the time needed to send the data
  Serial.print("Processing time: "); Serial.println(millis()-lastTime);
}
By printing the processing time you can see how much time the data transmission takes.
Post Reply

Return to “General discussion”