Урок №03. Основы синтаксиса языка программирования(Правила языка).

## Разбор основного функционала Arduino IDE.

   Интерфейс среды содержит следующие основные элементы: текстовый редактор для написания кода [1], область для вывода сообщений [2], текстовая консоль [3], панель инструментов с традиционными кнопками [4] и главное меню [5].

Разберем их всех по порядку.

Программы, создаваемые в среде разработки Arduino, их обычно называют скетчами. Скетчи пишутся в текстовом редакторе [1] и сохраняются в файлах с расширением .ino. Встроенный текстовый редактор [1] имеет стандартные инструменты копирования, вставки, поиска, замены текста и т.д.

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

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

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

## Синтаксис языка C++

### ";" и "{ }"

Главным правилом в языке программирования С++ является разделение строк кода точкой с запятой ";". Каждая команда должна заканчиваться точкой с запятой.

Пример:

```
int num = 13; //объявляем переменную типа целое с именем num и присваиваем ей значение 13

```

Вся программа на языке программирования С++ состоит из так называемых блоков, начало и конец блока обозначаются фигурными скобками, а содержимое записывается внутри этих скобок. Когда мы программируем Arduino, в программе должны присутствовать 2 стандартные функции: setup() и loop():

```
void setup()
{
  оператор;
}

void loop()
{
  оператор;
}

```

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

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

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

### Переменные

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

Небольшая табличка типов данных:

 real
 String
 char
 boolean

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

```
int a = 1;     // одна или несколько букв

```

```
int a1 = 1;    // сочетание букв и цифр

```

```
int num_1 = 1; // имя переменной может содержать нижнее подчеркивание

```

```
int numA = 1;  // имя переменной может содержать заглавные и строчные буквы. При этом numa
               //не то же самое что и numA

```

Теперь приведем примеры имен для переменных, которые приведут к ошибке компиляции.

```
int a 1 = 1;     // имя не должно содержать пробелов

```

```
int a%:- = 1;     // имя не должно содержать специальных знаков

```

```
int имя = 1;     // имя не должно содержать кириллических знаков

```

Когда переменная объявлена, можно обращаться к ней по имени. Давайте создадим переменную sum и прибавим к ней числа от 1 до 3:

```
void setup()
{
  int a = 0;
  a = a+1;
  a = a+2;
  a = a+3;
}

void loop()
{

}

```

Обратите внимание, что если мы объявляем переменную в рамках некоторого блока, например в void setup(), то эта переменная будет существовать только в нем, это называется **локальная переменная**. Например:

```
void setup()
{
  int a = 0;
  a = a+1;
  a = a+2;
  a = a+3;
}

void loop()
{
  a = a+4; // Ошибка! Переменной не существует!
}

```

Правильно сделать следующим образом:

```
int a = 0;

void setup()
{
  a = a+1;
  a = a+2;
  a = a+3;
}

void loop()
{
  a = a+4;
}

```

Такая переменная называется **глобальной**. К ней можно обратиться в любое время и в любом месте.

## Основные операторы

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

### Арифметические операторы

Чтобы внести ясность, уточним "+", "-", "\*", "\", "=", "%" - это операторы сложения, вычитания, умножения, деления, равенства и остатка соответственно. Для их выполнения нужно два участника, иными словами это двухместные операторы. Существуют так же одноместные операторы: "++", "--", "+=", "-=", "\=", "\*=".

Зададим переменную a и b:

```
int a = 10;
int b = 5;

```

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

```
int a = 0;

void setup()
{
  a += 1;
  a += 2;
  a += 3;
}

void loop()
{
  a += 4;
}

```

## Основные функции

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

### Работа с цифровыми портами

Самая важная команда при работе с аналоговым или цифровым портом - pinMode(). Эта команда настраивает определенный порт в определенный режим работы. Как уже говорилось на прошлых занятиях, порты могут работать в режиме входа или выхода. В режиме входа мы получаем некоторую информацию на пин, а в режиме выхода наоборот посылаем. В программе эти режимы называются INPUT(вход) и OUTPUT(выход). Давайте настроим 13-ый пин как выход, а 12-ый пин как вход:

```
void setup()
{
  pinMode(13, OUTPUT); //через запятую вводим сперва номер пина, а потом режим работы
  pinMode(12, INPUT);
}

```

Грамотнее сделать так:

```
int PIN1 = 13;
int PIN2 = 12;
void setup()
{
  pinMode(PIN1, OUTPUT); //Вместо номера вводим имя переменной, которую мы создали глобально
  pinMode(PIN2, INPUT);
}

void loop()
{

}

```

У такого способа два преимущества:

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

Теперь, чтобы работать с этими цифровыми пинами нам понадобятся 2 команды: digitalRead(), и digitalWrite(). Первая команда считывает значение с порта-входа, а вторая может посылать сигналы с пина, настроенного как выход.

В функцию digitalRead() нужно вписать номер пина, с которого нужно считать значение. Обратите внимание, что пин цифровой, соответсвенно значений может быть всего 2: 0 - если на пин не поступает напряжение или 1 - если на пин поступает 5V. Так же считанное значение нужно записать в какую-нибудь переменную, чтобы с ним в дальнейшем работать.

В функцию digitalWrite() необходимо вписать номер пина и уровень сигнала, который необходимо отправить. Так как это цифровой пин, то доступно два варианта LOW - низкий уровень напряжения (0V) или HIGH - высокий уровень напряжения (5V).

Давайте добавим в наш код несколько строк:

```
int PIN1 = 13;
int PIN2 = 12;
void setup()
{
  pinMode(PIN1, OUTPUT); //Вместо номера вводим имя переменной, которую мы создали глобально
  pinMode(PIN2, INPUT);
}

void loop()
{
  int value = digitalRead(PIN2); //записываем значение, считанное с 12-ого пина в value
  digitalWrite( PIN1, HIGH);   // подаем на 13-ый пин 5V

}

```

### Работа со временем

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

Давайте добавим в наш код еще несколько строк:

```
int PIN1 = 13;
int PIN2 = 12;
void setup()
{
  pinMode(PIN1, OUTPUT); //Вместо номера вводим имя переменной, которую мы создали глобально
  pinMode(PIN2, INPUT);
}

void loop()
{
  int value = digitalRead(PIN2); //записываем значение, считанное с 12-ого пина в value
  digitalWrite( PIN1, HIGH);   // подаем на 13-ый пин 5V
  delay(1000); //задерживаем высокий сигнал  на 1 секунду.
  digitalWrite( PIN1, LOW);   // подаем на 13-ый пин 0V
  delay(1000); //задерживаем низкий сигнал  на 1 секунду.

}

```

Так как loop() непрерывно повторяется, то мы получим непрерывно сменяемую подачу высокого и низкого сигнала на 13-ый пин. Если подсоединить к этому пину светодиод, то он будет мигать, а изменяя время задержки мы меняем режим его мигания.

## Практическое занятие

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

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