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


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

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



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

void setup() {

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

}

void loop() {

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

}

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

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

 

Пример простейшей программы.

 

Void setup()

{

Serial.begin(9600);

}

Void loop()

{

Serial.println(millis()); delay(1000);

}

Контрольные вопросы:

1. Как устроены цифровые выводы Arduino?

2. Как устроены аналоговые входы Arduino?

3. Объяснить широтно-импульсную модуляцию.

4. Как устроена память Arduino?

5. Какая структура программы Arduino?

 


Лекция 47 Синтаксис и операторы

Цели лекции:

1. Изучение управляющих операторов

2. Изучение основных правил синтаксиса

 

Управляющие операторы

Оператор if (условие) и операторы сравнения ==,!=, <, >

Оператор if используется в сочетании с операторами сравнения, он проверяет, дос­тигнута ли истинность условия — например, превышает ли входное значение заданное число. Формат оператора if следующий:

if (someVariable > 50){

// выполнять действия }

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

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

Операторы сравнения:

- x == y (x равно y);

- x!= y (x не равно y);

- x < y (x меньше чем y);

- x > y (x больше чем y);

- x <= y (x меньше чем или равно y);

- x >= y (x больше чем или равно y).

 


Оператор if..else

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

Например:

if (pinInput==HIGH)

{doFun1();}

else

{doFun2();}

Else позволяет делать отличную от указанной в if проверку, чтобы можно было осуществлять сразу несколько взаимоисключающих проверок. Каждая проверка позволяет переходить к следующему за ней оператору не раньше, чем получит ло­гический результат ИСТИНА. Когда проверка с результатом ИСТИНА найдена, запускается вложенный в нее блок операторов, и затем программа игнорирует все следующие строки в конструкции if..else. Если ни одна из проверок не получила результат ИСТИНА, по умолчанию выполняется блок операторов в else, если по­следний присутствует, и устанавливается действие по умолчанию. Конструкция else if может быть использована с или без заключительного else и наоборот. До­пускается неограниченное число таких переходов else if

Пример

if (pinAnalogInput < 100)

{doFun1();} else if (pinAnalogInput >= 150)

{doFun2();}

else

{doFun3();}

 

Другой способ создания переходов со взаимоисключающими проверками исполь­зует оператор switch case.

Конструкция switch... case управляет процессом выполнения программы, позволяя программисту задавать альтернативный код, который будет выполняться при раз­ных условиях. Оператор switch сравнивает значение переменной со значением, определенном в операторах case. Когда найден оператор case, значение которого равно значению переменной, выполняется программный код в этом операторе. Ключевое слово break является командой выхода из оператора case и обычно ис­пользуется в конце каждого case. Без оператора break оператор switch будет про­должать вычислять следующие выражения, пока не достигнет break или конец опе­ратора switch. Синтаксис команды switch...case:

switch (var)

{

case label1:

// код для выполнения break;

case label2:

 

Оператор for

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

Заголовок цикла for состоит из трех частей:

for (initialization; condition; increment) {операторы, выполняющиеся в цикле}

Инициализация (initialization) выполняется самой первой и один раз. Каждый раз в цикле проверяется условие (condition), если оно верно, выполняется блок опера­торов и приращение (increment), затем условие проверяется вновь. Когда логи­ческое значение условия становится ложным, цикл завершается.

 


Пример затемнения светодиода с использованием ШИМ-вывода:

int PWMpin = 10; // Светодиод последовательно с R=470 Ом на 10 выводе

void setup()

{;}

void loop()

{

for (int i=0; i <= 255; i++)

{

analogWrite(PWMpin, i); delay(10);

}

// код для выполнения break;

case label3:

// код для выполнения

break;

default:

// код для выполнения break;

}

Параметры:

 var — переменная, которая вычисляется для сравнения с вариантами в case;

 label — значение, с которым сравнивается значение переменной.

 

Оператор while

Оператор while будет вычислять в цикле непрерывно и бесконечно до тех пор, по­ка выражение в круглых скобках не станет равно логическому ЛОЖНО. Что-то должно изменять значение проверяемой переменной, иначе выход из цикла while никогда не будет достигнут. Это изменение может происходить как в программном коде, например, при увеличении переменной, так и во внешних условиях, напри­мер, при тестировании датчика. Синтаксис команды следующий:

while(выражение)

{

// операторы }

 

Пример использования оператора while:

var i=0; while($i<100)

{

// операторы

i++;

}

 

Оператор do... while

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

Пример использования оператора do... while:

do {

delay(50); // подождать, пока датчики стабилизируются

x = readSensors(); // проверить датчики

}

while (x < 100);

 

Оператор break

Оператор break используется для принудительного выхода из циклов do, for или while, не дожидаясь завершения цикла по условию. Он также используется для вы­хода из оператора switch.

Пример

for (x = 0; x < 255; x ++)

{

digitalWrite(PWMpin, x);

sens = analogRead(sensorPin);

if (sens > threshold)

{

// выходим из цикла, если есть сигнал с датчика

x = 0;

break;

}

delay(50);

}

 

Оператор continue

Оператор continue пропускает оставшиеся операторы в текущем шаге цикла. Вместо них выполняется проверка условного выражения цикла, которая происхо­дит при каждой следующей итерации.

Пример

for (x = 0; x < 255; x ++)

{

if (x > 40 && x < 120)

{ // если истина то прыгаем сразу на следующую итерацию цикла continue;

}

digitalWrite(PWMpin, x); delay(50);

}

 

Оператор return

Оператор return прекращает вычисления в функции и возвращает значение из пре­рванной функции в вызывающую, если это нужно.

Пример возврата значения из функции в зависимости от значения на входе аналогового входа:

int checkSensor()

{

if (analogRead(0) > 200) return 1; else{ return 0;

}

 


Синтаксис

 

; (точка с запятой); (semicolon)

; (точка с запятой) используется для обозначения конца оператора.

int a = 13;

 

{} (фигурные скобки) {} (curly braces)

Фигурные скобки {} — важный элемент языка программирования С. Открывающая скобка { должна всегда сопровождаться закрывающей скобкой }. Это условие, из­вестное как парность (симметричность) фигурных скобок.

Основные способы использования фигурных скобок:

а) функции:

- void НазваниеФункции (тип данных аргумента) { оператор(ы) };

б)  циклы:

- while (логическое выражение){ оператор(ы)};

- do { оператор(ы)} while (логическое выражение);

- for (инициализация; условие окончания цикла; приращения цикла)

- { оператор(ы)};

в)  условные операторы:

-  if (логическое выражение) {оператор(ы)}.

Комментарии // (single line comment), /* */(multi-line comment)

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

Есть два способа пометить строку как комментарий:

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

 многострочный комментарий — /*... */.

Пример.

x = 5; // Это комментарий в одной строке. Все после двойного // слэша

 /* это многострочный комментарий - используйте его для закомментирования целых кусков кода */

 

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

= (assignment) = оператор присваивания

Присваивает переменной слева от оператора значение переменной или выражения, находящееся справа:

int sensVal;   //  объявление    переменной типа integer

senVal=analogRead(0); // присваивание переменной sensVal значение,

// считанное с аналогового входа 0

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

 

+ Сложение), - (вычитание), * (умножение), / (деление)

Операторы +, -, * и /, соответственно, возвращают результат выполнения арифме­тических действий над двумя операндами. Возвращаемый результат будет зависеть от типа данных операндов, например, 9 / 4 возвратит 2, т. к. операнды 9 и 4 имеют тип int. Также следует следить за тем, чтобы результат не вышел за диапазон до­пустимых значений для используемого типа данных. Так, например, сложение 1 с переменной типа int и значением 32 767 возвратит -32 768. Если операнды име­ют разные типы, то тип с более "широким" диапазоном будет использован для вычислений. Если один из операндов имеет тип float или double, то арифметика "с плавающей запятой" будет использована для вычислений.

 % (modulo)

Возвращает остаток от деления одного целого (int) операнда на другой. Примеры:

x = 9 % 5; // x имеет значение 4 x = 5 % 5; // x имеет значение 0

Нельзя применить к типу float.

Операторы сравнения

Операторы сравнения:

- x == y (x равно y);

- x!= y (x не равно y);

- x < y (x меньше чем y);

- x > y (x больше чем y);

- x <= y (x меньше чем или равно y);

- x >= y (x больше чем или равно y).

 

Логические операторы

Логические операторы чаще всего используются в проверке условия оператора if.

 && (логическое И)

Истина, если оба операнда истина (true). Пример:

if (digitalRead(2) == HIGH && digitalRead(3) == HIGH)

Serial.println("ok");

 || (логическое ИЛИ)

Истина, если хотя бы один операнд истина. Пример:

if (digitalRead(2) == || digitalRead(3) == HIGH)

Serial.println("ok");

! (логическое отрицание)

Истина, если операнд false, и наоборот. Пример:

if (!(digitalRead(2)== HIGH))

Serial.println("okM);

 

Унарные операторы

++ (увеличение значения) / -- (уменьшение значения)

Унарные (имеющие один операнд) операторы ++, -- увеличивают, уменьшают зна­чение переменной соответственно

Например:

x++; // увеличивает значение x на единицу и возвращает старое значение x

++x; // увеличивает значение x на единицу и возвращает новое значение x

x—; // уменьшает значение x на единицу и возвращает старое значение x

—x; // уменьшает значение x на единицу и возвращает новое значение x

+=, -=, *=, /=

Короткий способ записи арифметических действий над переменной и одним опе­рандом.

Например:

x+=y; // эквивалент записи x=x+y;

Контрольные вопросы:

1. Какие используются управляющие операторы и их конструкции в программе Arduino?

2. Какие используются операторы сравнения в программе Arduino?

3. Как работают циклы while и do…while?

4. Для какой цели используются операторы break, continue, return?

5. Назвать и объяснить назначение арифметических операторов.

6. Назвать и объяснить назначение логических операторов.

7. Назвать и объяснить назначение унарных операторов.


Лекция 48 Данные

Цели лекции:

1. Изучение типов данных.

2. Изучение работы с константами.

3. Изучение работы с переменными.

4. Изучение методов преобразования типов данных.

 

Типы данных

Компилятор Arduino определяет следующие типы данных:

boolean unsigned long
char float
byte double
int string
unsigned int массив(array)
long void

 

 boolean

Логический (булевый) тип данных — boolean. Может принимать одно из двух зна­чений: true или false. Данные типа boolean занимают в памяти один байт.

 char

Переменная типа char занимает 1 байт памяти и может хранить один алфавитно­цифровой символ (литеру). При объявлении литеры используются одиночные ка­вычки: 'A' (двойные кавычки используются при объявлении строки символов — тип string: "ABC").

Символ хранится в памяти как число, соответствующее коду символа в таблице кодировки символов ASCII. Так как символ хранится как число, в памяти над ним возможно производить арифметические действия (например, 'A' + 1 будет 66, т. к. ASCII код для 'A' — 65).

Тип char знаковый тип, т. е. число (код), хранящийся в памяти, может принимать значения от -128 до 127. Если необходима знаковая однобайтовая переменная, ис­пользуйте тип byte.

Пример:

char myChar = 'A';

char myChar = 65; //  Варианты эквивалентны

 

Byte

Хранит восьмибитовое числовое значение без десятичной точки. Имеет диапазон от 0 до 255.

Пример:

byte someVariable=150; // объявление переменной someVariable,

// имеющей тип byte

 int

Тип данных int (от англ. integer — целое число) — один из наиболее часто исполь­зуемых типов данных для хранения чисел. int занимает 2 байта памяти и может хранить числа от -32 768 до 32 767.

Для размещения отрицательных значений int использует так называемый допол­нительный код представления числа. Старший бит указывает на отрицательный знак числа, остальные биты инвертируются с добавлением 1.

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

Когда переменная типа int вследствие арифметической операции достигает своего максимального значения, она "перескакивает" на самое минимальное значение и наоборот

Пример:

int x;

x = -32,768;

x = x - 1; // x теперь равно 32,767

x = 32,767;

x = x + 1; // x теперь равно -32,768

 

Unsigned int

Тип данных unsigned int — беззнаковое целое число, так же как и тип int (знако­вое), занимает в памяти 2 байта. Но в отличие от int, тип unsigned int может хра­нить только положительные целые числа в диапазоне от 0 до 65 535.

Отличие кроется в том, как unsigned int использует старший бит, иногда называе­мый знаковым битом. Если старший бит равен 1, то для типа int компилятор Arduino считает, что это число отрицательное, а остальные 15 битов несут инфор­мацию о модуле целого числа в дополнительном коде представления числа, в то время как unsigned int использует все 16 битов для хранения модуля числа.

Когда переменная типа unsigned int вследствие арифметической операции дости­гает своего максимального значения, она "перескакивает" на самое минимальное значение и наоборот.

Пример:

unsigned int x; x = 0;

x = x - 1; // x теперь равна 65535

x = x + 1; // x теперь 0

 

Long

Тип данных long используется для хранения целых чисел в расширенном диапазоне от -2 147 483 648 до 2 147 483 647. long занимает 4 байта в памяти.

Пример:

long var1 = -178000;

 

unsigned long

Unsigned long используется для хранения положительных целых чисел в диапазоне от 0 до 4 294 967 295 и занимает 32 бита (4 байта) в памяти.

Пример вывода в мил­лисекундах (мс) с начала выполнения программы:

void loop()

{

Serial.print(”Time: ”); time = millis();

//выводит время, прошедшее с момента начала выполнения программы

Serial.println(time);

function1();

}

 

Float

Тип данных float служит для хранения чисел с плавающей запятой. Этот тип часто используется для операций с данными, считываемыми с аналоговых входов. Диапа­зон значений — от -3,4028235E+38 до 3,4028235E+38. Переменная типа float за­нимает 32 бита (4 байта) в памяти.

Тип float имеет точность 6-7 знаков, имеются в виду все знаки, а не только ман­тисса. Обычно для увеличения точности используют другой тип — double, но на платформе Arduino double и float имеют одинаковую точность.

 

Double

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

Тип double поддерживается в Arduino для совместимости кода с другими платфор­мами.

 

  string — текстовые строки

Текстовые строки в Arduino объявляются как массив (array) типа char (символов, литер), оканчивающийся символом "конца строки". Возможны следующие вариан­ты объявления текстовых строк:

- объявить массив символов без присваивания значений;

- объявить массив символов и присвоить значения всем элементам, кроме послед­него, компилятор Arduino автоматически добавит символ конца строки;

- явно объявить завершающий символ;

- инициализировать массив строковой константой в двойных кавычках. Компиля­тор автоматически задаст требуемый размер на массив, равный количеству сим­волов плюс завершающий символ;

- инициализировать массив с явным заданием размера и присвоением строковой константы;

- инициализировать массив с явным заданием дополнительного размера (с запа­сом), фактически превышающего размер строковой константы при начальном присвоении.

Варианты объявления и присвоения строк:

char Str1[15];

char Str2[8] = {'a','r','d','u','i','n','o'};

char Str3[8] = {'a','r','d','u','i','n','o','\0'};

char Str4[ ] = "arduino";

char Str5[8] = "arduino";

char Str6[15] = "arduino";

Обычно строки оканчиваются нулевым символом (код 0 в ASCII). Это позволяет функциям (таким как Serial.print()) выявлять окончание строки. В противном случае могут считаться байты памяти, не принадлежащие переменной.

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

Строки всегда объявляются внутри двойных кавычек ("Abc").

При работе с большими объемами текстовой информации бывает удобно использо­вать массивы строк. Так как строки сами по себе массивы, массив строк будет дву­мерным массивом.

Пример: символ звездочки после объявления типа "char*" указывает на то, что это массив указателей. Это необходимо для задания двумерного массива.

char* myStrings[]={"string 1", "string 2", "string 3","string 4",

"string 5","string 6"};

void setup()

{Serial.begin(9600);} void loop()

{

for (int i = 0; i < 6; i++){

Serial.println(myStrings[i]); delay(500);

}

}

 

Массивы

Массивы (arrays) — именованный набор однотипных переменных с доступом к отдельным элементам по их индексу. Существует несколько вариантов объявле­ния массива:

- массив может быть объявлен без непосредственной инициализации элементов массива:

int mylnts[6];

- массив может быть объявлен без явного задания размера. Компилятор сам по­считает фактическое количество элементов и создаст в памяти массив необхо­димого размера:

int myPins[] = {2, 4, 8, 3, 6};

- при объявлении массива размер может быть задан явно, одновременно с ини­циализацией элементов массива, при создании массива типа char необходим дополнительный элемент массива для нулевого символа:

int mySensVals[6] = {2, 4, -8, 3, 2};

char message[6] = "hello";

Индексация массива начинается с 0. Присваивание значения элементу массива происходит следующим образом:

mySensVals[0] = 10;

Получение значения массива: x = mySensVals[4];

Чаще всего для перебора элементов цикла используется цикл for, счетчик цикла используется как индекс для доступа к каждому элементу массива. Например, для вывода массива через последовательный порт (Serial) можно использовать сле­дующий код:

int i;

for (i = 0; i < 5; i = i + 1)

{ Serial.println(myPins[i]); }

 

Void

Ключевое слово void используется при объявлении функций, если функция не воз­вращает никакого значения при ее вызове.

 

Константы

Константы — предопределенные значения. Они используются, чтобы делать про­граммы более легкими для чтения.

true/false это булевы константы, определяющие логические уровни. false лег­ко определяется как 0 (ноль), а true, как 1, но может быть и чем-то другим, отлич­ным от нуля. Поэтому -1, 2 и 200 — это все тоже определяется как true.

#define true 0x1

#define false 0x0

 

high/low — уровни сигналов порта high и low:

#define HIGH 0x1

#define LOW 0x0

input/output — настройка цифровых портов на ввод (input) и вывод (output) сиг­налов:

#define INPUT 0x0

#define OUTPUT 0x1

 

Цифровые порты могут использоваться на ввод или вывод сигналов. Изменение порта с ввода на вывод производится при помощи функции pinMode():

pinMode(13, OUTPUT); // 13 вывод будет выходом

pinMode(12, INPUT); // 12 - входом

 

В программе можно создавать собственные константы:

#define LEFT 0x95

#define MESS_LEFT "поворот влево"

 

Переменные

Переменные — это способ именовать и хранить числовые значения для последую­щего использования программой. Переменные — это значения, которые могут по­следовательно меняться, в отличие от констант, чье значение никогда не меняется. Переменные нужно декларировать (объявлять). Следующий код объявляет пере­менную inputVariable, а затем присваивает ей значение, полученное от второго анало­гового порта:

int inputVariable=0;

inputVariable=analogRead(2);

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

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

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

Следующий пример показывает, что объявленная переменная inputVariable имеет тип int, и ее начальное значение равно нулю. Это называется простым присваива­нием.

int inputVariable = 0;

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

 

Границы переменных

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

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

Локальные переменные определяются внутри функций или таких частей, как цикл for. Они видимы и могут использоваться только внутри функции, в которой объяв­лены. Таким образом, могут существовать несколько переменных с одинаковыми именами в разных частях одной программы, которые содержат разные значения. Уверенность, что только одна функция имеет доступ к ее переменной, упрощает программу и уменьшает потенциальную опасность возникновения ошибок.

 

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

Char()

char () приводит значение к типу char.


Синтаксис:

char(x);

где x — переменная любого типа.

 

 byte()

byte () приводит значение к типу byte.

Синтаксис:

byte(x);

где x — переменная любого типа.

 

 into

int() приводит значение к типу int.

Синтаксис:

int(x);

где x — переменная любого типа.

 

L ong()

long () приводит значение к типу long.

Синтаксис:

long(x);

где x — переменная любого типа.

 

Float()

float() приводит значение к типу float.

Синтаксис:

long(x);

где x — переменная любого типа.

 


Контрольные вопросы:

1. Какие используются типы данных в программе Arduino?

2. Какие используются преобразования типов данных в программе Arduino?

3. Какие используются константы в программе Arduino и для чего они предназначены?

4. Как и где объявляются переменные?

 

 


Лекция 49 Функции

Цели лекции:

1. Знакомство с функциями цифрового ввода/вывода.

2. Знакомство с функциями аналогового ввода/вывода.

3. Знакомство с дополнительными функциями ввода/вывода.

4. Знакомство с функциями времени.

5. Знакомство с функциями математическими.

6. Знакомство с тригонометрическими функциями.

7. Знакомство с функциями генераторов случайных величин.

8. Знакомство с функциями операций с битами и байтами.

9. Знакомство с функциями внешних прерываний.

 

Цифровой ввод/вывод

Рассмотрим функции цифрового ввода/вывода:

- pinMode();

- digitalWrite();

- digitalRead().

 

Функция pinMode

Устанавливает режим работы заданного входа/выхода (pin) как входа или как вы­хода.

Синтаксис:

pinMode(pin, mode);

Параметры:

 pin — номер входа/выхода (pin), который вы хотите установить;

 mode — режим. Одно из двух значений: input или output устанавливает на вход или выход соответственно.

Пример:

int ledPin = 13; // Светодиод, подключенный к входу/выходу 13

void setup()

{

pinMode(ledPin,OUTPUT); // устанавливает режим работы - выход     }

 

  Функция digitalWrite()

Подает high или low значение на цифровой вход/выход (pin).

Если вход/выход (pin) был установлен в режим выход (output) функцией pinMode(), то для значения high напряжение на соответствующем входе/выходе (pin) будет 5 В (3,3 В для плат 3,3 В) и 0 В (земля) для low.

Если вход/выход (pin) был установлен в режим вход (input), то функция digitalwrite со значением high будет активировать внутренний нагрузочный рези­стор 20 K. Подача low в свою очередь отключает этот резистор. Нагрузочного рези­стора достаточно, чтобы светодиод, подключенный к входу, светил тускло. Если вдруг светодиод работает, но очень тускло, возможно необходимо установить режим выход (output) функцией pinMode().

Синтаксис:

digitalWrite(pin, value);

Параметры:

 pin — номер входа/выхода (pin);

 value — значение high или low.

Пример:

int ledPin = 13;// Светодиод, подключенный к входу/выходу 13

Void setup()

{

pinMode(ledPin, OUTPUT); // устанавливает режим работы-выход }

Void loop()

{

digitalWrite(ledPin, HIGH); // включает светодиод

delay(1000); // ждет секунду

digitalWrite(ledPin, LOW); // выключает светодиод   delay(1000); // ждет секунду

}

 

Функция digitalRead()

Функция считывает значение с заданного входа: high или low.

Синтаксис:

digitalRead(pin);

Параметр: pin — номер входа/выхода (pin), который вы хотите считать.

Пример:

int ledPin = 13; // Светодиод, подключенный к входу/выходу 13

int inPin = 7; // кнопка на входе 7

int val = 0; // переменная для хранения значения

void setup()

{

pinMode(ledPin, OUTPUT); // устанавливает режим работы - выход для 13

pinMode(inPin, INPUT); // устанавливает режим работы - вход для 7 }

void loop()

{

val = digitalRead(inPin); // считываем значение с входа digitalWrite(ledPin, val); // устанавливаем значение на светодиоде // равным значению входа кнопки

}

 

Если вход не подключен, то digitalRead может возвращать значения HIGH или LOW случайным образом. Аналоговые входы (analog pins) могут быть использованы как цифровые входы/выходы (digital pins). Обращение к ним идет по номерам от 14 (для аналогового входа 0) до 19 (для аналогового входа 5).

 

Аналоговый ввод/вывод

Рассмотрим функции аналогового ввода/вывода:

- analogRead();

- analogReference();

- analogWrite().

 

Функция analogRead()

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

Большинство плат Arduino имеют 6 каналов (8 каналов у платы Mini и Nano, 16 — у Mega) с 10-битным аналого-цифровым преобразователем (АЦП). Напряжение, поданное на аналоговый вход (обычно от 0 до 5 вольт), будет преобразовано в значение от 0 до 1023 — это 1024 шага с разрешением 0,0049 вольт. Разброс напряжения и шаг может быть изменен функцией analogReference (). Считывание значения с аналого­вого входа занимает примерно 100 микросекунд (0,0001 сек), т. е. максимальная частота считывания приблизительно 10 000 раз в секунду.

Синтаксис:

analogRead(pin);

Параметр: pin — номер порта аналогового входа, с которого будет производиться считывание: 0..5 для большинства плат, 0..7 для Mini и Nano и 0..15 для Mega.

Возвращаемое значение int (0 to 1023).

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

Пример:

int analogPin = 3; // номер порта, к которому подключен потенциометр

int val = 0; // переменная для хранения считываемого значения

void setup()

{

Serial.begin(9600); // установка связи по serial

}

void loop()

{

val = analogRead(analogPin); // считываем значение Serial.println(val); // выводим полученное значение

}

 

Функция analogReference()

Функция определяет опорное напряжение, относительно которого происходят ана­логовые измерения. Функция analogRead() возвращает значение с разрешением 8 битов (1024) пропорционально входному напряжению на аналоговом входе и в зависимости от опорного напряжения.

Возможные настройки:

 default — стандартное опорное напряжение 5 В (на платформах с напряжением питания 5 В) или 3,3 В (на платформах с напряжением питания 3,3 В);

 internal — встроенное опорное напряжение 1,1 В на микроконтроллерах ATmega168 и ATmega328 и 2,56 В на ATmega8;

 external — внешний источник опорного напряжения, подключенный к выводу AREF.

Синтаксис:

analogReference(type);

Параметр: type — определяет используемое опорное напряжение (default, internal или external).

Внешнее напряжение рекомендуется подключать к выводу AREF через резистор 5 кОм.

Рекомендуемой настройкой для вывода AREF является external. При этом про­исходит отключение обоих внутренних источников, и внешнее напряжение будет являться опорным для АЦП.

 

Функция analogWrite()

Выдает аналоговую величину (ШИМ-волну) на порт входа/выхода. Функция может быть полезна для управления яркостью подключенного светодиода или скоростью вращения электродвигателя. После вызова analogWrite () на выходе будет генери­роваться постоянная прямоугольная волна с заданной шириной импульса до сле­дующего вызова analogWrite (или вызова digitalWrite или digitalRead на том же порту входа/выхода). Частота ШИМ-сигнала приблизительно 490 Гц.

На большинстве плат Arduino (на базе микроконтроллера ATmega168 или ATmega328) ШИМ поддерживают порты 3, 5, 6, 9, 10 и 11, на плате Arduino Mega — порты с 2 по 13. На более ранних версиях плат Arduino analogWrite() ра­ботал только на портах 9, 10 и 11.

Для вызова analogWrite () нет необходимости устанавливать тип входа/выхода функцией pinMode(). Функция analogWrite() никак не связана с аналоговыми вхо­дами и с функцией analogRead ().

Синтаксис:

analogWrite(pin, value);

Параметры:

 pin — порт входа/выхода, на который подается ШИМ-сигнал;

 value — период рабочего цикла: значение между 0 (полностью выключено) и 255 (сигнал подан постоянно).

Период ШИМ-сигнала на портах входа/выхода 5 и 6 будет несколько длиннее. Это связано с тем, что таймер для данных выходов также задействован функциями millis() и delay(). Данный эффект более заметен при установке коротких периодов ШИМ-сигнала (0-10).

Пример задания яркости светодиода пропорционально значению, снимаемому с потенциометра:

int ledPin = 9; // Светодиод подключен к выходу 9

int analogPin = 3; // потенциометр подключен к выходу 3 int val = 0; // переменная для хранения значения

void setup()

{

pinMode(ledPin, OUTPUT); // установка порта на выход }

void loop()

{

val = analogRead(analogPin); // считываем значение с порта,

// подключенного к потенциометру analogWrite(ledPin, val / 4); // analogRead возвращает значения от 0 // до 1023, analogWrite должно быть // в диапазоне от 0 до 255

}

 



Поделиться:


Последнее изменение этой страницы: 2021-02-07; просмотров: 370; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.216.186.164 (0.408 с.)