Serial monitor stops printing a while after sending a command

Hello everyone,

I have been working on a project that uses two IMUs, specifically the MIKROE-1996 board with the LSM9DS1, these two sensors are above a steel pipe and a motor moves them along said pipe. The sensors communicate with the Arduino by I2C.
I am interested in obtaining the magnetometers readings and send the 6 values (3 for each axis of each sensor) through the serial port to my laptop, catch those values in Matlab and store them in a matrix.

I have written the sketch to drive the motor with an H-bridge and read from the sensors and send the measurements, and also the code in Matlab to read the serial port and store the information as described. These two codes work correctly to some extent and I haven't been able to find a solution to my problem after reading a lot of posts in this and other similar forums. Let me describe my problem:

As previously said, I read 6 values from the 2 sensors and send them to the serial monitor. If I open the monitor, I can see the 6 values separated by a comma. There is a 50ms delay between each print. To drive the motor, I send a command through the serial port. After a few moments with the motor ON, the serial monitor stops showing the measurements. However, if I don't send any command to turn the motor on (forward or backward), the serial monitor never stops sending the values. I tested this by leaving the code running for almost two hours and it didn't stop, but when I turn the motor on sometimes the code stops after 30 seconds or 50 seconds, it's not even consistent on that. Also, when the monitor stops printing I can't send other commands to stop the motor's movement.

Originally, I thought it was a problem with my code in Matlab and started tweaking some parts of my code, but after some tests using only the Arduino IDE I realized it was a problem with my sketch, one that I haven't been able to find. The serial monitor starts printing again only when I manually reset the Arduino board. Something strange about this is that the serial monitor only stops when the motor is moving in a direction but not in the opposite.

This is my code, I omitted all the setting up of the sensors:

// Magnetoresistive sensors and motor driver
#include <Wire.h>
#include <SPI.h>
#include <SparkFunLSM9DS1.h>

int motorcito[] = {12, 13}; //Output pins to control H-bridge


LSM9DS1 sensor1; //Creating LSM9DS1 objects
LSM9DS1 sensor2; //

#define PRINT_SPEED 50 // 50 ms between prints
static unsigned long lastPrint = 0; // Keep track of print time


void setup() {
  // put your setup code here, to run once:

  pinMode(motorcito[0], OUTPUT);
  pinMode(motorcito[1], OUTPUT);
  Serial.begin(115200);

  ///////////// Setting up sensors ////////////
   //
  //
 //
//
}


void loop() {

  if (Serial.available() > 0) {
    char data = Serial.read();
    //Serial.print("data: ");
    switch (data) {
      case 'f':
        motor_forward();
        break;
      case 'b':
        motor_backward();
        break;
      case 's':
        motor_stop();
        break;
      default:
        break;
    }
 }

  // Update sensor values when new data available
  if ( sensor1.magAvailable() || sensor2.magAvailable())
    {
      sensor1.readMag();
      sensor2.readMag();
    }
    if ((lastPrint + PRINT_SPEED) < millis()) {
      printMag(); // Print magnetometer readings
      lastPrint = millis();

    }
  Serial.flush(); //I included this function because I read that it might be useful
                       //but I'm not completely sure about it
}

void motor_stop() {
  digitalWrite(motorcito[0], LOW);
  digitalWrite(motorcito[1], LOW);
}
void motor_forward() {
  digitalWrite(motorcito[0], HIGH);
  digitalWrite(motorcito[1], LOW);
}
void motor_backward() {
  digitalWrite(motorcito[0], LOW);
  digitalWrite(motorcito[1], HIGH);
}

void printMag() {
  
  Serial.print(sensor1.calcMag(sensor1.mx), 4);
  Serial.print(F(","));
  
  Serial.print(sensor1.calcMag(sensor1.my), 4);
  Serial.print(F(","));
  
  Serial.print(sensor1.calcMag(sensor1.mz), 4);
  Serial.print(F(","));
  
  Serial.print(sensor2.calcMag(sensor2.mx), 4);
  Serial.print(F(","));
  
  Serial.print(sensor2.calcMag(sensor2.my), 4);
  Serial.print(F(","));
  
  Serial.print(sensor2.calcMag(sensor2.mz), 4);
  Serial.println(F(","));

  // I am using the F() macro because I found it might be useful but I didn't see any improvement with it
  
}

I would restructuring your code a bit, use the software serial library to send data to Matlab, this leaves your console open for debug. This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil

gilshultz:
I would restructuring your code a bit, use the software serial library to send data to Matlab, this leaves your console open for debug. This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil

Thank you for your suggestion. I am not sure how using the SoftwareSerial library would be helpful because I am not having problems to send the data to Matlab. As described above, the problem only occurs when I send the command so the motor starts rotating. If I leave my Arduino code running without sending any command to start the motor, it can run continuously for a long time and the same happens when I run the Matlab code without the commands.

I thought that there might be some back currents from the H-bridge going to the Arduino pins that control it and may cause a short-circuit. However, the IC I am using has internal diodes to avoid this from happening, so I think this is unlikely.

I'll leave the code running with the monitor open printing the timestamp overnight to see if it ever stops.

It seems from your description that the running motor is interfering with something. Maybe there is no sensorX.magAvailable().

What happens if you disconnect the motor and run the program?

As @gilshultz has said it would be great if you have a separate channel for debug messages so you could get more info about what the program is actually doing. However SoftwareSerial won't work at 115200 baud. 9600 is good and it may work at 38400.

If you have a USB TTL cable you could use SoftwareSerial for the debug messages.

Another useful debug tool is to flash an LED at a regular interval - for example every time sensor data is detected.

By the way this

if ((lastPrint + PRINT_SPEED) < millis()) {

should be

if (millis() - lastPrint >= PRINT_SPEED) {

You should always use subtraction to avoid a problem when the value of millis() rolls over to 0.

...R

Thank you for your time and suggestions @Robin2.

Robin2:
It seems from your description that the running motor is interfering with something. Maybe there is no sensorX.magAvailable().

What happens if you disconnect the motor and run the program?

I came to the same conclusion because last night (8pm) I left the program running with the motor disconnected and with no commands sent to the H-bridge. It's 10:40am and the program is still running with no errors.

Robin2:
As @gilshultz has said it would be great if you have a separate channel for debug messages so you could get more info about what the program is actually doing. However SoftwareSerial won't work at 115200 baud. 9600 is good and it may work at 38400.

If you have a USB TTL cable you could use SoftwareSerial for the debug messages.

Another useful debug tool is to flash an LED at a regular interval - for example every time sensor data is detected.

I'll definitely investigate more about SoftwareSerial for debugging. I tried doing the flashing LED thing but I think the program is running too fast that I can only see the LED either ON or OFF, or maybe I am not doing it correctly haha that's always an option.

EDIT: I was doing the flash LED thing incorrectly. Now I can see it flashing with every print and that my program halts before that part and the led stays on.

Robin2:
By the way this

if ((lastPrint + PRINT_SPEED) < millis()) {

should be

if (millis() - lastPrint >= PRINT_SPEED) {

You should always use subtraction to avoid a problem when the value of millis() rolls over to 0.

...R

I find it unlikely that for my project millis() will ever roll over but it certainly is something worth knowing, cheer for that.

I'll continue working on ideas to correct this, and I'll post the solution once I find it.

deividbrnal:
I came to the same conclusion because last night (8pm) I left the program running with the motor disconnected and with no commands sent to the H-bridge. It's 10:40am and the program is still running with no errors.

I had envisaged that you would do the test with commands sent to the H-bridge, but with the motor disconnect (assuming, of course, that that would not damage the H-bridge).

...R