| Предыдущая версия справа и слеваПредыдущая версияСледующая версия | Предыдущая версия |
| products:aruno:exp5 [2020/05/24 11:27] – alexnik | products:aruno:exp5 [2020/08/27 16:16] (текущий) – alexnik |
|---|
| Схема эксперимента не изменилась по сравнению с прошлым, изменения будут только в программной части | Схема эксперимента не изменилась по сравнению с прошлым, изменения будут только в программной части |
| |
| {{ :products:esp-iot:exp3.4.png?nolink |}} | {{ :products:ardu:exp3.4.png?nolink |}} |
| //Рисунок 1. Электрическая принципиальная схема эксперимента// | //Рисунок 1. Электрическая принципиальная схема эксперимента// |
| |
| На рисунке изображен токоограничительный резистор последовательно со светодиодом. При сборке схемы мы не будем устанавливать его сами так как он уже установлен на плате конструктора. | |
| |
| Соберем эту схему: | Соберем эту схему: |
| {{ :products:esp-iot:exp3.png?direct&600 |}} | {{ :products:ardu:exp03.png?direct&600 |}} |
| //Рисунок 2. Монтажная схема эксперимента// | //Рисунок 2. Монтажная схема эксперимента// |
| |
| ==== Программный код эксперимента ==== | ==== Программный код эксперимента ==== |
| |
| <file python Exp5.py[enable_line_numbers="2", start_line_numbers_at="1"]> | <file cpp Exp5[enable_line_numbers="2", start_line_numbers_at="1"]> |
| from machine import Pin | // инициализация констант |
| _init() | |
| | |
| ButtonPin = 16 | |
| LedPin = 0 | |
| old_button_value = 0 | |
| LedState = 0 | |
| | |
| Button = Pin(ButtonPin, Pin.IN) | |
| Led = Pin(LedPin, Pin.OUT) | |
| | |
| while True: | |
| button_value = Button.value() | |
| if old_button_value != button_value and button_value == 1: | |
| if LedState: | |
| Led.off() | |
| LedState = 0 | |
| else: | |
| Led.on() | |
| LedState = 1 | |
| | |
| old_button_value = button_value | |
| </file> | |
| | |
| Создадим две переменные: | |
| * ''old_button_value'' будем использовать для хранения результата прошлой проверки состояния кнопки. Это нам потребуется для выявления факта нажатия на кнопку. Если при прошлой проверке кнопка была не нажата, а при текущей проверке нажата — значит только что произошло нажатие. | |
| * ''LedState'' будем использовать для хранения текущего состояния светодиода — включен он или выключен. Для того, чтобы менять это состояние на противоположное после фиксации факта нажатия на кнопку. | |
| | |
| Считываем сосотояние кнопки и проверяем факт нажатия: | |
| <code python [enable_line_numbers="2", start_line_numbers_at="13"]> | |
| button_value = Button.value() | |
| if old_button_value != button_value and button_value == 1: | |
| </code> | |
| | |
| Выражение ''old_button_value != button_value'' проверяет факт того, что новое состояние кнопки не равно предыдущему. Оператор ''!='' — оператор неравенства. Выражение ''button_value == 1'' проверяет текущее состояние кнопки. Это выражение истинно, когда кнопка нажата. А между этими двумя выражениями мы применили логический оператор ''and''. Он переводится как И, возвращает истину когда оба выражения (слева и справа от него) истины. Если хотя бы одно из них не выполняется, то и все выражение целиком ложно. | |
| | |
| Иными словами проверяем условие того, что состояние кнопки изменилось И, что новым состоянием кнопки является нажатое состояние. Это выражение позволяет выявить факт нажатия на кнопку. | |
| | |
| После регистрации факта нажатии на кнопку нам нужно изменить состояние светодиода на противоположное. Если он был включен — выключаем. Если выключен — включаем. | |
| | |
| Напоследок обновляем старое состояние состояние кнопки. | |
| <code python [enable_line_numbers="2", start_line_numbers_at="22"]> | |
| old_button_value = button_value | |
| </code> | |
| |
| | #define LED 2 //определение константы LED с номером пина 2 |
| | #define BUTTON 12 //определение константы BUTTON с номером пина 12 |
| |
| | // инициализация переменных |
| | int switchState = 0; // актуальный статус кнопки |
| | int oldSwitchState = 0; // статус последней проверки кнопки |
| | boolean lightsOn = false; // статус светодиода on = true или off = false |
| |
| | void setup() { |
| | pinMode(BUTTON, INPUT); |
| | pinMode(LED, OUTPUT); |
| | } |
| |
| | void loop() { |
| | switchState = digitalRead(BUTTON); |
| | if (switchState != oldSwitchState) { |
| | oldSwitchState = switchState; |
| | if (switchState == HIGH) { |
| | lightsOn = !lightsOn; |
| | } |
| | } |
| | if(lightsOn) { |
| | digitalWrite(LED, HIGH); // зажигаем светодиод |
| | } |
| | else { |
| | digitalWrite(LED, LOW); // гасим светодиод |
| | } |
| | } |
| | </file> |
| |
| ==== Дополнительные задания ==== | в начале программы определим две **константы** ''LED'' и ''BUTTON'' для хранения номеров пинов к которым подключены кнопка и светодиод.\\ |
| | далее для реализации задуманного нам понадобятся переменные: |
| | * ''switchState'' - переменная для хранения текущего уровня считанного сигнала с пина. |
| | * ''oldSwitchState'' - будем использовать для хранения результата прошлой проверки состояния кнопки. Это нам потребуется для выявления факта нажатия на кнопку. Если при прошлой проверке кнопка была не нажата, а при текущей проверке нажата — значит только что произошло нажатие. |
| | * ''lightsOn'' будем использовать для хранения текущего состояния светодиода — включен он или выключен. Для того, чтобы менять это состояние на противоположное после фиксации факта нажатия на кнопку. |
| |
| <WRAP center round tip 60%> | выражение ''switchState = digitalRead(BUTTON);'' записывает в переменную **switchState** текущий уровень сигнала на пине кнопки, далее идет проверка события "была ли нажата кнопка". |
| Модифицируй программу так, чтобы светодиод зажигался или выключался только после двух нажатий. Подсказка: потребуется переменная для хранения количества нажатий. | в строке 18 оператором **if** сравниваются переменные **switchState** и **oldSwitchState** в которые записан текущий сигнал и сигнал считанный и записанный ранее. |
| </WRAP> | Оператор ''!='' — оператор неравенства. |
| | Если значение переменной **switchState** не равно значению переменной **oldSwitchState** (была нажата кнопка), то мы перезаписываем старое значение на новое и переходим к проверке того, какой именно поступает текущий сигнал. Если сигнал соответствует **HIGH**, то значение переменной **lightsOn** необходимо изменить на противоположное, поскольку была нажата кнопка.\\ |
| | Обратите внимание, что эта проверка происходит только если выполняется условие предыдущей проверки.\\ |
| | третий оператор **if** проверяет значение переменной ''lightsOn'', если значение равно **true** то выполняется выражение ''digitalWrite(LED, HIGH);'', светодиод загорается, и будет гореть до тех пор пока не будет нажата кнопка, после этого значение переменной измениться на **false**, и выполнится выражение ''digitalWrite(LED, LOW);'', и светодиод погаснет.\\ |
| |
| | Теперь загрузим скетч в контроллер, но по какой то причине кнопка не всегда срабатывает так как мы задумывали.\\ |
| | Данную проблему и ее решение рассмотрим в следующем эксперименте. |