Arduino:Хакинг/Написание библиотеки: различия между версиями
Myagkij (обсуждение | вклад) Нет описания правки |
Myagkij (обсуждение | вклад) Нет описания правки |
||
Строка 7: | Строка 7: | ||
=Написание библиотеки<ref>[https://www.arduino.cc/en/Hacking/LibraryTutorial www.arduino.cc - Writing a Library for Arduino]</ref>= | =Написание библиотеки<ref>[https://www.arduino.cc/en/Hacking/LibraryTutorial www.arduino.cc - Writing a Library for Arduino]</ref>= | ||
Эта статья объясняет, как создать собственную библиотеку для | Эта статья объясняет, как создать собственную библиотеку для [[Arduino]]. Объяснение будет на примере кода, позволяющего моргать [[азбукой Морзе]] на [[светодиод]]ах [[Arduino]]. Далее будет показано, как конвертировать этот код в библиотеку. Это позволит другим пользователям без особого труда использовать и обновлять написанный вами код. | ||
Более подробно читайте в [https://www.arduino.cc/en/Reference/APIStyleGuide этом руководстве] – оно объясняет, как написать хороший | Более подробно читайте в [https://www.arduino.cc/en/Reference/APIStyleGuide этом руководстве] – оно объясняет, как написать хороший [[API]] в стиле [[Arduino]] для вашей библиотеки. | ||
Начнем со | Начнем со [[скетч]]а, который выполняет простой код с [[азбукой Морзе]]: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
int pin = 13; | int pin = 13; | ||
Строка 46: | Строка 46: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Если запустить этот скетч, он | Если запустить этот скетч, он «напечатает» на 13-ом контакте «SOS» (сигнал бедствия). | ||
Этот скетч состоит из нескольких частей, которые нужно перенести в библиотеку. Во-первых, у нас есть функции '''dot()''' и '''dash()''', которые, собственно, и выполняют мигание. Во-вторых, там есть переменная '''ledPin''', которую эти функции используют, чтобы узнать, на каком именно контакте нужно выполнить мигание. Наконец, в | Этот [[скетч]] состоит из нескольких частей, которые нужно перенести в библиотеку. Во-первых, у нас есть функции '''dot()''' и '''dash()''', которые, собственно, и выполняют мигание. Во-вторых, там есть переменная '''ledPin''', которую эти функции используют, чтобы узнать, на каком именно контакте нужно выполнить мигание. Наконец, в [[скетч]]е вызывается функция [[Arduino:Справочник языка Arduino/Функции/Цифровой ввод/вывод/pinMode()|pinMode()]], которая выставляет контакт в режим [[Arduino:Справочник языка Arduino/Константы/OUTPUT|OUTPUT]]. | ||
Итак, приступим к превращению скетча в библиотеку! | Итак, приступим к превращению скетча в библиотеку! | ||
Для библиотеки понадобится как минимум два файла: заголовочный файл (с расширением | Для библиотеки понадобится как минимум два файла: заголовочный файл (с расширением «[[*.h]]») и файл-исходник (с расширением «[[*.cpp]]»). Заголовочный файл содержит эдакий список основных понятий, т.е. список всего, что находится внутри библиотеки. Сам код находится внутри файла-исходника. Мы даем нашей библиотеке название «Morse», поэтому наш заголовочный файл будет называется «Morse.h». | ||
Давайте-ка взглянем, что у него внутри. На первый взгляд, его содержимое может показаться странным, но вы все поймете, когда мы заглянем внутрь файла-исходника. | Давайте-ка взглянем, что у него внутри. На первый взгляд, его содержимое может показаться странным, но вы все поймете, когда мы заглянем внутрь файла-исходника. | ||
«Сердцевина» заголовочного файла состоит из списка функций и необходимых переменных (одна строчка/переменная – одна функция), «обернутых» в класс: | |||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
class Morse | class Morse | ||
{ | { | ||
Строка 70: | Строка 70: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Класс – это просто коллекция функций и переменных, хранящихся в одном месте. Эти функции и переменные могут быть [[public]] («публичными», могут употребляться внутри любой функции) или [[private]] («приватными», могут употребляться лишь внутри самого класса). У каждого класса есть специальная функция-конструктор, которая используется для создания экземпляра класса. Конструктор имеет то же имя, что и класс, но ничего не возвращает. | |||
Содержимое заголовочного файла на этом, впрочем, не заканчивается. Во-первых, вам нужно вписать туда директиву [[Arduino:Справочник языка Arduino/Синтаксис/include|#include]], дающую доступ к стандартным типам и константам языка | Содержимое заголовочного файла на этом, впрочем, не заканчивается. Во-первых, вам нужно вписать туда директиву [[Arduino:Справочник языка Arduino/Синтаксис/include|#include]], дающую доступ к стандартным типам и константам языка [[Arduino]] (она автоматически добавляется к обычным скетчам, но не к библиотекам). Это выглядит примерно так (и ставится выше блока с классом, о котором писалось выше): | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
#include "Arduino.h" | #include "Arduino.h" | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 80: | Строка 80: | ||
Во-вторых, весь заголовочный файл нужно «обернуть» в одну очень странную конструкцию: | Во-вторых, весь заголовочный файл нужно «обернуть» в одну очень странную конструкцию: | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
#ifndef Morse_h | #ifndef Morse_h | ||
#define Morse_h | #define Morse_h | ||
Строка 95: | Строка 95: | ||
Давайте взглянем, как заголовочный файл будет выглядеть полностью: | Давайте взглянем, как заголовочный файл будет выглядеть полностью: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
/* | /* | ||
Morse.h – Библиотека для азбуки Морзе на светодиодах. | Morse.h – Библиотека для азбуки Морзе на светодиодах. | ||
Строка 121: | Строка 121: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Теперь давайте пробежимся по разным фрагментам файла-исходника – | Теперь давайте пробежимся по разным фрагментам файла-исходника – «Morse.cpp». | ||
Сначала идут две директивы [[Arduino:Справочник языка Arduino/Синтаксис/include|#include]]. Они дают остальному коду доступ к стандартным функциям языка | Сначала идут две директивы [[Arduino:Справочник языка Arduino/Синтаксис/include|#include]]. Они дают остальному коду доступ к стандартным функциям языка [[Arduino]], а также к понятиям, указанным в «Morse.h»: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
#include "Arduino.h" | #include "Arduino.h" | ||
#include "Morse.h" | #include "Morse.h" | ||
Строка 132: | Строка 132: | ||
Затем идет конструктор. Опять же, он объясняет, что должно произойти, если кто-то создаст экземпляр вашего класса. В данном случае пользователь должен указать, какой контакт он будет использовать. Мы выставляем этот контакт в режим [[Arduino:Справочник языка Arduino/Константы/OUTPUT|OUTPUT]] и сохраняем в приватную переменную для использования в других функциях: | Затем идет конструктор. Опять же, он объясняет, что должно произойти, если кто-то создаст экземпляр вашего класса. В данном случае пользователь должен указать, какой контакт он будет использовать. Мы выставляем этот контакт в режим [[Arduino:Справочник языка Arduino/Константы/OUTPUT|OUTPUT]] и сохраняем в приватную переменную для использования в других функциях: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
Morse::Morse(int pin) | Morse::Morse(int pin) | ||
{ | { | ||
Строка 146: | Строка 146: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
перед названием функции. Это значит, что эта функция является частью | перед названием функции. Это значит, что эта функция является частью класса Morse. Вы увидите такой фрагмент и при указании других функций этого класса. | ||
Вторая непонятная вещь – это нижнее подчеркивание при написании приватной переменной, '''_pin'''. По сути, эту переменную можно назвать как угодно – до тех пор, пока она соответствует определению, указанному в заголовочном файле. Добавление нижнего подчеркивания перед названием переменной – это общепринятый способ показать, что эта переменная является приватной, а также отличить ее от аргумента функции (в данном случае – '''pin'''). | Вторая непонятная вещь – это нижнее подчеркивание при написании приватной переменной, '''_pin'''. По сути, эту переменную можно назвать как угодно – до тех пор, пока она соответствует определению, указанному в заголовочном файле. Добавление нижнего подчеркивания перед названием переменной – это общепринятый способ показать, что эта переменная является приватной, а также отличить ее от аргумента функции (в данном случае – '''pin'''). | ||
Дальше идет, собственно, сам код из | Дальше идет, собственно, сам код из [[скетч]]а, который мы превращаем в библиотеку (наконец-то!). Он выглядит примерно так же, как в [[скетч]]е, за исключением | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
Строка 158: | Строка 158: | ||
, стоящим перед названиями функций, а также '''_pin''' вместо '''pin'''. | , стоящим перед названиями функций, а также '''_pin''' вместо '''pin'''. | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
void Morse::dot() | void Morse::dot() | ||
{ | { | ||
Строка 178: | Строка 178: | ||
Наконец, пишем в верхней части файла-исходника заголовочный комментарий. И давайте взглянем, что получилось: | Наконец, пишем в верхней части файла-исходника заголовочный комментарий. И давайте взглянем, что получилось: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
/* | /* | ||
Morse.cpp – Библиотека для азбуки Морзе на светодиодах. | Morse.cpp – Библиотека для азбуки Морзе на светодиодах. | ||
Строка 213: | Строка 213: | ||
По сути, это все, что нужно (но есть пара дополнений, о которых мы поговорим чуть позже). | По сути, это все, что нужно (но есть пара дополнений, о которых мы поговорим чуть позже). | ||
Теперь давайте рассмотрим, как использовать эту библиотеку. Сначала идем в папку | Теперь давайте рассмотрим, как использовать эту библиотеку. Сначала идем в папку «libraries», которая находится в папке скетчей (расположение папки скетчей можно узнать, кликнув в [[IDE Arduino]] на '''Файл > Настройки;''' откроется окно, в самой верхней части которого будет поле «Размещение папки скетчей») и создаем там папку «Morse». Затем копируем в эту папку файлы «Morse.h» и «Morse.cpp». Теперь запускаем [[IDE Arduino]] и кликаем по '''Скетч > Подключить библиотеку'''. Откроется выпадающее меню со списком загруженных библиотек, и в их числе уже должна быть наша Morse. Библиотека будет скомпилирована вместе со [[скетч]]ами, которые ее используют. Если библиотеки не видно, то убедитесь, что скопированные вами файлы действительно имеют расширения «[[*.h]]» и «[[*.cpp]]» (то есть, к примеру, без дополнительных «[[*.pde]]» или «[[*.txt]]»). | ||
Теперь давайте посмотрим, как можно воспроизвести наш старый скетч | Теперь давайте посмотрим, как можно воспроизвести наш старый скетч «SOS» при помощи новой библиотеки: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
#include <Morse.h> | #include <Morse.h> | ||
Строка 235: | Строка 235: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Как видите, этот скетч имеет пару отличий от старой версии (не считая того факта, что некоторый код переместился в саму библиотеку). | Как видите, этот [[скетч]] имеет пару отличий от старой версии (не считая того факта, что некоторый код переместился в саму библиотеку). | ||
Сначала в самом верху | Сначала в самом верху [[скетч]]а добавляется директива [[Arduino:Справочник языка Arduino/Синтаксис/include|#include]]. Благодаря этому скетч получает доступ к библиотеке Morse, а сама библиотека подключается к коду, который отправляется на плату. Таким образом, если вам в этом [[скетч]]е больше не понадобится библиотека Morse, удалите директиву [[Arduino:Справочник языка Arduino/Синтаксис/include|#include]] – чтобы сэкономить программную память. | ||
Во-вторых, создаем экземпляр класса ''' | Во-вторых, создаем экземпляр класса Morse и называем его '''morse''': | ||
<syntaxhighlight lang="c | <syntaxhighlight lang="c"> | ||
Morse morse(13); | Morse morse(13); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
При обработке этой строки – а это происходит до обработки функции [[Arduino:Справочник языка Arduino/setup()|setup()]] – вызывается конструктор для класса | При обработке этой строки – а это происходит до обработки функции [[Arduino:Справочник языка Arduino/setup()|setup()]] – вызывается конструктор для класса Morse, после чего ему передается аргумент в виде числа «13». | ||
Обратите внимание, что блок [[Arduino:Справочник языка Arduino/setup()|setup()]] пуст, потому что вызов [[Arduino:Справочник языка Arduino/Функции/Цифровой ввод/вывод/pinMode()|pinMode()]] теперь происходит внутри библиотеки (при создании экземпляра класса). | Обратите внимание, что блок [[Arduino:Справочник языка Arduino/setup()|setup()]] пуст, потому что вызов [[Arduino:Справочник языка Arduino/Функции/Цифровой ввод/вывод/pinMode()|pinMode()]] теперь происходит внутри библиотеки (при создании экземпляра класса). | ||
Наконец, чтобы вызвать функции '''dot()''' и '''dash()''', нужно подставить к ним префикс '''morse'''. Это название экземпляра класса, которое мы хотим использовать. Мы можем использовать несколько экземпляров класса | Наконец, чтобы вызвать функции '''dot()''' и '''dash()''', нужно подставить к ним префикс '''morse'''. Это название экземпляра класса, которое мы хотим использовать. Мы можем использовать несколько экземпляров класса Morse – каждый со своим контактом, хранящимся в приватной переменной '''_pin'''. Таким образом, при вызове функции, использующей какой-либо из этих экземпляров, будет использоваться переменная, указанная при создании этого экземпляра. Например, если воспользоваться двумя экземплярами класса Morse... | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
Morse morse(13); | Morse morse(13); | ||
Morse morse2(12); | Morse morse2(12); | ||
Строка 258: | Строка 258: | ||
...то внутри '''morse2.dot()''' приватной переменной '''_pin''' будет '''«12»'''. | ...то внутри '''morse2.dot()''' приватной переменной '''_pin''' будет '''«12»'''. | ||
Если вы попытаетесь написать новый скетч, то | Если вы попытаетесь написать новый скетч, то [[IDE Arduino]], возможно, не распознает ничего из вашей новой библиотеки, окрасив неизвестные конструкции цветными полосками. К сожалению, [[IDE Arduino]] не умеет автоматически распознавать, что именно вы задали в своей библиотеке (хотя такая функция очень пригодилась бы), поэтому ей нужно немножко помочь. Для этого в папке «Morse» нужно создать специальный файл «keywords.txt». Его содержимое должно выглядеть следующим образом: | ||
<syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS | <syntaxhighlight lang="c" line="GESHI_NORMAL_LINE_NUMBERS|GESHI_FANCY_LINE_NUMBERS"> | ||
Morse KEYWORD1 | Morse KEYWORD1 | ||
dash KEYWORD2 | dash KEYWORD2 | ||
Строка 266: | Строка 266: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Здесь каждая строчка начинается с ключевого слова, после чего идет {{клавиша|Tab}}(не пробелы) и тип ключевого слова. Классы – это '''KEYWORD1''' и окрашиваются в оранжевый; функции – это '''KEYWORD2''' и окрашиваются в коричневый. Чтобы | Здесь каждая строчка начинается с ключевого слова, после чего идет {{клавиша|Tab}}(не пробелы) и тип ключевого слова. Классы – это '''KEYWORD1''' и окрашиваются в оранжевый; функции – это '''KEYWORD2''' и окрашиваются в коричневый. Чтобы [[IDE Arduino]] начала распознавать новые ключевые слова, ее нужно перезапустить. | ||
Также будет полезно снабдить вашу библиотеку скетчем-примером, который демонстрирует, как ее использовать. Для этого создайте внутри папки | Также будет полезно снабдить вашу библиотеку скетчем-примером, который демонстрирует, как ее использовать. Для этого создайте внутри папки «Morse» папку «examples». Затем переместите или скопируйте папку со [[скетч]]ем (можно назвать ее «SOS»), который мы написали выше, в папку «examples». Чтобы найти скетч, в данный момент загруженный в [[IDE Arduino]], кликните на '''Скетч > Показать папку скетча'''. Далее перезапускаем [[IDE Arduino]] (обещаю, это в последний раз!), кликаем на '''Файл > Примеры;''' откроется выпадающий список, в котором должен быть пункт «Library-Morse». Также имеет смысл добавить пару комментариев, объясняющих, как использовать вашу библиотеку. | ||
Если вы хотите сами опробовать библиотеку, создание которой объяснялось в этой статье (в комплекте с ключевыми словами и скетчем-примером), то загрузить ее можно [[Media:Morse.zip|здесь]]. | Если вы хотите сами опробовать библиотеку, создание которой объяснялось в этой статье (в комплекте с ключевыми словами и скетчем-примером), то загрузить ее можно [[Media:Morse.zip|здесь]]. |
Версия от 08:16, 15 мая 2022
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Черновик |
Написание библиотеки[1]
Эта статья объясняет, как создать собственную библиотеку для Arduino. Объяснение будет на примере кода, позволяющего моргать азбукой Морзе на светодиодах Arduino. Далее будет показано, как конвертировать этот код в библиотеку. Это позволит другим пользователям без особого труда использовать и обновлять написанный вами код.
Более подробно читайте в этом руководстве – оно объясняет, как написать хороший API в стиле Arduino для вашей библиотеки.
Начнем со скетча, который выполняет простой код с азбукой Морзе:
int pin = 13;
void setup()
{
pinMode(pin, OUTPUT);
}
void loop()
{
dot(); dot(); dot();
dash(); dash(); dash();
dot(); dot(); dot();
delay(3000);
}
void dot()
{
digitalWrite(pin, HIGH);
delay(250);
digitalWrite(pin, LOW);
delay(250);
}
void dash()
{
digitalWrite(pin, HIGH);
delay(1000);
digitalWrite(pin, LOW);
delay(250);
}
Если запустить этот скетч, он «напечатает» на 13-ом контакте «SOS» (сигнал бедствия).
Этот скетч состоит из нескольких частей, которые нужно перенести в библиотеку. Во-первых, у нас есть функции dot() и dash(), которые, собственно, и выполняют мигание. Во-вторых, там есть переменная ledPin, которую эти функции используют, чтобы узнать, на каком именно контакте нужно выполнить мигание. Наконец, в скетче вызывается функция pinMode(), которая выставляет контакт в режим OUTPUT.
Итак, приступим к превращению скетча в библиотеку!
Для библиотеки понадобится как минимум два файла: заголовочный файл (с расширением «*.h») и файл-исходник (с расширением «*.cpp»). Заголовочный файл содержит эдакий список основных понятий, т.е. список всего, что находится внутри библиотеки. Сам код находится внутри файла-исходника. Мы даем нашей библиотеке название «Morse», поэтому наш заголовочный файл будет называется «Morse.h».
Давайте-ка взглянем, что у него внутри. На первый взгляд, его содержимое может показаться странным, но вы все поймете, когда мы заглянем внутрь файла-исходника.
«Сердцевина» заголовочного файла состоит из списка функций и необходимых переменных (одна строчка/переменная – одна функция), «обернутых» в класс:
class Morse
{
public:
Morse(int pin);
void dot();
void dash();
private:
int _pin;
};
Класс – это просто коллекция функций и переменных, хранящихся в одном месте. Эти функции и переменные могут быть public («публичными», могут употребляться внутри любой функции) или private («приватными», могут употребляться лишь внутри самого класса). У каждого класса есть специальная функция-конструктор, которая используется для создания экземпляра класса. Конструктор имеет то же имя, что и класс, но ничего не возвращает.
Содержимое заголовочного файла на этом, впрочем, не заканчивается. Во-первых, вам нужно вписать туда директиву #include, дающую доступ к стандартным типам и константам языка Arduino (она автоматически добавляется к обычным скетчам, но не к библиотекам). Это выглядит примерно так (и ставится выше блока с классом, о котором писалось выше):
#include "Arduino.h"
Во-вторых, весь заголовочный файл нужно «обернуть» в одну очень странную конструкцию:
#ifndef Morse_h
#define Morse_h
// директива #include и код пишутся тут...
#endif
Это призвано предотвратить проблемы, которые могут возникнуть, если кто-то случайно подключит (#include) вашу библиотеку дважды.
Наконец, в верхней части заголовочного файла пишется комментарий с названием библиотеки, кратким описанием того, что она делает, автором, датой и лицензией.
Давайте взглянем, как заголовочный файл будет выглядеть полностью:
/*
Morse.h – Библиотека для азбуки Морзе на светодиодах.
Создана Дэвидом А. Меллисом (David A. Mellis)
2 ноября 2007 года.
Опубликована без защиты авторских прав.
*/
#ifndef Morse_h
#define Morse_h
#include "Arduino.h"
class Morse
{
public:
Morse(int pin);
void dot();
void dash();
private:
int _pin;
};
#endif
Теперь давайте пробежимся по разным фрагментам файла-исходника – «Morse.cpp».
Сначала идут две директивы #include. Они дают остальному коду доступ к стандартным функциям языка Arduino, а также к понятиям, указанным в «Morse.h»:
#include "Arduino.h"
#include "Morse.h"
Затем идет конструктор. Опять же, он объясняет, что должно произойти, если кто-то создаст экземпляр вашего класса. В данном случае пользователь должен указать, какой контакт он будет использовать. Мы выставляем этот контакт в режим OUTPUT и сохраняем в приватную переменную для использования в других функциях:
Morse::Morse(int pin)
{
pinMode(pin, OUTPUT);
_pin = pin;
}
Далее идет пара странных вещей. Сначала
Morse::
перед названием функции. Это значит, что эта функция является частью класса Morse. Вы увидите такой фрагмент и при указании других функций этого класса.
Вторая непонятная вещь – это нижнее подчеркивание при написании приватной переменной, _pin. По сути, эту переменную можно назвать как угодно – до тех пор, пока она соответствует определению, указанному в заголовочном файле. Добавление нижнего подчеркивания перед названием переменной – это общепринятый способ показать, что эта переменная является приватной, а также отличить ее от аргумента функции (в данном случае – pin).
Дальше идет, собственно, сам код из скетча, который мы превращаем в библиотеку (наконец-то!). Он выглядит примерно так же, как в скетче, за исключением
Morse::
, стоящим перед названиями функций, а также _pin вместо pin.
void Morse::dot()
{
digitalWrite(_pin, HIGH);
delay(250);
digitalWrite(_pin, LOW);
delay(250);
}
void Morse::dash()
{
digitalWrite(_pin, HIGH);
delay(1000);
digitalWrite(_pin, LOW);
delay(250);
}
Наконец, пишем в верхней части файла-исходника заголовочный комментарий. И давайте взглянем, что получилось:
/*
Morse.cpp – Библиотека для азбуки Морзе на светодиодах.
Создана Дэвидом А. Меллисом (David A. Mellis) 2 ноября 2007 года.
Выпущена без защиты авторских прав.
*/
#include "Arduino.h"
#include "Morse.h"
Morse::Morse(int pin)
{
pinMode(pin, OUTPUT);
_pin = pin;
}
void Morse::dot()
{
digitalWrite(_pin, HIGH);
delay(250);
digitalWrite(_pin, LOW);
delay(250);
}
void Morse::dash()
{
digitalWrite(_pin, HIGH);
delay(1000);
digitalWrite(_pin, LOW);
delay(250);
}
По сути, это все, что нужно (но есть пара дополнений, о которых мы поговорим чуть позже).
Теперь давайте рассмотрим, как использовать эту библиотеку. Сначала идем в папку «libraries», которая находится в папке скетчей (расположение папки скетчей можно узнать, кликнув в IDE Arduino на Файл > Настройки; откроется окно, в самой верхней части которого будет поле «Размещение папки скетчей») и создаем там папку «Morse». Затем копируем в эту папку файлы «Morse.h» и «Morse.cpp». Теперь запускаем IDE Arduino и кликаем по Скетч > Подключить библиотеку. Откроется выпадающее меню со списком загруженных библиотек, и в их числе уже должна быть наша Morse. Библиотека будет скомпилирована вместе со скетчами, которые ее используют. Если библиотеки не видно, то убедитесь, что скопированные вами файлы действительно имеют расширения «*.h» и «*.cpp» (то есть, к примеру, без дополнительных «*.pde» или «*.txt»).
Теперь давайте посмотрим, как можно воспроизвести наш старый скетч «SOS» при помощи новой библиотеки:
#include <Morse.h>
Morse morse(13);
void setup()
{
}
void loop()
{
morse.dot(); morse.dot(); morse.dot();
morse.dash(); morse.dash(); morse.dash();
morse.dot(); morse.dot(); morse.dot();
delay(3000);
}
Как видите, этот скетч имеет пару отличий от старой версии (не считая того факта, что некоторый код переместился в саму библиотеку).
Сначала в самом верху скетча добавляется директива #include. Благодаря этому скетч получает доступ к библиотеке Morse, а сама библиотека подключается к коду, который отправляется на плату. Таким образом, если вам в этом скетче больше не понадобится библиотека Morse, удалите директиву #include – чтобы сэкономить программную память.
Во-вторых, создаем экземпляр класса Morse и называем его morse:
Morse morse(13);
При обработке этой строки – а это происходит до обработки функции setup() – вызывается конструктор для класса Morse, после чего ему передается аргумент в виде числа «13».
Обратите внимание, что блок setup() пуст, потому что вызов pinMode() теперь происходит внутри библиотеки (при создании экземпляра класса).
Наконец, чтобы вызвать функции dot() и dash(), нужно подставить к ним префикс morse. Это название экземпляра класса, которое мы хотим использовать. Мы можем использовать несколько экземпляров класса Morse – каждый со своим контактом, хранящимся в приватной переменной _pin. Таким образом, при вызове функции, использующей какой-либо из этих экземпляров, будет использоваться переменная, указанная при создании этого экземпляра. Например, если воспользоваться двумя экземплярами класса Morse...
Morse morse(13);
Morse morse2(12);
...то внутри morse2.dot() приватной переменной _pin будет «12».
Если вы попытаетесь написать новый скетч, то IDE Arduino, возможно, не распознает ничего из вашей новой библиотеки, окрасив неизвестные конструкции цветными полосками. К сожалению, IDE Arduino не умеет автоматически распознавать, что именно вы задали в своей библиотеке (хотя такая функция очень пригодилась бы), поэтому ей нужно немножко помочь. Для этого в папке «Morse» нужно создать специальный файл «keywords.txt». Его содержимое должно выглядеть следующим образом:
Morse KEYWORD1
dash KEYWORD2
dot KEYWORD2
Здесь каждая строчка начинается с ключевого слова, после чего идет Tab ⇆ (не пробелы) и тип ключевого слова. Классы – это KEYWORD1 и окрашиваются в оранжевый; функции – это KEYWORD2 и окрашиваются в коричневый. Чтобы IDE Arduino начала распознавать новые ключевые слова, ее нужно перезапустить.
Также будет полезно снабдить вашу библиотеку скетчем-примером, который демонстрирует, как ее использовать. Для этого создайте внутри папки «Morse» папку «examples». Затем переместите или скопируйте папку со скетчем (можно назвать ее «SOS»), который мы написали выше, в папку «examples». Чтобы найти скетч, в данный момент загруженный в IDE Arduino, кликните на Скетч > Показать папку скетча. Далее перезапускаем IDE Arduino (обещаю, это в последний раз!), кликаем на Файл > Примеры; откроется выпадающий список, в котором должен быть пункт «Library-Morse». Также имеет смысл добавить пару комментариев, объясняющих, как использовать вашу библиотеку.
Если вы хотите сами опробовать библиотеку, создание которой объяснялось в этой статье (в комплекте с ключевыми словами и скетчем-примером), то загрузить ее можно здесь.
На этом все, но в будущем, возможно, мы напишем более подробное руководство по написанию библиотек. Если у вас возникли какие-то проблемы или пожелания, поделиться ими можно на форуме.
Дополнительную информацию читайте в руководстве по написанию API для Arduino.
См.также
Внешние ссылки
Arduino продукты | |
---|---|
Начальный уровень | Arduino Uno • Arduino Leonardo • Arduino 101 • Arduino Robot • Arduino Esplora • Arduino Micro • Arduino Nano • Arduino Mini • Arduino Starter Kit • Arduino Basic Kit • MKR2UNO • TFT-дисплей Arduino |
Продвинутые функции | Arduino Mega 2560 • Arduino Zero • Arduino Due • Arduino Mega ADK • Arduino Pro • Arduino Motor Shield • Arduino USB Host Shield • Arduino Proto Shield • MKR Proto Shield • MKR Proto Large Shield • Arduino ISP • Arduino USB 2 Serial Micro • Arduino Mini USB Serial Adapter |
Интернет вещей | Arduino Yun • Arduino Ethernet • Arduino MKR1000 • Arduino WiFi 101 Shield • Arduino GSM Shield V2 • Arduino WiFi Shield • Arduino Wireless SD Shield • Arduino Wireless Proto Shield • Arduino Ethernet Shield V2 • Arduino Yun Shield • Arduino MKR1000 Bundle |
Носимые устройства | Arduino Gemma • Lilypad Arduino Simple • Lilypad Arduino Main Board • Lilypad Arduino USB • LilyPad Arduino SimpleSnap |
3D-печать | Arduino Materia 101 |
Устаревшие устройства | - |
Примеры Arduino | |
---|---|
Стандартные функции | |
Основы |
|
Цифровой сигнал |
|
Аналоговый сигнал |
|
Связь |
|
Управляющие структуры |
|
Датчики |
|
Дисплей |
Примеры, объясняющие основы управления дисплеем:
|
Строки |
|
USB (для Leonardo, Micro и Due плат) |
В этой секции имеют место примеры, которые демонстрируют использование библиотек, уникальных для плат Leonardo, Micro и Due.
|
Клавиатура |
|
Мышь |
|
Разное |
- Страницы, использующие повторяющиеся аргументы в вызовах шаблонов
- Справочник языка Arduino
- Arduino
- Перевод от Сubewriter
- Проверка:myagkij
- Оформление:myagkij
- Редактирование:myagkij
- Черновик
- Надо доработать
- Черновой вариант статьи
- Черновой вариант
- Страницы, где используется шаблон "Навигационная таблица/Телепорт"
- Страницы с телепортом
- Хакинг
- Хакинг Arduino