лабораторные Arduino. Лабораторная работа 1 Основы работы с Arduino Функция setup
Скачать 0.54 Mb.
|
|
pinMode(pin, INPUT); // назначить выводу порт ввода | |
digitalWrite(pin, HIGH); // включить подтягивающий резистор |
Подтягивающий резистор пропускает ток достаточный для того, чтобы слегка светился светодиод подключенный к выводу, работающему как порт ввода. Также легкое свечение светодиодов означает то, что при программировании вывод не был настроен как порт вывода в функции pinMode().
Подтягивающие резисторы управляются теми же регистрами (внутренние адреса памяти микроконтроллера), что управляют состояниями вывода: HIGH или LOW. Следовательно, если вывод работает как порт ввода со значением HIGH, это означает включение подтягивающего к питанию резистора, то конфигурация функцией pinMode() порта вывода на данном выводе микросхемы передаст значение HIGH. Данная процедура работает и в обратном направлении, т.е. если вывод имеет значение HIGH, то конфигурация вывода микросхемы как порта ввода функцией pinMode() включит подтягивающий к питанию резистор.
Примечание: Затруднительно использовать вывод микросхемы 13 в качестве порта ввода из-за подключенных к нему светодиода и резистора. При подключении подтягивающего к питанию резистора 20 кОм на вводе будет 1.7 В вместо 5 В, т.к. происходит падение напряжения на светодиоде и включенном последовательно резисторе. При необходимости использовать вывод микросхемы 13 как цифровой порт ввода требуется подключить между выводом и землей внешний подтягивающий резистор.
Выводы, сконфигурированные как порты вывода, находятся в низкоимпедансном состоянии. Данные выводы могут пропускать через себя достаточно большой ток. Выводы микросхемы Atmega могут быть источником (положительный) или приемником (отрицательный) тока до 40 мА для других устройств. Такого значения тока достаточно чтобы подключить светодиод (обязателен последовательно включенный резистор), датчики, но недостаточно для большинства реле, соленоидов и двигателей.
Короткие замыкания выводов Arduino или попытки подключить энергоемкие устройства могут повредить выходные транзисторы вывода или весь микроконтроллер Atmega. В большинстве случаев данные действия приведут к отключению вывода на микроконтроллере, но остальная часть схемы будет работать согласно программе. Рекомендуется к выходам платформы подключать устройства через резисторы 470 Ом или 1 кОм, если устройству не требуется больший ток для работы.
Задание 1. Запрограммировать мигание светодиода.
Собрать схему, представленную на рисунке.
На рисунке приведена схема подключения при использовании 8 пина.
В зависимости от номера варианта подключить светодиод к соответствующему выходу Arduino. Написать программу, позволяющую задать время свечения светодиода и временя между включениями в соответствии с вариантом.
Пример программы приведен ниже:
int led = 8; //объявление переменной целого типа, содержащей номер порта к которому мы подключили второй провод
void setup() //обязательная процедура setup, запускаемая в начале программы; объявление процедур начинается словом void
{
pinMode(led, OUTPUT); //объявление используемого порта, led - номер порта, второй аргумент - тип использования порта - на вход (INPUT) или на выход (OUTPUT)
}
void loop() //обязательная процедура loop, запускаемая циклично после процедуры setup
{
digitalWrite(led, HIGH); //эта команда используется для включения или выключения напряжения на цифровом порте; led - номер порта, второй аргумент - включение (HIGH) или выключение (LOW)
delay(1000); //эта команда используется для ожидания между действиями, аргумент - время ожидания в миллисекундах
digitalWrite(led, LOW);
delay(1000);
}
| Вариант 1 | Вариант 2 | Вариант 3 | Вариант 4 | Вариант 5 | Вариант 6 | Вариант 7 | Вариант 8 | Вариант 9 | Вариант 10 |
Номер вывода | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
Продолжительность импульса, с | 1 | 2 | 0,5 | 0,1 | 1,5 | 0,3 | 0,4 | 1,2 | 1,8 | 1,9 |
Время между импульсами, с | 2 | 0,5 | 1 | 0,3 | 0,8 | 0,4 | 1,2 | 1,3 | 0,9 | 0,6 |
Задание 2. Запрограммировать работу светодиода при включении кнопки
Схема подключения приведена на рисунке. Выводы для подключения светодиода использовать в соответствии с заданием 1. Кнопку подключить к любому свободному входу.
Пример программы приведен ниже.
int button = 2;
int led = 8;
void setup() {
pinMode(led, OUTPUT);
pinMode(button, INPUT);
}
void loop(){
if (digitalRead(button) == HIGH) {
digitalWrite(led, HIGH);
}
else {
digitalWrite(led, LOW);
}
}
Задание 3. Запрограммировать мигание светодиода при включении кнопки.
Схему подключения использовать из задания 2.
Лабораторная работа №2
Работа с последовательным портом
Для связи микроконтроллера с компьютером чаще всего применяют COM-порт.
Для запуска работы порта UART служит функция Serial.begin(). Единственный ее параметр – это скорость. О скорости необходимо договариваться на передающей и приемной стороне заранее, так как протокол передачи асинхронный.
Для записи значения в порт используются три функции:
Serial.write() – записывает в порт данные в двоичном виде.
Serial.print() может иметь много значений, но все они служат для вывода информации в удобной для человека форме. Например, если информация, указанная как параметр для передачи, выделена кавычками – терминальная программа выведет ее без изменения. Если вы хотите вывести какое-либо значение в определенной системе исчисления, то необходимо добавить служебное слово: BIN-двоичная, OCT – восьмеричная, DEC – десятичная, HEX – шестнадцатеричная. Например, Serial.print(25,HEX).
Serial.println() делает то же, что и Serial.print(), но еще переводит строку после вывода информации.
Для проверки работы программы необходимо, чтобы на компьютере была терминальная программа, принимающая данные из COM-порта. В Arduino IDE уже встроена такая. Для ее вызова выберите в меню Сервис->Монитор порта.
Задание 1. Загрузить на плату код, выводящий таблицу ASCII.
ASCII представляет собой кодировку для представления десятичных цифр, латинского и национального алфавитов, знаков препинания и управляющих символов.
int symbol = 33;
void setup() {
Serial.begin(9600);
Serial.println("ASCII Table Character Map");
}
void loop() {
Serial.write(symbol);
Serial.print(", dec: ");
Serial.print(symbol);
Serial.print(", hex: ");
Serial.print(symbol, HEX);
Serial.print(", oct: ");
Serial.print(symbol, OCT);
Serial.print(", bin: ");
Serial.println(symbol, BIN);
if(symbol == 126) {
while(true) {
continue;
}
}
symbol++;
}
Переменная symbol хранит код символа. Таблица начинается со значения 33 и заканчивается на 126, поэтому изначально переменной symbol присваивается значение 33.
Следующая часть кода:
if(symbol == 126) {
while(true) {
continue;
}
}
предназначена для остановки выполнение программы. Если ее исключить, то таблица будет выводиться бесконечно.
Задание 2.
Написать бесконечный цикл, который будет раз в секунду отправлять в последовательный порт имя с новой строки.
Отправка команд с ПК
Когда вы отправляете что-то с ПК устройству, данные помещаются в некоторый специальный раздел памяти. Как только устройство готово – оно вычитывает данные из буфера. Проверить состояние буфера позволяет функция Serial.avaliable(). Эта функция возвращает количество байт в буфере. Чтобы вычитать эти байты необходимо воспользоваться функцией Serial.read().
Задание 3.
Выполните пример:
int val = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
val = Serial.read();
Serial.print("I received: ");
Serial.write(val);
Serial.println();
}
}
После того, как код будет загружен в память микроконтроллера, откройте монитор COM-порта. Введите один символ и нажмите Enter. В поле полученных данных вы увидите: “I received: X”, где вместо X будет введенный вами символ. Программа бесконечно крутится в основном цикле. В тот момент, когда в порт записывается байт функция Serial.available() принимает значение 1, то есть выполняется условие Serial.available() > 0. Далее функция Serial.read() вычитывает этот байт, тем самым очищая буфер. После чего при помощи уже известных вам функций происходит вывод.
Использование встроенного в Arduino IDE монитора COM-порта имеет некоторые ограничения. При отправке данных из платы в COM-порт вывод можно организовать в произвольном формате. А при отправке из ПК к плате передача символов происходит в соответствии с таблицей ASCII. Это означает, что когда вы вводите, например символ “1”, через COM-порт отправляется в двоичном виде “00110001” (то есть “49” в десятичном виде).
Управление устройством через COM-порт
Очевидно, что по командам с ПК можно управлять любыми функциями микроконтроллера.
Задание 4.
Напишите программу, управляющую работой светодиода.
При отправке в COM-порт символа “H” происходит зажигание светодиода на выводе 8, а при отправке “L” светодиод будет гаснуть
int val = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
val = Serial.read();
if (val=='H') digitalWrite(8,HIGH);
if (val=='L') digitalWrite(8,LOW);
}
}
Задание 5.
Написать программу, которая по результатам приема данных из COM-порта в основном цикле должна выполнять разные действия. Для этого выполнить проверку условий в основном цикле
int val = '0';
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
val = Serial.read();}
if (val=='1') {
digitalWrite(13,HIGH); delay (100);
digitalWrite(13,LOW); delay (100);
}
if (val=='0') {
digitalWrite(13,HIGH); delay (500);
digitalWrite(13,LOW); delay (500);
}
}
Если в мониторе порта отправить значение “1” светодиод будет мигать с частотой 5Гц. Если отправить “0” – частота изменится на 1Гц.
Индивидуальные задания
Придумайте три светодиодных эффекта, переключение между которыми можно осуществлять при отправке различных символов с ПК.
Напишите программу, мигающую светодиодом с частой, заданной пользователем с ПК.
Лабораторная работа №3
Моделирование ШИМ
Широтно-Импульсная модуляция, сокращенно ШИМ (англ. PWM)
Широтно-Импульсная модуляция, или ШИМ, это операция получения изменяющегося аналогового значения посредством цифровых устройств. Устройства используются для получения прямоугольных импульсов - сигнала, который постоянно переключается между максимальным и минимальным значениями. Данный сигнал моделирует напряжение между максимальным значением (5 В) и минимальным (0 В), изменяя при этом длительность времени включения 5 В относительно включения 0 В. Длительность включения максимального значения называется шириной импульса. Для получения различных аналоговых величин изменяется ширина импульса. При достаточно быстрой смене периодов включения-выключения можно подавать постоянный сигнал между 0 и 5 В на светодиод, тем самым управляя яркостью его свечения.
На графике зеленые линии отмечают постоянные временные периоды. Длительность периода обратно пропорциональна частоте ШИМ. Т.е. если частота ШИМ составляет 500 Гц, то зеленые линии будут отмечать интервалы длительностью в 2 миллисекунды каждый. Вызов функции analogWrite() с масштабом 0 – 255 означает, что значение analogWrite(255) будет соответствовать 100% рабочему циклу (постоянное включение 5 В), а значение analogWrite(127) – 50% рабочему циклу.
Задание 3.1
Используя ШИМ, написать программу изменения яркости светодиода с определенным шагом, задаваемым в программе.
Задание 3.2
Написать программу для управления яркость светодиода, подключенного через резистор к пину D3, используя ШИМ. Потенциометр подключен к пину A0
Лабораторная работа №4
Создание вольтметра на базе Ардуино
Устройство должно измерять напряжения на аналоговом входе платы, и передавать измеренные значения на ЭВМ по последовательному порту.
Вольтметр должен измерять напряжение в пределах не меньше 0…20 В.
Плата Arduino UNO содержит 6 аналоговых входов, предназначенных для измерения напряжения сигналов. Измерение напряжение на входах производится аналого-цифровым преобразователем (АЦП) с коммутатором на 6 каналов. АЦП имеет разрешение 10 бит, что соответствует коду на выходе преобразователя 0…1023. Погрешность измерения не более 2 единиц младшего разряда. Для сохранения максимальной точности (10 разрядов) необходимо, чтобы внутреннее сопротивление источника сигнала не превышало 10 кОм. Это требование особенно важно при использовании резисторных делителей, подключенных к аналоговым входам платы.
Программные функции аналогового ввода
int analogRead(port)
Считывает значение напряжения на указанном аналоговом входе. Входное напряжение диапазона от 0 до уровня источника опорного напряжения (часто 5 В) преобразовывает в код от 0 до 1023.
При опорном напряжении равном 5 В разрешающая способность составляет 5 В / 1024 = 4,88 мВ.
int inputCod; // код входного напряжения
float inputVoltage; // входное напряжение в В
inputCod= analogRead(A3); // чтение напряжения на входе A3
inputVoltage= ( (float)inputCod * 5. / 1024. ); // пересчет кода в напряжение (В)
void analogReference(type)
Задает опорное напряжение для АЦП. Оно определяет максимальное значение напряжения на аналоговом входе, которое АЦП может корректно преобразовать. Величина опорного напряжения также определяет коэффициент пересчета кода в напряжение:
Напряжение на входе = код АЦП * опорное напряжение / 1024.
Аргумент type может принимать следующие значения:
DEFAULT – опорное напряжение равно напряжению питания контроллера (5 В или 3,3 В).
INTERNAL – внутреннее опорное напряжение 1,1 В для плат с контроллерами ATmega168 и ATmega328, для ATmega8 – 2,56 В.
INTERNAL1V1 – внутреннее опорное напряжение 1,1 В для контроллеров Arduino Mega.
INTERNAL2V56 – внутреннее опорное напряжение 2,56 В для контроллеров Arduino Mega.
EXTERNAL – внешний источник опорного напряжения, подключается к входу AREF.
В нашем случае используется Arduino UNO. Для данной платы напряжение питание равно 5 В.
analogReference(DEFAULT); // опорное напряжение равно 5 В
Если задать опорное напряжение равным 5 В, то аналоговые входы платы будут измерять напряжение в пределах 0…5 В. Согласно заданию необходимо обеспечить, измерение напряжения в пределах0…20 В, следовательно, необходимо использовать делитель напряжения.
Схема делителя напряжения приведена на рисунке 1
Рисунок 1. Схема делителя напряжения
Напряжение на входе и выходе делителя связаны соотношением:
Коэффициент передачи:
Нам необходим коэффициент передачи в согласно заданию 0,25.
Для сохранения максимальной точности (10 разрядов) рекомендуется, чтобы внутреннее сопротивление источника сигнала не превышало 10 кОм. Поэтому выбираем резистор R2 равным 4,7 кОм. Рассчитываем сопротивление резистора R1.
// программа измерения напряжения
#define MEASURE_PERIOD 500 // время периода измерения
#define R1 4.8 // сопротивление резистора R1
#define R2 1. // сопротивление резистора R2
uint32_t timer = 0; // переменная таймера
float u1; // измеренные напряжения
void setup() {
Serial.begin(9600); // инициализируем порт, скорость 9600
}
void loop() {
// период 500 мс
if (millis() - timer >= MEASURE_PERIOD) { // таймер на millis()
timer = millis(); // сброс
u1= ((float)analogRead(A0)) * 5. / 1024. /R2 * (R1 + R2);
// передача данных через последовательный порт
Serial.print("U1 = "); Serial.println(u1, 2);
}
}
Задание 2.
Разработать программу двухканального вольтметра, с разными пределами измерения: 1 канал от 0 до 10 В., 2 канал от 0 до 35 В.
Лабораторная работа №4
Управление сервоприводами
Сервопривод (сервомотор) является важным элементом при конструировании различных роботов и механизмов. Это точный исполнитель, который имеет обратную связь, позволяющую точно управлять движениями механизмов. Другими словами, получая на входе значение управляющего сигнала, сервомотор стремится поддерживать это значение на выходе своего исполнительного элемента.
Сервомотор имеет встроенный потенциометр, который соединен с выходным валом. Поворотом вала, сервопривод меняет значение напряжения на потенциометре. Плата анализирует напряжение входного сигнала и сравнивает его с напряжением на потенциометре, исходя из полученной разницы, мотор будет вращаться до тех пор, пока не выровняет напряжение на выходе и на потенциометре.