Format | [Addr#]EXTRA [X?] [Y?] [Z=ki_lock] [M?] |
---|---|
Type | Card-Addressed |
Remembered | Using [Addr#]SS Z |
Format | EXTRA [X?] [Y?] [Z=ki_lock] [M?] [M=button_code] |
---|---|
Remembered | Using SS Z |
X? Provides the CRISP
bottom line string as is shown on the LCD display.
Y? Returns the SNR
value shown on the LCD after log amp calibration.
The Z argument sets the integral error servo parameter. The default is 1
. Higher values may improve speed settling but can also generate instability. Use sparingly.
T? (MS2000 9.2o+
): The controller detects the resolution of the ADC during initialization.
M? Returns the button_flag_byte
and resets the value to 0
. (MS2000 9.2m+
and Tiger v3.35+
)
M=# Modify the button_flag_byte
with the button code and call the button functions associated with that code. (MS2000 9.2m+
)
This command differs from BE F which does not modify the button_flag_byte
and only calls a single button function.
button_flag_byte
stores the state of the last detected button press for each button. When the controller is powered on, the value is initialized to 0
. As the user presses buttons the value of the button_flag_byte
changes, it is important to note that this value only changes when you release the button.
After receiving the EXTRA M?
command, the internal value on the controller is reset to 0
, enabling you to detect new button presses.
If a button has already been pressed, and then is pressed again, the new state overwrites the old state for that button.
Example: if you do a Normal Press
and then a Long Press
on the Joystick Button
, the next time you send the “EXTRA M?
” command the state of the Joystick Button
will be Long Press
.
Zero/Halt button presses only have the states 0 and 1. (Not Pressed and Normal Press)
The button_flag_byte
is divided into four 2-bit
sections that each contain the state of a button:
Bits | Button |
---|---|
1-2 | @ Button |
3-4 | Home Button |
5-6 | Joystick Button |
7-8 | Zero/Halt Button |
Each 2-bit
section can take on the values 0-3
, these codes represent the state of the button.
Code | Type |
---|---|
0 | Not Pressed |
1 | Normal Press |
2 | Long Press |
3 | Extra Long Press |
Example:
EXTRA M?
Results of steps 1-5
in binary:
button_flag_byte = 00 00 00 01
button_flag_byte = 00 00 10 01
button_flag_byte = 00 11 10 01
button_flag_byte = 01 11 10 01
button_flag_byte = 00 00 00 00
(serial command reset
)
# the value returned from EXTRA M? button_flag_byte = 127 # bit masks mask_at = 0x03 # 00000011 mask_home = 0x0C # 00001100 mask_js = 0x30 # 00110000 mask_zero = 0xC0 # 11000000 # get the button states from button_flag_byte btn_at = button_flag_byte & mask_at btn_home = (button_flag_byte & mask_home) >> 2 btn_js = (button_flag_byte & mask_js) >> 4 btn_zero = (button_flag_byte & mask_zero) >> 6 # show the results in decimal and binary print(f"{button_flag_byte = } (binary {button_flag_byte :08b})") print(f"{btn_at = } (binary {btn_at:02b})") print(f"{btn_home = } (binary {btn_home:02b})") print(f"{btn_js = } (binary {btn_js:02b})") print(f"{btn_zero = } (binary {btn_zero:02b})") # console output: # button_flag_byte = 127 (binary 01111111) # btn_at = 3 (binary 11) # btn_home = 3 (binary 11) # btn_js = 3 (binary 11) # btn_zero = 1 (binary 01)
This command modifies the button_flag_byte
and calls the button functions associated with that button code.
The button codes are the same values that are returned by EXTRA M?
. The input value is clamped to the range: 0-127.
If a button code represents multiple button presses then the button functions will be called in the order ⇒
@, Home, Joystick, Zero/Halt (LSB ⇒ MSB)
You can expect the same behavior as if you were pressing physical buttons ⇒
EXTRA M=3
: button_flag_byte
= 3, @ Extra Long Press button function called.EXTRA M=1
: button_flag_byte
= 1, @ Normal Press button function called.EXTRA M=5
: button_flag_byte
= 5, @ Normal Press and Home Normal Press button functions called.
This demonstrates that button presses are overwritten as if you were interacting with the physical controller pressing buttons.
def create_button_code(at: int = 0, home: int = 0, joystick: int = 0, zero_halt: int = 0) -> int: assert at in range(4), "Must be in the range 0-3." assert home in range(4), "Must be in the range 0-3." assert joystick in range(4), "Must be in the range 0-3." assert zero_halt == 0 or zero_halt == 1, "Must be 0 or 1." button_code = 0 # bit masks BITMASK_AT = 0x03 # 00000011 BITMASK_HOME = 0x0C # 00001100 BITMASK_JS = 0x30 # 00110000 BITMASK_ZERO = 0xC0 # 11000000 # set bits button_code &= ~BITMASK_AT button_code |= at & BITMASK_AT button_code &= ~BITMASK_HOME button_code |= (home << 2) & BITMASK_HOME button_code &= ~BITMASK_JS button_code |= (joystick << 4) & BITMASK_JS button_code &= ~BITMASK_ZERO button_code |= (zero_halt << 6) & BITMASK_ZERO return button_code def main(): button_code = create_button_code(at=1, home=1) print(button_code) # prints 5 if __name__ == "__main__": main()