Skip to main content Why Sampling Period Affects Stability | IoT Worker

Why Sampling Period Affects Stability

Many closed-loop systems behave normally on the bench, then become shaky, slow, overshooting, or unstable in the field.

The gains did not change. The algorithm did not change. The actuator did not change. The difference may come from an ordinary-looking detail: the sampling period.

A controller does not observe the world continuously. An embedded device usually repeats this sequence:

read sensor
-> compute error
-> update controller
-> write actuator output
-> wait for the next period

That period decides how often the controller sees the system, how often it corrects output, how much delay exists, whether noise is amplified, and what integral and derivative action actually mean.

A Closed Loop Sees Discrete Time

The physical plant changes continuously, but the controller only sees it at sampling instants.

If the sampling period is 100 ms, the controller observes the plant only 10 times per second. Between two samples, temperature, motor speed, pressure, or liquid level keeps changing, but the controller does not know that yet.

This creates two immediate effects.

First, feedback is delayed. After a control action is sent, the controller must at least wait until the next sample before it can see the result. Sensor response, filtering, communication, and task scheduling add more delay.

Second, control action becomes stepwise. Output is not continuously corrected; it is updated once per period. The longer the period, the farther the plant can move between corrections.

A shorter period lets the controller see changes sooner. A longer period forces it to act on older information.

A Long Period Makes Correction Late

Closed-loop stability is sensitive to delay.

Take motor speed control. If load suddenly decreases, the real speed starts rising. With a long sampling period, the controller notices the higher speed late. During that time, it may keep the old output.

When the controller finally sees that speed is too high and reduces output, the motor may already have crossed the target. Then speed falls, the controller increases output late again, and the loop can oscillate around the target.

Thermal, level, and pressure control follow the same pattern:

slow sampling
-> error is detected late
-> correction is late
-> plant has already crossed the target
-> reverse correction is also late
-> overshoot or oscillation

The closer the sampling period is to the plant’s own response time, the harder the loop is to stabilize. If the plant changes quickly while the controller watches slowly, tuning becomes awkward no matter how careful the gain changes are.

A Very Short Period Is Not Always Better

Sampling is not automatically better when it is faster.

With a shorter period, the controller sees more detail, but it also sees more noise, quantization jumps, and transient disturbances.

The sensor itself may not be that fast. ADC conversion, digital sensor updates, mechanical motion, thermal conduction, and fluid response all have their own time scales. If the controller samples much faster than meaningful information changes, it may mostly see noise.

Common symptoms include:

  • readings jump by one count and output follows that jump
  • derivative action becomes spiky and kicks the actuator
  • the control task becomes frequent enough to raise CPU load
  • bus access becomes too dense and sensor reads become delayed
  • the actuator cannot respond before commands change again

An overly short period can bring measurement noise and scheduling pressure into the loop. It makes the controller busier, but not necessarily more stable.

Integral and Derivative Depend on the Period

Integral action in discrete PID is not abstract. It usually accumulates error once per period.

A simplified form is:

integral += error * sampling_period

When the period is larger, the same error contributes more integral action per update. When the period is smaller, each contribution is smaller, but updates happen more often.

If the code does not handle period changes correctly, or if the actual period differs from the assumed period, integral action becomes stronger or weaker than expected.

Derivative action is even more sensitive. It estimates how fast error changes:

derivative = error_change / sampling_period

With a very short period, a tiny measurement jump can become a large rate estimate. With period jitter, derivative estimation jitters too.

The same Kp, Ki, and Kd are not equivalent across sampling periods. Moving a PID tuned at 100 ms to 10 ms is not merely running the same controller faster.

Period Jitter Is Harder Than a Fixed Slow Period

A fixed slow period can at least be measured and accounted for. An unstable period is harder.

Control tasks rarely run alone on devices. They may share CPU and bus resources with logging, communication, file systems, display refresh, low-power management, network stacks, and sensor buses.

Common sources of jitter include:

  • logging that occasionally blocks
  • I2C, SPI, UART, or CAN access waiting
  • wireless communication tasks preempting control
  • variable low-power wake timing
  • sensor conversion time changing
  • interrupt storms or high-priority tasks consuming CPU
  • dynamic allocation, file writes, or flash erase causing long-tail delay

The symptoms can be misleading: the loop works most of the time, then one output update looks strange; disabling logs fixes the loop; heavy communication traffic makes control worse.

This can look like a narrow PID tuning margin, while the real problem is that the controller’s time base is moving.

Filter Windows Are Tied to Sampling Period

Filter parameters are often written as point counts: 8-point moving average, 16-sample mean, or 5 consecutive confirmations.

The closed loop cares about time.

If the sampling period is 10 ms, an 8-point moving average covers about 80 ms of data. If the period changes to 100 ms, the same 8 points cover about 800 ms.

The point count is unchanged, but the filter delay is ten times larger.

That directly changes control behavior:

  • the displayed curve looks smoother
  • the controller sees an older state
  • overshoot risk increases
  • response becomes slower
  • gains that were stable may start oscillating

Filtering, sampling period, and PID gains must be considered together. Changing one of them changes the loop’s timing.

The Period Should Match the Plant Time Scale

A suitable sampling period is not just a convenient integer.

It should at least consider:

  • how fast the plant changes
  • how often the sensor provides meaningful new information
  • how long the actuator takes to create physical effect

Thermal control may change on a scale of seconds; sampling much faster does not make heat move faster. Motor speed control may need a millisecond-scale period because the plant and actuator are fast. Level and pressure loops depend on fluid dynamics, valves, pumps, and pipe delay.

If the period is too slow, feedback is late. If it is too fast, noise and scheduling pressure enter the loop. A good period lets the controller see plant changes early enough without treating meaningless high-frequency disturbance as the control target.

Measure Time Before Tuning

Many closed-loop problems should start with timing measurements, not gain changes.

At minimum, record:

  1. Minimum, maximum, and average actual control task period.
  2. Sensor read time and conversion delay.
  3. Real time length of filter windows.
  4. Control computation time.
  5. Delay from output command to actuator response.
  6. Period jitter under communication, logging, and other high-load tasks.
  7. The sampling period associated with each PID gain set.

During debugging, logs can be reduced to low-rate summaries so they do not change the control period. GPIO toggling, a logic analyzer, an oscilloscope, or system tracing can reveal the real rhythm of the control task.

If you do not know how often the controller actually runs, it is hard to explain why PID feels stronger, weaker, noisy, or prone to overshoot.

Sampling period is not just a timer parameter in code. It is part of the closed loop’s time structure.

Stability is decided not only by PID gains, but also by when the controller sees the system, when it corrects the system, and whether those times are stable.