Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия | ||
products:laboratory_iot:exp35 [2020/05/22 13:15] – labuser29 | products:laboratory_iot:exp35 [2024/11/16 11:25] (текущий) – [Программный код эксперимента] labuser30 | ||
---|---|---|---|
Строка 4: | Строка 4: | ||
{{ : | {{ : | ||
+ | |||
+ | Видно, что из состояния 1 (красного сигнала) светофор может перейти только в состояние 2 (красный + желтый), | ||
+ | |||
+ | Конечные автоматы иногда очень полезны для описания состояний электроники. Возьмем тот же инкрементальный энкодер. Снова посмотрим на график сигналов от него: | ||
+ | {{ : | ||
+ | |||
+ | По графику видно, что состояния у энкодера не меняются хаотично. Они меняются только последовательно. Если крутить ручку в одну сторону, | ||
+ | |||
+ | Зная это мы можем отфильтровывать ложные показания из-за дребезга контактов и точно отслеживать импульсы. Попробуем обрабатывать сигналы энкодера с помощью конечного автомата. | ||
+ | |||
+ | ==== Схема эксперимента ==== | ||
+ | {{ : | ||
+ | // | ||
+ | |||
+ | {{ : | ||
+ | // | ||
+ | |||
+ | ==== Программный код эксперимента ==== | ||
+ | |||
+ | <file python Exp35.py[enable_line_numbers=" | ||
+ | from time import sleep_ms, ticks_ms | ||
+ | from machine import I2C, Pin | ||
+ | from esp8266_i2c_lcd import I2cLcd | ||
+ | _init() | ||
+ | |||
+ | DEFAULT_I2C_ADDR = 0x3F # Или 0x27 в зависимости от модели микросхемы на плате | ||
+ | |||
+ | encA = Pin(13, Pin.IN) | ||
+ | encB = Pin(12, Pin.IN) | ||
+ | |||
+ | states = ( | ||
+ | (0,0), | ||
+ | (1,0), | ||
+ | (1,1), | ||
+ | (0,1) | ||
+ | ) | ||
+ | |||
+ | old_state = 0 | ||
+ | |||
+ | count = 0 | ||
+ | |||
+ | |||
+ | def print_lcd(data): | ||
+ | lcd.clear() | ||
+ | lcd.putstr(str(data)) | ||
+ | |||
+ | |||
+ | i2c = I2C(scl=Pin(5), | ||
+ | lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, | ||
+ | lcd.backlight_on() | ||
+ | |||
+ | |||
+ | while True: | ||
+ | value_a = encA.value() | ||
+ | value_b = encB.value() | ||
+ | |||
+ | state = states.index((value_a, | ||
+ | | ||
+ | if (state - old_state == 1) or (state == 0 and old_state == 3): | ||
+ | count += 1 | ||
+ | print(' | ||
+ | print_lcd(count) | ||
+ | old_state = state | ||
+ | elif (state - old_state == -1) or (state == 3 and old_state == 0): | ||
+ | count -= 1 | ||
+ | print(' | ||
+ | print_lcd(count) | ||
+ | old_state = state | ||
+ | </ | ||
+ | |||
+ | Описываем возможные состояния конечного автомата: | ||
+ | <code python[enable_line_numbers=" | ||
+ | states = ( | ||
+ | (0,0), | ||
+ | (1,0), | ||
+ | (1,1), | ||
+ | (0,1) | ||
+ | ) | ||
+ | </ | ||
+ | Список из 4 элементов. В каждом элементе первая цифра это состояние сигнала A, вторая — сигнала B. | ||
+ | Номер состояния — это индекс элемента списка. Логика переключения состояний автомата простая — состояние может смениться только на соседнее: | ||
+ | |||
+ | В переменной '' | ||
+ | |||
+ | В основном цикле программы мы получаем данные о текущем состоянии линий А и B: | ||
+ | <code python[enable_line_numbers=" | ||
+ | value_a = encA.value() | ||
+ | value_b = encB.value() | ||
+ | </ | ||
+ | |||
+ | И определяем номер состояния конечного автомата, | ||
+ | <code python[enable_line_numbers=" | ||
+ | state = states.index((value_a, | ||
+ | </ | ||
+ | |||
+ | Формируем список с состояниями А и B '' | ||
+ | с помощью оператора '' | ||
+ | |||
+ | Теперь мы знаем индекс только что измеренного состояния линий. А индекс последнего состояния конечного автомата хранится в переменной '' | ||
+ | |||
+ | <code python[enable_line_numbers=" | ||
+ | if (state - old_state == 1) or (state == 0 and old_state == 3): | ||
+ | </ | ||
+ | |||
+ | Если индекс нового состояния на 1 больше старого или, если новое состояние 0, а старое 3, то регистрируем переход в новое состояние. Переводим конечный автомат в новое состояние '' | ||
+ | |||
+ | Аналогично для вращения в обратную сторону. Если индекс состояния уменьшился на один, то производим аналогичные действия. | ||
+ | |||
+ | Когда ты запустишь эту программу в конструкторе, |