Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Getting Started with Arduino.docx
Скачиваний:
4
Добавлен:
01.05.2025
Размер:
91 Кб
Скачать
☆

4.11 Как это работает?

В этом примере программы я показал две новых концепции: функция, которая возвращает результат своей работы, и выражение "if".

Выражение "if" - возможно, самая важная инструкция в языке программирования, так как она позволяет компьютеру (а мы помним что Arduino - это маленький компьютер) делать выбор. После ключевого слова "if" вы должны написать "вопрос" в круглых скобках, и если "ответ", или результат, верен, будет выполнен первый блок кода; и напротив, если ответ неверен, будет выполнен блок кода после "else". Обратите внимание, что я использовал символ "==" вместо "=". Первый используется при сравнении двух значений и возвращает "TRUE" (ИСТИНА) или "FALSE" (ЛОЖЬ); второй присваивает значение переменной. Удостоверьтесь что вы пользуетесь ими правильно, так как очень легко совершить подобную ошибку и использовать простое равно. В этом случае программа никогда не будет работать. Я знаю это по опыту 25 лет программирования и всё ещё могу ошибиться.

Держать палец на кнопке пока вам надо свет - не очень практично. Хотя это заставило-бы вас задуматься о том, сколько энергии тратися впустую когда вы оставляете лампу включённой, нам надо подумать о том, как-бы сделать чтобы кнопка "залипала".

4.12 Одна схема, тысяча применений

Огромное преимущество цифровой программируемой электроники над классической стало теперь очевидным: я покажу вас как реализовать множество различных "поведений" с использованием той-же электрической схемы из предыдущего раздела, просто изменяя программу.

Как мы поняли раньше, непрактично держать палец на кнопке чтобы свет оставался включённым. Поэтому мы должны осуществить что-то похожее на "память" в виде механизма программы, который будет запоминать что мы нажали кнопку и продолжать светить даже елси мы отпустим её.

Чтобы сделать это, нам придётся использовать нечто, называемое переменной (мы уже использовали её, но я не пояснял ничего о ней). Переменная - это место в памяти Arduino, в котором мы можем хранить данные. Думайте о ней как о липкой бумаге для заметок, которую вы иногда используете для записи чего-нибудь: например, телефонного номера - вы берёте листик, пишете на ней "Аня, 02 555 1212" и приклеиваете на компьютер. В языке Arduino это так-же легко: вы просто определяете тип данных, которые будут храниться (например, число или какой-то текст), даёте ей имя, и теперь при надобности вы можете сохранить в переменной данные, или получить их. Например:

int val = 0;

"int" означает, что в переменной будет храниться целое число, "val" - это имя переменной, а "= 0" - назначение переменной нулевого начального значения.

Переменная, как следует из названия, может быть изменена в любом месте вашего кода, так-что позднее в своей программе вы можете написать:

val = 112;

что изменит значение переменной с нуля на 112.

Примечание: Вы заметили, что Arduino каждая инструкция, кроме #define, заканчивается точкой с запятой? Это делается для того чтобы компилятор (часть Arduino, которая превращает ваш скетч в программу, которую может выполнить микроконтроллер) знал где заканчивается одно ваше выражение и начинается другое. Не забудьте использовать точку с запятой (кроме тех строк, которые начинаются с #define).

#define заменяются компилятором перед трансляцией кода в исполняемую программу.

В следующей программе val используется для хранения результата функции digitalRead(); что-бы ни получала Arduino со входа попадает в переменную и остаётся там до тех пор, пока другая строка кода не изменит её. Отметьте, что эти переменные хранятся в оперативной памяти, называемой (RAM). Она очень быстрая, но когда вы выключите свою плату, все данные в оперативной памяти будут потеряны (что означает что все переменные будут сброшены в начальные значения при включании платы). Ваша программа хранится во флеш-памяти (такой-же тип памяти используется в сотовых телефонах для хранения записной книжки) которая не изменяется при отключении платы от питания.

Давайте используем другую переменную для запоминания должен-ли светодиод оставаться включённым когда мы отпускаем кнопку. Пример 4-3 - это наша первая попытка:

Пример 4-3. Включить светодиод при нажатии кнопки и оставить его включённым при отпускании кнопки

#define LED 13 // the pin for the LED

#define BUTTON 7 // the input pin where the

// pushbutton is connected

int val = 0; // val will be used to store the state

// of the input pin

int state = 0; // 0 = LED off while 1 = LED on

void setup() {

pinMode(LED, OUTPUT); // tell Arduino LED is an output

pinMode(BUTTON, INPUT); // and BUTTON is an input

}

void loop() {

val = digitalRead(BUTTON); // read input value and store it

// check if the input is HIGH (button pressed)

// and change the state

if (val == HIGH) {

state = 1 - state;

}

if (state == 1) {

digitalWrite(LED, HIGH); // turn LED ON

} else {

digitalWrite(LED, LOW);

}

}

Попробуйте запустить этот код. Вы увидите что оно работает ... как-то. Вы увидите что светодиод изменяет своё состояние так быстро, что правильно установить его нажатием кнопки тяжело.

Посмотри на интересную часть кода: state - это переменная, которая хранит значение 0 или 1 для запоминания включён светодиод или нет. После отпускания кнопки мы устанавливаем её в 0 (светодиод выключен).

Далее мы считываем текущее состояние кнопки, и если она нажата (val == HIGH), мы изменяем state с 0 на 1, или наоборот. Поскольку state может быть равна только 1 или 0, используем небольшой трюк. Он заключается в маленьком математическом выражении, идея которого состоит в том, что 1 - 0 = 1, а 1 - 1 = 0:

state = 1 - state;

Такая строка не имеет смысла в математике, но он есть при программировании. Знак "=" означает "присвоить результат выражения после меня переменной передо мной" - в данном случае, новое значение state будет вычислено как единица минус старое значение state.

Далее в программе вы видите, что мы используем state для выяснения должен-ли светодиод быть включён или выключен. Как я говорил, это приводит к странному результату.

Результат странный из-за способа считывания кнопки. Arduino очень быстрая; она выполняет свои команды со скоростью 16 миллионов в секунду - вполне может быть, что и несколько миллионов строк кода за секунду. Это означает что пока ваш палец нажимает кнопку, Arduino может снять данные с кнопки несколько сотен раз и изменить столько-же раз состояние светодиода. Результат непредсказуем; светодиод может остаться выключённым когда вы хотите его включить и наоборот. Поскольку даже сломанные часы показывают верное время дважды в день, программа может выдавать верный результат каждый раз какое-то время, но и долгое время - неправильный.

Как ним исправить эту ситуацию? Требуется определить момент нажатися конпки - именно в этот момент следует изменять state. Способ, который мне нравится, таков - хранить старое значение val перед считыванием нового; это позволяет мне сравнить текущее положение кнопки с предыдущим и изменить state только когда кнопка стала "HIGH" после того, как была "LOW".

Пример 4-4 содержит следующий код:

Пример 4-4. Включить светодиод при нажатии кнопки и оставить его включённым после отпускания кнопки с новой, улучшеной формулой!

#define LED 13 // the pin for the LED

#define BUTTON 7 // the input pin where the

// pushbutton is connected

int val = 0; // val will be used to store the state

// of the input pin

int old_val = 0; // this variable stores the previous

// value of "val"

int state = 0; // 0 = LED off and 1 = LED on

void setup() {

pinMode(LED, OUTPUT); // tell Arduino LED is an output

pinMode(BUTTON, INPUT); // and BUTTON is an input

}

void loop(){

val = digitalRead(BUTTON); // read input value and store it

// yum, fresh

// check if there was a transition

if ((val == HIGH) && (old_val == LOW)){

state = 1 - state;

}

old_val = val; // val is now old, let's store it

if (state == 1) {

digitalWrite(LED, HIGH); // turn LED ON

} else {

digitalWrite(LED, LOW);

}

}

Попробуйте код, мы почти закончили!

Возможно вы заметили, что результат не отличный из-за другой проблемы механических переключателей. Кнопки очень простые устройства - два кусочка металла разделены пружинкой. При нажатии кнопки эти контакты соединяются и через них может протекать электричество. Это звучит красиво и просто, но в реальной жизни соединения не так прекрасны, особенно если кнопка нажата не полностью, и генерируют ложные сигналы, называемые дребезг.

Когда кнопка "дребезжит", Arduino видит быструю последовательность сигналов включения и выключения. Существует множество видов антидребезга, но для нашего, простого коде, я заметил что достаточно добавить 10...50-миллисекундную задержку чтобы код определил изменение.

Окончательный код показан в примере 4-5.

Пример 4-5. Включить светодиод при нажатии кнопки и оставить его включённым после отпускания кнопки, включая простой антидребезг. Теперь с новой, улучшенной формулой!

#define LED 13 // the pin for the LED

#define BUTTON 7 // the input pin where the

// pushbutton is connected

int val = 0; // val will be used to store the state

// of the input pin

int old_val = 0; // this variable stores the previous

// value of "val"

int state = 0; // 0 = LED off and 1 = LED on

void setup() {

pinMode(LED, OUTPUT); // tell Arduino LED is an output

pinMode(BUTTON, INPUT); // and BUTTON is an input

}

void loop(){

val = digitalRead(BUTTON); // read input value and store it

// yum, fresh

// check if there was a transition

if ((val == HIGH) && (old_val == LOW)){

state = 1 - state;

delay(10);

}

old_val = val; // val is now old, let's store it

if (state == 1) {

digitalWrite(LED, HIGH); // turn LED ON

} else {

digitalWrite(LED, LOW);

}

5. Продвинутый ввод-вывод

Всё, что мы изучили в четвёртой главе - в большинстве простейшие операции, которые мы можем делать с Arduino: управлять цифровым выводом и читать цифровод ввод. Если-бы Arduino был разговорным языком, это было-бы всего-лишь двумя буквами алфавита. Учитывая то, что в этом алфавите всего пять букв, вы можете увидеть сколько еще работы надо сделать чтобы писать поэмы на Arduino.

5.1 Пробуем другие датчики включения-выключения

5.1.1 Выключатели

То-же самое что и кнопка, но не изменяет автоматически своё состоянии при отпускании.

5.1.2 Термостаты

Выключатель, который срабатывает при достижении установленной температуры.

5.1.3 Магнитные переключатели, также известные как "герконы"

Имеют два контакта, которые соединяются если рядом расположить магнит, используются в сигнализация против взлома для определения открытого окна.

5.1.4 Ковровые переключатели

Маленькие пластинки, которые можно положить под ковёр чтобы определить присутствие человека (или тяжёлого кота).

5.1.5 Датчики наклона

Простой электронный компонент, сделанный из двух контактов и маленького металлического шарика (или капельки ртути, но я не рекомендую использовать такие). Рис. 5-1 показывает внутренности типичной модели. Когда датчик расположен вертикально, шарик замыкает оба контакта, и устройство работает как если-бы вы нажати кнопку. Когда вы наклоняете датчик, шарик движется и контакты размыкаются, как если-бы вы отпустили кнопку. Используя такой простой компонент, вы можете создавать, например, интерфейсы управления жестами, которые реагируют на движения или встряхивание обьекта.

Рис. 5-1. Конструкция датчика наклона

Другой датчик, который вы можете захотеть испытать, это инфракрасный датчик от охранной сигнализации (также известный как пассивный инфракрасный датчик, или ИК-датчик, см. рис. 5-2). Эти маленькие устройства срабатывают когда человек (или животное) движется в пределах его видимости. Это простой способ определить движение.

Рис. 5-2. Типичный инфракрасный датчик

Теперь вы можете поэкспериментировать, найдя всевозможные устройства, имеющие два замыкающихся контакта, такие как термостат, управляющий температурой в комнате (используйте старый, который не подключён к системе), или просто расположив рядом два контакта и капнув на них водой.

Например, используя пример из главы 4 и ИК-датчик, вы можете создать лампу, которая реагирует на присутствие человека, или вы можете применить датчик наклона чтобы она включалась при наклоне в определённую сторону.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]