SEm/escapeLab/safe
(→Verifying the codes) |
m (→Testing the opening of the safe) |
||
Line 200: | Line 200: | ||
display_sequence(test_sequence) | display_sequence(test_sequence) | ||
</source> | </source> | ||
+ | |||
+ | [[Category:Bachelor]] [[Category:SEm]] [[Category:EscapeLab]] |
Revision as of 14:57, 3 May 2022
|
Opening the safe
The safe is opened by turning an encoder up to the first value, then back to the second, and so on, until the 4 values have been reached. Once the final position has been reached, the rotating lever allows to open the safe. Pressing on the encoder button allows to verify the sequence currently stored by the safe's controller.
This can be tested with the sequence [12, 4, 15, 8]
which doesn't open the safe but displays a smiley.
Verifying the codes
The numbers of the test sequence can be verified by their Hamming code. Calculating the Hamming code is similar to a vector by matrix multiplication, where the product is implemented by an AND function and the sum by a XOR.
As an example, data value 3 has Hamming code 7:
The tasks have the follwing Hamming codes:
- task 1 : 7
- task 2 : 5
- task 3 : 1
- task 4 : 2
Testing the opening of the safe
The following code is programmed in the safe's microcontroller, except for the opening_sequence
.
It allows to find out how the unlocking system works.
# http://microbit-micropython.readthedocs.io/ from microbit import * # ----------------------------------------------------------------------------- # Constants # opening_sequence = [0, 0, 0, 0] test_sequence = [12, 4, 15, 8] positon_min = 0 positon_max = 99 safe_open_button = button_a encoder_button = button_b encoder_pin_high = pin8 encoder_pin_low = pin12 open_safe_pin = pin16 rotating_right = True rotating_left = not rotating_right count_to_display_units = 200 sequence_item_display_interval = 1000 test_sequence_found_image = Image.HAPPY safe_open_sequence_found_image = Image.FABULOUS open_safe_duration = 2000 # ----------------------------------------------------------------------------- # Functions # def get_encoder_value(): encoder_value = \ 2*encoder_pin_high.read_digital() + \ encoder_pin_low.read_digital() return(encoder_value) def update_position(position, encoder_previous_value, encoder_value): encoder_up = [1, 3, 0, 2] if encoder_value == encoder_up[encoder_previous_value]: position = position + 1 else: position = position - 1 if position < positon_min: position = positon_max if position > positon_max: position = positon_min return(position) def display_binary(position): no_intensity = '0' max_intensity = '9' bits_per_line = 4 # prepare bits 3:0 hex_line_0 = "" for index in range(bits_per_line): if position % 2 > 0: hex_line_0 = max_intensity + hex_line_0 else: hex_line_0 = no_intensity + hex_line_0 position = int(position/2) hex_line_0 = '0' + hex_line_0 # prepare bits 7:4 hex_line_1 = "" for index in range(bits_per_line): if position % 2 > 0: hex_line_1 = max_intensity + hex_line_1 else: hex_line_1 = no_intensity + hex_line_1 position = int(position/2) hex_line_1 = '0' + hex_line_1 # display image display.show(Image( "00000:" + hex_line_1 + ":00000:" + hex_line_0 + ":00000" )) def display_tens(position): if position > 9: display.show(str(int(position/10)), wait=False) else: display.show(str(position % 10), wait=False) def display_units(position): display.show(str(position % 10), wait=False) def display_sequence(sequence): for index in range(len(sequence)): if sequence[index] > 9: display.scroll(str(int(sequence[index]/10))) display_units(sequence[index]) sleep(sequence_item_display_interval) def add_to_history(value, history): new_history = history[1:] + [value] return(new_history) def open_safe(): open_safe_pin.write_digital(1) sleep(open_safe_duration) open_safe_pin.write_digital(0) # ----------------------------------------------------------------------------- # Main loop # encoder_value = get_encoder_value() previous_encoder_value = encoder_value encoder_position = 0 previous_encoder_position = encoder_position display_units(encoder_position) activity_counter = 0 history = [0, 0, 0, 0] rotating_direction = rotating_right previous_rotating_direction = rotating_direction while True: # read encoder encoder_value = get_encoder_value() # update position if previous_encoder_value != encoder_value: encoder_position = update_position( encoder_position, previous_encoder_value, encoder_value ) if encoder_position > previous_encoder_position: rotating_direction = rotating_right else: rotating_direction = rotating_left if rotating_direction != previous_rotating_direction: history = add_to_history(previous_encoder_position, history) display_binary(encoder_position) previous_encoder_value = encoder_value previous_encoder_position = encoder_position previous_rotating_direction = rotating_direction activity_counter = 0 # display history if encoder_button.is_pressed(): display_sequence(history) # check history and open safe if safe_open_button.is_pressed(): if add_to_history(encoder_position, history) == opening_sequence: display.show(safe_open_sequence_found_image) open_safe() elif add_to_history(encoder_position, history) == test_sequence: display.show(test_sequence_found_image) else: display_sequence(test_sequence)