Trying to do 4 things with machine state, but not getting far

Overview
I run a robot with 8 motors connected to UARTs and RS485 convertors.
I devoted 4 serial channels, 2 motors each.

When I send a serial command, I need to wait about 2-3ms for the response before I can send the next one.

I would like to have a timer system that runs 100 times per sec and reads the encoders non stop, and is able to send micro steps to the motors in the same 10mS span.

The 10ms allocation:
0-2 ms Read first encoder group of 4
2-4 ms Read second encoder group
4-7 ms Send motion command Motor group 1 ( these need 3ms , they have angle/speed data) //
7-10 ms Send same to Motor group 2

So I made a 10 ms stamp timer in the loop
if (millis() - ReadEncMillis >= 10)
{ Stamp = millis();
// Serial.println (Stamp);
ReadEncMillis = millis();
}

and then I wrote a little machine state function that is stuck in the first state

void MasterTimer ()

{
  if ( millis() - Stamp < 2)
  {
    C_States =  Enc_Gr_1;
    Serial.println ("Enc_Gr_1");
    return;
  }
  else if ( millis() - Stamp >= 2 and  millis() - Stamp < 4)
  { C_States =  Enc_Gr_2;
    Serial.println ("Enc_Gr_2");
  return;
  }

  else if ( millis() - Stamp >= 4 and  millis() - Stamp < 7)
  { C_States =  Mot_Gr_1;
   Serial.println ("Mot_Gr_1");
  return;
  }

  else if ( millis() - Stamp >= 7 and millis() - Stamp <10)
  { C_States =  Mot_Gr_2;
  Serial.println ("Mot_Gr_2");
  return;
  }

 // Serial.println (C_States);
 /* 
  switch (C_States)

  {
    case Enc_Gr_1:  // reading first Group of encoders
      Read_Enc (1);  //A on serial 2
      Read_Enc (12); //B-ser 3
      Read_Enc (11); //C-ser1
      Read_Enc (5);  //D-Ser4
      break;
      // 2mS later:
      case Enc_Gr_2:  // reading second group of encoders
    // Read_Enc (2);  // A on Serial 2
    //  Read_Enc (3); // C on Serial 1
     // Read_Enc (6); // D on Serial 4
    //  Read_Enc (13);// B on Serial 3
      break;
  
      ///next I was thinking to write motor commands group one and 2.
  }

  */

}

I was hoping to see the rolling states in the serial monitor, but it is stuck in the first one...

I know this is demanding, so I am using the teensy 4.1

Is there a smarter way to do this?

Thanks

I think your problem is timing. I am not sure how you set Stamp, but lets assume (since you didn't post ALL YOUR CODE) that Stamp starts out as 0. millis() will return by the time we have completed setup, a few milliseconds. If the execution drifts in timekeeping beyond 10 milliseconds, The following condition and all preceding conditions will return false for approximately 49 days, if they ever actually become true.

else if ( millis() - Stamp >= 7 and millis() - Stamp <10)

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

And see Using millis() for timing. A beginners guide if you need more explanation.

When I send a serial command, I need to wait about 2-3ms for the response before I can send the next one.

I can't imagine why it would be necessary to send commands by serial more frequently than once every 200 to 300 msecs. Why is a faster rate necessary?

...R

What baudrate are you using?
at 9600 baud this might be too slow

9600/8 = 1200 byte/sec
one byte 1/1200 = 0,83 milliseconds

                 12345678
Serial.println ("Enc_Gr_1");

sends 8 bytes
0,83 milliseconds * 8 = 6,66 milliseconds

it's always a good idea to post the complete code

best regards Stefan

Perehama:

They way I am setting Stamp is described in the initial post

if (millis() - ReadEncMillis >= 10)
{ Stamp = millis();
// Serial.println (Stamp);
ReadEncMillis = millis();
}

it works, they print out correctly

Robin2:
I am not trying to do several things at the same time.

I am trying to: read first set of encoders , wait 2 ms read second set of encoders, wait 2 ms
send first set of commands wait 3 ms and second set of commands wait 3 ms and

start all over.

These are NOT at the same time, they have to be delayed rigorously.

a crude way to do it, just for the encoders
Serial.println (Stamp);
ReadEncMillis = millis();
Read_Enc (1); //A
Read_Enc (12); //B-ser 3
Read_Enc (11); //C-ser1
Read_Enc (5); //D

delay (2);
Read_Enc (2); //
Read_Enc (3);
Read_Enc (6);
Read_Enc (13);

Sefan:

RX TX are running at 112500 baud, the motors don't allow for faster.
So does the serial monitor , 112500 baud, plenty of time to print out,

for the entire code, I attache it, it is huge,

RS485_Command_26_ABCD_Ch.ino (22.8 KB)

GoToFun.ino (21.9 KB)

Sw_Cse.ino (11.6 KB)

Read_Fun.ino (10.2 KB)

DataSplit.ino (7.04 KB)

Curr_Volts.ino (8.33 KB)

STOP_FUN.ino (2.53 KB)

IMU.ino (4.81 KB)

Write_Settings.ino (5.96 KB)

laptophead:
I am not trying to do several things at the same time.

It may make the programming easier if you use millis() (or micros() ) to do the timing in the way illustrated in Several Thingss"

I am trying to: read first set of encoders , wait 2 ms read second set of encoders, wait 2 ms
send first set of commands wait 3 ms and second set of commands wait 3 ms and

You have not explained why the commands are needed so frequently and I suspect that your command system is inappropriate, and may be interfering with useful work. Please describe the command system and tell us what is sending the commands.

...R