Cannot collect data from MinIMU-9 board more than 3 hours

Hi,

I am going to collect sensor data from MinIMU-9 board (LSM303DLM and L3G4200D) for characterizing these sensors. I am using serial port to collect data from Arduino uno board attached by MinIMU-9 board. The data are output into the serial monitor of Arduino IDE, which would be copied and pasted into a txt file lately. I need at least 3 hours data. After starting my program, everything is normal. All sensor data are normally output at 50Hz. However, the problem is that after 1 or 2 hours, the monitor window is always frozen, and I have to terminate it by using windows task manager. Thus I cannot do any copy and paste at all. The following is my code. It is very simple. Basically I am just print the sensor data plus the seq NO at 50Hz data rate. I dont know what the problem is. Could you please help me? Thanks!

#include <Wire.h>
#include <L3G.h>
#include <LSM303.h>

LSM303 compass;
L3G gyro;

unsigned long counter;
unsigned long time;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  
  if (!gyro.init())
  {
    Serial.println("Failed to autodetect gyro type!");
    while (1);
  }

  gyro.enableDefault();
  compass.init();
  compass.enableDefault();

  //set gyro range to 2000dps
  gyro.writeReg(L3G_CTRL_REG4, 0x20);
  //set gyro in normal power mode, with 100Hz rate, 12.5 cut-off
  gyro.writeReg(L3G_CTRL_REG1, 0x0F);

  //set acc sensor range to +-8g
  compass.writeAccReg(LSM303_CTRL_REG4_A, 0x30);
  //set acc in normal power mode, with 100Hz rate, 74 cut-off
  compass.writeAccReg(LSM303_CTRL_REG1_A, 0x2F);
  
  //set mag rate 220Hz
  compass.writeMagReg(LSM303_CRA_REG_M, 0x1C);
  //set mag range 1.3 gauss, x/y 1100 LSB/Gauss, Z 980 LSB/Gauss
  compass.writeMagReg(LSM303_CRB_REG_M, 0x20);
  //set mag in continuous-conversion mode
  compass.writeMagReg(LSM303_MR_REG_M, 0x00);

  Serial.print("Gyro mode (L3G_CTRL_REG1): ");
  Serial.println(gyro.readReg(L3G_CTRL_REG1));
  Serial.print("Gyro Scaling status (L3G_CTRL_REG4): ");
  Serial.println(gyro.readReg(L3G_CTRL_REG4));

  Serial.print("Acc mode (LSM303_CTRL_REG1_A): ");
  Serial.println(compass.readAccReg(LSM303_CTRL_REG1_A));
  Serial.print("Acc Scaling status (LSM303_CTRL_REG4_A): ");
  Serial.println(compass.readAccReg(LSM303_CTRL_REG4_A));

  Serial.print("Mag mode (LSM303_MR_REG_M): ");
  Serial.println(compass.readMagReg(LSM303_MR_REG_M));
  Serial.print("Mag Scaling status(A) (LSM303_CRA_REG_M): ");
  Serial.println(compass.readMagReg(LSM303_CRA_REG_M));
  Serial.print("Mag Scaling status(B) (LSM303_CRB_REG_M): ");
  Serial.println(compass.readMagReg(LSM303_CRB_REG_M));

  counter = 0;
  time = 0;
 }

void loop() {
  if (millis() - time >= 18)
  {
    gyro.read();
    compass.read();
    time = millis();
    counter = counter+1;
  
    Serial.print((int)gyro.g.x);
    Serial.print(" ");
    Serial.print((int)gyro.g.y);
    Serial.print(" ");
    Serial.print((int)gyro.g.z);
    Serial.print(" ");
  
    Serial.print((int)compass.a.x);
    Serial.print(" ");
    Serial.print((int)compass.a.y);
    Serial.print(" ");
    Serial.print((int)compass.a.z);
    Serial.print(" ");
  
    Serial.print((int)compass.m.x);
    Serial.print(" ");
    Serial.print((int)compass.m.y );
    Serial.print(" ");
    Serial.print((int)compass.m.z);
    Serial.print(" ");
  
    Serial.print(time);
    Serial.print(" ");
    Serial.println(counter);
  }
  
}

Hello again.

It is very unlikely that this is actually a problem with the MinIMU-9. It sounds like the Arduino IDE’s serial monitor program is crashing, which means there is a bug in it. I bet the same thing would happen if you took the MinIMU-9 out of the picture and just had the Arduino print some arbitrary string to its serial port at 50 Hz.

I recommend trying a different serial terminal, such as PuTTY, TeraTerm, or Bray Terminal. You will have to investigate the options of these programs to see which of them will allow you to have a large enough buffer. If we say 60 bytes per reading, 50 readings per second, and 3600 seconds per hour, three hours of data would take up 32,400,000 bytes. If none of the programs allow such a large buffer and you can’t find some other solution, you might have to write your own program. (What languages are you familiar with?)

Bray Terminal actually has a new CSV graph feature, so I would expect that it lets you have a big buffer. I would probably try Bray Terminal first.

–David

Thank you for your replying. Actually, I am writing my terminal with C# (MS visual studio 2010). However, I am not familiar with serial programming. There are several options for reading serial data with SerialPort class in C#, and there are stream object and buffer in SerialPort class. I tried several methods of SerialPort class. However, it seems not very reliable, sometimes it may miss the “\n” ending of the reading, and sometimes I got repeatedly readings from the serial port.

Are you familiar with serial programming with C#? if you are, could you please let me know the correct way for serial programming? For example, which methods I need to use? read(), readline(), readexisting() or readbyte()? Using event based processing, or just read data in a while loop? I tried several, the reliability is actually different!

Yes, I am familiar with C#. I have never encountered any bugs in the SerialPort class. For your application, since you are using lines in your data stream, I think ReadLine() would be a good choice. What are you doing with the data from ReadLine()? If you are just concatenating all the lines together into one big string without using StringBuilder, that would probably be a bad idea. There are many things you could do with the lines depending on your application, but one good choice would be to have a file open and write the lines to the file as they come in.

–David

Great! Currently, when I got a line, I just append it to a RichTextBox: myRichTextBox.AppendText(msg). After I collecting enough data, I just save all the data in the RichTextBox into a txt file. Does RichTextBox have enough buffer to contain all these data (more than 3 hours, 50Hz data)?

Another issues is that currently I am using the following code. However, I observed that there are redundant data displayed in the RichTextBox. Do you know what the problem may be?

private void Start_Btn_Click(object sender, EventArgs e)
        {
            if (!serialPort.IsOpen)
            {
                serialPort.PortName = comboBox1.SelectedItem.ToString();
                serialPort.Open();
                serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
                serialOpen = true;
                Start_Btn.Text = "Close Port";
            }
            else
            {
                serialPort.Close();
                serialOpen = false;
                Start_Btn.Text = "Open Port";
            }
        }
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (serialPort.IsOpen)
            {
                writeCallback d = new writeCallback(UpdateDisplay);

                byte[] buffer = new byte[serialPort.ReadBufferSize];
                int bytesRead = serialPort.Read(buffer, 0, buffer.Length);
                RxString += Encoding.ASCII.GetString(buffer, 0, bytesRead);

                this.Invoke(d, new object[] { RxString.ToString()});

            }
        }




        private void UpdateDisplay(string msg)
        {
            Display_Screen.AppendText(msg);
        }

I doubt that RichTextBox will work for this but it’s hard to be sure. You should read the link I posted above to get an idea about why the stuff you are doing might end up being very inefficient. Why are you doing “RxString +=” instead of "RxString = "? That would surely cause massive amounts of duplicate data to be displayed unless you are emptying RxString in some other part of the code that you didn’t post.

–David

Oh, I see. I just copied the code from my friend. That should be the problem! Thanks!