im doing a university project where we use 2 IMU sensors and a SD card reader to save the data from sensors.
As you will probably see from the code, we specify the sensor port we listen to, save data to strings and then we open a port to SD reader and save the data. Everything is in loop.
The problem is we only get around 5Hz (10Hz with only one sensor) - visible by the timer, which is sadly not enough for our project.
I heard about using a fifo buffer, but im not so good at low level programing. Anyway you can help? Also, do you think removing all Serial.print could help with a little performance boost?
sensors - https://wiki.dfrobot.com/Serial_6_Axis_Accelerometer_SKU_SEN0386#target_0
uCon - Arduino Uno Rev3
#include <DFRobot_WT61PC.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
#define FILE_BASE_NAME "Pomiar"
#define VCC2 7
const uint8_t CS_PIN = 4;
SoftwareSerial mySerial(2, 3);
SoftwareSerial mySerial2(5, 6);
DFRobot_WT61PC sensor(&mySerial);
DFRobot_WT61PC sensor2(&mySerial2);
File myFile;
File file;
const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
char fileName[] = FILE_BASE_NAME "00.txt";
void setup()
{
pinMode(VCC2,OUTPUT);
digitalWrite(VCC2,HIGH);
//Use Serial as debugging serial port
Serial.begin(9600);
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
while (1);
}
Serial.println("initialization done.");
while (SD.exists(fileName)) {
if (fileName[BASE_NAME_SIZE + 1] != '9') {
fileName[BASE_NAME_SIZE + 1]++;
} else if (fileName[BASE_NAME_SIZE] != '9') {
fileName[BASE_NAME_SIZE + 1] = '0';
fileName[BASE_NAME_SIZE]++;
} else {
Serial.println(F("Can't create file name"));
return;
}
}
//Use software serial port mySerial as communication seiral port
mySerial.begin(9600);
mySerial2.begin(9600);
//Revise the data output frequncy of sensor FREQUENCY_0_1HZ for 0.1Hz, FREQUENCY_0_5HZ for 0.5Hz, FREQUENCY_1HZ for 1Hz, FREQUENCY_2HZ for 2Hz,
// FREQUENCY_5HZ for 5Hz, FREQUENCY_10HZ for 10Hz, FREQUENCY_20HZ for 20Hz, FREQUENCY_50HZ for 50Hz,
// FREQUENCY_100HZ for 100Hz, FREQUENCY_125HZ for 125Hz, FREQUENCY_200HZ for 200Hz.
sensor.modifyFrequency(FREQUENCY_100HZ);
sensor2.modifyFrequency(FREQUENCY_100HZ);
}
void loop()
{
long timestamp = millis();
String acc1 = "";
String acc2 = "";
String acc3 = "";
String gyro1 = "";
String gyro2 = "";
String gyro3 = "";
String angle1 = "";
String angle2 = "";
String angle3 = "";
String acc12 = "";
String acc22 = "";
String acc32 = "";
String gyro12 = "";
String gyro22 = "";
String gyro32 = "";
String angle12 = "";
String angle22 = "";
String angle32 = "";
mySerial.listen();
if (sensor.available()) {
acc1 = sensor.Acc.X;
acc2 = sensor.Acc.Y;
acc3 = sensor.Acc.Z;
gyro1 = sensor.Gyro.X;
gyro2 = sensor.Gyro.Y;
gyro3 = sensor.Gyro.Z;
angle1 = sensor.Angle.X;
angle2 = sensor.Angle.Y;
angle3 = sensor.Angle.Z;
Serial.print("Acc\t"); Serial.print(sensor.Acc.X); Serial.print("\t"); Serial.print(sensor.Acc.Y); Serial.print("\t"); Serial.println(sensor.Acc.Z); //acceleration information of X,Y,Z
Serial.print("Gyro\t"); Serial.print(sensor.Gyro.X); Serial.print("\t"); Serial.print(sensor.Gyro.Y); Serial.print("\t"); Serial.println(sensor.Gyro.Z); //angular velocity information of X,Y,Z
Serial.print("Angle\t"); Serial.print(sensor.Angle.X); Serial.print("\t"); Serial.print(sensor.Angle.Y); Serial.print("\t"); Serial.println(sensor.Angle.Z); //angle information of X, Y, Z
Serial.println(" ");
}
mySerial2.listen();
if (sensor2.available()) {
acc12 = sensor2.Acc.X;
acc22 = sensor2.Acc.Y;
acc32 = sensor2.Acc.Z;
gyro12 = sensor2.Gyro.X;
gyro22 = sensor2.Gyro.Y;
gyro32 = sensor2.Gyro.Z;
angle12 = sensor2.Angle.X;
angle22 = sensor2.Angle.Y;
angle32 = sensor2.Angle.Z;
Serial.print("Acc2\t"); Serial.print(sensor2.Acc.X); Serial.print("\t"); Serial.print(sensor2.Acc.Y); Serial.print("\t"); Serial.println(sensor2.Acc.Z); //acceleration information of X,Y,Z
Serial.print("Gyro2\t"); Serial.print(sensor2.Gyro.X); Serial.print("\t"); Serial.print(sensor2.Gyro.Y); Serial.print("\t"); Serial.println(sensor2.Gyro.Z); //angular velocity information of X,Y,Z
Serial.print("Angle2\t"); Serial.print(sensor2.Angle.X); Serial.print("\t"); Serial.print(sensor2.Angle.Y); Serial.print("\t"); Serial.println(sensor2.Angle.Z); //angle information of X, Y, Z
Serial.println(" ");
}
myFile = SD.open(fileName, FILE_WRITE);
if (myFile) {
myFile.print(timestamp);
myFile.print("|");
myFile.print(acc1);
myFile.print("|");
myFile.print(acc2);
myFile.print("|");
myFile.print(acc3);
myFile.print("|");
myFile.print(gyro1);
myFile.print("|");
myFile.print(gyro2);
myFile.print("|");
myFile.print(gyro3);
myFile.print("|");
myFile.print(angle1);
myFile.print("|");
myFile.print(angle2);
myFile.print("|");
myFile.print(angle3);
myFile.println("");
myFile.print(timestamp);
myFile.print("|");
myFile.print(acc12);
myFile.print("|");
myFile.print(acc22);
myFile.print("|");
myFile.print(acc32);
myFile.print("|");
myFile.print(gyro12);
myFile.print("|");
myFile.print(gyro22);
myFile.print("|");
myFile.print(gyro32);
myFile.print("|");
myFile.print(angle12);
myFile.print("|");
myFile.print(angle22);
myFile.print("|");
myFile.print(angle32);
myFile.println("");
myFile.close();
} else {
Serial.println("error opening test.txt");
}
}
do you think removing all Serial.print could help with a little performance boost?
... why are you asking this? ... what is preventing you from doing a test?millis()
what exactly is taking so much time? And why are you saving all the data in strings? The data is of typefloat
float
s intoString
s will take some time, did you benchmark this? -- To get least overhead for debugging, you can simply toggle some pin and measure the time with an oscilloscope. With respect to the communication signals to/from the sensors you will see where the time is spent.