Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия |
products:laboratory_iot_c:exp35 [2024/11/16 11:24] – [Программный код эксперимента] labuser30 | products:laboratory_iot_c:exp35 [2024/11/16 11:46] (текущий) – [Программный код эксперимента] labuser30 |
---|
| |
Описываем возможные состояния конечного автомата: | Описываем возможные состояния конечного автомата: |
<code python[enable_line_numbers="2", start_line_numbers_at="11"]> | <code python[enable_line_numbers="2", start_line_numbers_at="9"]> |
states = ( | bool states[4][2] = { |
(0,0), | {0,0}, |
(1,0), | {1,0}, |
(1,1), | {1,1}, |
(0,1) | {0,1} |
) | }; |
</code> | </code> |
Список из 4 элементов. В каждом элементе первая цифра это состояние сигнала A, вторая — сигнала B. | Двумерный массив 4×2. Первая цифра это состояние сигнала A, вторая — сигнала B. |
Номер состояния — это индекс элемента списка. Логика переключения состояний автомата простая — состояние может смениться только на соседнее: состояние 0 на 1, 1 на 2, 2 на 3, 3 на 0. И в обратном направлении. Состояние не может измениться "перескочив" через другое. Эту логику мы опишем в программе далее. | Номер состояния — это индекс элемента списка. Логика переключения состояний автомата простая — состояние может смениться только на соседнее: состояние 0 на 1, 1 на 2, 2 на 3, 3 на 0. И в обратном направлении. Состояние не может измениться "перескочив" через другое. Эту логику мы опишем в программе далее. |
| |
В переменной ''old_state'' будем хранить последнее состояние конечного автомата, чтобы понимать какое состояние было и какое у него теперь будет. | В переменной ''state_old'' будем хранить последнее состояние конечного автомата, чтобы понимать какое состояние было и какое у него теперь будет. |
| |
В основном цикле программы мы получаем данные о текущем состоянии линий А и B: | В основном цикле программы мы получаем данные о текущем состоянии линий А и B: |
<code python[enable_line_numbers="2", start_line_numbers_at="34"]> | <code arduino[enable_line_numbers="2", start_line_numbers_at="46"]> |
value_a = encA.value() | value_a = digitalRead(ENC_A); |
value_b = encB.value() | value_b = digitalRead(ENC_B); |
</code> | </code> |
| |
И определяем номер состояния конечного автомата, соответствующего такому состоянию А и B: | И определяем номер состояния конечного автомата, соответствующего такому состоянию А и B с помощью написанной нами функцией ''index()'': |
<code python[enable_line_numbers="2", start_line_numbers_at="37"]> | <code python[enable_line_numbers="2", start_line_numbers_at="49"]> |
current_state = states.index((value_a, value_b)) | state = index(value_a, value_b); |
</code> | </code> |
| |
Формируем список с состояниями А и B ''(value_a, value_b)'' и | Функция ''index(a, b)'' принимает два параметра типа ''bool'', осуществляет поиск соответствующего элемента в массиве states и возвращает индекс найденного элемента. Ключевое слово ''return'' прерывает работу функции и возвращает указанное после него значение. |
с помощью оператора ''index'' мы получаем индекс такого состояния в ''states''. | |
| |
Теперь мы знаем индекс только что измеренного состояния линий. А индекс последнего состояния конечного автомата хранится в переменной ''old_state''. Теперь нам нужно понять можем ли мы из состояния записанного в ''old_state'' переключиться в новое состояние, индекс которого мы определили и записали в ''current_state''. | <code arduino[enable_line_numbers="2", start_line_numbers_at="46"]> |
| int index(bool a, bool b){ |
| for (int i = 0; i < 4; i++){ |
| if (states[i][0] == a and states[i][1] == b) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| </code> |
| |
<code python[enable_line_numbers="2", start_line_numbers_at="39"]> | Зачем же нужна строка ''return -1;'' в конце функции, если в цикле ''for'' в любом случае будет найден и возвращен индекс? Компилятор не на столько умный и не знает об этом, но для всех функций обязательно возвращение значения, иначе программа не скомпилируется. Поэтому мы возвращаем заведомо нереальное значение, т.к. в нашем случае строка ''return -1;'' никогда не будет выполнена. |
if (current_state - old_state == 1) or (current_state == 0 and old_state == 3): | |
| Теперь мы знаем индекс только что измеренного состояния линий. А индекс последнего состояния конечного автомата хранится в переменной ''state_old''. Теперь нам нужно понять можем ли мы из состояния записанного в ''state_old'' переключиться в новое состояние, индекс которого мы определили и записали в ''state''. |
| |
| <code arduino[enable_line_numbers="2", start_line_numbers_at="51"]> |
| if ((state - state_old == 1) or (state == 0 and state_old == 3)) { |
</code> | </code> |
| |
Если индекс нового состояния на 1 больше старого или, если новое состояние 0, а старое 3, то регистрируем переход в новое состояние. Переводим конечный автомат в новое состояние ''old_state = current_state''. Увеличиваем на 1 счетчик ''count'', печатаем + в терминал и отображаем счетчик на дисплее. | Если индекс нового состояния на 1 больше старого или, если новое состояние 0, а старое 3, то регистрируем переход в новое состояние. Переводим конечный автомат в новое состояние ''state_old = state''. Увеличиваем на 1 счетчик ''count'', печатаем + в терминал и отображаем счетчик на дисплее. |
| |
Аналогично для вращения в обратную сторону. Если индекс состояния уменьшился на один, то производим аналогичные действия. | Аналогично для вращения в обратную сторону. Если индекс состояния уменьшился на один, то производим аналогичные действия. |
| |
Когда ты запустишь эту программу в конструкторе, то увидишь, что значение на дисплее всегда меняется сразу на 2 и в терминале появляется по два + или -. Дело в том, что наш энкодер имеет фиксацию положений (при вращении ощущаются толчки). И эта фиксация осуществляется не в каждом состоянии, а через один. Таким образом от щелчка до щелчка энкодер проходит 2 состояния. Поэтому и число изменяется на 2. | Когда ты запустишь эту программу в конструкторе, то увидишь, что значение на дисплее всегда меняется сразу на 2 и в терминале появляется по два + или -. Дело в том, что наш энкодер имеет фиксацию положений (при вращении ощущаются толчки). И эта фиксация осуществляется не в каждом состоянии, а через один. Таким образом от щелчка до щелчка энкодер проходит 2 состояния. Поэтому и число изменяется на 2. |