Skip to content
This repository has been archived by the owner on Nov 25, 2024. It is now read-only.

Commit

Permalink
noArcadeShieldMode: thorough documentation complete.
Browse files Browse the repository at this point in the history
  • Loading branch information
KierPalin committed Sep 10, 2024
1 parent c5feb1d commit 1c0ba9d
Showing 1 changed file with 93 additions and 2 deletions.
95 changes: 93 additions & 2 deletions noArcadeShieldMode.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
namespace microcode {
/**
* Sensor Selection cycles between 'animations' of the options; animations are an LED loop specific to that sensor.
* Mutated by the A & B button
*/
const enum UI_MODE {
SENSOR_SELECTION,
LOGGING
};


/**
* Represents the internal state of the UI diplay when in SENSOR_SELECTION UI_MODE;
*
* Mutated by the A & B button & .dynamicSensorSelectionLoop()
*
* Which LED should be shown and what Sensor object should it be converted to when complete.
* see .uiSelectionToSensor()
*
* Notice the RADIO element; which is not a sensor; see .uiSelectionToSensor() since it is handled differently.
*/
const enum UI_SENSOR_SELECT_STATE {
ACCELERATION,
TEMPERATURE,
Expand All @@ -12,12 +27,32 @@ namespace microcode {
RADIO
};


/** For module inside of B button. */
const SENSOR_SELECTION_SIZE = 5;
/** How long should each LED picture be shown for? Series of pictures divide this by how many there are. */
const SHOW_EACH_SENSOR_FOR_MS: number = 1000;

/**
* Simple class to enable the use of MicroData w/o an Arcade Shield for recording data for the sensors listed in UI_SENSOR_SELECT_STATE.
* Invoked if an arcade shield is not detected from app.ts
* The LED is used to represent sensor options, the user can press A to select one; which starts logging.
* Or press B to move onto the next one.
*
* Logging happens every second and is indefinite. The user may cancel the logging via the B button.
*
* Whilst the sensors are cycled between the sensor being displayed may dynamically update if the readings from that sensor are in excess.
* See .dynamicSensorSelectionLoop()
* It checks all sensors inside UI_SENSOR_SELECT_STATE; if there is one that has a reading beyond the threshold then it will switch this.uiSensorSelectState to that sensor.
* This allows the user to cycle between UI elements phsyically - by shining light on or shaking the microbit.
*
* Fibers and special waiting functions .waitUntilSensorSelectStateChange & .waitUntilUIModeChanges are required to maintain low-latency and the dynamic behaviour described above.
*/
export class NoArcadeShieldMode {
private app: App;
/** Mutated by the A & B button */
private uiMode: UI_MODE;
/** Mutated by the B button & .dynamicSensorSelectionLoop() */
private uiSensorSelectState: UI_SENSOR_SELECT_STATE;

constructor(app: App) {
Expand Down Expand Up @@ -50,6 +85,15 @@ namespace microcode {
}


/**
* Runs in background fiber.
* Polls all UI_SENSOR_SELECT_STATE except RADIO for abormally high readings.
* If the reading is beyond the threshold then this.uiSensorSelectState is mutated.
*
* Turned off if not in UI_MODE.SENSOR_SELECTION
*
* Invoked at start and when moving back from logging via pressing the B button.
*/
private dynamicSensorSelectionLoop() {
const dynamicInfo = [
{sensor: new AccelerometerXSensor(), uiState: UI_SENSOR_SELECT_STATE.ACCELERATION, threshold: 0.25},
Expand Down Expand Up @@ -79,6 +123,21 @@ namespace microcode {
})
}


//-------------------------
// Special Waiting Methods:
//-------------------------

/**
* Wait time number of milliseconds but in increments of check_n_times. Exit if initialState changes.
* To show led animations you need to wait inbetween each frame. But you need to switch to another state if a button is pressed immediately.
* used by .showSensorIcon()
*
* @param time milliseconds
* @param check_n_times period = time / check_n_times
* @param initialState this.uiSensorSelectState != causes pre-mature exit; returning false.
* @returns true if neither this.uiSensorSelectState nor this.uiMode changed; meaning that the full time was waited.
*/
private waitUntilSensorSelectStateChange(time: number, check_n_times: number, initialState: UI_SENSOR_SELECT_STATE): boolean {
const period = time / check_n_times;

Expand All @@ -91,6 +150,16 @@ namespace microcode {
return true;
}

/**
* Wait time number of milliseconds but in increments of check_n_times. Exit if initialState changes.
* To show led animations you need to wait inbetween each frame. But you need to switch to another state if a button is pressed immediately.
* used by .log()
*
* @param time milliseconds
* @param check_n_times period = time / check_n_times
* @param initialState this.uiMode != causes pre-mature exit; returning false.
* @returns true if this.uiMode did not change; meaning that the full time was waited.
*/
private waitUntilUIModeChanges(time: number, check_n_times: number, initialState: UI_MODE): boolean {
const period = time / check_n_times;

Expand All @@ -104,6 +173,16 @@ namespace microcode {
}


//-----------------
// Display Methods:
//-----------------


/**
* Starts a fiber that loops through UI_SENSOR_SELECT_STATE:
* Showing each as an animation, checking for this.uiMode & this.uiSensorSelectState changes whilst waiting.
* Invoked at start & by the B button if re-entering SENSOR_SELECTION UI_MODE from the LOGGING UI_MODE
*/
private showSensorIcon() {
control.inBackground(() => {
while (this.uiMode == UI_MODE.SENSOR_SELECTION) {
Expand Down Expand Up @@ -227,7 +306,11 @@ namespace microcode {
});
}



/**
* Get the sensor(s) that the user selected and start logging them.
* Exit if the UI_MODE changes back to SENSOR_SELECTION (upon the user pressing B)
*/
private log() {
const sensors = this.uiSelectionToSensors();
let time = 0;
Expand All @@ -249,11 +332,19 @@ namespace microcode {
if (!this.waitUntilUIModeChanges(Math.max(0, 1000 - (input.runningTime() - start)), 80, UI_MODE.LOGGING)) break;
time += 1000;
}
return;
});
return;
}


/**
* this.uiSensorSelectState -> relevant sensors
* Most are only 1 sensor, but UI_SENSOR_SELECT_STATE.ACCELERATION gives all X,Y,Z sensors.
*
* Special note to UI_SENSOR_SELECT_STATE.RADIO which leaves NoArcadeShieldMode & starts the DistributedLoggingProtocol().
*
* @returns sensors used by .log()
*/
private uiSelectionToSensors(): Sensor[] {
switch (this.uiSensorSelectState) {
case UI_SENSOR_SELECT_STATE.ACCELERATION:
Expand Down

0 comments on commit 1c0ba9d

Please sign in to comment.