-1

I have the following part of a big code which sends a hex code to a torque sensor thought serial1 and receives a response then it converts the hex value to decimal, converts the decimal to float, then sends it to serial0 (pc).

This should happen while a stepper motor is running using Accelstepper library.

The motor is running fast and smoothly without the MeasureTorque(), function but while using the MeasureTorque() function the stepper is so slow.

As I understood, the Serial1.readbytes is blocking my code between steps, so what is another way to do the same without blocking the code?

I'm using arduino mega2560 if that matters.

Here is the relevant part of the code:


void MeasureTorque(){

  Serial1.write(getvalue, sizeof(getvalue));
  
    Serial1.readBytes(response, sizeof(response));
    decvalue = (response[3]<<24) | (response[4]<<16) | (response[5]<<8) | response[6];

    if(decvalue>>9999){
      decvalue = -(4294967296-decvalue);
      fltvalue = (float)decvalue/100.0;
      }

    else{
      fltvalue = (float)decvalue/100.0;
    }

    Serial.println(fltvalue);


    memset(response, 0, sizeof(response));
    decvalue=0;
    fltvalue=0;
  

}

void loop() {
  CheckButtons();
  Motor.run();
  CheckQueuedTest();
  MeasureTorque();
}

I tried to make the code receive one byte a time during one loop cycle but it didn't work, seems I didn't understand well how that should be done.

1 Answers1

0

while using the MeasureTorque() function the stepper is so slow

That's because you fail to grasp the time interval spent in MeasureTorque(). The inclusion of a new routine into loop() affects how often Motor.run() is called, which presumably is directly related to the problem.

The Serial1.write() takes time to be performed, just like the Serial1.readBytes() and Serial.println(). I/O looks trivial in the source code, but can/will consume CPU cycles (or cause task suspension if your kernel supports that).

But the significant time killer is probably the hidden time delay of unknown length caused by waiting for the response when calling the Serial1.readBytes(). Your processing loop is dead in the water while waiting for the sensor to process the request and generate/send its response.


One solution that retains your simple loop to perform all "tasks" involves breaking up MeasureTorque() into "tasklets" that execute quickly so that iterations of loop() occur at a reasonable pace. Each call of MeasureTorque() from loop() is modified to only perform one "tasklet" in order to consume only a reasonable execution time. This solution will utilize a simple state machine to select which "tasklet" to perform during each invocation of MeasureTorque().

The state machine is controlled by the variable mt_state. The value of mt_state determines what MeasureTorque() will perform when it is called. But before MeasureTorque() returns, mt_state is updated so that a different "tasklet" can be performed during the next call.


void MeasureTorque()
{
    static int mt_state = 0;
    static unsigned char getvalue = { ... };
    static int decvalue;
    static float fltvalue;
    static unsigned char response;

    switch (mt_state) {
        default:
            /* report invalid state */
            ...
            mt_state = 0; /* try to recover */
            /* fall through */
        case 0:
            memset(response, 0, sizeof(response));
            decvalue = 0;
            fltvalue = 0;
            ++mt_state;
            break;
        case 1:
            Serial1.write(getvalue, sizeof(getvalue));
            ++mt_state;
            break;
        case 2:  /* optimization for slow responses */
            if (response_is_available())
                ++mt_state;
            /* else repeat this state */
            break;
        case 3:
            Serial1.readBytes(response, sizeof(response));
            ++mt_state;
            break;
        case 4:
            /* perform calculations on response */
            ...
            ++mt_state;
            break;
        case 5:
            Serial.println(fltvalue);
            mt_state = 0; /* restart state machine */
            break;
    }
    return;
}
sawdust
  • 16,103
  • 3
  • 40
  • 50
  • thank you for your help, actually unfortunately the way you suggest didn't make improvements in the motor speed, although it make sense and it should have worked, but I still don't know what's wrong with it – Elias Taalab Apr 13 '23 at 10:44