Unable to get fast data output through serial monitor - runs slowly (~6 Hz)

Hiya!

I'm currently designing a mechanical testing system using a load cell and a linear actuator. The actuator and load cell also output data to Excel using PLX-DAQ so that it can be analyzed later. I have the code below.

The main problem I am having is that during the Test function, the data outputs only around 6 times per second which is nowhere near enough to get good resolution for data analysis. I used to be able to get 10 data points per second (which is still slow), and I'm not sure what is slowing it down. From my understanding, PLX-DAQ gets information from serial monitor since I have to println in a certain format, but I'm unsure.

Thank you for all and any suggestions. Please let me know if this is in the wrong section so that I can move it.

#include <HX711.h>
#include <Servo.h>

Servo myServo;
HX711 load;

#define DOUT 3
#define CLK 2
#define PIN_SERVO (9)
#define RIGHT 12
#define LEFT 11
#define MIDDLE 13

const int positionPin = 0;

float calibration_factor = 144500;

void SetStrokePerc(float strokePercentage) {
    if ( strokePercentage >= 1.0 && strokePercentage <= 99.0 ) {
      int usec = 1000 + strokePercentage * ( 2000 - 1000 ) / 100.0 ;
      myServo.writeMicroseconds( usec );
    }
  }
  
void SetStrokeMM(int strokeReq,int strokeMax) {
    SetStrokePerc( ((float)strokeReq) / strokeMax );
  }

float readVoltage = 0;
int mode = 0;
unsigned long Time = 0;
int i = 10; // starting actuator at 10% 

void initiate() {
  if ( mode == 1 ) {
  
  SetStrokePerc(i);

  //i needs to increase by 1 every second - use millis() function
  //record millis() as Ti me and when millis() is 1000 more than Time
  //make millis() = Time and increase i by 1

  if (Time + 800 <= millis()) { // for incrementation without delay function
        Time = millis();
        i = i + 1;
    }

  if (load.get_units() > 0.003) {
      //i = i - 5; // actuator retracts 1% after load
      mode = 2; // sets mode to 1 which activates next function and stops this one
      Time = millis(); // For test function activation after waiting without delay
    }     
  //once load is above ~3g mode = 2 which begins the test
  }
}

void Test() {
  if (mode == 2 ) {
    Serial.print("DATA,TIMER,");
    float val = analogRead(positionPin);
    float voltage = val * 5 / 1023.0 + 0.04;
    float displacement = 150.55 - 45.406 * voltage;
    Serial.print(displacement);
    Serial.print(",");
    Serial.println(load.get_units(), 3);

    SetStrokePerc(i);

   if ( Time + 800 <= millis()) {
     i = i + 1;
     Time = millis();
   }
    if (load.get_units() <= 0.01){
      i = i - 5;
      SetStrokePerc(i);
      mode = 0;
    }
    
  }
//  when actuator() stops/activate = 1, begin outputting data to excel
//  actuator moves incrementally with increasing load
//  when load drops, actuator stops moving and retracts (decrease in length)
}

void Stop() { // End phase. Actuator will reset and on command, test will restart 
  if ( mode == 0 ) {
    Serial.println(load.get_units(), 3);
    Serial.println(mode);
    
  }
}

void reset() {
  if (digitalRead(RIGHT) == LOW) {
    mode = 1;
  }
}

void Tare() {
  if (digitalRead(LEFT) == LOW) {
    load.tare();
  }
}

void END() {
  if (digitalRead(MIDDLE) == LOW) {
    mode = 0;
  }
}


void setup() {
  Serial.begin(2000000);
  load.begin(DOUT, CLK);
  load.set_scale(calibration_factor);
  load.tare();
  load.tare(); // I need to add 2 since for some reason the first one doesn't completely tare the scale

  Serial.println("CLEARDATA");
  Serial.println("LABEL,Timer (s),Position (mm),Load (kg)");
  Serial.println("RESETTIMER");
  myServo.attach(PIN_SERVO);
  pinMode(RIGHT, INPUT_PULLUP);
  pinMode(LEFT, INPUT_PULLUP);
  pinMode(MIDDLE, INPUT_PULLUP);
  SetStrokePerc(i);

}

void loop() {
  initiate();
  Test();
  Stop();
  reset();
  Tare();
  END();
}

i'm curious, what is your serial interface that communicates at 2Mbps?

what bit-rate do you think is needed?

It’s just connected through the USB.

I have the baud rate that high from just testing if it would change anything. It was 250,000 previously. It didn’t make that much of a difference if any at all.

Does setting a high baud rate cause issues?

navynuke:
PLX-DAQ gets information from serial monitor since I have to println in a certain format,

PLX-DAQ gets its information from Arduino. You may input serial data from the serial monitor, but there is no clear evidence that you are doing that.
I'm not going to try deciphering the code any further but, after actually finding the loop, the very names of the subroutines therein are cause for concern. Also, there seems to be a total absence of timing control, and one has to wonder about that.

You might try running the serial communication at some more ordinary rate, like 115200, and see if it is really any slower. Don't be surprised if it isn't. Indeed, I seem to recall that 115200 is the maximum rate allowed in Windows.

that's what i'm curious about. what does the hardware do if it can't run at the rate configured

does 6Hz mean 6 chars/sec?

how have you tested the rate? have you written some test code to generate as much serial data to verify communication at the bit rates you've configured without doing anything else?

assuming 11 bits / character (start, data, parity, 2 stop), 9600 bit/sec is 1.25 msec/char or 800 char/sec. would that be fast enough? how much would?u

I’m trying to analyze the failure of a surface mount solder joint. I need high data resolution to analyze the load at different times throughout the test, however, my linear actuator can only move so slow and I’d like to make up for that by having faster data acquisition so I can capture the precise load that the solder failed and can analyze the stress strain properties.

I’ll go ahead and try 115200 baud rate to see if that does anything.

Also, during one of the subroutines I have data outputting to the serial monitor and it looks like it’s roughly outputting at 10 per second. It’s only when it starts doing the output to excel subroutine that it slows down.

I examined this change in rate by looking at the data output on excel which showed that there were only 6 data points being produced each second. Changing the baud rate did not noticeably change that.

What do you mean by time management? I have time being recorded by assigning millis() to a variable every time it loops.

The name of the subroutines relate to the phase of the test.

I apologize for any errors or my brevity, I am currently typing on the a mobile phone.

It's only when it starts doing the output to excel subroutine that it slows down.

what is the excel subroutine?

don't you capture the data and later move it into excel?

navynuke:
I have time being recorded by assigning millis() to a variable every time it loops.

That isn't management, that is just reading the time, which is meaningless. There is no timing control in the loop, which is probably not a good idea.

The name of the subroutines relate to the phase of the test.

The names suggest operations that should not be in the loop.

gcjr, the Testing subroutine runs the print commands that the PLX-DAQ macro reads.

These subroutines are all in the loop, however, only one is active at any time because of the "mode" that sets

I'm not sure why I would need time management. I thought that it'd be irrelevant as long as I can read time which I am doing to incrementally change the movement of the linear actuator. Nothing else relies on the time.

Would having the other subroutines in the loop slow the println output that much? Even if they're not running? I understand that the code is doing a check to see if it's in the appropriate mode to run that subroutine in the loop, but I would imagine that only takes a fraction of a fraction of a second.

Regardless, what could slow down the printing so much?

Hello Navynuke

What do you see if you don't run PLX-DAQ and use only the serial monitor .
You should set "Show Timestamp"

Regards,
bidouilleelec