Task 1: Implement the Real-Time Control Loop

Objective

Configure a fixed-interval control loop that runs deterministically. The loop should execute at a consistent sampling rate (for example, every 10 ms). All sensing, PID computation, and actuator updates must occur inside this timed loop.

Implementation Guidance

  • Use a non-blocking timing method (such as millis() or a hardware timer) to maintain a constant loop interval
  • Store the loop interval in seconds for proper integral and derivative calculation
  • Ensure that sensor readings are filtered before entering the PID equation
  • Print loop timing and position values to Serial during early testing
const unsigned long LOOP_INTERVAL_MS = 10;  // 10ms = 100Hzconst float dt = LOOP_INTERVAL_MS / 1000.0; // Convert to secondsunsigned long previousTime = 0;void setup() {    Serial.begin(115200);    initSensor();    initMotor();}

void loop() { unsigned long currentTime = millis(); if (currentTime - previousTime >= LOOP_INTERVAL_MS) { previousTime = currentTime; // 1. Read and filter sensor float position = readFilteredPosition(); // 2. Compute PID output float output = computePID(setpoint, position, dt); // 3. Update actuator setMotorOutput(output); // Debug output Serial.print("Pos: "); Serial.print(position); Serial.print(" Out: "); Serial.println(output); }}

Key Requirements

  • Loop must run at consistent intervals (10ms recommended)
  • All control code inside the timed section
  • dt stored in seconds for PID calculations
  • Sensor filtering before PID computation

Key Takeaways

  • Use non-blocking timing with millis()
  • 10ms loop interval = 100Hz sampling rate
  • Store dt in seconds for PID math
  • Filter sensor readings before PID