Лабораторная №2. Введение в С++ (специализированное под Arduino IDE)
Типы данных, циклы, ветвления, функции.
Цель: изучить основные типы данных, используемых при разработке программ в среде Arduino. Изучить существующие конструкции циклов. Научиться различать и правильно использовать циклы с предусловием и постусловием. Ознакомиться с функциями и битовыми операциями.
Лабораторное оборудование
Плата Arduino – 1шт
Беспаечная макетная плата – 1шт
Светодиоды – 10шт
Резисторы 300 Ом – 10шт
Резисторы 4.7 кОм – 2 шт
Кнопка – 1шт
Варианты задания
Используя набор из десяти светодиодов организовать следующие режимы индикации.
Змейка вперед - включение линейки светодиодов слева направо и выключение их в том же направлении. Змейка назад - включение линейки светодиодов справа налево и выключение их в том же направлении. «Бегущий диод вперед-назад» - загорается только один диод, который «бежит» с одной стороны линейки в другой. Режим схождения-расхождения - включение светодиодов к центру линейки и их выключение от центра к краям. Заполнение линейки светодиодов слева направо (по одному диоду). Заполнение линейки светодиодов справа налево (по одному диоду). Поочередное включение четных и нечетных (по номерам) светодиодов.При выполнении задания каждый режим организовать функцией. При написании программы пользоваться циклами, применять стандартные функции ввода-вывода Arduino для организации вывода, описанного задачей.
Выполнение работы
Ознакомиться с задачей. Изучить (просмотреть) теоретический материал. Собрать из предоставленных элементов и лабораторного оборудования лабораторный стенд. Приступить к выполнению задания.Теоретическая часть
1. Любая программа, которая пишется в среде Arduino, обязательно должна иметь две основные функции (блоки), а именно: void setup():
void setup()
{
// В этом блоке настраиваются параметры портов
}
и void loop().
void loop()
{
// Блок для основного кода программы (ее тело)
// Весь код, находящийся в этом блоке будет повторяться
// бесконечное количество раз.
}
Каждый из этих блоков выступает функцией (далее этот вопрос будет рассмотрен подробнее) и без них невозможна компиляция кода в среде Arduino IDE.
В теле функции void setup() обычно настраивают конфигурацию портов и проводят другие начальные настройки платы. Однако в этой функции можно выполнять и другие операции, например арифметические. Функция void setup() вызывается автоматически при загрузке микроконтроллера и выполняется только один раз.
В теле функции void loop() пишется основной код программы. Эта функция выполняется бесконечно. Эквивалентом ей выступает бесконечный цикл (далее в этой лабораторной работе будут рассмотрены и циклы).
2. Типы данных
Основные типы данных делятся на три категории: целые, с плавающей точкой и неопределенные (voіd). Целые типы данных работают с целыми числами. Типы данных с плавающей точкой работают с данными, имеющими дробную часть. Неопределенный тип данных соответствует пустому множеству значений.
Основными типами данных являются:
char – целый тип, содержит символы. (8 бит, диапазон значений от -127 до 127)
int – целые числа (как отрицательные, так и положительные) и 0 (16 бит, от -32767 до 32767)
short – тип данных short int (или сокращенно short) является целым типом, содержащим целые числа, размер или меньше или равен типу іnt.
long – тип данных long іnt (или сокращенно long) является целым типом, содержащим целые числа, размер или больше или равен типа іnt. (32 бит, -2 147 483 647 до -2 147 483 647)
double – тип данных с плавающей точкой. (64 бит, 1Е-37 до 1Е+37 с точностью не менее 10 значащих цифр)
float – наименьший тип данных с плавающей точкой. (64 бит, 1Е-37 до 1Е+37 с точностью не менее 6 значащих цифр)
long double – тип данных с плавающей точкой, больше чем double.
Переменные могут быть локальными и глобальными. Локальная переменная - переменная, значение которой действительно только в пределах функции, в которой она объявлена. Глобальная переменная - действительна в любом месте кода.
Имейте в виду! Локальная и глобальная переменная с одинаковым именем являются разными переменными. Это может вызвать путаницу, поэтому не советуют называть локальные и глобальные переменные одинаковыми именами.
Рассмотрим пример:
// Комментарий - строки кода, которые не обрабатываются
// компилятором
// Это комментарий. Пишите комментарии - они полезны!
/*
Это
многострочный
Комментарий
*/
//Объявление глобальных переменных
int led = 13;
char q = 'F';
long w = 153;
double e = 6436.34;
float r = 345.23;
long double t = 5433423.7;
short int y=5;
void setup()
{
pinMode(led, OUTPUT);
//настройка пина с номером 13, как выход.
}
//объявление функции
void variable( /*параметры, которые передаются в функцию*/ )
{
//тело функции
//объявление локальных переменных
int y = 5; //отличается от глобальной переменной short int y
float fl = 438;
}
void loop()
{
//код программы
}
3. Циклы
Циклы - это конструкции, в теле которых команды выполняются заданное количество раз. Циклы применяются в случаях, когда необходимо выполнить определенное количество однотипных задач. Всегда существует условие выхода из цикла, однако это условие не всегда достижимо, в таком случае цикл будет повторяться до тех пор, пока будет функционировать ЭВМ, на которой выполняется данная программа. Такое событие называется зацикливанием. Один проход цикла называется итерацией.
Существующие типы циклов
А. Безусловные – иногда условие выхода из цикла не предусматривается логикой программы.
//Условие выполняется, пока значение в скобках не 0
while(1)
{
//тело цикла
}
//условие все время истинно
while(true)
{
// тело цикла
}
В. Циклы с предусловием - выполняется пока это условие истинно. Условие проверяется перед началом выполнения тела цикла. Если условие изначально не является истиной - цикл не выполнится ни разу.
К циклам с предусловием относят for и while
//для переменной і с начальным значением 0 выполнять действия
//пока выполняется условие і<5 выполнять тело цикла
//после выполнения тела цикла увеличить переменную і на единицу
for ( i=0; i<5; i++)
{
//тело цикла выполнится 5 раз
}
//пока выполняется условие
//выполнять тело цикла
while (<условие>)
{
//тело цикла
}
С. Циклы с постусловием - условие проверяется после выполнения тела цикла. В этом случае цикл выполнится хотя бы один раз.
do
{
// тело цикла выполнится хотя бы один раз
}
while (<условие>) 4. Массивы
Массив - набор переменных, каждая из которых имеет свой индекс (порядковый номер). Индексирование начинается с 0, т. е. первый элемент массива имеет индекс 0, второй - 1 и так далее...
Массивы используются для хранения однотипных переменных. В массиве типа int могут храниться значения только типа int.
//Объявление одномерного массива размерностью 6 элементов (индексы от 0 до 5)
int myInts[6];
Пример использования:
// Пин 13 подключен к светодиоду в большинстве плат ARDUINO
// Объявляем его:
int led = 13;
// Объявление одномерного массива с 5 элементами.
int pins[5] = {2,3,7,8,9};
void setup() {
// Настройка цифрового пина на вывод.
// Пин с номером 13 будет работать для подачи сигналов
pinMode(led, OUTPUT);
//создаем цикл
//тут же объявляем переменную-счетчик і с начальным значением 0
//эта переменная прекратит свое существование после завершения
//всех итераций цикла
for (int i = 0; i<5; i++)
{
//Настраиваем пин, который отвечает значению элемента
//массива с индексом "і" выводом.
pinMode(pins[i],OUTPUT);
}
}
void loop() {
for (int i = 0; i<5; i++)
{
digitalWrite(pins[i],HIGH);
}
5. Операторы сравнения, равенства и логические
Операторы сравнения:
меньше <
больше >
меньше или равно <=
больше или равно >=
Операторы равенства:
равно ==
не равно!=
Логические операторы:
отрицание!
логическое «и» &&
логическое «или» ||
Очень важно не путать операторы равенства и присваивания, например a == b – это проверка на равенство, т. е. если a и b равны, то выражение вернет true (правда), в противном случае false (ложь), а в выражении a = b переменная a станет равной b. Приведем пример с инструкцией іf, она имеет вид:
іf(условие)
{
инструкции
}
Эта конструкция означает: если условие выполняется, то выполняются и инструкции.
Пример кода:
void loop ()
{
іnt a = 0;
іnt b = 4;
іf(a!= b) //если a не равно b, то
{
a = b; //a становится равно b
}
іf(a == b) //если a равно b, то
{
a = b + 1; //a принимает значение b + 1
}
}
Нужно знать, что инструкция іf - else похожа и тесно связана с инструкцией іf, и имеет вид:
іf(условие)
{
//инструкции 1
}
else
{
//инструкции 2
}
Если условие истинно, то выполняются инструкции 1, а инструкции 2 пропускаются, если условие ложно, то выполняются инструкции 2, а инструкции 1 пропускаются. Например:
іnt maіn()
{
іnt a = 0;
іnt b = 4;
іf(a == b)
{
a = 4;
}
else
{
a = 3;
}
return 0;
}
6. Функции
Разбиение кода на сегменты с помощью функций позволяет создавать части кода, которые выполняют определенные задачи. После выполнения функции происходит возврат в то место кода программы, из которого она была вызвана.
Преимущества использования функции
1. Упрощают организацию программы
2. Позволяют структурировать код
3. Упрощают отладку программы
4. Увеличивают читабельность кода
Рассмотрим функцию на примере function()
//объявление глобальной переменной
char mychar;
int myint=0;
void setup()
{
}
/*
int – тип параметра, который возвращается функцией
если логикой программы не предусмотрено возвращение параметра - указывается тип void
function – название функции
в круглых скобках после названия функции указываются типы параметров, которые передаются в функцию
*/
int function (int var1, char var2)
{
var1 += 1;
//return возвращает значение и прерывает выполнение функции
return var1;
//эта часть кода является недостижимой
var2 = 'C';
}
void loop()
{
mychar='a';
//вызывается функция и в нее передаются параметры
myint = function (1,char1);
}


