timed_encoders – sensing wheel encoders with hardware timers

Wheel encoder driver, using Timer Input Capture

Manage the wheel encoders using ‘Input Capture’ for microsecond level measurement.

class timed_encoders.CaptureEncoder(tmr_channel, max_samples)[source]

Input-capture based handler for single encoder. Maintains circular buffer of 32-bit samples.

class timed_encoders.TimedEncoders(max_samples=20)[source]
Manage the wheel encoders using ‘Input Capture’ for microsecond level measurement.
  • Call ‘snapshot()’ then grab ‘data(n)’ to get historical (ticks,timestamps) for an encoder.
  • The ‘max_samples’ value just needs to be large enough to accommodate the longest interval over which you’ll want to calculate distance. For example, if you’re updating a PID control every 100ms you’d ideally want enough samples to cover that interval. At that rate, 20 samples covers a full revolution (100ms) at theoretical top-speed of 10rev/s.
  • The ‘ticks’ value is an ever-increasing integer. Starting at zero, I’m pretty sure it won’t rollover for the life of the motors. (a 32 bit integer would cover 532,380 miles)
Implementation details:
  • Buffers last ‘max_samples’ timestamps of each wheel encoder. (circular buffer)
  • Running ‘tick_count’ for each encoder.
  • Index ‘i_next’ locates tail (oldest entry) of circular buffer.

Notes

  • There are min(tick_count, max_samples) of valid data in buffers. (Don’t just assume you have ‘max_samples’ valid data in buffer!)
data(n)[source]

Get encoder data lists: oldest to newest. Requires a snapshot prior to calling. Returns two equal length lists: tick counts and timestamps of each sample captured respectively.

Parameters:n (int) – Which encoder (0=LEFT, 1=RIGHT)
Returns:tuple (ticks, samples) containing latest snapshot data lists for given encoder.
dump()[source]

Take a snapshot and print both encoder data-capture records to the console.

dump_raw()[source]

Print raw encoder data-capture values without taking a snapshot.

snapshot()[source]

Copy sample buffers from encoders, so we can work with them outside interrupt context

t_cur()[source]

Get the current microsecond count

t_diff(sample_new, sample_old)[source]

Calculate time difference (uS) between samples, accounting for rollover.