Показаны различия между двумя версиями страницы.
| Следующая версия | Предыдущая версия | ||
| products:laboratory_iot_c:exp35 [2024/11/16 11:14] – создано labuser30 | products:laboratory_iot_c:exp35 [2024/11/16 11:46] (текущий) – [Программный код эксперимента] labuser30 | ||
|---|---|---|---|
| Строка 23: | Строка 23: | ||
| ==== Программный код эксперимента ==== | ==== Программный код эксперимента ==== | ||
| - | < | + | < |
| - | from time import sleep_ms, ticks_ms | + | #include < |
| - | from machine import I2C, Pin | + | |
| - | from esp8266_i2c_lcd import I2cLcd | + | |
| - | _init() | + | |
| - | DEFAULT_I2C_ADDR | + | #define ENC_A 13 |
| + | #define ENC_B 12 | ||
| + | # | ||
| - | encA = Pin(13, Pin.IN) | + | LCDI2C_Generic lcd(DEFAULT_I2C_ADDR, 16, 2); |
| - | encB = Pin(12, Pin.IN) | + | |
| - | states = ( | + | bool states[4][2] |
| - | (0,0), | + | {0,0}, |
| - | (1,0), | + | {1,0}, |
| - | (1,1), | + | {1,1}, |
| - | (0,1) | + | {0,1} |
| - | ) | + | }; |
| - | old_state | + | bool value_a |
| + | bool value_b = 0; | ||
| - | count = 0 | + | int count = 0; |
| + | int state = 0; | ||
| + | int state_old = 0; | ||
| + | void printLcd(int number) { | ||
| + | lcd.clear(); | ||
| + | lcd.print(number); | ||
| + | } | ||
| - | def print_lcd(data): | + | int index(bool a, bool b){ |
| - | | + | |
| - | | + | |
| + | return i; | ||
| + | } | ||
| + | } | ||
| + | return -1; | ||
| + | } | ||
| + | void setup() { | ||
| + | Serial.begin(9600); | ||
| + | lcd.init(); | ||
| + | lcd.setBacklight(0); | ||
| + | pinMode(ENC_A, | ||
| + | pinMode(ENC_B, | ||
| + | } | ||
| + | |||
| + | void loop() { | ||
| + | value_a = digitalRead(ENC_A); | ||
| + | value_b = digitalRead(ENC_B); | ||
| - | i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000) | + | state = index(value_a, value_b); |
| - | lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, | + | |
| - | lcd.backlight_on() | + | |
| - | + | if ((state - state_old | |
| - | while True: | + | count++; |
| - | value_a = encA.value() | + | |
| - | value_b = encB.value() | + | |
| - | + | | |
| - | current_state = states.index((value_a, | + | } |
| - | + | else if ((state | |
| - | if (current_state | + | count--; |
| - | count += 1 | + | |
| - | print('+'); | + | |
| - | | + | |
| - | | + | } |
| - | | + | } |
| - | count -= 1 | + | |
| - | print('-'); | + | |
| - | | + | |
| - | | + | |
| </ | </ | ||
| Описываем возможные состояния конечного автомата: | Описываем возможные состояния конечного автомата: | ||
| - | <code python[enable_line_numbers=" | + | <code python[enable_line_numbers=" |
| - | states = ( | + | bool states[4][2] |
| - | (0,0), | + | {0,0}, |
| - | (1,0), | + | {1,0}, |
| - | (1,1), | + | {1,1}, |
| - | (0,1) | + | {0,1} |
| - | ) | + | }; |
| </ | </ | ||
| - | Список из 4 элементов. В каждом элементе первая цифра это состояние сигнала A, вторая — сигнала B. | + | Двумерный массив 4×2. Первая цифра это состояние сигнала A, вторая — сигнала B. |
| Номер состояния — это индекс элемента списка. Логика переключения состояний автомата простая — состояние может смениться только на соседнее: | Номер состояния — это индекс элемента списка. Логика переключения состояний автомата простая — состояние может смениться только на соседнее: | ||
| - | В переменной '' | + | В переменной '' |
| В основном цикле программы мы получаем данные о текущем состоянии линий А и B: | В основном цикле программы мы получаем данные о текущем состоянии линий А и B: | ||
| - | < | + | < |
| - | value_a = encA.value() | + | value_a = digitalRead(ENC_A); |
| - | value_b = encB.value() | + | value_b = digitalRead(ENC_B); |
| </ | </ | ||
| - | И определяем номер состояния конечного автомата, | + | И определяем номер состояния конечного автомата, |
| - | <code python[enable_line_numbers=" | + | <code python[enable_line_numbers=" |
| - | | + | |
| </ | </ | ||
| - | Формируем список с состояниями А и B '' | + | Функция '' |
| - | с помощью оператора '' | + | |
| + | <code arduino[enable_line_numbers=" | ||
| + | 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; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Зачем же нужна строка '' | ||
| - | Теперь мы знаем индекс только что измеренного состояния линий. А индекс последнего состояния конечного автомата хранится в переменной '' | + | Теперь мы знаем индекс только что измеренного состояния линий. А индекс последнего состояния конечного автомата хранится в переменной '' |
| - | < | + | < |
| - | if (current_state | + | if ((state |
| </ | </ | ||
| - | Если индекс нового состояния на 1 больше старого или, если новое состояние 0, а старое 3, то регистрируем переход в новое состояние. Переводим конечный автомат в новое состояние '' | + | Если индекс нового состояния на 1 больше старого или, если новое состояние 0, а старое 3, то регистрируем переход в новое состояние. Переводим конечный автомат в новое состояние '' |
| Аналогично для вращения в обратную сторону. Если индекс состояния уменьшился на один, то производим аналогичные действия. | Аналогично для вращения в обратную сторону. Если индекс состояния уменьшился на один, то производим аналогичные действия. | ||
| Когда ты запустишь эту программу в конструкторе, | Когда ты запустишь эту программу в конструкторе, | ||