Различия

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

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

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
products:laboratory_iot:exp35 [2020/05/22 13:36] labuser29products:laboratory_iot:exp35 [2024/11/16 11:25] (текущий) – [Программный код эксперимента] labuser30
Строка 23: Строка 23:
 ==== Программный код эксперимента ==== ==== Программный код эксперимента ====
  
-<file python Exp35[enable_line_numbers="2", start_line_numbers_at="1"]>+<file python Exp35.py[enable_line_numbers="2", start_line_numbers_at="1"]>
 from time import sleep_ms, ticks_ms from time import sleep_ms, ticks_ms
 from machine import I2C, Pin from machine import I2C, Pin
Строка 29: Строка 29:
 _init() _init()
  
-DEFAULT_I2C_ADDR = 0x3F+DEFAULT_I2C_ADDR = 0x3F # Или 0x27 в зависимости от модели микросхемы на плате
  
 encA = Pin(13, Pin.IN) encA = Pin(13, Pin.IN)
Строка 35: Строка 35:
  
 states = ( states = (
-    (1,1), 
-    (0,1), 
     (0,0),     (0,0),
-    (1,0)+    (1,0), 
 +    (1,1), 
 +    (0,1)
 ) )
  
Строка 60: Строка 60:
     value_b = encB.value()     value_b = encB.value()
  
-    current_state = states.index((value_a, value_b))+    state = states.index((value_a, value_b))
          
-    if (current_state  old_state == 1) or (current_state == 0 and old_state == 3):+    if (state - old_state == 1) or (state == 0 and old_state == 3):
         count += 1         count += 1
-        if not (count % 2): +        print('+'); 
-            print('+'); +        print_lcd(count) 
-            print_lcd(int(count/2)+        old_state = state 
-        old_state = current_state +    elif (state - old_state == -1)  or (state == 3 and old_state == 0):
-    elif (current_state  old_state == -1)  or (current_state == 3 and old_state == 0):+
         count -= 1         count -= 1
-        if not (count % 2): +        print('-'); 
-            print('-'); +        print_lcd(count) 
-            print_lcd(int(count/2)+        old_state = state
-        old_state = current_state+
 </file> </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.