Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
products:laboratory_iot:exp35 [2020/05/22 13:36] labuser29products:laboratory_iot:exp35 [2024/11/16 11:25] (текущий) – [Программный код эксперимента] labuser30
Строка 20: Строка 20:
 {{ :products:esp-iot:exp14_mon.png?direct&600 |}} {{ :products:esp-iot:exp14_mon.png?direct&600 |}}
 //Рисунок 2. Монтажная схема эксперимента// //Рисунок 2. Монтажная схема эксперимента//
 +
 +==== Программный код эксперимента ====
 +
 +<file python Exp35.py[enable_line_numbers="2", start_line_numbers_at="1"]>
 +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), 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()
 +
 +    state = states.index((value_a, value_b))
 +    
 +    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
 +</file>
 +
 +Описываем возможные состояния конечного автомата:
 +<code python[enable_line_numbers="2", start_line_numbers_at="11"]>
 +states = (
 +    (0,0),
 +    (1,0),
 +    (1,1),
 +    (0,1)
 +)
 +</code>
 +Список из 4 элементов. В каждом элементе первая цифра это состояние сигнала A, вторая — сигнала B.
 +Номер состояния — это индекс элемента списка. Логика переключения состояний автомата простая — состояние может смениться только на соседнее: состояние 0 на 1, 1 на 2, 2 на 3, 3 на 0. И в обратном направлении. Состояние не может измениться "перескочив" через другое. Эту логику мы опишем в программе далее.
 +
 +В переменной ''old_state'' будем хранить последнее состояние конечного автомата, чтобы  понимать какое состояние было и какое у него теперь будет.
 +
 +В основном цикле программы мы получаем данные о текущем состоянии линий А и B:
 +<code python[enable_line_numbers="2", start_line_numbers_at="34"]>
 +    value_a = encA.value()
 +    value_b = encB.value()
 +</code>
 +
 +И определяем номер состояния конечного автомата, соответствующего такому состоянию А и B:
 +<code python[enable_line_numbers="2", start_line_numbers_at="37"]>
 +    state = states.index((value_a, value_b))
 +</code>
 +
 +Формируем список с состояниями А и B ''(value_a, value_b)'' и 
 +с помощью оператора ''index'' мы получаем индекс такого состояния в ''states''.
 +
 +Теперь мы знаем индекс только что измеренного состояния линий. А индекс последнего состояния конечного автомата хранится в переменной ''old_state''. Теперь нам нужно понять можем ли мы из состояния записанного в ''old_state'' переключиться в новое состояние, индекс которого мы определили и записали в ''state''.
 +
 +<code python[enable_line_numbers="2", start_line_numbers_at="39"]>
 +if (state - old_state == 1) or (state == 0 and old_state == 3):
 +</code>
 +
 +Если индекс нового состояния на 1 больше старого или, если новое состояние 0, а старое 3, то регистрируем переход в новое состояние. Переводим конечный автомат в новое состояние ''old_state = state''. Увеличиваем на 1 счетчик ''count'', печатаем + в терминал и отображаем счетчик на дисплее.
 +
 +Аналогично для вращения в обратную сторону. Если индекс состояния уменьшился на один, то производим аналогичные действия.
 +
 +Когда ты запустишь эту программу в конструкторе, то увидишь, что значение на дисплее всегда меняется сразу на 2 и в терминале появляется по два + или -. Дело в том, что наш энкодер имеет фиксацию положений (при вращении ощущаются толчки). И эта фиксация осуществляется не в каждом состоянии, а через один. Таким образом от щелчка до щелчка энкодер проходит 2 состояния. Поэтому и число изменяется на 2.