Перейти к содержимому

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

  • автор:

Справочник по C#

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

Ключевые слова в C#
Ссылки на сведения о ключевых словах и синтаксисе языка C#.

Операторы в C#
Ссылки на сведения об операторах и синтаксисе языка C#.

Специальные символы в C#
Предоставляет ссылки на сведения о специальных контекстные символов в C# и их использовании.

Директивы препроцессора C#
Ссылки на сведения о командах компилятора для внедрения в исходном коде C#.

Параметры компилятора C#
Сведения о параметрах компилятора и их использовании.

Ошибки компилятора C#
Фрагменты кода, демонстрирующие причины и способы исправления ошибок и предупреждений компилятора C#.

Спецификация языка C#
Спецификация языка C# версии 6.0 Это черновой вариант для языка C# версии 6.0. Этот документ будет пересмотрен в рамках работы с комитетом по стандартам C# ECMA. Версия 5.0 была выпущена в декабре 2017 г. как стандартный 5-й выпуск ECMA-334.

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

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

Предложения по спецификации C# 7.1
В версию C# 7.1 добавлено несколько новых возможностей. Можно написать метод Main , возвращающий Task или Task . Это позволяет добавлять модификатор async в метод Main . Выражение default можно использовать без типа в тех расположениях, где возможен вывод типа. Кроме того, появилось еще одно дополнительное усовершенствование: вывод имен элементов кортежа. И, наконец, сопоставление шаблонов можно использовать с универсальными шаблонами.

Предложения по спецификации C# 7.2
В версию C#7.2 добавлен ряд простых функций. С помощью ключевого слова in можно передавать аргументы по ссылке только для чтения. Внесен ряд незначительных изменений для поддержки безопасности во время компиляции для Span и связанных типов. В некоторых ситуациях можно использовать именованные аргументы, если следующие за ними аргументы являются позиционными. Модификатор доступа private protected позволяет указывать, что вызывающие объекты ограничены производными типами, реализованными в той же сборке. Оператор ?: можно использовать для разрешения в ссылку на переменную. С помощью разделителя начальных цифр можно форматировать шестнадцатеричные и двоичные числа.

Предложения по спецификации C# 7.3
Версия C# 7.3 является очередным промежуточным выпуском, содержащим несколько небольших обновлений. К параметрам универсальных типов можно применять новые ограничения. Другие изменения упрощают работу с полями fixed , включая использование выделений stackalloc . Локальные переменные, объявленные с ключевым словом ref , можно переназначать для указания на новое хранилище. Можно применять атрибуты к автоматически реализуемым свойствам, предназначенным для созданного компилятором резервного поля. Переменные выражений можно использовать в инициализаторах. Кортежи можно проверять на равенство (или неравенство). Кроме того, были внесены некоторые улучшения в разрешение перегрузки.

Предложения по спецификации C# 8.0
Версия C# 8.0 доступна для .NET Core 3.0. В число возможностей входят использование ссылочных типов, допускающих значения NULL, рекурсивное сопоставление шаблонов, методы интерфейса по умолчанию, асинхронные потоки, диапазоны и индексы, использование шаблонов и объявлений using, назначение объединения со значением NULL и члены экземпляров с доступом только на чтение.

Предложения по спецификации C# 9
Версия C# 9 доступна для .NET 5. Предлагаемые функции включают записи, инструкции верхнего уровня, усовершенствованное сопоставление шаблонов, методы задания только для инициализации, выражения new с целевым типом, модульные инициализаторы, расширение методов partial, статические анонимные функции, условные выражения с целевым типом, ковариантные типы возвращаемого значения, метод расширения GetEnumerator в циклах foreach, пустые переменные в качестве параметров лямбда-выражений, атрибуты для локальных функций, целочисленные значения с системным размером, указатели на функцию, подавляемое порождение флага localsinit и аннотации для параметров неограниченного типа.

Предложения по спецификации C# 10
Версия C# 10 доступна для .NET 6. Предлагаемые функции включают структуры записи, конструкторы структур без параметров, глобальные директивы «using», пространства имен на уровне файлов, шаблоны расширенных свойств, улучшенные интерполированные строки, постоянные интерполированные строки, улучшения функции лямбда, поддержку атрибута сведений о вызывающем выражении аргумента, расширенные директивы #line , универсальные атрибуты, улучшенный анализ определенного присваивания и переопределение AsyncMethodBuilder .

Связанные разделы

Использование среды разработки Visual Studio для C#
Ссылки на концептуальные разделы и разделы задач, описывающие интегрированную среду разработки и редактор.

Руководство по программированию на C#
Сведения об использовании языка программирования C#.

Вычисление каналов

Можно воспользоваться эффектами наложения, связанными со слоями, для совмещения каналов в новых изображениях. Также можно воспользоваться командой «Внешний канал» (для одного или совмещенного каналов) либо командой «Вычисления» (для одиночных каналов). Эти команды обеспечивают два дополнительных режима наложения, которые недоступны из панели «Слои», — «Сложение» и «Вычитание». Несмотря на то что можно создавать новые сочетания каналов, копируя каналы в слои панели «Слои», быстрее будет воспользоваться командами-вычислениями для наложения данных каналов.

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

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

Наложение каналов при помощи команды «Внешний канал»

Команда «Внешний канал» позволяет накладывать слой и канал одного изображения (источника) на слой и канал активного изображения (места назначения).

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

Примечание.

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

Выберите меню «Изображение» > «Внешний канал».

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

Для просмотра результатов в окне изображения установите флажок «Просмотр».

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

В меню «Наложение» выберите параметр наложения.

Дополнительные сведения о параметрах «Сложение» и «Вычитание» см. в разделе Режимы наложения «Сложение» и «Вычитание». Информацию о других параметрах наложения см. в разделе Описание режимов наложения.

Введите значение «Непрозрачность» для определения силы эффекта.

Чтобы применить изменения только к непрозрачным областям итогового слоя, выберите параметр «Сохранить прозрачность».

Чтобы применить наложение через маску, установите флажок «Маска». Затем выберите изображение и содержащий маску слой. Для поля «Канал» в качестве маски можно выбрать любой цвет либо альфа-канал. Можно также воспользоваться маской, созданной на основе активного выделения или границ выбранного слоя («Прозрачность»). Установите флажок «Инверсия», чтобы поменять местами маскированные и немаскированные области канала.

Наложение каналов при помощи команды «Вычисления»

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

Откройте исходное изображение или несколько изображений.
Примечание.

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

Выберите меню «Изображение» > «Вычисления».
Для просмотра результатов в окне изображения установите флажок «Просмотр».

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

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

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

Дополнительные сведения о параметрах «Сложение» и «Вычитание» см. в разделе Режимы наложения «Сложение» и «Вычитание». Информацию о других параметрах наложения см. в разделе Описание режимов наложения.

Введите значение «Непрозрачность» для определения силы эффекта.

Чтобы применить наложение через маску, установите флажок «Маска». Затем выберите изображение и содержащий маску слой. Для поля «Канал» в качестве маски можно выбрать любой цвет либо альфа-канал. Можно также воспользоваться маской, созданной на основе активного выделения или границ выбранного слоя («Прозрачность»). Установите флажок «Инверсия», чтобы поменять местами маскированные и немаскированные области канала.

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

Режимы наложения «Добавить» и «Вычитание»

Режимы наложения «Добавление» и «Вычитание» доступны только для команд «Внешний канал» и «Вычисления».

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

Так как более высокое значение пикселов означает более светлые цвета, сложение каналов с пересекающимися пикселами будет высветлять изображение. Черные области обоих каналов останутся черными (0 + 0 = 0). Белые области обоих каналов останутся белыми (255 + любое значение = 255 или больше).

Режим «Сложение» делит сумму значений пикселов на величину «Масштаб», а затем прибавляет значение параметра «Сдвиг» к сумме. Например, чтобы найти среднее значение пикселов в двух каналах, сложите их, разделите на 2 и не вводите значения параметра «Сдвиг».

Параметр «Масштаб» может быть любым числом от 1,000 до 2,000. При вводе более высокого значения параметра «Масштаб» изображение становится более темным.

Параметр «Сдвиг» позволяет делать пикселы более яркими или более темными в конечном канале, изменяя значение яркости от +255 до –255. Отрицательные значения затемняют изображение, положительные значения высветляют изображение.

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

Параметр «Масштаб» может быть любым числом от 1,000 до 2,000. Значение параметра «Сдвиг» позволяет делать пиксели более яркими или более темными в конечном канале, изменяя значение яркости от +255 до –255.

Лекция №1 — Основы работы в математическом пакете Mathcad

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

  • Использоваться как калькулятор для простых вычислений.
  • Определять значения выражений, заданных в символьном виде.
  • Производить матричные и векторные преобразования.
  • Решать линейные, нелинейные уравнения и системы уравнений.
  • Заменять справочные таблицы.
  • Производить дифференцирование, интегрирование, статистические расчеты и анализ данных.
  • Строить двумерные и трехмерные графики и т.п.

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

После запуска приложения MathCAD открывается окно, как это показано на рис. 1.1.

Главное окно оформлено стандартным для Windows-приложений образом: заголовок, главное меню, панель инструментов, окно редактирования, строка состояния.

Рис. 1.1. Рабочее окно системы MathCAD

1.1. Основные команда MathCad

Главное меню системы MathCAD представлено набором команд, общим для большинства приложений операционной системы MS Windows, а также командами, представляющими специфические возможности:

  • Меню File (Файл) — работа с файлами.
  • Меню Edit (Правка) — редактирование документов.
  • Меню View (Вид) — настройка элементов окна. Команды меню View представлены на рис. 1.2.

ToolBars – содержит кнопки панелей инструментовStandard, Formatting, Math. Если отсутствует какая-либо из панелей, то следует включить соответствующую опцию, например, командой ViewToolbarsMath.

Status Bar – позволяет включать и отключать отображение строки состояния.

Ruler – позволяет включать и отключать отображение горизонтальной линейки для точного позиционирования документов на листе.

Regions – делает видимыми/невидимыми границы областей.

Zoom – изменение масштаба.

Refresh – обновить содержимое экрана.

Animate – анимация.

PlayBack – воспроизведение.

Preferences – настройки.

Рис. 1.2. Команды меню View (Вид) – редактирование документов

  • Меню Insert (Вставка) — позволяет помещать в MathCAD – документ графики, функции, матрицы, гиперссылки, компоненты и настраивать объекты.
  • Меню Format (Формат) — содержит команды, предназначенные для задания различных параметров, определяющих внешнее представление чисел, формул, текста, абзацев, колонтитулов и т.д.
  • Меню Math (Математика) — позволяет установить режимы и параметры вычислений.
  • Меню Symbolics (Символы) — реализует символьные вычисления.
  • Меню Window (Окно) — содержит команды для упорядочения взаимного расположения нескольких окон и позволяет активизировать одно из них.
  • Меню Help (Помощь) — информационный центр и справочники. Команда Help открывает окно, представленное на рис. 5.3. На вкладке «Содержание» справочные сведения распределены по темам. На вкладке «Указатель» темы представлены в алфавитном порядке. Вкладка «Поиск» позволяет находить конкретное понятие.

Рис. 1.3. Окно меню справки

1.2. Кнопки панели Math

Одна из сильных сторон MathCAD – это представление и ввод математических символов и выражений в привычной для человека форме. Это обеспечивается развитым графическим интерфейсом и инструментами, располагающимися на панелях инструментов приложения MathCAD (Math, Graph …). Открыть соответствующую панель инструментов можно с помощью команды главного меню ViewToolbars. Для удобства работы ссылки на них объединены на панели Math.

На панели Math расположены 9 кнопок. Каждая из кнопок, в свою очередь, открывает панели инструментов специального назначения. Это следующие кнопки (в развернутом виде эти панели представлены на рис. 5.4):

  • Calculator (Калькулятор). На этой панели находятся кнопки для задания математических операций, а также некоторых часто используемых функций. Эту кнопку можно использовать как калькулятор.
  • Boolean (Булева) – для ввода операторов сравнения и логических операций.
  • Evaluation (Вычисление) – содержит кнопки для ввода операторов присвоения значений переменных и функций.
  • Graph (Графика) – инструменты для построения графика.
  • VectorandMatrix (Векторы и Матрицы) – инструменты для работы с векторами и матрицами.
  • Calculus (Исчисление) – представляет математические выражения с элементами интегрирования, дифференцирования в привычном виде. Кнопки этой панели позволяют вычислять значения пределов, сумм, произведений.
  • Programming (Программирование) – инструменты для написания программ.
  • GreakSymbol (Греческий алфавит).
  • Symbolic (Символы) – для символьных вычислений.

Рис. 1.4. Рабочее окно системы MathCAD с развернутыми панелями инструментов панели Math

1.3. Запись команд в рабочем документе системы MathCad

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

MathCAD реализует вычисления в строго определенном порядке, как это делает человек: читая страницу книги, т.е. слева направо и сверху вниз. Правильный порядок выполнения блоков — основа правильного функционирования системы при обработке документа. Например, если в некотором блоке содержатся операции, требующие данных из другого блока, то этот «другой» блок обязательно должен выполняться первым и располагаться перед использующим его блоком. Иначе ошибка. Сигнал ошибки в системе имеет вид всплывающей надписи, заключенной в прямоугольник.

1.4. Используемые типы констант

В системе MathCAD предусмотрены следующие типы данных:

  1. Целые ( 2, –543, +13).
  2. Вещественные (1.876, –375.08).
  3. Комплексные (2.5+3i). Следует иметь в виду, что при записи мнимой единицы следует использовать специальную кнопку панели Calculator.
  4. Строковые. Обычно это комментарий «Вычисление суммы».
  5. Системные. Системная константа – это предварительно определенная переменная, значение которой задается в начале загрузки системы. Примерами таких констант являются числа e или .

1.5. Простые вычисления

Результат арифметического выражения отображается, если после него стоит знак «=» или знак «». В первом случае результат представляется в численном виде, а во втором – в символьном. Например, если записать арифметическое выражение в виде:

то в результате будем иметь: 123 + 256 = 379.

Пример символьного вычисления:

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

  • извлечения корня;
  • возведения в степень;
  • интегрирования и дифференцирования;
  • знаков факториала и суммирования и т.д.

Часть из этих операций можно «взять» на панели Calculator (Калькулятор). Примером записи выражения может быть:

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

Если набрать выражение=, то в окне документа будет отображено значение этой константы в виде: =3.141592.

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

Рис. 1.5. Рабочее окно команды главного меню Format (формат Result )

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

После знака «» отображен результат символьного вычисления. Для замены результата символьного вычисления численным значением применена команда float, расположенная на панели Symbolic. Эта команда предоставляет шаблон, в котором пользователю предлагается задать количество знаков (цифр) для отображения результата.

1.6. Использование встроенных функций

Важным понятием в математике является функция, т.е. некоторая зависимость одной переменной от другой или ряда других переменных и констант. В системе MathCAD имеется множество встроенных функций. Для избегания возможных ошибок не рекомендуется имя функции вводить с клавиатуры. Наиболее часто используемые функции, такие как: sin,cos, ln,… можно задать, используя их обозначение на панели инструментов Calculator. К другим функциям можно обратиться с помощью команды главного меню Insert (вставка функции), либо с помощью команды (кнопки) f(x). В окне, которое предоставляет команда (рис. 5.6), пользователь может установить категорию функции, познакомиться с примером ее записи и спецификацией (описанием), а затем произвести нужный выбор. После этого система предоставляет пользователю шаблон, в который требуется вписать необходимые параметры.

Рис. 1.6. Рабочее окно команды вставка функции: InsertFunction

Особенностью функции является возврат значения, т.е. функция в ответ на обращение к ней по имени с указанием её аргументов должна возвратить свое значение. Например, если где-то используется функция sin(0.452·), то вместо нее будет подставлено число, равное значению синуса с аргументом, равным значению выражения 0.452·.

1.7. Определение переменных и пользовательских функций

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

1.8. Локальные и глобальные переменные

Как и в других языках программирования в MathCAD различают локальные и глобальные переменные. Присваивание локальным переменным своего значения в системе MathCAD реализуют с помощью знака «:=». Для этого достаточно ввести знак двоеточие. Если ввести «X:5» то на экране появится «X:=5» (т.е. переменной X присваивается значение 5).

X := 1

sin(X) = 0.841

X := 1

Y := sin(X)

Y= 0.841

Глобальная переменная вводится следующим образом: “переменная~выражение”. Вид, который принимает в документе введенное таким образом присваивание: “переменнаявыражение”. Отличие глобальных переменных от локальных переменных в том, что глобальные переменные могут использоваться в любом месте документа (в том числе, слева от их определения и над ним).

Пример введение глобальной переменной.

1.9. Определение и использование пользовательских функций

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

Чтобы воспользоваться собственной функцией, нужно:

  1. Описать функцию.
  2. Вызвать описанную функцию для выполнения.

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

Формат определения функции:

Имя_функции(список формальных параметров) := выражение

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

Можно поместить результат в отдельную переменную:

Имя_переменной_результата:=Имя_функции(список_фактических параметров)

Имя_функции(список_фактических параметров)=

Пример 1. Требуется определить функцию Dist, которая будет возвращать расстояние заданной точки от начала координат. Использовать эту функцию для вычисления расстояний от точек А(1.96; –3.8) и В(6; 42.5) до начала координат.

Решение. Из курса линейной алгебры известно, что расстояние от начала координат до некоторой точки A(x, y) определяется по формуле . Здесь (x, y) – координаты заданной точки. Эта формула и будет составлять основу функцию Dist. При описании функции следует предусмотреть два формальных параметра — координаты точки. На место этих параметров должны будут вписаны фактические координаты заданных точек.

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

Во втором случае результат помещается во вспомогательную переменную.

Пример 2. Дана функция вида: . Требуется найти ее максимальное и минимальные значения.

Решение. Для решения поставленной задачи целесообразно воспользоваться функцией поиска максимального значенияmaximize(f, var1, var2, . ), которая имеется в библиотеке стандартных функций системы MathCAD. Первым параметром у этой функции должно быть имя пользовательской функции, максимальные значения которой требуется найти. Следующие параметры задают имена переменных, в которых будут помещены искомые значения. В нашем случае это будет одна переменная х. Чтобы воспользоваться этой функцией, необходимо поставить перед ней блок решения с ключевым словом Given (Дано). Кроме этого итерационный алгоритм, обеспечивающий решение поставленной перед функцией maximize задачи, требует задания начальных значений искомого аргумента. Установку начальных значений следует произвести до блока решения. Аналогичное описание у функции minimize которая предназначена для поиска минимального значения определенной функции. Фрагмент с решением задачи представлен на рис. 5.7.

Рис. 1.7. Поиск максимального и минимального значений заданной функции

1.10. Определение переменных, принимающих значения из заданного промежутка

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

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

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

Формат определения переменной:

Имя_переменной := начальное_значение,начальное_значение + шаг .. конечное_значение

Заметим, что при наборе знак «:=» проявляется после набора «:» , а знак «..» проявляется после набора «;».

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

Кроме этого MathCAD предоставляет возможность не задавать следующее значение, если шаг по величине совпадает со значением 1 или –1.

В этом случае формат определения переменной можно представить в виде:

Имя_переменной := начальное_значение .. конечное_значение

Пример 3. Требуется определить переменную р, принимающую значения на интервале [0, 1] с шагом 0,1.

Решение. На рис. 5.8 представлены два фрагмента с решением поставленной задачи. На рис. 5.8, а представлено решение в соответствии с форматом, принятым для определения заданной переменной. А на рис. 5.8, b – такое же определение, но с введением вспомогательных переменных для обозначения и задания границ интервала, и величины шага, необходимых для определения переменной.

Список команд Arduino

На этой странице представлен список всех (или почти всех) доступных “из коробки” команд для Arduino с кратким описанием и примерами. Часть информации взята из Гугла, в основном некоторые особенности языка, часть получена методом проб и ошибок. Полную информацию о том, как этим пользоваться, можно получить из уроков или официального reference. Также изо всех сил рекомендую вот этот онлайн справочник по C++, из него можно узнать гораздо больше о некоторых особенностях использования операторов и типов данных.

А ещё у меня есть краткий сборник всех основных Ардуино-функций для печати! Смотри в этом уроке.

Структура скетча

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

/* этот код не компилируется */
// этот код // не компилируется

Ставится в конце каждого действия

void setup() <>

Функция, содержимое которой выполняется один раз при запуске микроконтроллера. Подробнее – в этом уроке.

Функция, содержимое которой выполняется (или пытается выполняться) “по кругу” на протяжении всего времени работы МК. Подробнее – в этом уроке.

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

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

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

Директива, дающая команду препроцессору заменить указанное название на указанное значение. Чаще всего таким образом объявляют константы:

#define MOTOR_PIN 10 // пин мотора 10 #define LED_PIN 3 // пин светодиода 3

После компиляции все встречающиеся в тексте программы слова MOTOR_PIN будут заменены на цифру 10, а LED_PIN – на цифру 3. Такой способ хранения констант не использует оперативную память микроконтроллера. Также define позволяет делать т.н. макро функции. Например Ардуиновская функция sq (квадрат) является макро, который при компиляции превращается в умножение:

#define sq(x) ((x)*(x))

#if, #elif, #else, #endif

Директивы препроцессору, позволяющие включать или исключать участки кода по условию

#define TEST 1 // определяем TEST как 1 #if (TEST == 1) // если TEST 1 #define VALUE 10 // определить VALUE как 10 #elif (TEST == 0) // TEST 0 #define VALUE 20 // определить VALUE как 20 #else // если нет #define VALUE 30 // определить VALUE как 30 #endif // конец условия

При помощи условной компиляции очень удобно собирать и настраивать сложные проекты с кучей настроек и библиотек, подключаемых “по условию”. Например:

#define DEBUG 1 void setup()

Если параметру DEBUG установить 1, то будет подключена библиотека Serial, если 0 – то нет. Таким образом получаем универсальный оптимизированный проект с отладкой. Подробнее – в этом уроке.

#ifdef, #ifndef

Условные директивы препроцессору, позволяют включать или исключать участки кода по условию: ifdef – определено ли? ifndef – не определено ли? Подробнее – в этом уроке.

#define TEST // определяем TEST #ifdef TEST // если TEST определено #define VALUE 10 // определить VALUE как 10 #else // если закоммент. #define TEST #define VALUE 20 // определить VALUE как 20 #endif // конец условия

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

for (byte r = 0; r < 255; r++) < for (byte g = 255; g >-1; g--) < for (byte b = 0; b < 255; b++) < if (analogRead(0) >250) < // уйти из сравнений goto bailout; >// еще код > > > bailout: // перенеслись сюда

Оператор прерывания функции, он же оператор возврата значения из функции. Подробнее – в этом уроке

Условия (if, switch)

if, else if, else

Оператор сравнения и его друзья. Подробнее – в этом уроке.

// при выполнения одного действия <> необязательны if (a > b) c = 10; // если a больше b, то c = 10 else c = 20; // если нет, то с = 20 // вместо сравнения можно использовать лог. переменную boolean myFlag, myFlag2; if (myFlag) c = 10; // сложные условия if (myflag && myFlag2) c = 10; // если оба флага true // при выполнении двух и более <> обязательны if (myFlag) < с = 10; b = c; >else < с = 20; b = a; >byte buttonState; if (buttonState == 1) a = 10; // если buttonState 1 else if (buttonState == 2) a = 20; // если нет, но если buttonState 2 else a = 30; // если и это не верно, то вот

Укороченная запись условия: (логика) ? правда : ложь. Подробнее – в этом уроке.

int с = (a > b) ? 10 : -20; // если a > b, то с = 10. Если нет, то с = -20 boolean flag = true; Serial.println( (flag) ? ("флаг поднят") : ("флаг опущен") );

switch.. case

Оператор выбора, заменяет конструкцию с else if. Подробнее – в этом уроке.

switch (val) < case 1: // выполнить, если val == 1 break; case 2: // выполнить, если val == 2 break; default: // выполнить, если val ни 1 ни 2 // default опционален break; >

Оператор break очень важен, позволяет выйти из switch. Но можно использовать так:

switch (val) < case 1: case 2: case 3: case 4: // выполнить, если val == 1, 2, 3 или 4 break; case 5: // выполнить, если val == 5 break; >

Циклы (for, while)

Цикл – “счётчик”. for (инициализация; условие; инкремент). Подробнее – в этом уроке.

for (int i = 0; i < 10; i++) < a = i; // а примет значения от 0 до 9 на каждой итерации Serial.println(a); // вывод в порт >// для одного действия <> не нужны for (int i = 0; i < 10; i++) Serial.println(i); // вывод в порт

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

for (;;); // крутимся в цикле вечно

Цикл с предусловием. Подробнее – в этом уроке.

while (a < b) < // выполняется, пока a меньше b >

Может быть использован для создания замкнутого цикла, выход только через break или goto

while (true) < // крутимся в цикле вечно >

Цикл с постусловием. Подробнее – в этом уроке.

do < // выполняется, пока a меньше b >while (a < b);

Отличается от while тем, что гарантированно выполнится хотя бы один раз

Пропускает все оставшиеся в теле цикла действия и переходит к следующей итерации

Выходит из цикла

Операторы

Запятая ,

Запятая тоже является оператором, используется в следующих случаях:

  • Перечисление элементов в массивах (урок про массивы)
  • Перечисление аргументов в функциях (урок про функции)
  • Выполнение последовательности действий (сделать это И это)

Рассмотрим третий случай здесь:

// объявить a и b и дать им значения int a = 5, b = 10; // присвоить 3 к b // прибавить 1 к b // приравнять к a a = (b = 3, ++b); // a == 4 // объявить i и j // прибавлять i+1 и j+2 for (byte i = 0, j = 0; i < 10; i++, j += 2) < // тут i меняется от 0 до 9 // и j меняется от 0 до 18 >

Арифметические

Арифметические операторы – самые простые и понятные из всех

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

Большой урок по математическим действиям.

Сравнение и логика

  • == равенство (a == b)
  • != неравенство (a != b)
  • >= больше или равно
  • > больше
  • < меньше
  • ! логическое НЕ, отрицание. Аналог – оператор not
  • && логическое И. Аналог – оператор and
  • || логическое ИЛИ. Аналог – оператор or

Подробный урок по сравнениям и условиям.

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

  • ++ (плюс плюс) инкремент: a++ равносильно a = a + 1
  • -- (минус минус) декремент: a — равносильно a = a – 1
  • += составное сложение: a += 10 равносильно a = a + 10
  • -= составное вычитание: a -= 10 равносильно a = a – 10
  • *= составное умножение: a *= 10 равносильно a = a * 10
  • /= составное деление: a /= 10 равносильно a = a / 10
  • %= прибавить остаток от деления: a %= 10 равносильно a = a + a % 10
  • &= составное битовое И: a &= b равносильно a = a & b
  • ^= составное исключающее ИЛИ: a ^= b равносильно a = a ^ b
  • |= составное ИЛИ: a |= b равносильно a = a | b

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

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

  • & битовое И
  • >> битовый сдвиг вправо
  • ^ битовое исключающее ИЛИ (аналогичный оператор – xor)
  • | битовое ИЛИ
  • ~ битовое НЕ

По битовым операциям читай урок у меня на сайте.

Указатели и ссылки

  • & – возвращает адрес данных в памяти (адрес первого блока данных)
  • * – возвращает значение по указанному адресу
  • -> – оператор косвенного обращения к членам и методам (для указателей на структуры и классы). Является короткой записью конструкции через указатель: a->b равносильно (*a).b

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

Работа с данными

Типы данных, переменные

Переменная – элементарная ячейка для хранения данных (цифр). Переменные разных типов имеют разный “размер ячейки” и имеют разный лимит на размер числа.

Название Альт. название Вес Диапазон Особенность
boolean bool 1 байт 0 или 1, true или false Логическая переменная. bool на Arduino тоже занимает 1 байт, а не бит!
char 1 байт -128… 127 Хранит номер символа из таблицы символов ASCII
int8_t 1 байт -128… 127 Целые числа
byte uint8_t 1 байт 0… 255 Целые числа
int int16_t, short 2 байта -32 768… 32 767 Целые числа
unsigned int uint16_t, word 2 байта 0… 65 535 Целые числа
long int32_t 4 байта -2 147 483 648… 2 147 483 647 Целые числа
unsigned long uint32_t 4 байта 0… 4 294 967 295 Целые числа
float - 4 байта -3.4E+38 3.4E+38 Числа с плавающей точкой (десятичные дроби). Точность: 6-7 знаков
double - 4 байта -1.7E+308.. 1.7E+308 Для AVR то же самое, что float. А так он 8 байт
- int64_t 8 байт -(2^64)/2… (2^64)/2-1 Целые числа
- uint64_t 8 байт 2^64-1 Целые числа

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

  • wchar_t – 16 битный символ
  • char16_t – 2-х байтный char
  • char32_t – 4-х байтный char

Также есть такое понятие, как переопределение типов данных (не создавая новых типов), для этого используется ключевое слово typedef. Typedef работает следующим образом: typedef ; – создать новый тип данных на основе типа . Пример:

typedef byte color;

Создаёт тип данных под названием color, который будет абсолютно идентичен типу byte (то есть принимать 0-255). Теперь с этим типом можно создавать переменные:

color R, G, B;

Создали три переменные типа color, который тот же byte, только в профиль. Это всё!

Более подробно о переменных и данных можно почитать вот здесь.

Структуры

Структура (struct) – очень составной тип данных: совокупность разнотипных переменных, объединённых одним именем.

struct  < ; ; ; >;

Ярлык будет являться новым типом данных, и, используя этот ярлык, можно объявлять уже непосредственно саму структуру:

 ; // объявить одну структуру , ; // объявить две структуры типа  [5]; // объявить массив структур

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

struct < ; ; ; > ;
  • Обращение к члену структуры производится вот по такой схеме: . и позволяет менять или читать значение.
  • Если две структуры имеют одинаковую структуру (объявлены одним ярлыком) то можно одну структуру просто приравнять к другой, все переменные запишутся соответственно на свои места.
  • Ещё одним удобным вариантом является присваивание значения вот таким образом: = ( ) < , , >;

Более подробно про структуры читай тут.

Перечисления

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

Объявление перечисления чем-то похоже на объявление структуры:

enum , , , , >;

Таким образом мы объявили ярлык. Теперь, используя этот ярлык, можно объявить само перечисление:

Также как и у структур, можно объявить перечисление без создания ярлыка (зачем нам лишняя строчка?):

enum , , , , > ;

Созданное таким образом перечисление является переменной, которая может принимать указанные для неё , также с этими именами её можно сравнивать. Теперь самое главное: имена для программы являются числами, начиная с 0 и далее по порядку увеличиваясь на 1. В абстрактном примере выше равно 0, равно 1, равно 2, и так далее. Помимо указанных имён, перечислению можно приравнять и число напрямую, но как бы зачем.

Более подробно про перечисления читай тут.

Классы

Классы в С++ – это основной и очень мощный инструмент языка, большинство “библиотек” являются классами. Иерархия такая:

  • Класс
  • Объект
  • Свойства и методы

Класс объявляется следующим образом:

class /*имя класса*/ < private: // список свойств и методов для использования внутри класса public: // список методов доступных другим функциям и объектам программы protected: // список средств, доступных при наследовании >;

Более подробно про работу с классами читай вот в этом уроке про классы.

Массивы

Для объявления массива достаточно указать квадратные скобки после имени переменной, тип данных – любой. Более подробно про массивы читай в уроке.

// указываем количество ячеек и всё, дальше можно с ними работать int myInts[6]; // указываем содержимое ячеек, компилятор сам посчитает их количество int myPins[] = ; // указываем и то и то, количество ячеек в [ ] должно совпадать с < >или быть больше! float Sens[3] = ; // храним символы char message[6] = "hello"; // помним, что порядок ячеек начинается с нуля! myInts[0] = 10; // записать 10 в ячейку 0 массива myInts

Строки (объект String)

String – очень мощный инструмент для работы со строками, т.е. текстовыми данными. Объявить строку можно несколькими способами:

String string0 = "Hello String"; // заполняем словами в кавычках String string1 = String("lol ") + String("kek"); // сумма двух строк String string2 = String('a'); // строка из символа в одинарных кавычках String string3 = String("This is string"); // конвертируем строку в String String string4 = String(string3 + " more"); // складываем строку string3 с текстом в кавычках String string5 = String(13); // конвертируем из числа в String String string6 = String(20, DEC); // конвертируем из числа с указанием базиса (десятичный) String string7 = String(45, HEX); // конвертируем из числа с указанием базиса (16-ричный) String string8 = String(255, BIN); // конвертируем из числа с указанием базиса (двоичный) String string9 = String(5.698, 3); // из float с указанием количества знаков после запятой (тут 3) // можно формировать название из кусочков, например для работы с файлами #define NAME "speed" #define TYPE "-log" #define EXT ".txt" // при сложении достаточно указать String 1 раз для первой строки String filename = String(NAME) + TYPE + EXT; // filename будет равна speed-log.txt // доступ к элементу строки работает по такому же механизму, как массив string1[0] = "a"; // теперь вместо Hello String у нас aello String

Подробнее про строки String и массивы символов читай в этом уроке.

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

myString.charAt(index);

Возвращает элемент строки myString под номером index. Аналог – myString[index];

myString.setCharAt(index, val);

Записывает в строку myString символ val на позицию index. Аналог – myString[index] = val;

myString.compareTo(myString2);

  • Возвращает отрицательное число, если myString идёт до myString2
  • Возвращает положительное число, если myString идёт после myString2
  • Возвращает 0, если строки одинаковы

myString.concat(value);

Присоединяет value к строке (value может иметь любой численный тип данных). Возвращает true при успешном выполнении, false при ошибке. Аналог – сложение, myString + value;

myString.endsWith(myString2);

Проверяет, заканчивается ли myString символами из myString2. В случае совпадения возвращает true

startsWith()

myString.startsWith(myString2);

Проверяет, начинается ли myString символами из myString2. В случае совпадения возвращает true

myString.equals(myString2);

Возвращает true, если myString совпадает с myString2. Регистр букв важен

equalsIgnoreCase()

myString.equalsIgnoreCase (myString2);

Возвращает true, если myString совпадает с myString2. Регистр букв неважен

myString.indexOf(val);
myString.indexOf(val, from);

Ищет и возвращает номер (позицию) значения val в строке, ищет слева направо, возвращает номер первого символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.

lastIndexOf()

myString.lastIndexOf(val);
myString.lastIndexOf(val, from);

Ищет и возвращает номер (позицию) значения val в строке, ищет справа налево, возвращает номер последнего символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.

myString.length();

Возвращает длину строки в количестве символов

myString.remove(index);
myString.remove(index, count);

Удаляет из строки символы, начиная с index и до конца, либо до указанного count

myString.replace(substring1, substring2);

В строке myString заменяет последовательность символов substring1 на substring2.

String myString = "lol kek 4eburek"; // заменить чебурек на пельмень myString.replace("4eburek", "pelmen");

myString.reserve(size);

Зарезервировать в памяти количество байт size для работы со строкой

myString.c_str();

Преобразовывает строку в “СИ” формат (null-terminated string) и возвращает указатель на полученную строку

myString.trim();

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

myString.substring(from);
myString.substring(from, to);

Возвращает кусок строки, содержащейся в myString начиная с позиции from и до конца, либо до позиции to

String myString = "lol kek 4eburek"; String chebur = myString.substring(8); // строка chebur содержит в себе "4eburek"

toCharArray()

myString.toCharArray(buf, len);

Раскидывает строку в массив – буфер buf (типа char []) с начала и до длины len

myString.getBytes(buf, len);

Копирует указанное количество символов len (вплоть до unsigned int) в буфер buf (byte [])

myString.toFloat();

Возвращает содержимое строки в тип данных float

myString.toDouble();

Возвращает содержимое строки в тип данных double

myString.toInt();

Возвращает содержимое строки в тип данных int

String myString = "10500"; int val = myString.toInt(); // val теперь 10500

toLowerCase()

myString.toLowerCase();

Переводит все символы в нижний регистр. Было ААААА – станет ааааа

toUpperCase()

myString.toUpperCase();

Переводит все символы в верхний регистр. Было ааааа – станет ААААА

Спецификаторы переменных

  • const – константа, такую переменную нельзя изменить (будет ошибка). const int val = 10;
  • static – позволяет объявить локальную переменную внутри функции, и эта переменная не будет заново переобъявляться при повторном вызове функции. Эдакая локальная глобальная переменная. Почитать
  • volatile – указывает компилятору, что переменную не нужно оптимизировать, что её значение может меняться извне. Такой спецификатор должен быть применён к переменным, которые меняют своё значение в прерывании. Почитать
  • extern – указывает компилятору, что эта переменная объявлена в другом файле программы, но мы хотим пользоваться именно ей, а не создавать новую с таким же именем в этом файле программы. Позволяет читать/записывать в переменные, созданные в других файлах (библиотеках)!

Преобразование типов данных

Переменные разных типов данных могут быть преобразованы в друг друга, для этого достаточно указать нужный тип данных в скобках перед преобразуемой переменной (тип_данных)переменная . Результат вернёт переменную с новым типом данных, сам же тип данной у переменной не изменится (работает в рамках одного действия):

// переменная типа byte byte val = 10; // передаём какой-то функции, которая ожидает int sendVal( (int)val );

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

И для строк мы уже рассматривали выше

  • toInt()
  • toFloat()
  • toCharArray()

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

  • reinterpret_cast – приведение типов без проверки, непосредственное указание компилятору. Применяется только в случае полной уверенности программиста в собственных действиях. Не снимает const и volatile , применяется для приведения указателя к указателю, указателя к целому и наоборот;
  • static_cast – преобразует выражения одного статического типа в объекты и значения другого статического типа. Поддерживается преобразование численных типов, указателей и ссылок по иерархии наследования как вверх, так и вниз. Преобразование проверяется на уровне компиляции и в случае ошибки приведения типов будет выдано сообщение;
  • dynamic_cast – используется для динамического приведения типов во время выполнения. В случае неправильного приведения типов для ссылок вызывается исключительная ситуация std::bad_cast, а для указателей будет возвращен 0;
  • const_cast – самое простое приведение типов. Снимает const и volatile , то есть константность и отказ от оптимизации компилятором переменной. Это преобразование проверяется на уровне компиляции и в случае ошибки приведения типов будет выдано сообщение.

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

// переменная типа byte byte val = 10; // передаём какой-то функции, которая ожидает int sendVal( static_cast(val) );

Подробный урок по типам данных смотри тут.

“Символьные” функции

Все следующие функции принимают как аргумент символ (тип char), анализируют его и возвращают true или false в зависимости от предназначения.

  • isAlpha(thisChar) – возвращает true, если thisChar – буква
  • isAlphaNumeric(thisChar) – возвращает true, если thisChar – буква или цифра
  • isAscii(thisChar) – возвращает true, если thisChar входит в таблицу ASCII
  • isControl(thisChar) – возвращает true, если thisChar – контрольный символ
  • isDigit(thisChar) – возвращает true, если thisChar – цифра
  • isGraph(thisChar) – возвращает true, если thisChar – печатаемый знак (кроме пробела)
  • isPrintable(thisChar) – возвращает true, если thisChar – печатаемый знак (включая пробел)
  • isHexadecimalDigit(thisChar) – возвращает true, если thisChar цифра 0-9 или буква A-F
  • isPunct(thisChar) – возвращает true, если thisChar – знак пунктуации
  • isLowerCase(thisChar) – возвращает true, если thisChar – буква в нижнем регистре (маленькая)
  • isUpperCase(thisChar) – возвращает true, если thisChar – буква в верхнем регистре (большая)
  • isSpace(thisChar) – возвращает true, если thisChar – пробел
  • isWhitespace(thisChar) – возвращает true, если thisChar – форматированный пробел (formfeed (‘\f’), newline (‘\n’), carriage return (‘\r’), horizontal tab (‘\t’), and vertical tab (‘\v’))

Работа с цифрами

Целые и дробные числа

Arduino поддерживает работу с целыми числами в разных системах исчисления:

Базис Префикс Пример Особенности
2 (двоичная) B или 0b (ноль бэ) B1101001 цифры 0 и 1
8 (восьмеричная) 0 (ноль) 0175 цифры 0 – 7
10 (десятичная) нет 100500 цифры 0 – 9
16 (шестнадцатеричная) 0x (ноль икс) 0xFF21A цифры 0-9, буквы A-F

ВАЖНО! Для арифметических вычислений по умолчанию используется ячейка long (4 байта), но при умножении и делении используется int (2 байта), что может привести к непредсказуемым результатам! Если при умножении чисел результат превышает 32’768, он будет посчитан некорректно. Для исправления ситуации нужно писать (тип данных) перед умножением, что заставит МК выделить дополнительную память для вычисления (например (long)35 * 1000). Также существую модификаторы, делающие примерно то же самое.

  • u или U – перевод в формат unsigned int (от 0 до 65’535). Пример: 36000u
  • l или L – перевод в формат long (-2 147 483 648… 2 147 483 647). Пример: 325646L
  • ul или UL – перевод в формат unsigned long (от 0 до 4 294 967 295). Пример: 361341ul

Посмотрим, как это работает на практике:

long val; val = 2000000000 + 6000000; // посчитает корректно (т.к. сложение) val = 25 * 1000; // посчитает корректно (умножение, меньше 32'768) val = 35 * 1000; // посчитает НЕКОРРЕКТНО! (умножение, больше 32'768) val = (long)35 * 1000; // посчитает корректно (выделяем память (long) ) val = 35 * 1000L; // посчитает корректно (модификатор L) val = 35 * 1000u; // посчитает корректно (модификатор u) val = 70 * 1000u; // посчитает НЕКОРРЕКТНО (модификатор u, результат > 65535) val = 1000 + 35 * 10 * 100; // посчитает НЕКОРРЕКТНО! (в умножении больше 32'768) val = 1000 + 35 * 10 * 100L; // посчитает корректно! (модификатор L) val = (long)35 * 1000 + 35 * 1000; // посчитает НЕКОРРЕКТНО! Второе умножение всё портит val = (long)35 * 1000 + (long)35 * 1000; // посчитает корректно (выделяем память (long) ) val = 35 * 1000L + 35 * 1000L; // посчитает корректно (модификатор L)

Arduino поддерживает работу с числами с плавающей точкой (десятичные дроби). Этот тип данных не является для неё “родным”, поэтому вычисления с ним производятся в несколько раз дольше, чем с целочисленным типом (около 7 микросекунд на действие). Arduino поддерживает три типа ввода чисел с плавающей точкой:

Тип записи Пример Чему равно
Десятичная дробь 20.5 20.5
Научный 2.34E5 2.34*10^5 или 234000
Инженерный 67e-12 67*10^-12 или 0.000000000067

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

float val; val = 100 / 3; // посчитает НЕПРАВИЛЬНО (результат 3.0) val = (float)100 / 3; // посчитает правильно (указываем (float)) val = 100.0 / 3; // посчитает правильно (есть число float) val = 100 / 3.0; // посчитает правильно (есть число float) float val2 = 100; val = val2 / 3; // посчитает правильно (есть число float)

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

int val; val = 3.25; // val принимает 3 val = 3.92; // val принимает 3 val = round(3.25); // val принимает 3 val = round(3.92); // val принимает 4

Математические функции и константы

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

Математические функции из math.h

Функция Описание
cos (x) Косинус (радианы)
sin (x) Синус (радианы)
tan (x) Тангенс (радианы)
fabs (x) Модуль для float чисел
fmod (x, y) Остаток деления x на у для float
modf (x, *iptr) Возвращает дробную часть, целую хранит по адресу iptr http://cppstudio.com/post/1137/
modff (x, *iptr) То же самое, но для float
sqrt (x) Корень квадратный
sqrtf (x) Корень квадратный для float чисел
cbrt (x) Кубический корень
hypot (x, y) Гипотенуза ( корень(x*x + y*y) )
square (x) Квадрат ( x*x )
floor (x) Округление до целого вниз
ceil (x) Округление до целого вверх
frexp (x, *pexp) http://cppstudio.com/post/1121/
ldexp (x, exp) x*2^exp http://cppstudio.com/post/1125/
exp (x) Экспонента (e^x)
cosh (x) Косинус гиперболический (радианы)
sinh (x) Синус гиперболический (радианы)
tanh (x) Тангенс гиперболический (радианы)
acos (x) Арккосинус (радианы)
asin (x) Арксинус (радианы)
atan (x) Арктангенс (радианы)
atan2 (y, x) Арктангенс (y / x) (позволяет найти квадрант, в котором находится точка)
log (x) Натуральный логарифм х ( ln(x) )
log10 (x) Десятичный логарифм x ( log_10 x)
pow (x, y) Степень ( x^y )
isnan (x) Проверка на nan (1 да, 0 нет)
isinf (x) Возвр. 1 если x +бесконечность, 0 если нет
isfinite (x) Возвращает ненулевое значение только в том случае, если аргумент имеет конечное значение
copysign (x, y) Возвращает x со знаком y (знак имеется в виду + -)
signbit (x) Возвращает ненулевое значение только в том случае, если _X имеет отрицательное значение
fdim (x, y) Возвращает разницу между x и y, если x больше y, в противном случае 0
fma (x, y, z) Возвращает x*y + z
fmax (x, y) Возвращает большее из чисел
fmin (x, y) Возвращает меньшее из чисел
trunc (x) Возвращает целую часть числа с дробной точкой
round (x) Математическое округление
lround (x) Математическое округление (для больших чисел)
lrint (x) Округляет указанное значение с плавающей запятой до ближайшего целого значения, используя текущий режим округления и направление

Размеры типов данных

Константа Значение
UINT8_MAX 255
INT8_MAX 127
UINT16_MAX 65535
INT16_MAX 32767
UINT32_MAX 4294967295
INT32_MAX 2147483647

Ардуино - функции

Функция Значение
min(a, b) Возвращает меньшее из чисел a и b
max(a, b) Возвращает большее из чисел
abs(x) Модуль числа
constrain(val, low, high) Ограничить диапазон числа val между low и high
map(val, min, max, outMin, outMax) Перевести диапазон числа val (от min до max) в новый диапазон (от outMin до outMax). val = map(analogRead(0), 0, 1023, 0, 100); – получить с аналогового входа значения 0-100 вместо 0-1023. Работает только с целыми числами!
round(x) Математическое округление
radians(deg) Перевод градусов в радианы
degrees(rad) Перевод радиан в градусы
sq(x) Квадрат числа

Математические константы

Константа Значение Описание
INT8_MAX 127 Максимальное значение для char, int8_t
UINT8_MAX 255 Максимальное значение для byte, uint8_t
INT16_MAX 32767 Максимальное значение для int, int16_t
UINT16_MAX 65535 Максимальное значение для unsigned int, uint16_t
INT32_MAX 2147483647 Максимальное значение для long, int32_t
UINT32_MAX 4294967295 Максимальное значение для unsigned long, uint32_t
M_E 2.718281828 Число e
M_LOG2E 1.442695041 log_2 e
M_LOG10E 0.434294482 log_10 e
M_LN2 0.693147181 log_e 2
M_LN10 2.302585093 log_e 10
M_PI 3.141592654 pi
M_PI_2 1.570796327 pi/2
M_PI_4 0.785398163 pi/4
M_1_PI 0.318309886 1/pi
M_2_PI 0.636619772 2/pi
M_2_SQRTPI 1.128379167 2/корень(pi)
M_SQRT2 1.414213562 корень(2)
M_SQRT1_2 0.707106781 1/корень(2)
NAN __builtin_nan(“”) nan
INFINITY __builtin_inf() infinity
PI 3.141592654 Пи
HALF_PI 1.570796326 пол Пи
TWO_PI 6.283185307 два Пи
EULER 2.718281828 Число Эйлера е
DEG_TO_RAD 0.01745329 Константа перевода град в рад
RAD_TO_DEG 57.2957786 Константа перевода рад в град

Псевдослучайные числа

  • random(max) – возвращает случайное число в диапазоне от 0 до (max – 1)
  • random(min, max) – возвращает случайное число в диапазоне от min до (max – 1)
  • randomSeed(value) – дать генератору случайных чисел новую опорную точку для счёта. value – любое число. Обычно при старте программы (в setup) подают значение с неподключенного аналогового пина, получая таким образом 1024 набора случайных чисел

Биты и байты

Битовые операции – подробнее читай в отдельном уроке.

  • bit(val) – считает значение байта val по порядку (0 будет 1, 1 будет 2, 2 будет 4, 3 будет 8 и.т.д.)
  • bitClear(x, n) – устанавливает на 0 бит, находящийся в числе x под номером n
  • bitSet(x, n) – устанавливает на 1 бит, находящийся в числе x под номером n
  • bitWrite(x, n, b) – устанавливает на значение b (0 или 1) бит , находящийся в числе x под номером n
  • bitRead(x, n) – возвращает значение бита (0 или 1), находящегося в числе x под номером n
  • highByte(x) – извлекает и возвращает старший (крайний левый) байт переменной типа word (либо второй младший байт переменной, если ее тип занимает больше двух байт).
  • lowByte(x) – извлекает и возвращает младший (крайний правый) байт переменной (например, типа word).
  • bit_is_set(x, n) – проверка (возвращает 1 если включен) бита n в числе x
  • bit_is_clear(x, n) – проверка (возвращает 1 если выключен) бита n в числе x
  • loop_until_bit_is_set(x, n) – висеть в цикле (ждать), пока включен бит n в числе x
  • loop_until_bit_is_clear(x, n) – висеть в цикле (ждать), пока выключен бит n в числе x

Ввод-вывод

Цифровые пины

pinMode(pin, mode)

Устанавливает режим работы пина pin (ATmega 328: D0-D13, A0-A5) на режим mode:

  • INPUT – вход (все пины сконфигурированы так по умолчанию)
  • OUTPUT – выход (при использовании analogWrite ставится автоматически)
  • INPUT_PULLUP – подтяжка к питанию (например для обработки кнопок)

digitalRead(pin)

Читает состояние пина pin и возвращает :

  • 0 или LOW – на пине 0 Вольт (точнее 0-2.5В)
  • 1 или HIGH – на пине 5 Вольт (точнее 2.5-опорное В)

digitalWrite(pin, value)

Подаёт на пин pin сигнал value:

  • 0 или LOW – 0 Вольт (GND)
  • 1 или HIGH – 5 Вольт (точнее, напряжение питания)

analogWrite(pin, value)

Запускает генерацию ШИМ сигнала (отдельный урок про ШИМ) на пине pin со значением value. Для стандартного 8-ми битного режима это значение 0-255, соответствует скважности 0-100%. Подробнее о смене частоты и разрядности ШИМ смотрите в этом уроке. ШИМ пины:

  • ATmega 328/168 (Nano, UNO, Mini): D3, D5, D6, D9, D10, D11
  • ATmega 32U4 (Leonardo, Micro): D3, D5, D6, D9, D10, D11, D13
  • ATmega 2560 (Mega): D2 – D13, D44 – D46

Аналоговые пины

analogRead(pin)

Читает и возвращает оцифрованное напряжение с пина pin. АЦП на большинстве плат Arduino имеет разрядность 10 бит, так что возвращаемое значение 0 – 1023 при напряжении 0 – опорное на пине. Урок про аналоговые пины.

analogReference(mode)

Устанавливает режим работы АЦП согласно mode:

  • DEFAULT: опорное напряжение равно напряжению питания МК
  • INTERNAL: встроенный источник опорного на 1.1V для ATmega168 или ATmega328P и 2.56V на ATmega8
  • INTERNAL1V1: встроенный источник опорного на 1.1V (только для Arduino Mega)
  • INTERNAL2V56: встроенный источник опорного на 2.56V (только для Arduino Mega)
  • EXTERNAL: опорным будет считаться напряжение, поданное на пин AREF

Как это влияет на работу? Значение 1023 функции analogRead() будет соответствовать опорному напряжению или выше его, соответственно поставив INTERNAL можно измерять напряжение от 0 до 1.1V с точностью (1.1 / 1023 ~ 1.2 мВ), напряжение выше 1.1V будет всегда 1023. После изменения источника опорного напряжения (вызова analogReference) первые несколько измерений могут быть нестабильными.

Нельзя использовать напряжение меньше 0V или выше 5V в качестве внешнего опорного в пин AREF. Также при использовании режима EXTERNAL нужно вызвать analogReference(EXTERNAL) до вызова функции analogRead(), иначе можно повредить микроконтроллер. Также можно подключить опорное в пин AREF через резистор на ~5 кОм, но так как вход AREF имеет собственное сопротивление в 32 кОм, реальное опорное будет например 2.5 * 32 / (32 + 5) = ~2.2V

Аппаратные прерывания

attachInterrupt(pin, ISR, mode)

Подключить прерывание (читай урок про прерывания) на номер прерывания pin, назначить функцию ISR как обработчик и установить режим прерывания mode:

  • LOW – срабатывает при сигнале LOW на пине
  • RISING – срабатывает при изменении сигнала на пине с LOW на HIGH
  • FALLING – срабатывает при изменении сигнала на пине с HIGH на LOW
  • CHANGE – срабатывает при изменении сигнала (с LOW на HIGH и наоборот)

Не все пины могут в прерывания:

МК / номер прерывания INT 0 INT 1 INT 2 INT 3 INT 4 INT 5
ATmega 328/168 (Nano, UNO, Mini) D2 D3
ATmega 32U4 (Leonardo, Micro) D3 D2 D0 D1 D7
ATmega 2560 (Mega) D2 D3 D21 D20 D19 D18

digitalPinToInterrupt(pin)

Согласно выбранной в ArduinoIDE плате возвращает номер прерывания согласно номеру пина pin, таким образом можно объявить прерывания так: attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)

detachInterrupt(pin)
Отключить прерывание на пине pin
interrupts()
Разрешить все прерывания (макрос на функцию sei() )
noInterrupts()
Запретить все прерывания (макрос на функцию cli() )

Генерация и обработка сигналов

tone(pin, frequency), tone(pin, frequency, duration)

Генерировать звук частоты frequency (Герц) на пине pin. Опционально – делать это в течение времени duration, миллисекунды. Может генерировать звук только на одном пине! Прежде, чем начать делать это на другом, нужно отключить генерацию функцией noTone(pin). tone использует системный Timer 2

noTone(pin)
Принудительно выключить генерацию звука на пине pin
pulseIn(pin, value), pulseIn(pin, value, timeout)

Обрабатывает импульс на пине pin со значением value (HIGH или LOW) и возвращает его продолжительность в микросекундах. Если value HIGH, функция ждёт, пока пин изменит состояние с LOW на HIGH, и измеряет время до следующего включения на LOW. И наоборот. Можно задать timeout таймаут ожидания импульса, по умолчанию 1 секунда.

Работает с импульсами от 10 мкс до 3 минут.

pulseInLong(pin, value), pulseInLong(pin, value, timeout)

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

Работает с импульсами от 10 мкс до 3 минут.

shiftIn(dataPin, clockPin, bitOrder)

Осуществляет побитовый сдвиг и считывание байта данных, начиная с самого старшего (левого) или младшего (правого) значащего бита. Процесс считывания каждого бита заключается в следующем: тактовый вывод clockPin переводится в высокий уровень, считывается очередной бит из линии данных dataPin, после чего тактовый вывод сбрасывается в низкий уровень. bitOrder принимает MSBFIRST (начиная со старшего бита) или LSBFIRST (начиная с младшего бита). Функция возвращает считанный байт.

shiftOut(dataPin, clockPin, bitOrder, value)

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

Примечание: Для взаимодействия с устройствами, тактируемыми по фронту импульсов, перед вызовом shiftOut() необходимо убедиться, что тактовый вывод переключен в низкий уровень, например с помощью функции digitalWrite(clockPin, LOW).

bitOrder принимает MSBFIRST (начиная со старшего бита) или LSBFIRST (начиная с младшего бита)

Другое

Работа с Serial

Serial.begin(speed)

Запустить связь по Serial (читай отдельный урок про Serial) на скорости speed (baud rate, бит в секунду). Список скоростей для монитора порта Arduino IDE:

  • 300
  • 1200
  • 2400
  • 4800
  • 9600 чаще всего используется, можно назвать стандартной для большинства устройств с связью через TTL
  • 19200
  • 38400
  • 57600
  • 115200 тоже часто встречается
  • 230400
  • 250000
  • 500000
  • 1000000
  • 2000000

Прекратить связь по Serial. Для УНО/НАНО (ATmega328) это позволяет освободить пины 0 и 1 для обычных целей (чтение/запись)

Serial.available()
Возвращает количество байт, хранящихся в буфере (объём буфера 64 байта) и доступных для чтения
Serial.availableForWrite()

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

Serial.write(val), Serial.write(buf, len)

Отправляет в порт val численное значение или строку, или отправляет количество len байт из буфера buf. Важно! Отправляет данные как байт (см. таблицу ASCII), то есть отправив 88 вы получите букву X: Serial.write(88); выведет букву X

Serial.print(val), Serial.print(val, format)

Отправляет в порт значение val – число или строку. В отличие от write выводит именно символы, т.е. отправив 88 вы получите 88: Serial.print(88); выведет 88.

Serial.print(78); // выведет 78 Serial.print(1.23456); // 1.23 (умолч. 2 знака) Serial.print('N'); // выведет N Serial.print("Hello world."); // Hello world. // можно сделать форматированный вывод в стиле Serial.print("i have " + String(50) + " apples"); // выведет строку i have 50 apples // вместо чисел можно пихать переменные byte appls = 50; Serial.print("i have " + String(appls) + " apples"); // выведет то же самое

format позволяет настраивать вывод данных: BIN, OCT, DEC, HEX выведут число в соответствующей системе исчисления, а цифра после вывода float позволяет настраивать выводимое количество знаков после точки

Serial.print(78, BIN); // вывод "1001110" Serial.print(78, OCT); // вывод "116" Serial.print(78, DEC); // вывод "78" Serial.print(78, HEX); // вывод "4E" Serial.print(1.23456, 0); // вывод "1" Serial.print(1.23456, 2); // вывод "1.23" Serial.print(1.23456, 4); // вывод "1.2345"

Serial.println(), Serial.println(val), Serial.println(val, format)

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

Serial.flush()
Ожидает окончания передачи данных
Serial.peek()

Возвращает текущий байт с края буфера, не убирая его из буфера. При вызове Serial.read() будет считан тот же байт, но из буфера уже уберётся

Serial.read()

Читает и возвращает байт как код символа из таблицы ASCII. Если нужно вернуть цифру, делаем Serial.read() – ‘0’;

Serial.setTimeout(time)

Устанавливает time (миллисекунды) таймаут ожидания приёма данных для следующих ниже функций. По умолчанию равен 1000 мс (1 секунда)

Serial.find(target), Serial.find(target, length)

Читает данные из буфера и ищет набор символов target (тип char), опционально можно указать длину length. Возвращает true, если находит указанные символы. Ожидает передачу по таймауту

// будем искать слово hello char target[] = "hello"; void setup() < Serial.begin(9600); >void loop() < if (Serial.available() >0) < if (Serial.find(target)) Serial.println("found"); // вывести found, если было послано >>

Serial.findUntil(target, terminal)

Читает данные из буфера и ищет набор символов target (тип char) либо терминальную строку terminal. Ожидает окончания передачи по таймауту, либо завершает приём после чтения terminal

Serial.readBytes(buffer, length)

Читает данные из порта и закидывает их в буфер buffer (массив char [] или byte []), также указывается количество байт, который нужно записать – length (чтобы не переполнить буфер)

Serial.readBytesUntil(character, buffer, length)

Читает данные из порта и закидывает их в буфер buffer (массив char [] или byte []), также указывается количество байт, который нужно записать – length (чтобы не переполнить буфер) и терминальный символ character. Окончание приёма в buffer происходит при достижении заданного количества length, при приёме терминального символа character (он в буфер не идёт) или по таймауту

Serial.readString()

Читает буфер порта и формирует из данных строку String, которую возвращает. Заканчивает работу по таймауту

Serial.readStringUntil(terminator)

Читает буфер порта и формирует из данных строку String, которую возвращает. Заканчивает работу по таймауту или после приёма символа terminator (символ char)

Serial.parseInt(), Serial.parseInt(skipChar)

Читает целочисленное значение из буфера порта и возвращает его (тип long). Заканчивает работу по таймауту. Останавливает чтение на всех знаках, кроме знака – (минус). Можно также отдельно указать символ skipChar, который нужно пропустить, например кавычку-разделитель тысяч (10’325’685), чтобы принять такое число

Serial.parseFloat()
Читает значение с плавающей точкой из буфера порта и возвращает его. Заканчивает работу по таймауту

Функции времени

delay(time)

“Приостанавливает” выполнение кода на time миллисекунд. Дальше функции delay выполнение кода не идёт, за исключением прерываний. Использовать рекомендуется только в самых крайних или тех случаях, когда delay не влияет на скорость работы устройства. time принимает тип данных unsigned long и может приостановить выполнение на срок от 1 мс до ~50 суток (4 294 967 295 миллисекунд) с разрешением в 1 миллисекунду. Работает на системном таймере Timer 0. Читай урок по функциям времени.

delayMicroseconds(time)

Аналог delay(), приостанавливает выполнение кода на time микросекунд. Может приостановить выполнение на срок от 4 до 16’383 микросекунд с разрешением 4 микросекунды. Для бОльших периодов используйте delay(). Читай урок по функциям времени.

Возвращает количество миллисекунд, прошедших с запуска. Возвращает unsigned long (uint32_t), от 1 до 4 294 967 295 миллисекунд (~50 суток), имеет разрешение 1 миллисекунда, после переполнения сбрасывается в 0. Работает на системном таймере Timer 0. Читай урок по функциям времени.

Возвращает количество микросекунд, прошедших с запуска. Возвращает unsigned long (uint32_t), от 4 до 4 294 967 295 микросекунд (~70 минут), имеет разрешение в 4 микросекунды, после переполнения сбрасывается в 0. Работает на системном таймере Timer 0. Читай урок по функциям времени.

Встроенные макро/константы

HIGH и LOW 1 и 0 соответственно
INPUT , OUTPUT , INPUT_PULLUP 0, 1 и 2 соответственно
SERIAL , DISPLAY 0 и 1 соответственно
LSBFIRST , MSBFIRST 0 и 1 соответственно
CHANGE , FALLING , RISING 1, 2 и 3 соответственно
F_CPU Частота процессора в Гц
__DATE__ Дата компиляции в формате Feb 28 2019
__TIME__ Время компиляции в формате 14:12:12

Утилиты

sizeof(variable)

Возвращает вес переменной variable в байтах, работает с численными переменными всех типов, массивами, строками

// массивы разных типов byte arrayB[5]; int arrayI[5]; long arrayL[5]; float arrayF[5]; String myString = "lol kek"; // выводим суммарный вес массива Serial.println(sizeof(arrayB)); // вывод: 5 Serial.println(sizeof(arrayI)); // вывод: 10 Serial.println(sizeof(arrayL)); // вывод: 20 Serial.println(sizeof(arrayF)); // вывод: 20 Serial.println(sizeof(myString)); // вывод: 6 // выводим количество ячеек массива, разделив на вес одной Serial.println(sizeof(arrayB) / sizeof(arrayB[0])); // вывод: 5 Serial.println(sizeof(arrayI) / sizeof(arrayI[0])); // вывод: 5 Serial.println(sizeof(arrayL) / sizeof(arrayL[0])); // вывод: 5 Serial.println(sizeof(arrayF) / sizeof(arrayF[0])); // вывод: 5

Утилита позволяет на этапе загрузки скетча поместить данные (отдельные значения, массивы, строки) во Flash память микроконтроллера и читать их во время работы, таким образом экономя SRAM память. Пример использования:

// сохраняем несколько целых чисел const uint16_t ints[] PROGMEM = ; // сохраняем несколько десятичных дробей const float floats[] PROGMEM = ; // сохраняем несколько символов const char message[] PROGMEM = ; void setup() < Serial.begin(9600); Serial.println(pgm_read_word(&(ints[2]))); // выведет 16843 Serial.println(pgm_read_float(&(floats[1]))); // выведет 120.25 for (byte i = 0; i < 13; i++) Serial.print((char)pgm_read_byte(&(message[i]))); // выведет Hello! Lolkek >

Основная функция чтения из progmem – pgm_read_. Мы можем использовать вот эти 4:

  • pgm_read_byte(data); – для 1-го байта (char, byte, int8_t, uint8_t)
  • pgm_read_word(data); – для 2-х байт (int, word, unsigned int, int16_t, int16_t)
  • pgm_read_dword(data); – для 4-х байт (long, unsigned long, int32_t, int32_t)
  • pgm_read_float(data); – для чисел с плавающей точкой

Внимание! При чтении отрицательных (signed) чисел, нужно привести тип данных. Пример:

// сохраняем несколько целых с разными знаками const int16_t ints[] PROGMEM = ; // setup Serial.println((int)pgm_read_word(&(ints[2]))); // выведет -16843

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

Так называемая “F() macro” позволяет хранить строки во Flash памяти, не занимая место в SRAM. Работает очень просто и эффективно, позволяя делать девайс с расширенным общением/отладкой через Serial порт и не думать о забитой оперативке:

// данный вывод (строка, текст) занимает в оперативной памяти 18 байт Serial.println("Hello !"); // данный вывод ничего не занимает в оперативной памяти, благодаря F() Serial.println(F("Type /help to help"));

Работа с памятью

  • malloc() – выделение памяти
  • free() – освобождение памяти
  • new() – выделение памяти (полный аналог malloc)
  • delete() – освобождение памяти (полный аналог free)
  • memset() – заполняет блоки памяти по адресу

Другие операторы и слова

Разное

  • export – слово не используется (зарезервировано), читать тут
  • virtual – спецификатор виртуальной функции, читать тут
  • yield() – часть библиотеки Schelduer для создания “многопоточности”. Читать тут
  • complex – комплексный класс. Читать тут
  • explict – позволяет создать неконвертирующий конструктор
  • union – объект “объединение”, читать тут
  • friend – дружественные функции, читать тут
  • NULL и null – пустые указатели

Квалификаторы и спецификаторы

  • register – данный спецификатор указывает компилятору хранить значение переменной не в памяти, а в регистре процессора
  • auto – не имеет смысла
  • mutable – позволяет создать “неприкосновенный” объект

Ковариантный возврат

  • override – модификатор
  • final – модификатор

Обработка исключений

Почитать можно тут и тут

  • try – попытка
  • throw – вызов исключения
  • catch – обработка исключения

Пространство имён

  • namespace – создание пространства имён
  • using – позволяет использовать имя из пространства имён без оператора ::

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

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *