Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия |
products:laboratory_iot:exp34 [2020/05/21 19:58] – [Схема эксперимента] labuser29 | products:laboratory_iot:exp34 [2024/11/15 20:41] (текущий) – [Программный код эксперимента] labuser30 |
---|
//Рисунок 1. Электрическая принципиальная схема эксперимента// | //Рисунок 1. Электрическая принципиальная схема эксперимента// |
| |
Обрати внимание, что резисторы R1 и R2 уже припаяны на плате модуля энкодера и нам не нужно устанавливать на макетной плате. Зачем же нужны резисторы R3, R4 и конденсаторы C1, C2? Дело в том, что контакты энкодера, как и любые механические контакты, подвержены неприятному эффекту, называемому //дребезгом контактов//. На самом деле при нажатии на кнопку и отпускании кнопки замыкание и размыкание контактов не происходит мгновенно. После замыкания происходят многократные неконтролируемые замыкания и размыкания контактов за счет упругости материалов и деталей контактной системы — некоторое время контакты отскакивают друг от друга при соударениях, размыкая и замыкая электрическую цепь. Этому явлению подвержены и контакты энкодера. | Обрати внимание, что резисторы R1 и R2 уже припаяны на плате модуля энкодера и нам не нужно устанавливать на макетной плате. Зачем же нужны резисторы R3, R4 и конденсаторы C1, C2? Дело в том, что контакты энкодера, как и любые механические контакты, подвержены неприятному эффекту — //дребезгу контактов//. На самом деле при нажатии на кнопку и отпускании кнопки замыкание и размыкание контактов не происходит мгновенно. После замыкания происходят многократные неконтролируемые замыкания и размыкания контактов за счет упругости материалов и деталей контактной системы — некоторое время контакты отскакивают друг от друга при соударениях, размыкая и замыкая электрическую цепь. Это и называется дребезгом контактов. Этому явлению подвержены и контакты энкодера. |
| |
Соберем эту схему как показано на Рисунке 3. | С дребезгом нужно бороться программным или электрическим способом. В нашей схеме резистор с конденсатором являются фильтром для коротких импульсов, возникающих при дребезге контактов. Благодаря этому фильтру данный эффект можно в значительной мере устранить. |
| |
{{ :products:esp-iot:exp14_mon.png?direct&600 |}} | {{ :products:esp-iot:exp14_mon.png?direct&600 |}} |
//Рисунок 3. Монтажная схема эксперимента// | //Рисунок 2. Монтажная схема эксперимента// |
| |
| ==== Программный код эксперимента ==== |
| |
| <file python Exp34.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) |
| |
| old_value_a = 1 |
| |
| 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() |
| |
| if value_a != old_value_a: |
| if (value_a and value_b) or (not value_a and not value_b): |
| print('+') |
| count += 1 |
| print_lcd(count) |
| elif (not value_a and value_b) or (value_a and not value_b): |
| print('-') |
| count -= 1 |
| print_lcd(count) |
| old_value_a = value_a |
| </file> |
| |
| Настраиваем выводы для работы с энкодером: |
| <code python[enable_line_numbers="2", start_line_numbers_at="8"]> |
| encA = Pin(13, Pin.IN) |
| encB = Pin(12, Pin.IN) |
| </code> |
| |
| Объявляем переменную ''old_value_a'' для хранения предыдущего состояния сигнала A и переменную ''count'' в которой подсчитываем количество сигналов от энкодера. |
| |
| Чтобы лучше понять алгоритм работы программы еще раз посмотрим на график сигналов энкодера: |
| {{ :encoder.png?nolink&600 |}} |
| |
| В основном цикле программы получаем текущие состояния линий А и B. |
| Если состояние линии А изменилось, то проверяем условие вращения против часовой стрелки: |
| <code python[enable_line_numbers="2", start_line_numbers_at="31"]> |
| if (value_a and value_b) or (not value_a and not value_b): |
| </code> |
| Если уровни сигналов А и B оба стали высокими (состояние 2) или оба стали низкими (состояние 0), то увеличиваем значение ''count'' на 1, печатаем в терминал символ ''+'' и обновляем информацию на дисплее. |
| |
| Если условие выше не подтвердилось, то проверяем второй вариант: вращение по часовой стрелке: |
| <code python[enable_line_numbers="2", start_line_numbers_at="35"]> |
| elif (not value_a and value_b) or (value_a and not value_b): |
| </code> |
| Если уровень сигнала А стал низким, а сигнала B высоким (состояние 3) или уровень сигнала А стал высоким, а B низким (состояние 1), то уменьшаем значение ''count'' на 1, печатаем символ ''-'' в терминал и обновляем информацию на дисплее. |
| |
| Если ни одно из этих условий не выполнено, то игнорируем сигналы. Перед завершением итерации записываем текущее состояние линии А как старое, для использования в следующей итерации. |
| <code python[enable_line_numbers="2", start_line_numbers_at="39"]> |
| old_value_a = value_a |
| </code> |
| ==== Дополнительное задание ==== |
| <WRAP center round tip 60%> |
| * Попробуй убрать конденсаторы из схемы и покрутить энкодер. Программа будет работать не так, как хотелось бы. Необходимость конденсаторов станет очевидной. |
| </WRAP> |