# 4.7. External Interface

This section describes the external interfaces to the motor control application framework, including potentiometer, pushbuttons, and LEDs. At present, this is the only supported external interface, however we are considering a future enhancement that would allow a communications channel (CAN/UART/LIN/USB) as a mechanism for external control.

## 4.7.1. General UI guidelines

The dsPICDEM® MCLV‑2 Development Board and the Low Voltage Bundle have (per motor) two LEDs, two pushbuttons, and one potentiometer. The dsPICDEM® MCHV‑2 Development Board and dsPICDEM® MCHV‑3 Development Board have two LEDs, one pushbutton, and one potentiometer for its single motor. The LEDs in MCLV-2 and the Low Voltage Bundle are located next to each other; the LEDs in MCHV-2 and MCHV-3 are located several inches apart on opposite sides of the PIM. In order to support all these systems, the following guidelines are suggested.

- Pushbuttons
  - The primary pushbutton should provide required functionality.
  - The secondary pushbutton should provide optional functionality.
  - Each pushbutton can provide different types of inputs depending on the duration of press and release:
    - debounce: release → press and press → release transitions occur in less than some time T1 (e.g. 20msec). This is ignored.
    - single press: release → press and press → release transitions occur in some time T where T1 ≤ T ≤ T2
    - sustained press: release → press transition occurs, and press is held for more than some time T2 (e.g. 2 seconds). This is available for providing seldom-used input. Once a time T2 has elapsed, if a sustained press is allowed, an LED will provide some type of visual feedback that a sustained press has occurred.
    - double press: two single press events occur within some interval T3 (e.g. 0.5 seconds). This is available for providing seldom-used input.

- LEDs
  - Each LED can provide different types of indication depending on how it is energized over time:
    - Fully off
    - Fully on
    - Modulated at high frequency (>100 Hz) in order to operate at ½ perceived brightness. (NOTE: because of the quirks of the human brain, this may not be at 50% duty cycle.)
    - Perceptible blink rates and duty cycles (e.g. 5%/50%/95% duty at 0.5 / 1 / 2Hz blink rates)
    - Blink rates between 2Hz and 55Hz should be avoided: although LEDs are fairly small in visual extent, these frequencies can be a trigger to people who have photosensitive epilepsy.
    - Error codes — sequences of on/off patterns that are repeated and easily perceptible, e.g. 250msec on-time separated by different-length delimiting spaces of off-time (250msec, 750msec, 2250msec); see section on error codes for more information
  - Some coordination between the two LEDs should be maintained to provide simple visual information (it is difficult to interpret two LEDs blinking at different rates next to each other)
  - For indicating “liveness”, dynamic patterns should be preferred over static patterns, to indicate that the controller is alive and not stuck in a particular state.
- Potentiometer
  - The potentiometer should only represent a continuous range input.

Aside from these general guidelines, the choice of UI behavior is somewhat arbitrary.

## 4.7.2. Required Features

The following are required features:

- [LED] Continuous indication of system state (e.g. disabled/startup/running/shutdown/fault)
- [LED] Error code indicator in fault state
- [button] Start/stop control
- [button] Manual restart from fault
- [potentiometer] Velocity control in a given direction, from low to high magnitude (speed)

The following are desired features:

- [button] Control direction of velocity command (forward / reverse)

## 4.7.3. Implemented Behavior

- Start/stop:
  - Single press events on primary button provide a “start” and “stop” input. (request to start motor if it is stopped; request to stop motor if it is not stopped) This was done to be consistent with the behavior of existing application notes AN1078 and AN1292.
- Reverse direction:
  - Direction flag is maintained
  - Reverse direction request:
    - If 2nd button is present: single press event of 2nd button
    - If 2nd button is not present: sustained press of first button, first supported in MCAF R2.
        The time needed for this is nominally 3 seconds, set by `MCAF_BOARDSERVICE_ISR_PRESCALER` in `board_service_types.h` and `BSP_EMULATED_BUTTON_DELAY_COUNT` in `hardware_access_functions_params.h`, along with the motor control loop frequency. (see errata)
  - If reverse direction request occurs when motor is stopped, direction flag is reversed but no other action is taken.
  - If reverse direction request occurs when motor is running, then the following sequence occurs:
    - Request to stop motor
    - Motor reaches a stopped state
    - Direction flag reversed
    - Request to start motor
- Manual restart from a recoverable fault (see Table 4.5):
  - Single press event, if in fault state, clears fault latch and restarts normal operation.
- Velocity control:
  - Potentiometer adjusts magnitude of velocity (speed) from minimum to maximum. Same as behavior of existing appnotes.
- State indication: see table below

direction | state | LED1 | LED2
--- | --- | --- | ---
both | `RESTART` | off | off
forward | `STOPPED` | off | 1/16 s on @ 1Hz
forward | `STARTING` | on | 1/16 s on @ 1Hz
forward | `RUNNING` | on | 15/16 s on @ 1Hz
forward | `STOPPING` | off | 15/16 s on @ 1Hz
reverse | `STOPPED` | 1/16 s on @ 1Hz | off
reverse | `STARTING` | 1/16 s on @ 1Hz | on
reverse | `RUNNING` | 15/16 s on @ 1Hz | on
reverse | `STOPPING` | 15/16 s on @ 1Hz | off
both | `TEST_DISABLED` | 1/16 s on @ 1Hz | 1/16 s on @ 1Hz
both | `TEST_ENABLED` | 15/16 s on @ 1Hz | 15/16 s on @ 1Hz
both | `FAULT` | error code blink | error code blink

## 4.7.4. Error Codes

The MCAF has fault detection logic to cover a number of different conditions and summarize as a unique fault code. The MCAF displays this fault code as a blinking LED pattern based on groups of 1-4 blinks. The rationale for this approach is that blink counts greater than 4 are difficult to count.

### 4.7.4.1. Error Code LED Behavior

#### 4.7.4.1.1. Converting Error Code to LED Blink Pattern

Given a positive (nonzero) integer X which represents an error code, and an LED that can be turned on:

1. Convert X to a sequence of base 4 digits, least significant digit first, ending in the last nonzero digit.
2. Add 1 to each value in the sequence.
3. For each value k in the sequence:
   1. Repeat k times:
      1. Turn LED on for 250msec
      2. Turn LED off for 250msec
   2. Wait 500 msec
4. Wait 1500 msec, then goto step 3

This always produces a sequence containing at least one double/triple/quadruple blink.

#### 4.7.4.1.2. Converting LED Blink Pattern to Error Code

This is not usually necessary (error code tables include a column indicating the number of blinks directly), but to convert back to a numeric error code:

1. Count the number of blinks as a sequence of numbers from 1-4
2. Subtract 1 from each value in the sequence
3. Interpret the sequence as a base 4 number, least significant digit first

#### 4.7.4.1.3. Examples

The examples below include a visual representation of a blink pattern. Each of the `+` symbols represents the LED turning on, and the pattern is drawn to scale in time (each character represents 250msec).

Error code | Sequence of base 4 digits | k sequence | two repetitions of blink pattern
--- | --- | --- | ---
1 | [1] | [2] | `+ + + +`
2 | [2] | [3] | `+ + + + + +`
3 | [3] | [4] | `+ + + + + + + +`
4 | [0, 1] | [1, 2] | `+ + + + + +`
7 | [3, 1] | [4, 2] | `+ + + + + + + + + + + +`
13 | [1, 3] | [2, 4] | `+ + + + + + + + + + + +`
35 | [3, 0, 2] | [4, 1, 3] | `+ + + + + + + + + + + + + + + +`
100 | [0, 1, 2, 1] | [1, 2, 3, 2] | `+ + + + + + + + + + + + + + + +`

## 4.7.5. Timing and Fault-Clearing Issues in UI Indicators

There are two associated issues that are indirectly related to error-code reporting:

- timing of UI indicators (how delays are implemented)
- fault-clearing issues (what has to happen in order for the system to return to normal operation)

The MCAF uses chosen the following strategy, based on recoverability:

Table 4.5 Error recoverability
recoverability | timing | fault-clearing
--- | --- | ---
Recoverable: faults expected to be caused by a momentary condition: overcurrent, overspeed, overvoltage, etc. | We rely on the system state machine running at a periodic rate as a timebase for UI delays. | User intervention required: press the start/stop input button.
Nonrecoverable: something really bad has happened, such as an oscillator failure, stack overflow, or watchdog timeout. | We cannot necessarily rely on the system state machine operating properly, and instead go into a “paranoid” mode (see below); busy-waiting for a fixed number of CPU cycles is used for timing. | User intervention via a manual reset is required.

Upon nonrecoverable faults (“paranoid mode”), the following actions occur:

- Disable all interrupts
- Put PWM outputs at a safe state
- Report error code via LEDs, relying on busy-waiting to create time delays for UI

## 4.7.6. Implementation

### 4.7.6.1. External interface errata

- LED patterns are not displayed when in the `TEST_DISABLE` or `TEST_ENABLE` states. (DB_MC-1922; Applicability: MCAF R1, R2, R3.)
- Timing of emulated button press for MCHV-2 and MCHV-3 are not guaranteed; if there are long-running tasks within the main loop, this can delay the time needed to detect an extended button press. (DB_MC-1920; Applicability: MCAF R2, R3.)

### 4.7.6.2. Modules

Module | Files | Description | Comments
--- | --- | --- | ---
`error_codes` | `error_codes.h` | List of all error codes | The Appendix contains an annotated list of error codes
`ui` | `ui.c` `ui.h` `ui_types.h` | User interface |