Using async/await for automation sequences in embedded systems?

Something that happens a lot in embedded systems is to represent a particular process/sequence (e.g. a calibration sequence) using a state machine which gets polled to completion. This sounds almost exactly like the definition of Futures.

For example, I could imagine wanting to write something like this:

/// Find out the total travel distance along a particular axis.
async fn calibrate_axis(axis: &mut Axis, front: &InputPin, back: &InputPin) -> Result<f32, Fault> {
  // first, move to the rear limit
  move_axis_to_limit(axis, back, 42.0).await?;

  // store the current location
  let rear_location = axis.current_position();

  // then go to the front limit
  move_axis_to_limit(axis, front, -42.0).await?;

  let front_location = axis.current_position();
  Ok(rear_location - front_location)
}

async fn move_axis_to_limit(axis: &mut Axis, limit: &InputPin, velocity: f32) -> Result<(), Fault> {
  // tell the machine to start moving at the desired speed
  axis.set_target_velocity(velocity)?;
  // then wait until the rising edge
  wait_for_rising_edge(limit).await?;
  Ok(())
}

enum Fault { ... }

Is there any existing work/experimentation in this area? I've got a couple projects where this could be useful (e.g. Adventures in Motion Control), but I'm not sure what an embedded executor would look like given the hardware limitations of #[no_std] environments.

Take a look at the platform in this recent announcement.. possibly just what you're looking for

AFAIK google fuchsia OS is heavily relied on Futures aync system.

There's been some previous discussion on how async/await fits into the embedded-hal ecosystem: https://github.com/rust-embedded/embedded-hal/issues/149

1 Like