diff --git a/src/main.ts b/src/main.ts
index 57ed56f..febc9c5 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -16,6 +16,8 @@ import { DelayCommand } from './scenario/DelayCommand.js';
 import { ExpectPinCommand } from './scenario/ExpectPinCommand.js';
 import { SetControlCommand } from './scenario/SetControlCommand.js';
 import { WaitSerialCommand } from './scenario/WaitSerialCommand.js';
+import { WaitPinCommand } from './scenario/WaitPinCommand.js';
+import { WaitPinChangeCommand } from './scenario/WaitPinChangeCommand.js';
 import { uploadFirmware } from './uploadFirmware.js';
 
 const millis = 1_000_000;
@@ -141,6 +143,8 @@ async function main() {
       'expect-pin': new ExpectPinCommand(),
       'set-control': new SetControlCommand(),
       'wait-serial': new WaitSerialCommand(expectEngine),
+      'wait-pin': new WaitPinCommand(),
+      'wait-pin-change': new WaitPinChangeCommand(),
     });
     scenario.validate();
   }
diff --git a/src/scenario/WaitPinChangeCommand.ts b/src/scenario/WaitPinChangeCommand.ts
new file mode 100644
index 0000000..8e40821
--- /dev/null
+++ b/src/scenario/WaitPinChangeCommand.ts
@@ -0,0 +1,24 @@
+import chalkTemplate from 'chalk-template';
+import type { APIClient } from '../APIClient.js';
+import type { IScenarioCommand, TestScenario } from '../TestScenario.js';
+
+export interface IExpectPinParams {
+  'part-id': string;
+  pin: string;
+  value: number;
+}
+
+export class WaitPinChangeCommand implements IScenarioCommand {
+  async run(scenario: TestScenario, client: APIClient, params: IExpectPinParams) {
+    const partId = params['part-id'];
+    const pinName = params.pin;
+    const initalValue = (await client.pinRead(partId, pinName))?.value ? 1 : 0;
+    scenario.log(
+      chalkTemplate`wait-pin-toggle {yellow ${partId}}:{magenta ${pinName}} to change from {yellow ${initalValue}}`,
+    );
+    let value = (await client.pinRead(partId, pinName))?.value ? 1 : 0;
+    while (value == initalValue) {
+      value = (await client.pinRead(partId, pinName))?.value ? 1 : 0;
+    }
+  }
+}
diff --git a/src/scenario/WaitPinCommand.ts b/src/scenario/WaitPinCommand.ts
new file mode 100644
index 0000000..54f99e3
--- /dev/null
+++ b/src/scenario/WaitPinCommand.ts
@@ -0,0 +1,24 @@
+import chalkTemplate from 'chalk-template';
+import type { APIClient } from '../APIClient.js';
+import type { IScenarioCommand, TestScenario } from '../TestScenario.js';
+
+export interface IExpectPinParams {
+  'part-id': string;
+  pin: string;
+  value: number;
+}
+
+export class WaitPinCommand implements IScenarioCommand {
+  async run(scenario: TestScenario, client: APIClient, params: IExpectPinParams) {
+    const partId = params['part-id'];
+    const pinName = params.pin;
+    const expectedValue = params.value;
+    scenario.log(
+      chalkTemplate`wait-pin {yellow ${partId}}:{magenta ${pinName}} == {yellow ${expectedValue}}`,
+    );
+    let value = (await client.pinRead(partId, pinName))?.value ? 1 : 0;
+    while (value !== expectedValue) {
+      value = (await client.pinRead(partId, pinName))?.value ? 1 : 0;
+    }
+  }
+}