Как пишется комментарий в по arduino ide

Синтаксис и структура кода

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

Синтаксис


  • Тела функций заключаются в фигурные скобки { }. Код внутри фигурных скобок иногда называют блоком кода.
  • Каждая команда заканчивается точкой с запятой ;
  • Метод применяется к объекту через точку. Пример: Serial.begin();
  • Вызов функции или метода всегда заканчивается скобками, даже если функция не принимает параметров. Пример: loop()
  • Разделитель десятичных дробей – точка. Пример: 0.25 У запятой тут другое применение.
  • Запятыми перечисляются аргументы функций и методов, члены массива, также через запятую можно выполнить несколько действий в одну строчку. Пример: digitalWrite(3, HIGH); массив – int myArray[] = {3, 4, 5 ,6};
  • Одиночный символ заключается в одиночные кавычки 'а'
  • Строка и массив символов заключается в двойные кавычки "строка"
  • Имена переменных могут содержать латинские буквы в верхнем и нижнем регистре (большие и маленькие), цифры и подчеркивание. Пример: myVal_35 .
  • Имена переменных не могут начинаться с цифры. Только с буквы или подчёркивания.
  • Регистр имеет значение, т.е. большая буква отличается от маленькой. Пример: имена val и Val – не одно и то же.

К синтаксису также можно отнести комментарии, т.к. в разных языках они выделяются по-разному. Комментарий это обычный текст, который игнорируется на этапе компиляции и не попадает в итоговую программу для МК. Комментарии нужны для пояснения кода, как себе самому, так и другим возможным его читателям. В C++ у нас два типа комментариев:

  • Однострочный комментарий
    // однострочный комментарий
    // компилятор меня игнорирует =(
  • Многострочный комментарий
    /* Многострочный
    комментарий */

Оформление


Есть такое понятие, как форматирование (выравнивание) кода, то есть соблюдение пробелов и интервалов. Чисто для примера, сравните эти два куска кода. Какой смотрится более понятно?
Не бойтесь, во всех серьезных средах разработки есть автоформатирование кода, оно работает как в процессе написания, так и “по кнопке”. Arduino IDE – не исключение, в ней код форматируется комбинацией клавиш Ctrl+T:

  • Между математическими действиями, знаками сравнения, присваивания и всем подобным ставится пробел.
  • Как и в обычном тексте, пробел ставится после и не ставится перед запятой, двоеточием, точкой с запятой.
  • Отступ от левого края экрана – знак табуляции, код сдвигается вправо и на одном расстоянии формируются команды из одного блока кода. В Arduino IDE одна табуляция равна двум пробелам. Можно использовать клавишу Tab.
  • Каждое действие выполняется с новой строки (автоформатирование это не исправляет).
  • Имена функций и переменных принято называть с маленькой буквы. Пример: value
  • Если имя состоит из двух и более слов, то их принято разделять. Есть два способа:
    • camelCase (верблюжий стиль): первая буква маленькая, каждая первая буква следующего слова – большая.
    • under_score (подчёркивание): все буквы маленькие, разделитель – подчёркивание.
  • Имена типов данных и классов принято писать с большой буквы. Пример: Signal, Servo
  • Имена констант принято писать в верхнем регистре, разделение – подчеркивание. Пример: MOTOR_SPEED
  • При написании библиотек и классов, имена внутренних (приватных) переменных принято писать, начиная со знака подчёркивания. Пример: _position
  • Несколько общепринятых сокращений для названий переменных, вы часто будете встречать их в чужих прошивках и библиотеках:
    • button – btn, кнопка
    • index – idx – i, индекс
    • buffer – buf, буфер
    • value – val, значение
    • variable – var, переменная
    • pointer – ptr, указатель
  • Имена функций и методов принято начинать с глагола, кратко описывающего действие функции. Вот те из них, которые вы будете встречать постоянно:
    • get – получить значение (getValue)
    • set – установить значение (setTime)
    • print, show – показать что-то
    • read – прочитать
    • write – записать
    • change – изменить
    • clear – очистить
    • begin, start – начать
    • end, stop – закончить, остановить

Частый вопрос: влияет ли длина названия переменной на занимаемую прошивкой память? На вес файла с программой на компьютере – влияет. На вес загруженной в микроконтроллер прошивки – не влияет, потому что код преобразуется в машинный, в котором нет имён.

Структура кода


Прежде чем переходить к структуре и порядку частей кода, нужно кое-что запомнить:

  • Переменная любого типа должна вызываться только после своего объявления. Иначе будет ошибка
  • Объявление и использование классов или типов данных из библиотеки/файла должно быть после подключения библиотеки/файла
  • Функция может вызываться как до, так и после объявления, потому что C++ компилируемый язык, компиляция проходит в несколько этапов, и функции “выделяются” отдельно, поэтому могут вызываться в любом месте программы

При запуске Arduino IDE даёт нам заготовку в виде двух обязательных функций: setup() и loop()

Код в блоке setup() выполняется один раз при каждом запуске МК. Код в блоке loop() выполняется “по кругу” на всём протяжении работы программы, начиная с момента завершения выполнения setup(). Для любознательных: если вы уже знакомы с языком C++, то вероятно спросите “а где же int main() и вообще файл main.cpp?”. Всё очень просто: int main() за вас уже написали внутри файла main.cpp, который лежит глубоко в файлах “ядра”, а setup() и loop() встроены в него следующим образом:

// main.cpp
// где-то в глубинах ядра Arduino
int main() {
  setup();    
    for (;;) {
      loop();
    }        
  return 0;
}

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

  1. Описание прошивки, ссылки, заметки
  2. Константы-настройки (define и обычные)
  3. Служебные константы (которые следует менять только с полным осознанием дела)
  4. Подключаемые библиотеки и внешние файлы, объявление соответствующих им типов данных и классов
  5. Глобальные переменные
  6. setup()
  7. loop()
  8. Свои функции

Пример кода

/*
  Данный скетч плавно крутит
  сервопривод туда-обратно
  между мин. и макс. углами
  by AlexGyver
*/

// -------- НАСТРОЙКИ ---------
#define SERVO_PIN 13    // сюда подключена серво
#define SERVO_SPEED 3   // скорость серво
#define MIN_ANGLE 50    // мин. угол
#define MAX_ANGLE 120   // макс. угол

// ------- БИБЛИОТЕКИ -------
#include <Servo.h>
Servo myservo;

// ------- ПЕРЕМЕННЫЕ -------
uint32_t servoTimer;
boolean servoDirection;
int servoAngle;

// --------- SETUP ----------
void setup() {
  myservo.attach(SERVO_PIN);
}

// ---------- LOOP ----------
void loop() {
  turnServo();
}

// --------- ФУНКЦИИ --------
void turnServo() {
  if (millis() - servoTimer >= 50) {  // каждые 50 мс
    servoTimer = millis();
    if (servoDirection) {
      servoAngle += SERVO_SPEED;
      if (servoAngle >= MAX_ANGLE) {
        servoAngle = MAX_ANGLE;
        servoDirection = false;
      }
    } else {
      servoAngle -= SERVO_SPEED;
      if (servoAngle <= MIN_ANGLE) {
        servoAngle = MIN_ANGLE;
        servoDirection = true;
      }
    }
    myservo.write(servoAngle);
  }
}

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

Подключение библиотек и файлов


В реальной работе вы очень часто будете использовать библиотеки или просто внешние файлы, они подключаются в главный файл (файлу прошивки) при помощи директивы #include. Данная команда сообщает компилятору, что нужно найти и добавить в программу указанный файл. Этот файл может содержать свои #include и тянуть за собой и другие файлы, таким образом программа может быть разбита на множество независимых файлов. Рассмотрим пример:

#include <Servo.h> // подключает библиотеку Servo.h

#include “Servo.h” // тоже подключает библиотеку Servo.h

В чём отличие <> и ""? Когда указываем название "в кавычках", компилятор сначала ищет файл в папке со скетчем, а затем в папке с библиотеками. При использовании <галочек> компилятор ищет файл только в папке с библиотеками! К слову о папках с библиотеками: их две, в обеих будет производиться поиск библиотек.

  • Пользовательская папка: Документы/Arduino/libraries. Сюда библиотеки попадают при добавлении их через “подключить .zip библиотеку” и при установке из менеджера библиотек.
  • Папка с программой: C:/Program Files (x86)/Arduino/libraries (или C:/Program Files/Arduino/libraries для 32-разрядной Windows). Здесь хранятся встроенные стандартные библиотеки.

Не используйте мышку!


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

  • Ctrl+← , Ctrl+→ – переместить курсор влево/вправо НА ОДНО СЛОВО
  • Home , End – переместить курсор в начало/конец строки
  • Shift+← , Shift+→ – выделить символ слева/справа от курсора
  • Shift+Ctrl+← , Shift+Ctrl+→ – выделить слово слева/справа от курсора
  • Shift+Home , Shift+End – выделить все символы от текущего положения курсора до начала/конца строки
  • Ctrl+Z – отменить последнее действие
  • Ctrl+Y – повторить отменённое действие
  • Ctrl+C – копировать выделенный текст
  • Ctrl+X – вырезать выделенный текст
  • Ctrl+V – вставить текст из буфера обмена

Местные сочетания:

  • Ctrl+U – загрузить прошивку в Arduino
  • Ctrl+R – скомпилировать (проверить)
  • Ctrl+Shift+M – открыть монитор порта
  • Ctrl+T – автоформатирование

Для отодвигания комментариев в правую часть кода используйте TAB, а не ПРОБЕЛ. Нажатие TAB перемещает курсор по некоторой таблице, из-за чего ваши комментарии будут установлены на одинаковом расстоянии.

Видео


Полезные страницы


  • Набор GyverKIT – большой стартовый набор Arduino моей разработки, продаётся в России
  • Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
  • Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
  • Полная документация по языку Ардуино, все встроенные функции и макросы, все доступные типы данных
  • Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
  • Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
  • Поддержать автора за работу над уроками
  • Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту ([email protected])

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

Комментарии

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

Есть два способа выделения комментариев в скетче:

1. Символ «//». Так выделяются комментарии, которые помещаются в одной строчке:

// Это комментарий в одну строку

Код программы перед «//» никак не изменится.

delay(1000); // задержка на одну секунду

2. Символы «/*» и «*/». Они применяются, когда необходимо написать длинный комментарий. Всё, что написано между этими символами, будет восприниматься как комментарий.

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

или

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

Типы данных/Data

В процессе программирования используются числовые, символьные и другие типы данных. Язык программирования С («Си») позволяет работать с несколькими типами данных, например:

  • int. Целочисленные данные, такие как 0, 12, -1
  • float. Вещественные числа, такие как 0.1, -1.2
  • char. Символьные данные, такие как ‘a’, ‘@’, ‘0’

Для того, чтобы познакомиться со всем набором типов данных, используемых в Arduino, вы можете посетить страничку в интернете: arduino.ru/Reference

Константы/Constants

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

Переменные/Varibles

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

Переменные нужно объявлять перед использованием в программе, например:

int i;

«int» указывает на тип переменной «i», а символ «;» обозначает конец оператора. После объявления переменной вы можете её использовать в программе, например:

i = 0; // в этой строке переменной «i» присваивается значение «0»

Переменной, находящейся слева от оператора присваивания («=») присваивается значение переменной или выражения, находящегося справа. Переменная должна быть способна хранить присваиваемое значение, то есть соответствовать его типу и диапазону допустимых значений.

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

int i, j;
i = 0; // переменной i присваивается 0 
i = 1; // теперь i принимает значение 1
j = i; // значение переменной i присваивается переменной j, то есть j теперь равно 1

Функция/Function

Функцией называется набор операторов, которые выполняются в определенном порядке и решают определенную задачу. Давайте для наглядного примера напишем функцию мигания светодиодом:

void blink() { 
  digitalWrite(13, HIGH); 
  delay(1000); 
  digitalWrite(13, LOW); 
  delay(1000); 
}
  • void — указывает на то, что функция не возвращает никакого значения.
  • () — в круглые скобки заключаются параметры функции. Если внутри скобок ничего нет, то это означает, что в функцию не передаётся никаких параметров.
  • {} — между двумя фигурными скобками записывается основной код функции. После объявления функции она может быть вызвана из любой части программы своим названием, как показано ниже:
blink();

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

...
delay(500); 
blink(); 
delay(500); 
blink();
... 

Некоторые функции могут иметь один или несколько параметров (передаваемых ей значений). В таких случаях параметры указывабтся внутри круглых скобок «( )»:

digitalWrite(13, HIGH); // включить светодиод L 
delay(1000); // подождать 1 с 

Здесь digitalWrite и delay — это тоже функции, только заранее определённые в самой среде программирования Arduino.

Предыдущий урок | В начало | Следующий урок

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

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

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

С появлением сторонних редакторов кода и IDE, таких, как PlatformIO, следить за соблюдением стилистики кода стало намного проще.

Отступы

Первое и самое важное правило: отступы нужно использовать. Обязательно. Давайте сравним такой код:

...
int checkSum()
{
int a;
for (int i = 0; i < 10; i++)
{
a++;
}
return a;
}

и такой:

...
int checkSum()
{
  int a;
  for (int i = 0; i < 10; i++)
  {
    a++;
  }
  return a;
}

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

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

Чаще всего в коде для Arduino для отступов используется 2 пробела. Реже — 4 или 3.

Пробелы

Пробелы делают код более читаемым. Например сравните:

for(int i=0;i<10;i++){
  a++;
}

и

for (int i = 0; i < 10; i++) {
  a++;
}

Второй вариант явно удобнее читать. Есть еще такой вариант:

for (int i=0; i<10; i++) {
  a++;
}

Каждый решает сам. Но именно второй вариант наиболее распространен и чаще принято использовать именно его.

Фигурные скобки

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

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

if (a == 1) 
{
  b++;
}

if (a == 1) {
  b++;
}

if (a == 1)
  b++;

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

Ставить открывающуюся скобку на той же строчке или на следующей — вопрос личного выбора. Наиболее частое правило: при написании функции скобка ставится на следующей строчке, а при написании операторов — на той же, отделенная одним пробелом:

void setup()
{
}

void loop()
{
  if (a != b) {
    for (int i = 0; i < 10; i++) {
      a += b;
    }
  }
}

Комментарии

Комментарий — текст, который игнорируется компилятором и служит для лучшего понимание программы при чтении кода.

Для создание однострочного комментария используется два символа прямого слэша — //:

// функция проверки четности числа
bool isEven(int num)
{
  ...
}

Для создание комментария из нескольких строк следует перед началом текста комментария поставить /*, а после текста — */:

/* Функция проверки четности числа.
Входные параметры:
num - целое число 
*/
bool isEven(int num)
{
  ...
}

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

CC

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

Предыдущий урок     Список уроков     Следующий урок

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

  • Структура программы Ардуино
  • Первоначальные правила синтаксиса языка C
  • Переменные и типы данных
  • Арифметические операции
  • Операции отношения
  • Логические операции
  • Операции над указателями
  • Битовые операции
  • Операции смешанного присваивания
  • Выбор вариантов, управление программой
  • Массивы
  • Функции
  • Рекомендации по оформлению программ на языке C

Структура программы Ардуино.

Структура программы Ардуино  достаточно проста и в минимальном варианте состоит из двух частей setup() и loop().

void setup()  {

//  код выполняется один раз при запуске программы

}

void loop()  {

// основной код, выполняется в цикле

}

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

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

Первоначальные правила синтаксиса языка C.

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

z = x + y;
z=      x      
+ y     ;

{   }  фигурные скобки определяют блок функции или выражений. Например, в функциях setup() и loop().

/* … */ блок комментария, обязательно закрыть.

/* это блок      комментария  */

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

// это одна строка комментария

Переменные и типы данных.

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

Тип данных Разрядность, бит Диапазон чисел
boolean 8 true, false
char 8 -128 … 127
unsigned char 8 0 … 255
byte 8 0 … 255
int 16 -32768 … 32767
unsigned int 16 0 … 65535
word 16 0 … 65535
long 32 -2147483648 … 2147483647
unsigned long 32 0 … 4294967295
short 16 -32768 … 32767
float 32 -3.4028235+38 … 3.4028235+38
double 32 -3.4028235+38 … 3.4028235+38

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

Объявление переменных.

Указывается тип данных, а затем имя переменной.

int x;                      // объявление переменной с именем x типа int
float widthBox;   // объявление переменной с именем widthBox типа float

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

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

  • Переменные, объявленные в начале программы, до функции void setup(), считаются глобальными и доступны в любом месте программы.
  • Локальные переменные объявляются внутри функций или таких блоков, как цикл for, и могут использоваться только в объявленных блоках. Возможны несколько переменных с одним именем, но разными областями видимости.

int mode;           // переменная доступна всем функциям

void setup()  {
//  пустой блок, начальные установки не требуются

}

void loop()  {

long  count;                     // переменная count доступна только в функции loop()

for ( int i=0; i < 10;)      // переменная i доступна только внутри цикла   
  {
     i++;
    }
}

При объявлении переменной можно задать ее начальное значение (проинициализировать).

int x = 0;              // объявляется переменная x с начальным значением 0
char d = ‘a’;        // объявляется переменная d с начальным значением равным коду символа ”a”

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

int x;                     // переменная int
char y;                  // переменная char
int z;                     // переменная int

z = x + (int) y;     // переменная y явно преобразована в int

Арифметические операции.

= присваиваниее
+ сложение
вычитание
* произведение
/ деление
% остаток от деления

Операции отношения.

== равно
!= не равно
< меньше
> больше
<= меньше или равно
>= больше или равно

Логические операции.

&& логическое И
|| логическое ИЛИ
! логическое НЕ

Операции над указателями.

* косвенная адресация
& получение адреса переменной

Битовые операции.

& И
| ИЛИ
^ ИСКЛЮЧАЮЩЕЕ ИЛИ
~ ИНВЕРСИЯ
<< СДВИГ ВЛЕВО
>> СДВИГ ВПРАВО

Операции смешанного присваивания.

++ + 1 к переменной
— 1 к переменной
+= сложение
-= вычитание
*= умножение
/= деление
%= остаток от деления
&= битовое И
|= битовое ИЛИ

Выбор вариантов, управление программой.

Оператор IF проверяет условие в скобках и выполняет последующее выражение или блок в фигурных скобках, если условие истинно.

if (x == 5)             // если x=5, то выполняется z=0  
z=0;

if (x > 5)               // если x > 5, то выполняется блок z=0, y=8;
{    z=0;    y=8; }

IF … ELSE позволяет сделать выбор между двух вариантов.

if (x > 5)               // если x > 5, то выполняется блок z=0, y=8;
 {
   z=0;
   y=8;
  }
 else                       // в противном случае выполняется этот блок
 {
   z=0;
   y=0;
  }

ELSE IF – позволяет сделать множественный выбор

if (x > 5)               // если x > 5, то выполняется блок z=0, y=8;
  {
    z=0;
    y=8;
   }

else if (x > 20)   // если x > 20, выполняется этот блок
  {
   }

else                       // в противном случае выполняется этот блок
  {
   z=0;
   y=0;
   }

SWITCH CASE — множественный выбор. Позволяет сравнить переменную (в примере это x) с несколькими константами (в примере 5 и 10) и выполнить блок, в котором переменная равна константе.

switch (x)  {

case 5 :     
     // код выполняется если  x = 5
      break;

case 10 :
     // код выполняется если  x = 10
     break;

default :
     // код выполняется если  не совпало ни одно предыдущее значение
     break;
}

Цикл FOR. Конструкция позволяет организовывать циклы с заданным количеством итераций. Синтаксис выглядит так:

for ( действие до начала цикла;
         условие продолжения цикла;
        действие в конце каждой итерации )  {

// код тела цикла

}

Пример цикла из 100 итераций.

for ( i=0; i < 100; i++ )     // начальное значение 0, конечное 99, шаг 1

{
     sum = sum + I;
}

Цикл WHILE. Оператор позволяет организовывать циклы с конструкцией:

while ( выражение )
{
// код тела цикла
}

Цикл выполняется до тех пор, пока выражение в скобках истинно. Пример цикла на 10 итераций.

x = 0;
while ( x < 10 )
 {
  // код тела цикла
   x++;
  }

DO WHILE – цикл с условием на выходе.

do
{
  // код тела цикла
}   while ( выражение );

Цикл выполняется пока выражение истинно.
BREAK – оператор выхода из цикла. Используется для того, чтобы прервать выполнение циклов  for, while, do while.

x = 0;
while ( x < 10 )
{
  if ( z > 20 ) break;             // если z > 20, то выйти из цикла
// код тела цикла
  x++;
  }

GOTO – оператор безусловного перехода.

goto  metka1;                   // переход на metka1
………………
metka1:

CONTINUE —  пропуск операторов до конца тела цикла.

x = 0;
while ( x < 10 )
{
// код тела цикла
if ( z > 20 ) continue;      // если z > 20, то вернуться на начало тела цикла
// код тела цикла
x++;
 }

Массивы.

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

Объявляется массив так.

int ages[10];                      // массив из 10 переменных типа int

float weight[100];          // массив из 100 переменных типа float

При объявлении массивы можно инициализировать:

int ages[10] = { 23, 54, 34, 24, 45, 56, 23, 23, 27, 28};

Обращаются к переменным массивов так:

x = ages[5];        // x присваивается значение из 5 элемента массива.
ages[9] = 32;      // 9 элементу массива задается значение 32

Нумерация элементов массивов всегда с нуля.

Функции.

Функции позволяют выполнять одни и те же действия с разными данными. У функции есть:

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

Описывается пользовательская функция вне функций setup() и loop().

void setup()  {
//  код выполняется один раз при запуске программы
}

void loop()  {
 // основной код, выполняется в цикле
}

// объявление пользовательской функции с именем functionName
type  functionName( type argument1, type argument1, … , type argument)
   {
    // тело функции
     return();
   }

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

int sumQwadr (int  x, int y)
{
  return( x* x + y*y);
}

Вызов функции происходит так:

d= 2; b= 3;
z= sumQwadr(d, b);                    // в z будет сумма квадратов переменных d и b

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

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

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

Рекомендации по оформлению программ на языке C.

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

Имена в языке C.

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

Signal, TimeCount

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

signal, timeCount

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

MAX_TEMP, RED

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

getTime, setTime

Об остальных формальностях в следующих уроках, по мере необходимости.

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

Предыдущий урок     Список уроков     Следующий урок

Автор публикации


261

Комментарии: 1869Публикации: 183Регистрация: 13-12-2015

Микроконтроллер  способен выполнять только точные инструкции. Общение с микроконтроллером происходит на языке программирования, который имеет свой синтаксис и нормы оформления. Непосредственно в сам микроконтроллер загружается бинарный машинный код. Данный код может быть получен из любого языка программирования, тут всё зависит от среды разработки и транслятора. Официальной средой разработки является Arduino IDE, где программирование осуществляется на языке программирования C++ (читается «Си плюс плюс») , одном из самых популярных и мощных языков. Сами разработчики называют язык Arduino Wiring, так как в стандартной библиотеке Arduino.h используются функции и инструменты из фреймворка Wiring. Но языком из которого берётся синтаксис, является C (читается «Си»). Помимо С существуют среды разработки, позволяющие писать на Java, например Espruino WEB IDE, или B4R – на языке Basic, XOD – программирование с помощью визуальных блоков.

Синтаксис

Комментарии

Комментарии нужны для пояснения кода, как для себя, так и для других. Комментарий это обычный текст, который игнорируется на этапе компиляции, то есть перевода в машинный код. В C++ у нас два типа комментариев:

// однострочный комментарий

/* Многострочный

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

Переменные

Имена переменных могут содержать латинские буквы в верхнем и нижнем регистре (ЗАГЛАВНЫЕ и строчные), цифры и нижнее подчеркивание. Имена переменных не могут начинаться с цифры. Только с буквы или нижнего подчёркивания.

Пример: myVar_1 .

Регистр имеет значение, т. е. заглавная буква отличается от строчной. Пример: переменные var1 и Var1 – не одно и то же.

Операторы и функции

Каждая команда заканчивается точкой с запятой;

Вызов функции или метода всегда заканчивается скобками, даже если функция не принимает параметров. Пример: loop()

Тела функций заключаются в фигурные скобки { }

Разделитель десятичных дробей – точка. Пример: 0.25

Запятыми перечисляются аргументы функций и методов, а также членов массива. Пример: digitalWrite(3, HIGH);  массив – int myArray[] = {3, 4, 5 ,6}; Также запятая является самостоятельным оператором.

Одиночный символ заключается в одиночные кавычки ‘а’

Строка заключается в двойные кавычки “строка”

Метод применяется к объекту через точку. Например: Serial.begin();

 Оформление

Есть такое понятие, как форматирование (выравнивание) кода, то есть соблюдение пробелов и интервалов. Есть автоформатирование кода, оно работает как в процессе написания, так и по вызову. В Arduino IDE код форматируется по горячей комбинации Ctrl+T.

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

Отступ от левого края экрана – знак табуляции, код сдвигается вправо и на одном расстоянии формируются команды из одного блока кода. В Arduino IDE одна табуляция равна двум пробелам.

Каждое действие выполняется с новой строки (автоформатирование это не исправляет).

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

Общепринятые правила (не синтаксис) именования переменных, функций и методов.

Имена переменных принято писать начиная с маленькой буквы, называть их так, чтобы было понятно. Пример: value

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

Имена типов данных и классов принято писать с большой буквы. Пример: Signal, Servo

Имена констант принято писать в верхнем регистре, разделение – нижнее подчеркивание. Пример: MOTOR_SPEED

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

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

button – btn, кнопка

index – idx – i, индекс

buffer – buf, буфер

value – val, значение

variable – var, переменная

pointer – ptr, указатель

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

get – получить значение (getValue)

set – установить значение (setTime)

print, show – показать что-то

read – прочитать

write – записать

change – изменить

clear – очистить

begin, start – начать

end, stop – закончить, остановить

Структура кода

Прежде чем переходить к структуре и порядку частей кода, нужно кое-что запомнить:

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

Объявление и использование классов или типов данных из библиотеки/файла должно быть после подключения библиотеки/файла.

Функция может вызываться как до, так и после объявления, потому что C++ компилируемый язык, компиляция проходит в несколько этапов, и функции “выделяются” отдельно, поэтому могут вызываться в любом месте программы.

При запуске Arduino IDE даёт нам заготовку в виде двух обязательных функций: setup и loop.

Код в блоке setup выполняется один раз при каждом запуске микроконтроллера. Код в блоке loop выполняется в цикле (“по кругу”) на всём протяжении работы микроконтроллера, начиная с момента завершения выполнения setup.

Структура реального скетча:

  1. Описание прошивки, полезные ссылки, заметки, авторство.
  2. Константы настройки (define и обычные).
  3. Служебные константы (которые следует менять только с полным осознанием дела).
  4. Подключаемые библиотеки и внешние файлы, объявление соответствующих им типов данных и классов.
  5. Глобальные переменные.
  6. Блок setup.
  7. Блок loop.
  8. Пользовательские функции.
Пример кода
int led = 8;
void setup()
{
  pinMode(led, OUTPUT);
}
void loop()
{
  digitalWrite(led, HIGH);
  delay(1000);
  digitalWrite(led, LOW);
  delay(1000);
}
Пример того же кода с комментариями (пояснениями)
int led = 8; //объявление переменной целого типа, содержащей номер порта к которому мы подключили второй провод
void setup() //обязательная процедура setup, запускаемая в начале программы; объявление процедур начинается словом void
{
  pinMode(led, OUTPUT); //объявление используемого порта, led - номер порта, второй аргумент - тип использования порта - на вход (INPUT) или на выход (OUTPUT)
}
void loop() //обязательная процедура loop, запускаемая циклично после процедуры setup
{
  digitalWrite(led, HIGH); //эта команда используется для включения или выключения напряжения на цифровом порте; led - номер порта, второй аргумент - включение (HIGH) или выключение (LOW)
  delay(1000); //эта команда используется для ожидания между действиями, аргумент - время ожидания в миллисекундах
  digitalWrite(led, LOW);
  delay(1000);
}

Подключение библиотек и файлов

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

#include <Servo.h> // подключает библиотеку Servo.h

#include “Servo.h” // тоже подключает библиотеку Servo.h

Когда указываем название “в кавычках”, компилятор сначала ищет файл в папке со скетчем, а затем в папке с библиотеками. При использовании <галочек> компилятор ищет файл только в папке с библиотеками!

Практическое задание к уроку

Создавать небольшие проекты и программировать можно и при отсутствии платы Ардуино, в онлайн программном комплексе TinkerCad (https://www.tinkercad.com/). Для быстрого доступа (чтобы избавить вас от длительной процедуры регистрации) учащихся МОУ «Гимназия №6» г. Воркуты создан специальный виртуальный класс Arduino214 (как вы догадались, по номеру кабинета робототехники). Для реализации данного способа входа в программный комплекс необходимо:

  1. Зайти в класс Arduino214 по адресу https://www.tinkercad.com/joinclass/NDK3RBS86WX6.
  2. Ввести псевдоним, назначенный преподавателем (Если вы не получили или забыли псевдоним, то можно сделать запрос в электронном дневнике, отправив письмо на имя Янактаева Евгения Владимировича).

Практическая работа 2.1. Мигающий встроенный светодиод. 

Будем использовать в программном комплексе TinkerCad собранную на предыдущем уроке схему, в которую входят: плата Arduino Uno, малая макетная плата, мультиметр. 

После входа в программный комплекс выберите в левом меню Circuits, выберите созданную схему и нажмите Изменить

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

Создадим программу для управления встроенным светодиодом.

В верхнем меню справа выберите Код и поменяйте в выпадающем меню Блоки на Текст.

При появлении предупреждения нажмите на кнопку Продолжить. В рабочей области текстового редактора появится  следующий код:

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  digitalWrite(13, HIGH);
  delay(1000); // Wait for 1000 millisecond(s)
  digitalWrite(13, LOW);
  delay(1000); // Wait for 1000 millisecond(s)
}

В процедуре void setup() изменим используемый порт 13 на встроенный светодиод LED_BUILTIN. То же самое сделаем с функцией digitalWrite в процедуре void loop()

Получится следующий код:

void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
digitalWrite(LED_BUILTIN, HIGH);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(LED_BUILTIN, LOW);
delay(1000); // Wait for 1000 millisecond(s)
}

Нажмите на кнопку Начать моделирование. Встроенный светодиод должен включиться и через 1 секунду (времени моделирования, оно может отличаться от реального) выключиться. И так будет продолжаться в цикле: встроенный светодиод будет «мигать».

Разберем подробнее, как это все работает.

Обратите внимание на два блока со словами setup и loop. Это две функции, которые вызываются всегда, когда запускается наш скетч. Блоки ограничены фигурными скобками – все, что внутри них, принадлежит блоку. 

Блок функции void setup()

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

Синтаксис void setup():

void setup()
{
  // тут располагаются команды подпрограммы
}

Слово setup – это название функции. Все слово в нижнем регистре. Слово перед названием описывает тип возвращаемых данных. В данном случае никаких данных подпрограмма не возвращает, поэтому мы должны указать слово void. Все команды функции должны размещаться внутри фигурных скобок {}.

Чаще всего внутри void setup указываются следующие инструкции:

  • pinMode с указанием номера и типа порта. Это инструкция определяет режим работы портов Ардуино.
  • Serial.begin с указанием скорости (чаще всего, 9600). Эта инструкция инициализирует работы с последовательным портом на указанной скорости.
  • Инструкции подключения и инициализации различных объектов библиотек Ардуино. Например, servo.atach(10) укажет библиотеке, что сервопривод мы подключили к 10 порту, и все последующие действия код библиотеки будет совершать именно с этим портом.
  • Инициализацию глобальных переменных, если нет возможности инициализировать их в глобальной области видимости.
  • Выполнение других настроек и начальных значений для переменных и объектов.

Пример:

void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT); // 13 порт будет выходом (все остальные порты по умолчанию входы)
servo.atach(10); // Где-то был объявлен объект класса Servo, указываем, что сервопривод подсоединен к 10 порту.
}

В блоке функции loop() сосредоточены наши команды, управляющие светодиодом:

digitalWrite – это название функции, которая отвечает за подачу напряжения на определенный порт.

LED_BUILDIN – это название внутреннего светодиода. В большинстве плат этому названию соответствует порт 13. Для платы Uno можно было не менять значение 13 на LED_BUILDIN. 

HIGH – условное название высокого уровня сигнала. Включает светодиод. Можно заменить цифрой 1.

LOW – условное обозначение низкого уровня сигнала. Выключает светодиод. Можно заменить цифрой 0.

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

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

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

  • Как пишется команда мсконфиг
  • Как пишется коммент или коммент
  • Как пишется команда кип инвентори
  • Как пишется комитет совета федерации
  • Как пишется команда кип инвентари тру в майнкрафт