Это старая версия документа!
Коне́чный автома́т — абстрактный автомат, число возможных внутренних состояний которого конечно. Если говорить проще, то с помощью конечного автомата описываются состояния какого либо объекта и переходы между этими состояниями. Например, светофор можно описать с помощью конечного автомата.
Видно, что из состояния 1 (красного сигнала) светофор может перейти только в состояние 2 (красный + желтый), означающий скорое включение зеленого. Из состояния 2 светофор может перейти только в состояние 3 (зеленый сигнал). После зеленого всегда идет желтый сигнал (состояние 4), который сменяется красным (состояние 1). Главное, что у данного конечного автомата есть 4 состояния и мы знаем из какого состояния в какое он может переходить.
Конечные автоматы иногда очень полезны для описания состояний электроники. Возьмем тот же инкрементальный энкодер. Снова посмотрим на график сигналов от него:
По графику видно, что состояния у энкодера не меняются хаотично. Они меняются только последовательно. Если крутить ручку в одну сторону, то состояния сменяются 0-1-2-3-0…, а если в другую, то 0-3-2-1-0…
Зная это мы можем отфильтровывать ложные показания из-за дребезга контактов и точно отслеживать импульсы. Попробуем обрабатывать сигналы энкодера с помощью конечного автомата.
from time import sleep_ms, ticks_ms from machine import I2C, Pin from esp8266_i2c_lcd import I2cLcd _init() DEFAULT_I2C_ADDR = 0x3F encA = Pin(13, Pin.IN) encB = Pin(12, Pin.IN) states = ( (1,1), (0,1), (0,0), (1,0) ) old_state = 0 count = 0 def print_lcd(data): lcd.clear() lcd.putstr(str(data)) i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000) lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16) lcd.backlight_on() while True: value_a = encA.value() value_b = encB.value() current_state = states.index((value_a, value_b)) if (current_state - old_state == 1) or (current_state == 0 and old_state == 3): count += 1 if not (count % 2): print('+'); print_lcd(int(count/2)) old_state = current_state elif (current_state - old_state == -1) or (current_state == 3 and old_state == 0): count -= 1 if not (count % 2): print('-'); print_lcd(int(count/2)) old_state = current_state