Как сделать переменную в ардуино

Обновлено: 05.07.2024

CC

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

x = 0;
while ( x
<
// код тела цикла
x++;
>

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

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

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

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

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

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

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

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

Массивы.

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

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

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

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

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

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

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

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

Функции.

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

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

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

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

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

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

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

int sumQwadr (int x, int y)
<
return( x* x + y*y);
>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

типы данных, используемые в Arduino IDE

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

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


Преобразования между типами данных

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

функции преобразования данных

Диапазон переменных

Arduino IDE базируется на языке C/C++. Из него же позаимствован способ обработки переменных. При написании программы можно использовать как глобальные переменные, так и локальные переменные.

Глобальная переменная — это такая переменная, который инициализируется при запуске программы и доступна из любого места (функции) в течение всего времени действия программы.

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

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

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

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

Следующий код иллюстрирует место и способ декларации глобальных и локальных переменных:

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

Давайте рассмотрим другой код.

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

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

Изменим немного код:

Директивы const, static, volatile

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

Альтернативой const является define. Создатели Arduino IDE рекомендуют использовать именно const. Ниже приведены примеры для пользовательских констант:

Как видно const указывает на тип данных, а define присваивает значение без указания типа. Отсутствие точки с запятой в конце строки с define не упущение, а правильный синтаксис, заимствованный из C/C++.

Хорошей практикой является использование define для присвоения словесных обозначений для входов/выходов, а для остальных констант рекомендуется использовать директиву const.

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

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

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

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

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

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


Если Вы никогда не работали в среде разработки Arduino, по этой ссылке можно узнать как её установить и настроить.

Для работы с библиотекой её необходимо установить в Arduino IDE. Для установки скачайте библиотеку и в Arduino IDE в меню выберите Скетч -> Подключить библиотеку -> Добавить .ZIP библиотеку и выберите скачанный .zip файл библиотеки. Подробнее об установке библиотек можно узнать по этой ссылке.

В скетче ниже необходимо заменить "название_панели" на название Вашей панели и "название_переменной" на название переменной, которую мы создали ранее (например "myString" )

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

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

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

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

В данной ситуации светодиод мигнёт, затем включится и больше не выключается. Данный пример наглядно показывает, в чем отличие функции loop() и setup(). Если вам нужно выполнить 1 раз какое-то действие при включении Arduino, добавляем данный код в функцию setup().

Схема подключения Arduino.

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

Можно использовать встроенный светодиод на плате Arduino UNO, который подключен к 13 пину и на плате обозначается буквой L. Но данный пример не наглядный и будет сложно проверить и понять преимущества использования переменных. Вот почему желательно использовать схему подключения внешнего светодиода.

Схема подключения Arduino.

Цель урока: использование переменных в проектах на Arduino.

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

Применение переменных типа int в Arduino.

Использование переменных в проектах на Arduino помогает упростить код и сделать его более гибким. Сегодня в Arduino уроке мы рассмотрим переменные типа int (от англ. integer – целое число) один их наиболее часто используемых типов данных для хранения чисел. int занимает 2 байта памяти, и может хранить числа от -32 768 до 32 767 (от -2^15 до 2^15-1).

Для того, чтобы использовать переменную нужно её объявить, для этого пишем тип переменной в нашем случае int, название переменой ( в названии можно использовать латинские буквы, цифры и символы -,_), и указываем какое значение будет хранить переменная. Если не указать, чему равна переменная она будет равна 0.

Затем нам нужно заменить пин подключения 2 на переменную.

Сейчас достаточно изменить значение переменой led и подключить светодиод к выбранному пину. Например, если int led = 5; то схема подключения будет выглядеть вот так:

Применение переменных типа int в Arduino.

Или поменять одну переменную, а именно led, чтобы подключить светодиод к другому pin Arduino. Но код можно еще изменить, добавив переменную:

Переменная tim хранит время свечения светодиода, tim2 – время, сколько светодиод не светит.

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

Переменная tim хранит время свечения светодиода, tim2 – время, сколько светодиод не светит.

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

Загружаем код в Arduino UNO.

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

Загружаем код в Arduino UNO.

Если у вас возникли сложности с загрузкой кода, посмотрите эту статью:

Понравился урок 2, Переменные в Arduino IDE? Не забудь поделиться с друзьями в соц. сетях.

А также подписаться на наш канал на YouTube, вступить в группу Вконтакте, в группу на Facebook.

Читайте также: