   return new_turn_degx10;
 }
 /*---------------------------------------------------------------------------------------*/
+// @ToDo: Is this a work in progress?
 void newThrottlePID(){
   
 }

const int SelectCD = 49; // Select IC 3 DAC (channels C and D)
const int SelectAB = 53; // Select IC 2 DAC (channels A and B)

const unsigned long INVALID_DATA = 0;
volatile int rc_index = 0;
volatile unsigned long RC_rise[7];
volatile unsigned long RC_elapsed[7];
volatile boolean synced = false;
volatile unsigned long last_fallingedge_time = 4294967295; // max long
volatile bool RC_Done[7] = {0, 0, 0, 0, 0, 0, 0};
volatile bool flipping;

long speed_errors[ERROR_HISTORY];
long old_turn_degx1000;
unsigned long calibrationTime_ms;
unsigned long stoppedTime_ms;
unsigned long straightTime_ms;
int  throttle_control = MIN_ACC_OUT;
int  brake_control = MIN_BRAKE_OUT;
int  steer_control = STRAIGHT_TURN_OUT;

  //brake(MIN_BRAKE_OUT);
  Serial.begin(9600);
  rc_index = 0;
  for (int i = 0; i < RC_NUM_SIGNALS; i++)
  {
    RC_rise[i] = INVALID_DATA;
    RC_elapsed[i] = INVALID_DATA;
    RC_Done[i] = 0;
  }
  for (int i = 0; i < ERROR_HISTORY; i++)
  {
    speed_errors[i] = 0;
  }

  // @ToDo: Remove any test and calibration code.
  // //setupWheelRev(); // WheelRev4 addition
  //CalibrateTurnAngle(32, 20);
  //calibrationTime_ms = millis();

  attachInterrupt(digitalPinToInterrupt(IRPT_TURN),  ISR_TURN_rise,  RISING);
  //attachInterrupt(digitalPinToInterrupt(IRPT_RDR),   ISR_RDR_rise,   RISING);
  attachInterrupt(digitalPinToInterrupt(IRPT_GO),    ISR_GO_rise,    RISING);
  attachInterrupt(digitalPinToInterrupt(IRPT_ESTOP), ISR_ESTOP_rise, RISING);
  //attachInterrupt(digitalPinToInterrupt(IRPT_RVS),   ISR_RVS_rise,   RISING);
  attachInterrupt(digitalPinToInterrupt(IRPT_SWITCH), ISR_SWITCH_rise, RISING);
  attachInterrupt(digitalPinToInterrupt(IRPT_MOTOR_FEEDBACK), ISR_MOTOR_FEEDBACK_rise, RISING);
}

/*---------------------------------------------------------------------------------------*/

// Time at which this loop pass should end in order to maintain a
// loop period of LOOP_TIME_US.
unsigned long nextTime = micros();
// Time at which we reach the end of loop(), which should be before
// nextTime if we have set the loop period long enough.
unsigned long endTime;
// How much time we need to wait to finish out this loop pass.
unsigned long delayTime;

// Inter-module communications data.
SerialData Results;

void loop() {
  // Get the next loop start time. Note this (and the micros() counter) will
  // roll over back to zero after they exceed the 32-bit size of unsigned long,
  // which happens after about 70 minues of operation. If the new nextTime
  // value is <= LOOP_TIME_US, we've rolled over.
  nextTime = nextTime + LOOP_TIME_US;

  // ToDo: Verify why this is being copied, e.g. is it to avoid having the
  // values change while we're using them? Because they can change right here
  // while we're copying them. Would it help to disable interrupts while we
  // copy them? or does that just freeze them in some intermediate state?
  // How about if we just make sure that anytime we exit the interrupt routine,
  // the RC_elapsed values are in a valid state? Then we don't need to copy
  // them. (This is all under the assumption that we're copying to avoid
  // an inconsistent state.)
  for (int i = 0; i < RC_NUM_SIGNALS; i++)
    local_results[i] = RC_elapsed[i];

  byte automate = processRC(local_results);
  // @ToDo: Verify that this should be conditional. May be moot if it is
  // replaced in the conversion to the new Elcano Serial protocol.
  if (automate == 0x01)
  {
    processHighLevel(&Results);
  }

  // @ToDo: What is this doing?
  //Results.clear();
  Results.kind = MSG_SENSOR;
  Results.angle_deg = TurnAngle_degx10() / 10;
  // @ToDo: Is this working and should it be uncommented?
  // show_speed (&Results);

  // @ToDo: Remove all test or calibration code. If needed, put it in a separate file.
  //calibrationTime_ms += LOOP_TIME_US;
  //straightTime_ms = (steer_control == STRAIGHT_TURN_OUT) ? straightTime_ms + LOOP_TIME_US : 0;
  //stoppedTime_ms = (throttle_control == MIN_ACC_OUT) ? stoppedTime_ms + LOOP_TIME_US : 0;
  //if (calibrationTime_ms > 40000 && straightTime_ms > 3000 && stoppedTime_ms > 3000)
  //{
  //  //       int oldBrake = brake_control;
  //  //       brake(MAX_BRAKE_OUT);  // put on brakes
  //  CalibrateTurnAngle(16, 10);  // WARNING: No response to controls while calibrating
  //  //       brake(oldBrake);       // restore brake state
  //  calibrationTime_ms = 0;
  //}

  // @ToDo: What information do we need to send to C6? Is that communication already
  // hiding in here somewhere, or does it need to be added?

  // Figure out how long we need to wait to reach the desired end time
  // for this loop pass. First, get the actual end time. Note: Beyond this
  // point, there should be *no* more controller activity -- we want
  // minimal time between now, when we capture the actual loop end time,
  // and when we pause til the desired loop end time.
  endTime = micros();
  delayTime = 0L;

  // Did the micros() counter or nextTime overflow and roll over during
  // this loop pass? Did the loop's processing time overrun the desired
  // loop period? We have different computations for the delay time in
  // various cases:
  if ((nextTime >= endTime) &&
      (((endTime < LOOP_TIME_US) && (nextTime < LOOP_TIME_US)) ||
       ((endTime >= LOOP_TIME_US) && (nextTime >= LOOP_TIME_US)))) {
    // 1) Neither micros() nor nextTime rolled over --or-- micros() rolled
    // over *and* nextTime rolled over when we incremented it. For this case,
    // endTime and nextTime will be in their usual relationship, with
    // nextTime >= endTime, and both nextTime and endTime are either greater
    // than the desired loop period, or both are smaller than that.
    // In this case, we want a delayTime of nextTime - endTime here.
    delayTime = nextTime - endTime;
  } else {
    // (We get here if:
    // nextTime < endTime -or- exactly one of nextTime or endTime rolled over.
    // Negate the first if condition and use DeMorgan's laws...
    // Now pick out the "nextTime rolled over" case. We don't need to test both
    // nextTime and endTime as we know only one rolled over.)
    if (nextTime < LOOP_TIME_US) {
      // 2) nextTime rolled over when we incremented it, but the micros() timer
      // hasn't yet rolled over.
      // In this case, we know we didn't exhaust the loop time, and the time we
      // need to wait is the remaining time til micros() will roll over, i.e.
      // from endTime until the max long value, plus the time from zero to
      // nextTime.
      delayTime = ULONG_MAX - endTime + nextTime;
    } else {
      // (We get here if:
      // nextTime < endTime -or-
      // nextTime >= endTime -and- nextTime did not roll over but endTime did.)
      // What remains are these two cases:
      // 3) nextTime hasn't rolled over, but micros() has.
      // In this case, we overran the loop time. Since micros() has rolled over,
      // we can just use the normal overrun fixup. So combine this with...
      // 4) Neither nextTime nor micros rolled over, but we overran the desired
      // loop period.
      // In this case, we have no delay, but instead extend the allowed time for
      // this loop pass to the actual time it took.
      nextTime = endTime;
      delayTime = 0L;
    }
  }
  
  // Did we spend long enough in the loop that we should immediately start
  // the next pass?
  if (delayTime > 0L) {
    // No, pause til the next loop start time.
    delay(delayTime);
  }
}

// @ToDo: Can we remove all or most of this print code?
/*---------------------------------------------------------------------------------------*/
void PrintDone()
{
