Different time duration in a while loop

Hello! I am new here. I want to compute an average value by recording all readings for a specific time duration.

Logic in pseudo code:
/------------------------/
startTime=present;
ind=0;
do{
array[ind]=reading;
ind++;
timeDuration=present-startTime;
}while(timeDuration< desiredValue);
average=sum(array)/ind;
/----------------------/

Actual code:

#include "Wire.h"

#define numberOfElementForAve 50 // each reading will take about 2to3 milli seconds
#define aveTimeDuration 100 // the uplimit of time duration (in milli seconds) for computing average
// the above two constant has relationship, the rule of thumb is
// numberOfElementForAve*2 >=aveTimeDuration

// MPU6050 address
const int MPU_ADDR = 0x68;

// variables for holding data
int16_t aX;

int timeStart = 0, timeLoopStart, timeDuration, timeLoopDuration;
int16_t aveArr[numberOfElementForAve];
int aveCount;

void setup() {

//initialisation
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);

}

void loop() {

aveCount = 0;
timeStart = millis();

// a loop for taking average readings
do {

timeLoopStart = millis();

Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
Wire.requestFrom(MPU_ADDR, 7 * 2, true); // request a total of 7*2=14 registers

// take readings from MPU6050
aX = Wire.read() << 8 | Wire.read(); // reading registers: 0x3B (ACCEL_XOUT_H) and 0x3C (ACCEL_XOUT_L)

aveArr[aveCount] = aX;
aveCount++;

timeDuration = millis() - timeStart;
timeLoopDuration = millis() - timeLoopStart;

Serial.print("|| timeLoopDuration: ");
Serial.print(timeLoopDuration);
Serial.print("|| timeDuration: ");
Serial.println(timeDuration);

} while (timeDuration < aveTimeDuration);
delay(1000);

}

However, the time duration for each loop becomes (approximately)
1st loop: 2ms
2ns loop: 2ms
3rd loop: 20ms
4th loop: 45ms
nth loop: 45ms

I wonder what makes the 3rd and rests loops significantly slower than the first two. Is it possible to speed them to 2ms as well? Thanks in advance.

Serial prints take time. Try changing the baud rate from 9600 to something much higher.

1 Like

Amazing, it works (time duration=2ms) after I change from 9600 to 250000. Just curious, why the first two loops are so special? Thanks

Because there is an output buffer. For the first two loops, it just fills up while the previous characters are in the process of transmission. When the buffer is full, the program is forced to wait for free space in the buffer.

1 Like

Ah, that explains. Many thanks!

The buffer is 64 bytes for arduino UNO. Here is the code (HardwareSerial.h):

#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif

For any arduino board with less than 1K ram the transmit buffer is 16 bytes but otherwise is 64 bytes.

You should try printing shorter strings.

1 Like

thank you very much, that is a detailed explanation! :grinning_face_with_smiling_eyes:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.