Изучение основ программирования на Arduino - Учебное пособие для новичков

Попробуйте наш инструмент устранения неполадок





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

Вступление

Согласно с википедия микроконтроллер эквивалентен мини-компьютеру, встроенному в одну микросхему IC, имеющему собственный базовый процессор, программируемые входы, память и периферийные устройства вывода.



Микроконтроллер становится настолько полезным для пользователя, поскольку он предлагает встроенный процессор, память и порты ввода / вывода (также называемые GPIO или выводами ввода / вывода общего назначения), которыми пользователь может управлять в соответствии с любыми желаемыми спецификациями.

В этом руководстве мы будем работать с платой Arduino Uno для изучения и тестирования программ. Для тестирования и интеграции аппаратной сборки воспользуемся макетной платой.



Теперь давайте быстро перейдем к изучению того, как начать программировать на Arduino.

1.2 Установка программного обеспечения (Windows)

Для этого вам понадобится доступ в Интернет, который, очевидно, будет у вас на компьютере. Перейдите по следующей ссылке и загрузите программное обеспечение IDE:

ZIP-файл Windows для установки без администратора

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

значок загрузки arduino

Как только вы его получите, вы можете просто дважды щелкнуть по нему и установить интегрированную среду разработки (IDE) Arduino на свой компьютер. Полный процесс можно визуализировать в следующем видео:

https://youtu.be/x7AMn1paCeU

1.4 Начиная с нашего первого контура

Прежде чем мы начнем изучать фактические методы программирования, любому новичку будет полезно начать с базового компонента, такого как светодиод, и понять, как подключить его к Arduino.

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

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

Как показывает опыт, 330 Ом на 1/4 ватта идеально подходит для каждых 5 В на входе источника питания, чтобы ограничить ток до необходимого безопасного уровня. Следовательно, для 5 В это может быть 330 Ом, для 10 В - 680 Ом и так далее.

Использование макета для сборки

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

Базовую настройку подключения светодиодов можно увидеть ниже:

Светодиод с Arduino

Вы можете увидеть 3 основных компонента выше:

  1. Светодиод 5 мм, 20 мА
  2. резистор 330 Ом 1/4 Вт
  3. An Плата Arduino

Просто соберите систему согласно схеме.

Затем подключите 5 В от USB компьютера к Arduino. Как только вы это сделаете, вы увидите, как загорится светодиод.

Я знаю, что это довольно просто, но всегда хорошо начинать с нуля. Будьте уверены, по мере нашего продвижения вперед все будет становиться все интереснее.

1.5 Управление светодиодом с помощью Arduino

Теперь мы узнаем, как управлять светодиодом с помощью программы Arduino.

Чтобы написать программу, у нас должно быть как минимум 2 функции в каждой программе.

Функцию можно понимать как серию программных операторов, которым можно присвоить имя, как указано ниже:

  1. настраивать() это вызывается или выполняется во время запуска программы.
  2. петля() это вызывается или выполняется повторно в течение всего периода работы Arduino.

Поэтому, хотя она может и не иметь практических функций, технически кратчайшая законная программа Arduino может быть записана как:

Простейшая программа

void setup()
{
}
void loop()
{
}

Вы могли заметить, что во многих языках программирования система начинается с вывода на экран простого текста «Hello, World».

Электронный эквивалент этой фразы в интерпретации микроконтроллера - мигание светодиода, включенного и выключенного.

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

Мы попытаемся реализовать и понять процедуру с помощью следующего фрагмента кода:

Листинг 1.2: led1 / led1.pde

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
void loop()
{
digitalWrite(kPinLed, HIGH)
delay(500)
digitalWrite(kPinLed, LOW)
delay(500)
}

Хорошо, теперь давайте разберемся, что означает каждая строка кода и как она работает для выполнения функции:

const int kPinLed = 13

Это работает как константа, что позволяет нам использовать ее во время всего курса программирования, без необходимости использовать фактическое значение, которое ей присвоено.

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

void setup()
{
pinMode(kPinLed, OUTPUT)
}

Этот код настраивает конкретный вывод, к которому подключен наш светодиод. Другими словами, код говорит Arduino управлять аспектом «записи» на этом выводе, а не «читать» его.

void loop()
{
digitalWrite(kPinLed, HIGH)
delay(500)
digitalWrite(kPinLed, LOW)
delay(500)
}

Вышеупомянутые строки указывают на фактическое выполнение приложения. Код начинается с записи и визуализации HIGH на соответствующем подключении светодиода, при этом светодиод включается.

Здесь термин ВЫСОКИЙ просто означает получение + 5В на соответствующем выводе Arduino. Дополнительный член LOW просто указывает ноль или 0В на обозначенном контакте.

Затем мы вызываем delay() чья функция - создать задержку в миллисекундах (1/1000 секунды). Поскольку введена цифра 500, задержка будет составлять 1/2 секунды.

По прошествии этих 1/2 секунды выполняется следующая строка, которая выключает светодиод с термином LOW на том же контакте.

Следующая строка снова генерирует задержку в 1/2 секунды, чтобы светодиод оставался выключенным в течение 1/2 секунды.

И процесс продолжается бесконечно за счет выполнения строк кода, пока на Arduino остается питание.

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

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

Вы можете поиграть со временем задержки, изменив цифру «500» на какое-либо другое значение и обнаружив, что светодиод «слушает» команды и заставляет его мигать в соответствии с указанными значениями задержки.

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

1.7 Комментарии

Строки кода, которые мы поняли выше, были специально написаны для компьютерного программного обеспечения.

Однако, чтобы гарантировать, что пользователь может сослаться на значение строк и понять их, часто может быть полезно и разумно написать объяснение рядом с желаемыми строками кода.

Они называются Комментарии которые написаны только для справки человека или пользователя и закодированы так, чтобы компьютеры могли безопасно игнорировать его.

Язык этих комментариев написан в нескольких форматах:

  1. Блочный стиль комментария, в котором описание комментария заключено под начальным символом / * и конечным символом * /
  2. Это не обязательно должно ограничиваться одной строкой, а может быть расширено до следующих последующих строк в зависимости от длины комментария или описания, как показано в следующем примере:

/ * Это комментарий * /

/ * Это так * /

/* И
* это
* в качестве
* Что ж */

Для быстрого написания однострочного описания комментария достаточно двух символов косой черты // в начале. Это говорит компьютеру, что эта строка не имеет ничего общего с фактическим кодом и должна быть проигнорирована. Например:

// Это комментарий, который компьютеры игнорируют.

Вот пример для справки:

/*
* Program Name: Blink
* Author: Alan Smith
* Description:
* Turns an LED on for one half second, then off for one half second repeatedly.
*/

/* Pin Definitions */
const int kPinLed = 13
/*
* Function Name: setup
* Purpose: Run once when the system powers up.
*/
void setup()
{
pinMode(kPinLed, OUTPUT)
}
/*
* Function name: loop
* Purpose: Runs over and over again, as long as the Arduino has power
*/
void loop()
{
digitalWrite(kPinLed, HIGH)
delay(500)
digitalWrite(kPinLed, LOW)
delay(500)
}

1.8 Устранение неисправностей

Если вы обнаружите, что ваша программа показывает «ошибку» во время компиляции или какую-либо другую проблему, следующие советы, вероятно, помогут вам перепроверить свой код и избавиться от препятствия.

  1. Язык вашей программы будет чувствителен к регистру. Например, выражение myVar нельзя записать как MyVar.
  2. Все виды пробелов, которые могут быть выполнены при вводе с клавиатуры, в конечном итоге отображаются как единое пространство, которое видно или понимается только вами, компьютер не будет это учитывать. Проще говоря, свободные места любого вида не повлияют на результаты кода.
  3. Каждый блок кода должен быть заключен в левую и правую фигурные скобки, '{' и '}'
  4. Цифры цифр не следует разделять запятыми. Например, 1000 нельзя записать как 1000.
  5. Каждая строка кода, заключенная в фигурные скобки, должна заканчиваться точкой с запятой.

Создание интересной последовательности светодиодного освещения с помощью Arduino

В нашей предыдущей главе мы узнали, как постоянно мигать светодиодом, включенным / выключенным с постоянной задержкой.

Теперь мы узнаем, как различные шаблоны задержки могут выполняться на одном и том же светодиодах, обновив программный код.

Мы не будем использовать внешний светодиод, а будем использовать светодиод по умолчанию, встроенный в плату Arduino на контакте № 13. Вы можете найти этот крошечный светодиод SMD сразу за разъемом USB.

2.2 Понимание операторов IF

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

Заявление если становится 1-й структурой управления. Следующая реализация показывает, как это используется:

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
int delayTime = 1000
void loop()
{
delayTime = delayTime - 100
if(delayTime <= 0){ // If the delay time is zero or less, reset it.
delayTime = 1000
}
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
}

Мы попытаемся разобраться в приведенном выше коде поэтапно и узнать, как его можно использовать для других подобных исполнений.

Коды между 1-й и 7-й строками точно такие же, как в нашей исходной программе.

Первая модификация фактически происходит на 8-й строчке.

int delayTime = 1000

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

Это просто потому, что этот код не является константой. Вместо этого это определяется как Переменная , которая имеет свойство значения переменной в процессе программирования.

В приведенном выше примере вы можете видеть, что этой переменной присвоено значение 1000. Помните, что такие переменные, заключенные в фигурные скобки, должны быть строго записаны только в парах фигурных скобок и называются «локальными» переменными.

В качестве альтернативы переменные, которые должны находиться за пределами фигурных скобок, как та, которую мы сейчас обсуждаем, распознаются как «глобальные» и могут выполняться практически в любом месте программного кода.

Забегая вперед, вы увидите, что коды между строками 9 и 11 также похожи на коды первой программы, тем не менее, после строки 11 все становится интереснее.

delayTime = delayTime - 100

В этом коде мы видим, что значение по умолчанию delayTime изменяется путем вычитания из него 100.

Значение 100 вычитается из его первоначального значения 1000, обеспечивая новое значение 900.

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

Символы математического оператора Arduino

Теперь давайте оценим коды между строкой 13 и 15.

if(delayTime <= 0){ // If the delay time is zero or less, reset it.
delayTime = 1000
}

Основная цель приведенного выше фрагмента кода - обеспечить непрерывное мигание светодиода.

В связи с тем, что из первоначального вычитается 100 delayTime , это предотвращает мигание светодиода от нуля и позволяет миганию продолжаться постоянно.

На следующем изображении показано несколько операторов сравнения, которые мы будем использовать в наших кодах:

оператор сравнения для кодов Arduino

В нашем приведенном выше коде мы могли бы протестировать код как if(delayTime == 0).

Однако, поскольку отрицательная цифра может быть одинаково плохой, мы не пошли на это, и это рекомендуемая практика.

Подумайте, что могло бы получиться, если бы мы попытались вычесть 300 вместо 100 из delayTime?

Итак, теперь вы, возможно, поняли, что если delayTime записывается как меньше или равно нулю, тогда время задержки будет возвращено к исходному значению 1000.

digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)

Последние 4 строки кода, как показано выше, отвечают за постоянное включение / выключение и включение / выключение светодиода.

Здесь вы можете ясно заметить, что вместо числа цифр мы использовали переменную для назначения времени задержки, чтобы мы могли настроить его по своему усмотрению в течение рабочего периода кода. Круто, правда?

2.3 Заявления ELSE

Здесь мы узнаем, почему и как если срок может иметь пункт еще чтобы он решил ситуацию в случае если заявление ложно.

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

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
int delayTime = 1000
void loop()
{
if(delayTime <= 100){ // If it is less than or equal to 100, reset it
delayTime = 1000
}
else{
delayTime = delayTime - 100
}
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
}

Из приведенного выше вы можете хорошо видеть, что в 10-й строке код выполняется только тогда, когда delayTime меньше или равно 100, в противном случае выполняется код в 13-й строке, но оба вместе никогда не могут произойти, либо 10-я строка, либо 13-я строка кода будут реализованы, но никогда оба.

Возможно, вы заметили, что в отличие от того, что мы делали в предыдущем разделе 2.2, здесь мы сравнивали не с 0, а со 100. Это связано с тем, что в этом примере сравнивали ДО того, как мы вычитали 100, в отличие от раздела 2.2, мы сравнивали ПОСЛЕ того, как мы вычтено. Можете ли вы сказать, что могло бы произойти, если бы мы сравнили 0 вместо 100?

2.4 Операторы WHILE

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

Следующий пример поможет вам лучше понять это.

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
int delayTime = 1000
void loop()
{
while(delayTime > 0){ // while delayTime is greater than 0
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
delayTime = delayTime - 100
}
while(delayTime <1000){ // while delayTime is less than 1000
delayTime = delayTime + 100 // do this first so we don’t have a loop with delayTime = 0
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
}
}

Вы можете догадаться, на что запрограммирован приведенный выше код? Что ж, он предназначен для того, чтобы светодиод быстрее мигал, а затем медленнее.

2.5 Что верно, а что ложно?

На языке программирования ложный относится к нулю (0). На самом деле «истина» не используется, вместо этого предполагается, что когда ничего не ложно, тогда все, что включено, истинно.

Это выглядит немного странно, но справляется со своей задачей довольно хорошо.

Мы попытаемся разобраться в ситуации на следующем примере.

Иногда вы можете встретить код, приведенный ниже:

while (1){
digitalWrite(kPinLed, HIGH)
delay(100)
digitalWrite(kPinLed, LOW)
delay(100)
}

Это закодировано, похоже, светодиодное исполнение будет продолжать работать вечно, пока есть доступное питание.

Однако один недостаток этого типа кода может возникнуть, когда пользователь случайно применяет = вместо ==.

Я уверен, вы уже знаете, что = означает присвоение, то есть он используется для обозначения выбранного значения переменной, а == используется для проверки, если значение было таким же.

Например, предположим, что вам нужно, чтобы светодиод мигал последовательно и многократно, но неправильно использовал = вместо ==.

Тогда код будет выглядеть так:

int delayTime = 1000
void loop()
{
if(delayTime = 0){ // WRONG!!! the = should have been ==
delayTime = 1000
}
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
delayTime = delayTime - 100
}

Ошибка присвоит 0 delayTime и приведет к если оператор, чтобы проверить, было ли 0 истинным или нет. Поскольку 0 относится к false, он будет думать, что это неправда, и остановит принудительное выполнение delayTime = 1000, но вместо этого функция delayTime удерживается на 0 во время цикла ().

Это выглядит очень нежелательно !!

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

2.6 Комбинации

Иногда вы можете почувствовать необходимость протестировать несколько вещей вместе. Например, вы можете проверить, находится ли переменная между двумя числами. Хотя это можно реализовать с помощью оператора if несколько раз, может быть удобнее использовать логические комбинации для лучшего и легкого чтения.

Реализация комбинаций на логических терминах может быть выполнена тремя способами, как показано в следующей таблице:

таблица, показывающая методы комбинации Arduino

Было бы интересно узнать, что оператор NOT может работать как переключатель для переменной, которая может быть обозначена как истинный или же ложный (или НИЗКИЙ или ВЫСОКИЙ).

Следующий пример иллюстрирует условие:

int ledState = LOW
void loop()
{
ledState = !ledState // toggle value of ledState
digitalWrite(kPinLed, ledState)
delay(1000)
}

Здесь ledState будет НИЗКИЙ, и впоследствии, как только ledState = !ledState, он станет ВЫСОКИМ. Следующий цикл вызовет ledState быть ВЫСОКИМ, когда ledState = !ledState НИЗКИЙ.

2.7 Заявления FOR

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

Давайте разберемся в этом на следующем примере:

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
}
void loop()
{
for(int i = 0 i <4 i++){
digitalWrite(kPinLed, HIGH)
delay(200)
digitalWrite(kPinLed, LOW)
delay(200)
}
delay(1000) // 1 second
}

Вы можете найти что-то уникальное в линейке с за.

Это код я ++? . Это полезно для довольно ленивых программистов, которые хотят реализовать кодирование с помощью удобных ярлыков.

Вышеупомянутый термин известен как составные операторы, поскольку они выполняют работу по объединению одного оператора присваивания с другим оператором присваивания. Наиболее популярные из них представлены в следующей таблице:

составные операторы arduino

Вы обнаружите, что в операторе for есть 3 подвыражения. Он структурирован, как показано ниже:

for (statement1conditionstatement2){
// statements
}

Утверждение №1 встречается в самом начале и только один раз. Условие проверяется каждый раз в течение цикла. Когда бы это ни было истинный внутри фигурных скобок применяется следующий оператор №2. В случае ложный, система переходит к следующему блоку кода.

Подключение большего количества светодиодов

Хорошо, теперь посмотрим, как мы можем подключить большее количество светодиодов для получения более интересных эффектов.

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

Подключение нескольких светодиодов Arduino

Теперь давайте исправим программу, которая позволит нам проверить, правильно ли настроено наше оборудование или нет.

Всегда рекомендуется кодировать и выполнять небольшие фрагменты программ поэтапно, чтобы проверить, правильно ли подключено соответствующее оборудование.

Это помогает быстро устранить возможную ошибку.

В приведенном ниже примере кода светодиодам 2–5 задается определенный шаблон путем их циклического поворота один за другим.

const int kPinLed1 = 2
const int kPinLed2 = 3
const int kPinLed3 = 4
const int kPinLed4 = 5
void setup()
{
pinMode(kPinLed1, OUTPUT)
pinMode(kPinLed2, OUTPUT)
pinMode(kPinLed3, OUTPUT)
pinMode(kPinLed4, OUTPUT)
}
void loop()
{
// turn on each of the LEDs in order
digitalWrite(kPinLed1, HIGH)
delay(100)
digitalWrite(kPinLed2, HIGH)
delay(100)
digitalWrite(kPinLed3, HIGH)
delay(100)
digitalWrite(kPinLed4, HIGH)
delay(100)
// turn off each of the LEDs in order
digitalWrite(kPinLed1, LOW)
delay(100)
digitalWrite(kPinLed2, LOW)
delay(100)
digitalWrite(kPinLed3, LOW)
delay(100)
digitalWrite(kPinLed4, LOW)
}

Как вы могли заметить, в коде нет ничего плохого, кроме того факта, что он выглядит длинным и, следовательно, подвержен ошибкам.

Конечно, есть более эффективные способы написать приведенный выше код, следующий раздел покажет это.

2.9 Введение в массивы

Массивы могут быть группой переменных, которые можно индексировать с помощью порядковых номеров. Следующий пример поможет нам лучше понять это.

const int k_numLEDs = 4
const int kPinLeds[k_numLEDs] = {2,3,4,5} // LEDs connected to pins 2-5
void setup()
{
for(int i = 0 i pinMode(kPinLeds[i], OUTPUT)
}
}
void loop()
{
for(int i = 0 i digitalWrite(kPinLeds[i], HIGH)
delay(100)
}
for(int i = k_numLEDs - 1 i >= 0 i--){
digitalWrite(kPinLeds[i], LOW)
delay(100)
}
}

Хорошо, теперь давайте пройдемся по каждому разделу и поймем, как они на самом деле работают.

const int k_numLEDs = 4

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

const int kPinLeds[k_numLEDs] = {2,3,4,5} // LEDs connected to pins 2-5

В следующей строке мы настраиваем структуру массива. Цифры внутри скобок указывают количество элементов в массиве. Хотя фактическое количество можно было бы записать, запись в виде констант работает лучше. Обычно значения можно увидеть внутри скобок с запятыми и обозначить значения в массиве.

Когда вы найдете массив с индексом 0, это указывает на самый первый элемент в массиве, как показано в code: k_LEDPins is k_LEDPins[0].

Точно так же последний элемент будет показан как k_LEDPins[3], так как счет от 0 до 3 равен 4.

void setup()
{
for(int i = 0 i pinMode(kPinLeds[i], OUTPUT)
}
}

В приведенном выше коде показано использование цикла для прохождения каждого элемента массива и для установки их как ВЫХОДОВ. Мы используем квадратные скобки вместе с индексом, чтобы добраться до каждого элемента в массиве.

Если вам интересно, можно ли использовать контакт №2 и контакт №5 без массивов, ответ - да, это возможно. Но в этом примере это не сделано, потому что мы так не сделали. В следующих разделах вы можете отказаться от подхода массива, если выбранные выходные контакты не совпадают.

Забегая вперед, посмотрим, что делает следующий блок кода:

for(int i = 0 i digitalWrite(kPinLeds[i], HIGH)
delay(100)
}

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

for(int i = k_numLEDs - 1 i >= 0 i--){
digitalWrite(kPinLeds[i], LOW)
delay(100)
}

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

Он начинается с k_numLEDs - 1, потому что массивы имеют нулевой индекс. Мы не начинаем с k_LEDPins[4] потому что это приведет к пересечению конца массива.

Код использует> = 0 для проверки, чтобы первый элемент с индексом 0 не был пропущен или проигнорирован.

Глава 3

Что такое ввод

Итак, мы узнали, как управлять вещами с помощью Arduino. В этой главе мы обсудим, как воспринимать реальный мир, связывая входные данные с внешними параметрами.

3.1 Использование кнопок

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

3.1.1 Одна кнопка и светодиод

кнопка интерфейса с Arduino

Мы подключим Arduino с помощью кнопки к Arduino в соответствии с показанными выше деталями и изучим базовую работу и реализацию настройки.

Указанная кнопка, также называемая кнопкой микропереключателя, имеет всего 4 контакта (по 2 пары с каждой стороны). При нажатии каждая пара контактов соединяется внутри и обеспечивает соединение или проводимость через них.

В этом примере мы используем только одну пару этих штырей или контактов, другая пара не имеет значения и поэтому игнорируется.

Давайте продолжим, применяем следующий код и проверяем, что он работает!

const int kPinButton1 = 2
const int kPinLed = 9
void setup()
{
pinMode(kPinButton1, INPUT)
digitalWrite(kPinButton1, HIGH) // turn on pull-up resistor
pinMode(kPinLed, OUTPUT)
}
void loop()
{
if(digitalRead(kPinButton1) == LOW){
digitalWrite(kPinLed, HIGH)
}
else{
digitalWrite(kPinLed, LOW)
}
}

Вы можете найти здесь несколько необычных вещей. Давайте разберемся с ними поэтапно.

void setup()
{
pinMode(kPinButton1, INPUT)
digitalWrite(kPinButton1, HIGH) // turn on pull-up resistor
pinMode(kPinLed, OUTPUT)
}

Первое, что мы делаем, это исправляем buttonPin как ВХОД. Я знаю, что это довольно просто.

Далее присваиваем ВЫСОКО к ВХОД штырь. Вы удивляетесь, как можно на входе что-нибудь написать? Конечно, это может быть интересно.

Фактически, присвоение ВЫСОКОГО значения входу Arduino включает внутренний подтягивающий резистор 20 кОм (НИЗКИЙ уровень на этом выводе выключает его).

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

Хорошо, продолжаем, теперь давайте посмотрим на код основного цикла:

void loop()
{
if(digitalRead(kPinButton1) == LOW){
digitalWrite(kPinLed, HIGH)
}
else{
digitalWrite(kPinLed, LOW)
}
}

Когда вы нажимаете кнопку, проводной штифт подключается к земле, что дает НИЗКИЙ к этой булавке. И в непрессованном состоянии этот же штифт удерживается на ВЫСОКО или + 5 В через внутренний подтягивающий резистор 20 кОм.

Здесь мы хотим, чтобы Arduino загорался светодиодом при нажатии кнопки (LOW), поэтому мы пишем HIGH для выхода для каждого ответа LOW от кнопки, пока она нажата.

3.1.2 Две кнопки и светодиод

Что ж, вы можете задаться вопросом, что показанное выше действие можно было бы выполнить и без Arduino. Я понимаю, однако, что это ступенька, позволяющая узнать, как можно использовать кнопку с Ардуно.

До этого момента мы изучали написание кодов для включения (HIGH) или выключения (LOW) светодиода.

Теперь давайте посмотрим, как можно управлять яркостью светодиода с помощью Arduino.

Это можно сделать двумя способами:

  1. Ограничивая ток на светодиод
  2. Используя ШИМ или широтно-импульсная модуляция, при которой питание светодиода включается / выключается с некоторой желаемой скоростью очень быстро, создавая среднее освещение, интенсивность которого будет зависеть от ШИМ.

На плате Arduino поддержка ШИМ доступна на контактах, отмеченных тильдой (~), которые являются контактами 3, 4, 5, 9, 10 и 11) при 500 Гц (500 раз в секунду). Пользователь может указать любое значение от 0 до 255, где 0 означает отсутствие ВЫСОКОГО или + 5В, а 255 указывает Arduino постоянно получать ВЫСОКОЕ или + 5В. Для запуска этих команд вам нужно будет получить доступ к analogWrite () с желаемым значением.

Вы можете принять ШИМ равным x / 255, где x - желаемое значение, которое вы хотите отправить через analogWrite().

ШИМ-контроль Arduino

Настройте Arduino и другие параметры, как показано выше.

const int kPinButton1 = 2
const int kPinButton2 = 3
const int kPinLed = 9
void setup()
{
pinMode(kPinButton1, INPUT)
pinMode(kPinButton2, INPUT)
pinMode(kPinLed, OUTPUT)
digitalWrite(kPinButton1, HIGH) // turn on pullup resistor
digitalWrite(kPinButton2, HIGH) // turn on pullup resistor
}
int ledBrightness = 128
void loop()
{
if(digitalRead(kPinButton1) == LOW){
ledBrightness--
}
else if(digitalRead(kPinButton2) == LOW){
ledBrightness++
}
ledBrightness = constrain(ledBrightness, 0, 255)
analogWrite(kPinLed, ledBrightness)
delay(20)
}

Вы можете найти здесь 3 строки, требующие пояснений.

ledBrightness = constrain(ledBrightness, 0, 255)
25 analogWrite(kPinLed, ledBrightness)
26 delay(20)

Строка: ledBrightness = constrain(ledBrightness, 0, 255) иллюстрирует уникальную функцию внутри Arduino, известную как constrain ().

Эта внутренняя функция содержит код, похожий на следующий:

int ограничение (значение типа int, min, int max)
{
if(value > max){
value = max
}
if(value value = min
}
return value
}

Все коды, обсуждавшиеся до этого, начинались с пустота , что означало, что ничего не возвращать (void). В то время как приведенный выше код начинается с int , что означает, что он возвращает целое число. Мы обсудим больше в следующих разделах, пока просто помните, что целое число не имеет дробных частей.

Итак, это означает, что код: ledBrightness = constrain(ledBrightness, 0, 255) присваивает ledBrightness to be within the range of 0 and 255.

В следующей строке используется analogWrite к командам Arduino применить ШИМ к выбранному выводу с желаемым значением.

Следующая строка создает задержку в 20 миллисекунд, чтобы гарантировать, что мы не регулируем скорость, превышающую 50 Гц или 50 раз в секунду. Это потому, что люди могут быть намного медленнее, чем Arduino. Следовательно, если задержка не сделана, программа может заставить нас почувствовать, что нажатие первой кнопки выключило светодиод, а нажатие второй кнопки включило его (попробуйте сами, чтобы подтвердить).

3.2 Потенциометры

Давайте продвинемся вперед и узнаем, как использовать потенциометры с Arduino.

Чтобы узнать, как работает потенциометр или горшок, вы можете прочитать это статья .

Использование потенциометра с Arduino

Подключите показанные параметры к вашему Arduino, как показано выше.

В горшке будет 3 клеммы. Средний терминал будет соединяться с АНАЛОГОВЫМ ВХОДОМ 0 на Arduino. Две другие внешние клеммы могут быть подключены к шинам питания + 5В и 0В.

Запрограммируем и проверим результат:

const int kPinPot = A0
const int kPinLed = 9
void setup()
{
pinMode(kPinPot, INPUT)
pinMode(kPinLed, OUTPUT)
}
void loop()
{
int ledBrightness
int sensorValue = 0
sensorValue = analogRead(kPinPot)
ledBrightness = map(sensorValue, 0, 1023, 0, 255)
analogWrite(kPinLed, ledBrightness)
}

Вы найдете несколько вещей, которые могут выглядеть совершенно новыми и не вошли ни в один из наших предыдущих кодов.

  1. Константа kPinPot обозначается как A0, где A - это ярлык для описания одного из аналоговых контактов. Однако A0 также относится к контакту №14, A1 - к контакту №15 и так далее, и они позволяют использовать вас в качестве цифровых входов / выходов на случай, если у вас закончились контакты для эксперимента. Но помните, что вы не можете использовать цифровые выводы как аналоговые.
  2. Строка: ledBrightness = map(sensorValue, 0, 1023, 0, 255) представляет новую внутреннюю функцию в Arduino, известную как карта(). Эта функция выполняет повторную калибровку с одного диапазона на другой, что называется map (значение, fromLow, fromHigh, toLow, toHigh). Это может стать решающим, поскольку analogueRead выдает значение в диапазоне 0-1023, но analogWrite может принимать значение в диапазоне 0-255.

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

Нет проблем, теперь мы сделаем то, что невозможно сделать без Arduino.

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

Вот программа:

const int kPinPot = A0
const int kPinLed = 9
void setup()
{
pinMode(kPinLed, OUTPUT)
}
void loop()
{
int sensorValue
sensorValue = analogRead(kPinPot)
digitalWrite(kPinLed, HIGH)
delay(sensorValue)
digitalWrite(kPinLed, LOW)
delay(sensorValue)
}

3.2.3 Как избежать задержки ()

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

const int kPinPot = A0
const int kPinLed = 9
void setup()
{
pinMode(kPinLed, OUTPUT)
}
long lastTime = 0
int ledValue = LOW
void loop()
{
int sensorValue
sensorValue = analogRead(kPinPot)
if(millis() > lastTime + sensorValue){
if(ledValue == LOW){
ledValue = HIGH
}
else{
ledValue = LOW
}
lastTime = millis()
digitalWrite(kPinLed, ledValue)
}
}

Так чем же отличается приведенный выше код? Это следующая строка, которая имеет значение.

long lastTime = 0

До этого раздела мы обсуждали переменную int. Однако может быть гораздо больше переменных типов, к которым вы можете получить доступ. Список можно прочитать ниже:

Типы переменных Arduino

В настоящее время может быть крайне важно знать, что для хранения относительно больших чисел для int переменная, вы можете использовать термин длинный или длинный int.

Здесь вы можете увидеть еще одну интересную функцию под названием миллис ().

Это дает интервал времени в миллисекундах, в течение которого Arduino проработала с самого начала (это значение будет сбрасываться на 0 через каждые 50 дней). Здесь он возвращает long, потому что если он вернулся int , подсчет в течение длительного времени может оказаться невозможным. Не могли бы вы точно ответить, сколько времени? Ответ 32,767 секунды.

Поэтому вместо использования delay () мы проверяем millis (), и как только истечет определенное количество миллисекунд, мы меняем светодиод. Следовательно, мы сохраняем время последнего изменения в последний раз переменная, чтобы мы могли проверить ее снова, когда захотите.

3.3 RGB светодиоды

До сих пор мы играли с одноцветным светодиодом. Хотя цвет светодиода можно изменить, заменив светодиод на другой цвет, но как насчет использования светодиодов RGB? изменить цвета светодиодов без замены светодиодов?

Светодиод RGB - это в основном светодиод, в который встроены красный, зеленый и синий светодиоды, которые объединены в один светодиод. Он имеет один общий вывод, который идет на землю или шину питания 0 В, в то время как остальные 3 провода питаются разнообразными положительными сигналами ШИМ для реализации предполагаемого смешение цветов .

Вы можете подключить установку, как показано ниже:

Управление RGB с помощью Arduino

Это может показаться немного сложным, но на самом деле это копия нашей более ранней конструкции управления светодиодами с использованием ШИМ.

Вот программный код практики:

const int kPinPot1 = A0
const int kPinPot2 = A1
const int kPinPot3 = A2
const int kPinLed_R = 6
const int kPinLed_G = 10
const int kPinLed_B = 11
void setup()
{
pinMode(kPinLed_R, OUTPUT)
pinMode(kPinLed_G, OUTPUT)
pinMode(kPinLed_B, OUTPUT)
}
void loop()
{
int potValue
int ledValue
potValue = analogRead(kPinPot1)
ledValue = map(potValue, 0, 1023, 0, 255)
analogWrite(kPinLed_R, ledValue)
potValue = analogRead(kPinPot2)
ledValue = map(potValue, 0, 1023, 0, 255)
analogWrite(kPinLed_G, ledValue)
potValue = analogRead(kPinPot3)
ledValue = map(potValue, 0, 1023, 0, 255)
analogWrite(kPinLed_B, ledValue)
}

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

Вы обнаружите, что когда все 3 банка перемещены на максимальные позиции, вместо белого цвета вы увидите красный цвет. Это связано с тем, что красный цвет является наиболее заметным среди трех цветов и поэтому доминирует в этой ситуации. Однако вы можете поэкспериментировать с функцией карта() , перед выполнением его на красную часть светодиода, чтобы создать более разумный баланс.

Аудио с Arduino

В этом разделе мы узнаем, как добавить базовый звук и музыку в установку Arduino.

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

Чтобы быть более точным, мы попробуем среднюю ноту A, которая имеет частоту 440 Гц.

Для этого мы просто сыграем среднюю ноту A и оптимизируем синусоидальный сигнал с помощью прямоугольной волны.

Кроме того, мы рассчитаем количество времени, в течение которого громкоговоритель может оставаться включенным, используя формулу:

timeDelay = 1 секунда / 2 x тональная частота.

timeDelay = 1 секунда / 2 x 440

timeDelay = 1136 микросекунд

4.1 Подключим плату Arduino

Использование звукового эффекта в Arduino

4.2 Добавление простой заметки

Мы уже говорили о функции задерживать() где единица измерения - миллисекунды (секунда / 1000), однако вы найдете еще одну функцию delayMicroseconds() где единица измерения - микросекунды (миллисекунда / 1000).

Для данной настройки мы программируем код для включения / выключения + 5V на выбранном контакте, связанном с динамиком, со скоростью 440 импульсов в секунду.

Напомним, в прошлом обсуждении мы определили значение 1136 мкс для предполагаемой звуковой заметки.

Итак, вот программа для этого, которая позволит вам услышать звуковую ноту 440 Гц, как только вы запрограммируете Arduino с подключенным динамиком.

const int kPinSpeaker = 9
const int k_timeDelay = 1136
void setup()
{
pinMode(kPinSpeaker, OUTPUT)
}
void loop()
{
digitalWrite(kPinSpeaker, HIGH)
delayMicroseconds(k_timeDelay)
digitalWrite(kPinSpeaker, LOW)
delayMicroseconds(k_timeDelay)
}

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

Из кода мы понимаем, что Arduino включает в себя несколько интегрированных функций, которые дополнительно способствуют созданию музыки.

Первый тон () который работает с 2 элементами вместе с 3-м необязательным элементом, обозначенным как тон (пин, частота, продолжительность). или же тон (пин, частота)

Оба предназначены для исполнения в соответствии с назначенным вами периодом времени.

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

Это нужно будет сделать с помощью функции задержки в случае, если воспроизведение музыки - единственная фундаментальная вещь, которую вы реализуете.

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

Следующая функция Не один () обрабатывает один параметр и останавливает выбранный тон на конкретном назначенном контакте.

Своеобразное предупреждение: в любое время, когда тон () функция реализована, функция ШИМ на контактах 3 и 11 перестанет работать.

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

Хорошо, вот программа для воспроизведения музыки на динамике, хотя это не настоящая музыка, а скорее базовая нота C.

#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
const int kPinSpeaker = 9
void setup()
{
pinMode(kPinSpeaker, OUTPUT)
}
void loop()
{
tone(kPinSpeaker, NOTE_C4, 500)
delay(500)
tone(kPinSpeaker, NOTE_D4, 500)
delay(500)
tone(kPinSpeaker, NOTE_E4, 500)
delay(500)
tone(kPinSpeaker, NOTE_F4, 500)
delay(500)
tone(kPinSpeaker, NOTE_G4, 500)
delay(500)
tone(kPinSpeaker, NOTE_A4, 500)
delay(500)
tone(kPinSpeaker, NOTE_B4, 500)
delay(500)
tone(kPinSpeaker, NOTE_C5, 500)
delay(500)
noTone(kPinSpeaker)
delay(2000)
}

В приведенном выше коде вы могли заметить что-то новое, и это #определять .

Этот термин работает как команда поиска и замены для компьютера во время компиляции.

Всякий раз, когда он находит первое, что находится перед пробелом, он заменяет его оставшейся частью строки (называемой макросами).

Итак, в этом примере, когда компьютер видит ПРИМЕЧАНИЕ_E4 он быстро заменяет его количеством 330.

Для получения дополнительных примечаний и настроек вы можете обратиться к файлу на USB-накопителе с именем pitch.h , где можно найти большинство частот по своему вкусу.

4.4 Музыка с функциями

Приведенный выше код выглядит неплохо, но, похоже, имеет много повторов, должен быть какой-то способ сократить эти повторы, верно?

До сих пор мы работали с двумя важными функциями, включенными в Arduino. Теперь, возможно, пора создать наши собственные функции.

Каждая функция должна начинаться с типа переменной, с которой она может быть связана. Например, функция пустота относится к типу, который ничего не возвращает, отсюда и название void. Обратите внимание, что мы уже обсуждали список переменных в наших предыдущих разделах, вы можете обратиться к ним.

Следовательно, конкретное имя функции получает открывающую скобку '(' за которым следует список параметров, разделенных запятыми.

Каждый параметр получает свой тип вместе с именем и, наконец, закрытие ')' скобка.

Эти параметры можно применять в функции в виде переменных.

Давайте посмотрим на пример ниже, где мы разрабатываем функцию с именем ourTone () предназначен для объединения тон () с задерживать() строк таким образом, что функция перестает возвращаться, пока нота не завершит воспроизведение тона.

Мы реализуем эти функции в нашем предыдущем коде и получаем программу ниже, см. Последние строки:

#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
const int kPinSpeaker = 9
void setup()
{
pinMode(kPinSpeaker, OUTPUT)
}
void loop()
{
tone(kPinSpeaker, NOTE_C4, 500)
delay(500)
tone(kPinSpeaker, NOTE_D4, 500)
delay(500)
tone(kPinSpeaker, NOTE_E4, 500)
delay(500)
tone(kPinSpeaker, NOTE_F4, 500)
delay(500)
tone(kPinSpeaker, NOTE_G4, 500)
delay(500)
tone(kPinSpeaker, NOTE_A4, 500)
delay(500)
tone(kPinSpeaker, NOTE_B4, 500)
delay(500)
tone(kPinSpeaker, NOTE_C5, 500)
delay(500)
noTone(kPinSpeaker)
delay(2000)
}
void ourTone(int freq, int duration)
{
tone(kPinSpeaker, freq, duration)
delay(duration)
}

Функции могут быть чрезвычайно удобными, чтобы упростить понимание программы.

Ниже приведен пример, в котором мы можем указать выбор тембра, который мы хотим играть, используя два массива. Один массив для хранения нот, другой - для ударов.

#include 'pitches.h'
int kPinSpeaker = 9
#define NUM_NOTES 15
const int notes[NUM_NOTES] = // a 0 represents a rest
{
NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4,
NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4,
NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4,
NOTE_D4, NOTE_C4, 0
}
const int beats[NUM_NOTES] = {
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 }
const int beat_length = 300
void setup()
{
pinMode(kPinSpeaker, OUTPUT)
}
void loop()
{
for (int i = 0 i if (notes[i] == 0) {
delay(beats[i] * beat_length) // rest
}
else {
ourTone(notes[i], beats[i] * beat_length)
}
// pause between notes
noTone(kPinSpeaker)
delay(beat_length / 2)
}
}
void ourTone(int freq, int duration)
{
tone(kPinSpeaker, freq, duration)
delay(duration)
}

Вы можете ясно увидеть в первой строке введение #включают утверждение. Задача этого оператора - взять весь файл между кавычками и поместить его в позицию #включают утверждение. Согласно стандартным правилам, они размещаются строго в начале программы.

Глава 5

Измерение температуры

Просто напомним, помните, что вместо того, чтобы писать большие программы в целом, всегда разумно писать и анализировать небольшие части кода, что помогает быстро отслеживать ошибки.

5.1 Монитор последовательного порта

До сих пор обсуждаемые нами коды не представлялись настолько легкими для быстрого устранения неполадок. Здесь мы постараемся упростить мониторинг и облегчить решение возможной проблемы.

Arduino имеет функцию, которая позволяет ему «разговаривать» с компьютером. Вы можете заметить, что контакты 0 и 1 помечены как RX и TX рядом друг с другом. Эти контакты фактически отслеживаются отдельной микросхемой внутри Arduino, которая обновляет их для чтения через USB-кабель, когда он подключен к ПК.

В приведенном ниже разделе показана полноценная программа, просмотрите ее, позже мы узнаем о новых записях в коде. Этот код аналогичен приведенному в разделе 2.2, за исключением того факта, что он включает некоторые дополнительные данные, позволяющие нам определить, для чего он был закодирован.

const int kPinLed = 13
void setup()
{
pinMode(kPinLed, OUTPUT)
Serial.begin(9600)
}
int delayTime = 1000
void loop()
{
delayTime = delayTime - 100
if(delayTime <= 0){ // If it would have been zero or less, reset it.
delayTime = 1000
}
Serial.print('delayTime = ')
Serial.println(delayTime)
digitalWrite(kPinLed, HIGH)
delay(delayTime)
digitalWrite(kPinLed, LOW)
delay(delayTime)
}

Здесь вы можете выделить две новые вещи, новую строку в настраивать() функция.

Serial.begin(9600)

Эта строка просто выражает необходимость использования Serial1 код, чтобы обеспечить его со скоростью 9600 бод. (здесь серийный номер означает биты отправляются один за другим, а скорость передачи означает скорость, с которой они отправляются). Это значение скорости и значение внутри последовательного монитора (мы узнаем об этом позже) должны быть равны, иначе данные на последовательном мониторе будут показывать мусор. Стандарт 9600 становится более удобным в использовании.

Вторая новая запись выглядит следующим образом

Serial.print('delayTime = ')
Serial.println(delayTime)

Здесь вторая строка предполагает, что последующая вещь, выходящая из последовательного порта, начнется со следующей строки. Вот чем вторая линия отличается от первой.

Еще одна вещь, которую вы можете увидеть, - это кавычки ('). Это известно как строка, которая здесь будет использоваться только как константа, потому что дальнейшее обсуждение этой темы может быть слишком подробным и выходящим за рамки.

Хорошо, теперь мы можем загрузить приведенный выше код в Arduino и посмотреть, что произойдет.

Что, упс, похоже, ничего не произошло, светодиод на контакте № 13 Arduino мигнул и остановился, а светодиод Tx продолжал мигать.

Это потому, что окно Serial Monitor еще не исправлено.

Вам нужно щелкнуть поле Serial Monitor в вашей среде IDE, как показано выше. Не забудьте проверить скорость передачи, расположенную внизу справа, по умолчанию она должна быть 9600 и будет соответствовать коду. Если это не так, обязательно выберите 9600.

Следующий видеоклип объясняет, как это делается.

https://youtu.be/ENg8CUyXm10

Теперь давайте продолжим и узнаем, как указанная выше функция Serial Monitor может помочь в обработке измерение температуры с помощью Arduino

Мы будем использовать IC TMP36 в качестве датчика температуры с диапазоном от -40 до 150 градусов Цельсия.

Настройку можно увидеть ниже:

TMP36 с Arduino для измерения температуры

Следующий код инициирует измерение температуры, считывая выходные данные датчика TMP36 и отправляя их на последовательный монитор идентификатора.

const int kPinTemp = A0
void setup()
{
Serial.begin(9600)
}
void loop()
{
float temperatureC = getTemperatureC()
Serial.print(temperatureC)
Serial.println(' degrees C')
// now convert to Fahrenheit
float temperatureF = convertToF(temperatureC)
Serial.print(temperatureF)
Serial.println(' degrees F')
delay(500)
}
float getTemperatureC()
{
int reading = analogRead(kPinTemp)
float voltage = (reading * 5.0) / 1024
// convert from 10 mv per degree with 500mV offset
// to degrees ((voltage - 500mV) * 100)
return (voltage - 0.5) * 100
}
float convertToF(float temperatureC)
{
return (temperatureC * 9.0 / 5.0) + 32.0
}

Давайте разбираться в коде сверху.

float temperatureC = getTemperatureC()

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

Это единственный тип переменных, в котором хранится все, кроме целых чисел (числа без десятичной или дробной части).

Точность переменной с плавающей запятой может составлять от 6 до 7 цифр.

Смежный код getTemperatureC() это наша собственная функция, которая математически рассчитывает и преобразует измеренную разницу напряжения с датчика TMP36 в градусы Цельсия.

float getTemperatureC()
{
int reading = analogRead(kPinTemp)
float voltage = (reading * 5.0) / 1024
// convert from 10 mv per degree with 500mV offset
// to degrees ((voltage - 500mV) * 100)
return (voltage - 0.5) * 100
}

В следующем разделе кодов, поскольку член analogIn() назначено для возврата числа от 1 до 1023, мы можем оценить напряжение с датчика, умножив полученное значение на 5, а затем разделив его на 1024.

Датчик TMP36 предназначен для генерирования 0,5 В при 0 градусах Цельсия, а затем генерирует 10 мВ для каждого отдельного повышения в градусах Цельсия.

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

Калибровка температуры Arduino

Вы можете считать свою первую функцию, которая возвращает какое-то значение (обратите внимание, что все оставшиеся функции до сих пор не возвращали никакого значения, так как они были типа пустота ).

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

Когда мы говорим вернуть это означает, что функция возвращает ответ или ответ при каждом вызове, который может быть применен к переменной.

Когда это отправляется на Serial Monitor, показания конвертируются в градусы Фаренгейта через convertToF ().

float convertToF(float temperatureC)
{
return (temperatureC * 9.0 / 5.0) + 32.0
}

Эта функция определяет диапазон Цельсия и переводит его в градусы Фаренгейта.

Для преобразования Фаренгейта в Цельсия мы реализуем формулу Фаренгейт = 9 / 5 (Цельсия) + 32.

5.3 Подключение к ЖК-дисплею

Теперь давайте изучим, как взаимодействовать или подключать ЖК дисплей с Arduino для визуального отображения требуемых выходов.

В нашем приложении мы собираемся использовать графический ЖК-дисплей 84x48 с разрешением 84 пикселя или точек по горизонтали и 48 пикселей по вертикали. Поскольку выделенный контроллер становится обязательным для всех ЖК-дисплеев, настоящее устройство также включает в себя контроллер в виде контроллера PCD8544.

В этом руководстве мы подключим указанный выше ЖК-модуль к Arduino и применим определенные процедуры для создания текстовых сообщений на дисплее.

На следующем рисунке вы можете найти подробную информацию о подключении ЖК-дисплея, а также небольшой Регулятор напряжения 3.3V . Этот регулятор необходим, поскольку ЖК-дисплей рассчитан на работу от источника питания 3,3 В.

Вы также можете увидеть 8 распиновок от ЖК-модуля, характеристики распиновки можно изучить из следующей таблицы:

Детали распиновки ЖК-дисплея

Теперь давайте посмотрим, как мы можем подключить ЖК-дисплей и соответствующие параметры к нашей Arduino. Подробности можно визуализировать на иллюстрации ниже:

Базовое обучение Arduino

5.4 Связь с ЖК-дисплеем

Хотя можно написать сложные команды для взаимодействия с ЖК-дисплеем из Arduino, мы лучше научимся делать то же самое с помощью библиотек.

Библиотеки содержат набор кодов, которые можно быстро применить к выбранной программе Arduino.

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

5.4.1 Как установить библиотеку

Для этого вам нужно будет создать каталог под названием библиотеки на вашем компьютере Arduino IDE, как описано здесь

5.4.2 Реализация операций с ЖК-дисплеем

Как и в предыдущем подходе, мы сначала проверим весь код, а затем попытаемся понять детали отдельных строк.

#include
const int kPin_CLK = 5
const int kPin_DIN = 6
const int kPin_DC = 7
const int kPin_RESET = 8
PCD8544 lcd(kPin_CLK, kPin_DIN, kPin_DC, kPin_RESET)
void setup()
{
lcd.init()
lcd.setCursor(0,0)
lcd.print('Hello, World!')
}
void loop()
{
lcd.setCursor(0,1)
lcd.print(millis())
}

Строка включает код #include

Код #include инструктирует ПК выбрать упомянутый файл и заменить элемент #include содержимым файла во время компиляции программы.

Элемент #include может иметь угловые скобки, указывающие на поиск в каталоге библиотеки, или же он может содержать кавычки, указывающие на поиск в том же каталоге, в котором находится программа.

Последующие строки кода выражают распиновку ЖК-дисплея, а затем мы пишем новую форму переменной:

PCD8544 lcd(kPin_CLK, kPin_DIN, kPin_DC, kPin_RESET)

Здесь мы выражаем переменную с именем lcd, имеющую тип PCD8544, и инструктируем ПК изменить его распиновку, связанную с Arduino.

В этом процессе мы описываем переменную для ПК, указывая, как контакты clk, din, dc и reset взаимодействуют с Arduino.

void setup()
{
lcd.init()
lcd.setCursor(0,0)
lcd.print('Hello, World!')
}

Строка lcd.init() инициализирует работу ЖК-дисплея. Как только это будет выполнено, следующая строка принудительно установит курсор в левый верхний угол дисплея. В следующей следующей строке делается попытка вывести сообщение «Hello, World».

Это выглядит полностью идентично методике отправки сообщений через последовательный монитор. Единственное отличие состоит в использовании кода lcd.print вместо serial.print.

Следующий блок кода фактически вызывается повторно.

void loop()
{
lcd.setCursor(0,1)
lcd.print(millis())
}

Используя эту строку lcd.setCursor(0,1) мы фиксируем курсор на 0-м столбце слева от 1-го ряда над ЖК-дисплеем.

В следующей строке используется ярлык: lcd.print(millis())

Если вы помните, мы работали с millis() в наших предыдущих кодах мы могли применить то же самое и здесь через коды:

long numMillis = millis()
lcd.print(numMillis)

Однако из-за того, что здесь не задействованы периоды времени в миллисекундах, мы достигаем этого, просто отправляя millis() функция напрямую в lcd.print() .

5.5 Объединение всего

Хорошо, теперь давайте объединим все коды, которые мы узнали выше, для создания схемы температуры ЖК-дисплея, и посмотрим, как это выглядит:

#include
const int kPin_CLK = 5
const int kPin_DIN = 6
const int kPin_DC = 7
const int kPin_RESET = 8
const int kPin_Temp = A0
PCD8544 lcd(kPin_CLK, kPin_DIN, kPin_DC, kPin_RESET)
void setup()
{
lcd.init()
lcd.setCursor(10,0)
lcd.print('Temperature:')
}
void loop()
{
float temperatureC = getTemperatureC()
// now convert to Fahrenheit
float temperatureF = convertToF(temperatureC)
lcd.setCursor(21,1)
lcd.print(temperatureC)
lcd.print(' C')
lcd.setCursor(21,2)
lcd.print(temperatureF)
lcd.print(' F')
delay(100)
}
float getTemperatureC()
{
int reading = analogRead(kPin_Temp)
float voltage = (reading * 5.0) / 1024
// convert from 10 mv per degree with 500mV offset
// to degrees ((voltage - 500mV) * 100)
return (voltage - 0.5) * 100
}
float convertToF(float temperatureC)
{
return (temperatureC * 9.0 / 5.0) + 32.0
}

В приведенной выше программе все выглядит стандартно, кроме использования функции setCursor () . Это используется для выравнивания текста как можно дальше по центру дисплея.

Большой! Поздравляю, вы только что запрограммировали свой собственный маленький ЖК-индикатор температуры с помощью Arduino.

Практические приложения Arduino

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

Мы начнем с датчиков и посмотрим, как сенсорные устройства можно использовать с Arduino, выполнив несколько примеров кода.

7.1 Знакомство с датчиками

В этом руководстве мы узнаем о большом количестве датчиков, которые можно использовать с Arduino. Сюда могут входить такие устройства, как датчик освещенности LDR, датчик магнитного эффекта Холла, датчики наклона, датчик вибрации, датчик давления и т. Д.

Начнем с сопряжения датчик света LDR с Arduino, как показано на следующей диаграмме:

использовать LDR с Arduino

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

Интенсивность света обратно пропорциональна показанию сопротивления LDR.

Здесь мы узнаем, как это свойство можно интегрировать с Arduino для выполнения полезного приложения:

Полный программный код можно визуализировать, как показано ниже:

const int kPin_Photocell = A0
void setup()
{
Serial.begin(9600)
}
void loop()
{
int value = analogRead(kPin_Photocell)
Serial.print('Analog Reading = ')
Serial.print(value)
if(value <200){
Serial.println(' - Dark')
}else if(value <400){
Serial.println(' - Dim')
}
else if(value <600){
Serial.println(' - Light')
}
else if(value <800){
Serial.println(' - Bright')
}
else{
Serial.println(' - Very Bright')
}
delay(1000)
}

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

Значения были выбраны случайным образом, вы можете легко изменить их в соответствии с вашими предпочтениями.

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

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

Теперь посмотрим, как датчик наклона устройство может быть подключено. Изображение ниже дает нам представление о полной конфигурации:

взаимодействие датчика наклона с Arduino

const int kPin_Tilt = 3
const int kPin_LED = 13
void setup()
{
pinMode(kPin_Tilt, INPUT)
digitalWrite(kPin_Tilt, HIGH) // turn on built-in pull-up resistor
pinMode(kPin_LED, OUTPUT)
}
void loop()
{
if(digitalRead(kPin_Tilt) == HIGH){
digitalWrite(kPin_LED, LOW)
}
else{
digitalWrite(kPin_LED, HIGH)
}
}

В этом примере светодиод на контакте 13 по умолчанию используется в качестве индикатора наклона.

Вы можете ясно увидеть включение здесь подтягивающего резистора, очень похожего на то, что мы делали в разделе 3.1. Следовательно, термин LOW означает, что функция наклона не срабатывает.

7.4 Реле геркона (реле с миниатюрным магнитом)

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

Здесь мы также используем светодиод на контакте 13 для индикации ответа. Вы можете подключить внешний светодиод к этому контакту, если это необходимо, в соответствии с нашими предыдущими объяснениями.

const int kPinReedSwitch = 2
const int kPinLed = 13
void setup()
pinMode(kPinReedSwitch, INPUT)
digitalWrite(kPinReedSwitch, HIGH) // turn on pullup resistor
pinMode(kPinLed, OUTPUT)
}
void loop()
{
if(digitalRead(kPinReedSwitch) == LOW){
digitalWrite(kPinLed, HIGH)
}
else{
digitalWrite(kPinLed, LOW)
}
}

Кодовые термины должны быть знакомыми и понятными.

7.5 Датчик вибрации с пьезоэлектрическим преобразователем

В следующем примере программы мы увидим, как пьезоэлектрический преобразователь может использоваться как датчик вибрации для подсветки светодиода через Arduino.

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

Настройте Arduino и пьезоэлемент, как показано на следующем рисунке.

использование пьезо в качестве датчика вибрации с Arduino

const int kPinSensor = A5
const int kPinLed = 13
const int k_threshold = 100
int ledState = LOW // variable used to store the last LED status, to toggle the light
void setup()
{
pinMode(kPinLed, OUTPUT) // declare the ledPin as as OUTPUT
}
void loop()
{
int val = analogRead(kPinSensor)
if (val >= k_threshold) {
ledState = !ledState // toggle the value of ledState
digitalWrite(kPinLed, ledState)
delay(20) // for debouncing
}
}

Порог 100 введен только для того, чтобы убедиться, что Arduino реагирует только на настоящие вибрации посредством ударов, а не на другие более мелкие вибрации, такие как громкие звуки или гудки.

Выбор вывода A5 не является обязательным, вы можете выбрать любые другие аналоговые входы в соответствии с вашими предпочтениями и сопоставить его в программном коде.

Использование серводвигателя с Arduino

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

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

Arduino упрощает управление серводвигателем благодаря встроенному языку поддержки, что делает управление очень удобным и идеальным для серводвигателей.

Следующий пример покажет нам базовую программу настройки для реализации управления серводвигателем через Arduino:

Управление серводвигателем Arduino

Код приведен ниже:

#include
Servo servo1
const int kPinPot = A0
const int kPinServo1 = 9
void setup()
{
servo1.attach(kPinServo1)
}
void loop()
{
int val = analogRead(kPinPot)
val = map(val, 0, 1023, 0, 180)
servo1.write(val)
delay(15)
}

Здесь мы можем увидеть пару новых записей. Тот, который сообщает подключенному проводу сервопривода, к какому контакту он назначен. Другой - это код, который предоставляет штифту значение от 0 до 180 для определения угла поворота сервопривода.

Заключение

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

Надеюсь, здесь будет время от времени обновляться дополнительная информация, когда она доступна.

А пока наслаждайтесь курсом программирования, желаю вам счастья в Arduinoing !!




Предыдущая: Схема измерителя алкоголя с использованием модуля датчика MQ-3 Следующая статья: Цепь кормушки для собак, управляемая мобильным телефоном