Вызов подпрограммы на ардуино

Digitrode

цифровая электроника вычислительная техника встраиваемые системы

Как создавать и использовать методы (функции) в Arduino IDE

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

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

Чтобы создать метод, нам сначала нужно создать новый скетч. Поместите его в новую папку с именем, например, «Learn Functions» и переименуйте скетч, допустим, в «First Method». Метод всегда объявляется вне void loop() или void setup().Вот пример того, как это должно выглядеть:

Эта функция ничего не возвращает (void), она только выполняет ряд действий. Между фигурными скобками указано, что должна делать функция. Чтобы вызвать вашу созданную функцию, вы должны поместить на нее ссылку в «void loop()». Вы вызываете ее, помещая имя своей функции в «void loop()».

Подождите секунду, void loop() выглядит как функция! Да, вы совершенно правы, это встроенный метод. Теперь вы узнали о типе «void», и мы познакомим вас с совершенно новым типом.

Теперь, когда вы знакомы с типом «void», вы узнаете новый способ использования функций. Но не волнуйтесь! Это не так уж и сложно. В этом примере мы вычисляем значение с двумя переменными, которые уже объявлены.

Итак, перечислим, чем это отличается от void-метода: вместо void здесь int, в конце метода есть «return». Теперь возникает вопрос: что все это значит? Так, «int» означает, что метод должен возвращать целое число, подробнее о «return» позже. По сути это означает, что функция будет целым числом. «результат» является целым числом, поэтому наша функция также должна «быть» целым числом.

Оператор return – это то, что у функции должен быть конечный результат, в данном случае 357.

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

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

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

Источник

Функции Arduino

analogRead()

Функция analogRead() возвращает целочисленное значение в диапазоне от 0 до 1023, пропорциональное напряжению, поданному на аналоговый вход, номер которого мы передаем функции в качестве параметра pinA. В большинстве плат это порты 0-5. В платах Mini и Nano: 0-7, в плате Mega: 0-15.

analogWrite()

Устанавливает аналоговое значение PWM (ШИМ, Широтно-импульсная модуляция) для вывода. Используется для плавного изменения цвета у светодиода или скорости вращения мотора. Пины с поддержкой PWM обозначены на плате символом тильда (

). Для Arduino Uno выводы имеют номера 3, 5, 6, 9, 10 и 11.

Перед вызовом данной функции нет необходимости вызывать функцию pinMode().

Функция не возвращает значения и имеет два параметра.

  • pin — номер вывода для отправки сигнала
  • value — значение яркости от 0 (полностью выключен) до 255 (полная яркость) (значение скважности ШИМ)

Функция возвращает значение бита в указанной позиции.

Общий пример для функций с битами.

bitClear()

Функция устанавливает 0 в указанной позиции у числа.

bitRead()

Функция считывает биты с указанного числа. Возвращает значение бита (0 или 1)

  • x — число, которое нас интересует
  • n — какой бит нужно считать

bitSet()

Функция устанавливает бит в указанном числе в указанной позиции.

bitWrite()

Функция записывает бит в указанной позиции.

Функция находит ближайшее целое число к числу x, но не меньше чем само число x.

Функция находит косинус угла в радианах. Значение находится в интервале от -1 до 1.

delay()

Функция делает паузу в программе на указанное количество времени в миллисекундах , которое указывается в единственном параметре. Не возвращает значения.

  • ms — число миллисекунд для установки паузы (unsigned long). 1000 миллисекунд = 1 сек

digitalRead()

Функция digitalRead() считывает показания с цифрового вывода. Возвращается HIGH (высокое, 1) или LOW (низкое, 0):

  • pin — номер цифрового порта, на который мы отправляем сигнал

digitalWrite()

Функция digitalWrite() не возвращает значения и принимает два параметра:

  • pin — номер цифрового порта, на который мы отправляем сигнал
  • value — значение, которое мы отправляем на порт. Для цифровых портов значением может быть HIGH (высокое, 1) или LOW (низкое, 0)

floor()

Функция находит ближайшее целое число к числу x, но не больше чем само число x.

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

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

Преобразует число из одного диапазона в другой диапазон. Т.е. значение из fromLow попадёт в toLow, значение fromHigh попадёт в toHigh, а значения между ними пропорционально попадут в новые значения другого диапазона.

Нижнее значение диапазона может быть больше или меньше верхнего значения. Функция map() в таких случаях может работать в обратном порядке. Например.

Также допускаются отрицательные числа.

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

  • value — число для конвертации
  • fromLow — нижнее значение текущего диапазона
  • fromHigh — верхнее значение текущего диапазона
  • toLow — нижнее значение нового диапазона
  • toHigh — верхнее значение нового диапазона

Возвращается новое значение после преобразования.

Функция возвращает большее из двух чисел.

millis()

Функция без параметров возвращает число миллисекунд (unsigned long), прошедших с запуска Arduino.

Функция возвращает меньшее из двух чисел.

pinMode()

Функция pinMode() устанавливает режим для портов.

  • pin — вывод, с которым мы собираемся работать
  • mode — как должен работать указанный вывод: работать на выход (OUTPUT) или вход (INPUT) или INPUT_PULLUP

Функция для возведения числа в степень.

random()

Функция генерирует псевдослучайные числа.

  • min — нижняя граница случайных значений
  • max — верхняя граница случайных значений

Функция возвращает случайное число между min и max-1 (long)

setup()

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

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

Функция находит синус угла в радианах. Значение находится в интервале от -1 до 1.

shiftOut()

В качестве третьего аргумента передаётся параметр bitOrder (порядок битов), который определяет в какой последовательности подаваемые биты будут интерпретироваться регистром — в прямом или обратном. LSBFIRST (Least Significant Bit First) — означает, что вывод в регистр начнётся с последнего бита. Например, при передаче байта 00010111 на выходах регистра окажутся значения (с 1 по 8 пины) — 00010111. MSBFIRST (Most Significant Bit First) — означает, что вывод в регистр начнётся с первого бита. При передаче байта 00010111 на выходах регистра окажутся значения в обратном порядке (с 1 по 8 пины) — 11101000.

Функция извлекает корень из числа.

Функция находит тангенс угла в радианах.

Генерирует звук заданной частоты на указанном пине. Можно указать продолжительность звука. Если продолжительность не указана, то остановить воспроизведение можно с помощью функции noTone(). Вывод можно соединить с пьезопищалкой или другим устройством, способным выводить звук.

Можно выводить только одну ноту во время исполнения.

  • pin — вывод платы для воспроизведения звука
  • frequency — частота звука в герцах (unsigned int)
  • duration — продолжительность в миллисекундах (необязательно) — unsigned long

Функция не возвращает значения.

Serial

Класс, позволяющий общаться с компьютером.

available()

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

begin()

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

  • speed — скорость бит в секунду (long)

flush()

Очищает входной буфер последовательного порта. Находящиеся в буфере данные теряются, и дальнейшие вызовы Serial.read() или Serial.available() будут иметь смысл для данных, полученных после вызова Serial.flush().

print()

Печатает данные, поступаемые с серийного порта в виде ASCII-текста без символа перевода строки. Схожа с функцией Serial.println().

  • val — значение для печати
  • format — формат выводимых данных. Можно использовать константы DEC (десятичная система), HEX (шестнадцатеричная), OCT (восьмеричная), BIN (бинарная)

println()

Печатает данные, поступаемые с серийного порта в виде ASCII-текста. Данные заканчиваются символом перевода строки (ASCII 13, ‘\r’) и новой строки (ASCII 10, ‘\n’). Схожа с функцией Serial.print().

  • val — значение для печати
  • format — формат выводимых данных. Можно использовать константы DEC (десятичная система), HEX (шестнадцатеричная), OCT (восьмеричная), BIN (бинарная)

Считывает входящие данные из последовательного порта.

Возвращает первый байт входящих данных, если они есть или -1, если данные не доступны.

write()

Записывает данные в последовательный порт. Данные посылаются как байт или последовательность байт; для отправки символьной информации следует использовать функцию print().

  • val: переменная для передачи, как единственный байт
  • str: строка для передачи, как последовательность байт
  • buf: массив для передачи, как последовательность байт
  • len: длина массива

Разное

pulseIn() — Возвращает продолжительность в микросекундах следующего импульса с напряжением HIGH на заданном контакте

noTone() — Прерывает любые серии импульсов, запущенные вызовом tone

micros() — Действует подобно millis, но возвращает число микросекунд, прошедших с момента последнего сброса платы. Значение обнуляется примерно через 70 минут

delayMicroseconds() — минимальная задержка составляет 3 мкс, максимальная — около 16 мс

attachInterrupt() — Устанавливает функцию myFunction, как обработчик положительного фронта прерывания 1 (контакт D3 в UNO)

detachInterrupt() — Запрещает обработку сигналов от прерывания 1

Источник

Arduino.ru

Функции

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

Для программистов, работающих с BASIC, функции в Arduino позволяют использовать подпрограммы (GOSUB в BASIC).

Разделения кода на функции имеет ряд преимуществ:

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

Существуют две обязательные функции в скетчах Arduino setup() и loop(). Другие функции должны создаваться за скобками этих функций. В следующем примере будет создана простая функция умножения двух чисел.

Пример

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

Созданную функцию необходимо задекларировать вне скобок любой другой функции, таким образом «myMultiplyFunction()» может стоять выше или ниже функции «loop()».

Весь скетч будет выглядеть следующим образом:

Следующая функция будет считывать данные с датчика функцией analogRead() и затем рассчитывать среднее арифметическое. Затем созданная функция будет масштабировать данные по 8 битам (0-255) и инвертировать их. // датчик подключен к выводу 0

Вызов функции осуществляется присвоением ее переменной.

Источник

Курс Arduino — Прерывания, создание функций, советы

Функции и точность показаний

Помнишь свой первый эксперимент? А помнишь, как я учил делать его компактнее с помощью for? К чему я это. В этом уроке я покажу, как можно проще выполнять однотипные действия. Сильно доставляет, когда в коде нужно много раз выполнять одно и то же действие. Чтобы облегчить жизнь, я познакомлю тебя с созданием функций.

Еще мы рассмотрим такую полезную штуку, как прерывания. Чем она полезна, рассмотрим ниже.

Что понадобится?

  • Светодиоды
  • Резисторы на 220 Ом и на 10 кОм
  • Соединительные провода «ПАПА- ПАПА»
  • Фоторезистор
  • Тактовая кнопка

Функции

Соберем светофор из первого эксперимента.

Код

Пояснения

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

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

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

А чтобы вызвать функцию, мы должны написать ее имя с круглыми скобками вот так: function();

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

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

Прерывания

Чем полезны прерывания? Они позволяют приостановить выполнение основного кода для выполнения какого-нибудь действия. Это бывает полезно в считывании показаний с датчиков. Так как показания считываются только один раз за проход loopa. А если в нем есть паузы, то показания становятся неточными. Это важно в подсчете оборотов колеса, например.

Сейчас я докажу важность прерываний простым экспериментом.

Код

Пояснения

Volatile – для работы с прерываниями мы должны создать переменную с квалификатором. Этот квалификатор объявляется, когда переменная будет изменяться за пределами того участка, где она была объявлена.

attachInterrupt(№, Function, Mode); — Объявляем о создании прерывания.

№ — определяет номер прерывания. На Arduino Uno могут обрабатываться всего два прерывания. Прерывание 0 считывается со 2 пина, прерывание 1 – с 3.

Ко второму мы и подключили кнопку.

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

Она не должна иметь параметров и не должна возвращать значение. Кроме того, в функции, вызываемой прерываниями не работает delay(), значение millis() не изменяется и может быть потеря данных с Serial Monitor. А переменные, используемые в функции, должны быть volatile.

Mode – Это условие, при котором будет выполняться прерывание. Всего таких условий четыре:

LOW – когда на порту LOW.

CHANGE – когда значение меняется с LOW на HIGH и наоборот.

RISING – когда значение изменяется с LOW на HIGH.

FALLING – когда значение изменяется с HIGH на LOW.

Конец?

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

Советы

У тебя есть интернет, если ты читаешь эту статью. А интернет – это кладезь полезной информации. Нужно только знать, как ее оттуда извлечь.

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

Главное – захотеть. А дальше разберешься.

Подготовка

Решил собрать свою схему? Похвально! С чего начать? Начни с бумаги! Сначала определись с тем, что ты хочешь от своего устройства. После этого, придумай алгоритм выполнения поставленной задачи и запиши, а лучше – зарисуй его. Когда все продумано, определись с компонентами, необходимыми для сборки. После этого, приступай к написанию кода и сборке схемы.

Ошибки

А что делать, если код не работает?

Первым делом – проверь, подключена ли плата, выбрана ли нужная плата в IDE, выбран ли порт, к которому подключена плата.

Еще нужно перестать бояться выскакивающих ошибок.

Рассмотрим пример ошибки.

Это ошибка выскакивает, когда пропущена точка с запятой, о чем и говорит «expected ‘;’ before ‘>’ token»

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

А эта, когда ты не объявил переменную.

Если перевести текст ошибки, будет « ‘Val’ не был объявлен в этой области видимости. Еще хорошо, что не объявленная переменная подсвечивается, и нет надобности ее искать.

А такая ошибка возникает, если пропущена фигурная скобка.

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

Вгрузил. Не работает

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

В таких случаях нужно определить, где код выполняется как надо, а где что-то уже не так. Для этого можно воспользоваться индикаторами. Например, пищалкой или Serial monitor. Для этого, вставляем tone куда-либо в программу. Если звук произошел, то эта часть программы работает как надо. А если его не было, нужно вставить звук раньше или определить, что не так. Serial может передавать мини- отчеты о выполнении тех или иных частей программы.

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

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

Отдыхай!

Хватит на сегодня, пожалуй. Можешь быть горд, что познал основы Arduino. До скорого!

Источник

Adblock
detector