В первом материале, рассказывающем об обучающем наборе «Цифровая лаборатория» NR05 мы в общих чертах описали принципы построения, состав набора и плату расширения.
Рассмотрим теперь входящее в состав набора обучающее пособие, и разберем два несложных опыта с применением платы расширения, которые помогут понять, как подсоединяются внешние устройства и как можно использовать встроенные кнопки, приведем примеры скетчей.
Как мы уже говорили, на плате размещены группы разъемов для подключения различных внешних модулей: датчиков, исполнительных устройств и устройств, использующих некоторые стандартные шины обмена информацией.
В качестве исполнительного устройства на плате предусмотрено место для установки жидкокристаллического символьного двухстрочного LCD-индикатора с подсветкой. На таком индикаторе можно отобразить достаточно информации как в обучающих целях, так и при применении набора в качестве законченного устройства. В обучающем пособии рассказывается, как выводить символьную информацию на дисплей, как заставить дисплей отображать русские и английские буквы одновременно. Индикатор используется практически во всех описанных в брошюре проектах.
Рассмотрим самое простейшее исполнительное устройство – светодиод. В набор входит трехцветный (RGB – Red, Green, Blue) яркий светодиод. Из трех цветов такого светодиода с помощью изменения интенсивности каждого из них, в силу особенностей человеческого глаза можно получить любой цвет. Такой метод получения цвета называется аддитивным смешением цветов и используется, например, в телевизорах и мониторах. Смешав три цвета в равных пропорциях, мы получим белый цвет.
Подключим светодиод к разъему XP15 платы расширения, который дополнительно промаркирован «RGB_LED» с помощью четырех проводов или переходника. Мы применяем светодиод с общим катодом (общим «минусом»), поэтому самый длинный вывод светодиода подсоединяется к контакту GND («Ground»), а остальные выводы светодиода соединяем с контактами RED/D5 (красный), BLUE/D6 (синий), GREEN/D9 (зеленый).
D5, D6 и D9 – это цифровые выводы Ардуино, на которых можно получить широтно-импульсную модуляцию (ШИМ) для управления яркостью светодиода. В обучающем пособии приведен необходимый минимум теории ШИМ и способ реализации этой модуляции в Ардуино.
Приведем код программы (скетча), управляющей яркостью свечения RGB-светодиода:
// Управляем цветом RGB светодиода //----------------------------------------------------------------------- //называем выводы соответственно цвету int redPin = 5; int greenPin = 9; int bluePin = 6; //----------------------------------------------------------------------- /* Эта функция будет выполнена 1 раз в момент запуска программы Arduino в нашем случае она пустая*/ void setup() { } //----------------------------------------------------------------------- /* Эта функция будет выполнена после функции setup и будет бесконечное число раз повторятся после своего окончания.*/ void loop() { /* Цикл будет повторятся 256 раз. Каждое повторение переменная value будет увеличивать свое значение на 1.*/ for(int value = 0 ; value <= 255; value ++) { //яркость красного уменьшается от максимума к 0 analogWrite(redPin, 255-value); //яркость зеленого увеличивается analogWrite(greenPin, value); //синий не горит analogWrite(bluePin, 0); // Выдержим паузу в 30 миллисекунд delay(30); } /* Цикл будет повторятся 256 раз. Каждое повторение переменная value будет увеличивать свое значение на 1.*/ for(int value = 0 ; value <= 255; value ++) { //красный не горит analogWrite(redPin, 0); //яркость зеленого уменьшается от максимума к 0 analogWrite(greenPin, 255-value); //яркость синего увеличивается analogWrite(bluePin, value); // Выдержим паузу в 30 миллисекунд delay(30); } /* Цикл будет повторятся 256 раз. Каждое повторение переменная value будет увеличивать свое значение на 1.*/ for(int value = 0 ; value <= 255; value ++) { //яркость красного увеличивается analogWrite(redPin, value); //зеленый не горит analogWrite(greenPin, 0); //яркость синего уменьшается от максимума к 0 analogWrite(bluePin, 255-value); // Выдержим паузу в 30 миллисекунд delay(30); } // Функция loop начнет выполняться сначала }
При выполнении программы светодиод плавно меняет излучаемый цвет с красного на зеленый, потом с зеленого на синий, и далее с синего на красный.
Дополним нашу программу таким образом, чтобы на LCD-индикаторе отображались значения, в каждый момент времени соответствующие яркости каждого цвета от минимума (0) до максимума (255). Модифицированный код приведен под спойлером.
// Управляем цветом RGB светодиода //----------------------------------------------------------------------- //называем выводы соответственно цвету int redPin = 5; int greenPin = 9; int bluePin = 6; //задаем переменные для значений ШИМ int pwmRed; int pwmGreen; int pwmBlue; //----------------------------------------------------------------------- // Подключаем библиотеку LiquidCrystalRus #include <LiquidCrystalRus.h> // Подключаем библиотеки, которые использует LiquidCrystalRus #include <LiquidCrystalExt.h> #include <LineDriver.h> //----------------------------------------------------------------------- /* Инициализируем дисплей, объясняя программе куда подключены линии RS,EN,DB4,DB5,DB6,DB7 */ LiquidCrystalRus lcd(A1, A2, A3, 2, 4, 7); // Эта функция будет выполнена 1 раз в момент запуска программы Arduino void setup() { // Инициализируем LCD - 16 символов, 2 строки lcd.begin(16, 2); // Курсор находится на первой строке (верхней) и первом слева символе lcd.print(" RED GREEN BLUE"); } //----------------------------------------------------------------------- // Эта функция будет выполнена после функции setup и будет бесконечное число раз повторятся после своего окончания. void loop() { /* Цикл будет повторятся 256 раз. Каждое повторение переменная value будет увеличивать свое значение на 1.*/ for(int value = 0 ; value <= 255; value ++) { pwmGreen = value; pwmRed = 255 - value; //яркость красного уменьшается от максимума к 0 analogWrite(redPin, pwmRed); //яркость зеленого увеличивается analogWrite(greenPin, pwmGreen); //синий не горит analogWrite(bluePin, 0); // Выдержим паузу в 30 миллисекунд delay(30); Display(); } /* Цикл будет повторятся 256 раз. Каждое повторение переменная value будет увеличивать свое значение на 1.*/ for(int value = 0 ; value <= 255; value ++) { pwmBlue = value; pwmGreen = 255 - value; //красный не горит analogWrite(redPin, 0); //яркость зеленого уменьшается от максимума к 0 analogWrite(greenPin, pwmGreen); //яркость синего увеличивается analogWrite(bluePin, pwmBlue); // Выдержим паузу в 30 миллисекунд delay(30); Display(); } /* Цикл будет повторятся 256 раз. Каждое повторение переменная value будет увеличивать свое значение на 1.*/ for(int value = 0 ; value <= 255; value ++) { pwmRed = value; pwmBlue = 255 - value; //яркость красного увеличивается analogWrite(redPin, pwmRed); //зеленый не горит analogWrite(greenPin, 0); //яркость синего уменьшается от максимума к 0 analogWrite(bluePin, pwmBlue); // Выдержим паузу в 30 миллисекунд delay(30); Display(); } // Функция loop начнет выполняться сначала } // функция выводит на индикатор значения переменных, задающих ШИМ void Display(){ lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(1,1); lcd.print(pwmRed); lcd.setCursor(6,1); lcd.print(pwmGreen); lcd.setCursor(11,1); lcd.print(pwmBlue); }
Теперь рассмотрим пример использования встроенных в плату кнопок.
В общем случае каждая кнопка подключается к отдельному цифровому выводу Ардуино и программа последовательно опрашивает эти выводы для того, чтобы определить, какая кнопка нажата. Для экономии выводов Ардуино, которые необходимо задействовать для определения нажатия кнопки в плате расширения набора «Цифровая лаборатория» используется «аналоговая» клавиатура, подключенная всего к одному аналоговому входу Ардуино. Такой способ часто используются в бытовой технике. Программа измеряет выходное напряжение на выходе делителя напряжения, которое зависит от того, какая кнопка нажата. В обучающем пособии рассмотрена теория такого делителя и способ его применения в клавиатуре. Недостатком такого способа является то, что кнопки можно нажимать только по одной, последовательно.
Загрузим в Ардуино соответствующую программу:
// Подключаем аналоговую клавиатуру и на дисплее выводи номер нажатой кнопки //----------------------------------------------------------------------- // Обязательно подключаем стандартную библиотеку LiquidCrystal #include <LiquidCrystal.h> // Определяем сколько кнопок у нас подключено #define NUM_KEYS 5 // Для каждой кнопки заносим калибровочные значения(выведены экспериментально) int adcKeyVal[NUM_KEYS] = {30, 150, 360, 535, 760}; //----------------------------------------------------------------------- // Инициализируем дисплей, объясняя программе куда подключены линии RS,EN,DB4,DB5,DB6,DB7 LiquidCrystal lcd(A1, A2, A3, 2, 4, 7); //----------------------------------------------------------------------- // Эта функция будет выполнена 1 раз в момент запуска программы Arduino void setup() { // Инициализируем LCD как обычно -16 символов и 2 строки lcd.begin(16, 2); // Курсор находится на первой строке (верхней) и первом слева символе // И напишем на дисплее Keyboard lcd.print("Keyboard"); // Выдержим паузу в 2000 миллисекунд= 2 секунды delay(2000); } //----------------------------------------------------------------------- // Эта функция будет выполнена после функции setup и будет бесконечное число раз повторятся после своего окончания. void loop() { // Заводим переменную с именем key int key; // Записываем в эту переменную номер нажатой кнопки, вызывая на исполнение нижеописанную функцию get_key key = get_key(); // Очищаем дисплей от всех надписей lcd.clear(); // Курсор находится на первой строке (верхней) и первом слева символе // И напишем какую кнопку нажали. О- ни одна кнопка не нажата lcd.print(key); // Выдержим паузу в 100 миллисекунд= 0,1 секунду delay(100); // Функция loop начнет выполняться сначала } //----------------------------------------------------------------------- // Эта функция будет выполнена только когда ее вызвали из программы // Функция читает значение с АЦП, куда подключена аналоговая клавиатура // и сравнивает с калибровочными значениями, определяя номер нажатой кнопки int get_key() { int input = analogRead(A6); int k; for(k = 0; k < NUM_KEYS; k++) if(input < adcKeyVal[k]) return k + 1; return 0; }
Для отображения информации о том, какая кнопка нажата, используется LCD-индикатор. Если нажимать кнопки, то на индикаторе будет отображаться номер нажатой кнопки.
Функция get_key возвращает целое число, соответствующее номеру нажатой кнопки, которое может быть использовано в основной программе. Калибровочные значения, с которыми сравнивается напряжение с выхода делителя, определены экспериментальным путем с помощью вот такой программки:
#include <LiquidCrystal.h> LiquidCrystal lcd(A1, A2, A3, 2, 4, 7); void setup() { lcd.begin(16, 2); lcd.print("Press keys"); delay(2000); } void loop() { int input = analogRead(A6); lcd.clear(); lcd.print(input); delay(100); }
Попробуйте загрузить ее в Ардуино и посмотреть, какие значения отображаются, и сравнить их с калибровочными. Попробуем теперь использовать рассмотренные примеры для создания программы, которая реализует управление светодиодом с помощью кнопок. Зададим следующий функционал:
• при нажатии на кнопку 1 (крайнюю слева) загорается красный свет, на кнопку 2– зеленый, 3 – синий. При повторном нажатии на кнопку соответствующий свет гаснет. На индикаторе отображается, какие цвета включены.
• при нажатии на кнопку 4 включенные и выключенные цвета меняются местами
• при нажатии на кнопку 5 все цвета гаснут.
Вот один из возможных вариантов такого скетча:
// Используем аналоговую клавиатуру вместе с RGB-светодиодом //----------------------------------------------------------------------- // Обязательно подключаем стандартную библиотеку LiquidCrystal #include <LiquidCrystal.h> // Определяем сколько кнопок у нас подключено #define NUM_KEYS 5 // Для каждой кнопки заносим калибровочные значения(выведены экспериментально) int adcKeyVal[NUM_KEYS] = {30, 150, 360, 535, 760}; #define redLED 5 #define greenLED 9 #define blueLED 6 //----------------------------------------------------------------------- // Инициализируем дисплей, объясняя программе куда подключены линии RS,EN,DB4,DB5,DB6,DB7 LiquidCrystal lcd(A1, A2, A3, 2, 4, 7); int redLEDstate = 0; int greenLEDstate = 0; int blueLEDstate = 0; int flag = 0; //----------------------------------------------------------------------- // Эта функция будет выполнена 1 раз в момент запуска программы Arduino void setup() { pinMode(redLED, OUTPUT); pinMode(greenLED, OUTPUT); pinMode(blueLED, OUTPUT); // Инициализируем LCD как обычно -16 символов и 2 строки lcd.begin(16, 2); // Курсор находится на первой строке (верхней) и первом слева символе // И напишем на дисплее текст lcd.print("Try Keys + LEDs"); // Выдержим паузу в 1000 миллисекунд= 1 секунда delay(1000); // и очистим экран индикатора lcd.clear(); } //----------------------------------------------------------------------- // Эта функция будет выполнена после функции setup и будет бесконечное число раз повторятся после своего окончания. void loop() { // Заводим переменную с именем key int key; // Записываем в эту переменную номер нажатой кнопки, вызывая на исполнение нижеописанную функцию get_key key = get_key(); // Если нажата кнопка, меняем состояние соответствующего цвета на противоположное // C помощью переменной flag не допускаем изменения состояния цвета, если кнопка нажата и не отпущена if(key == 1 && flag == 0) { digitalWrite(redLED, !digitalRead(redLED)); flag = 1; } if(key == 2 && flag == 0) { // можно написать короче: if(key == 2 && !flag) digitalWrite(greenLED, !digitalRead(greenLED)); flag = 1; } if(key == 3 && !flag) { digitalWrite(blueLED, !digitalRead(blueLED)); flag = 1; } if(key == 4 && !flag) { digitalWrite(redLED, !digitalRead(redLED)); digitalWrite(greenLED, !digitalRead(greenLED)); digitalWrite(blueLED, !digitalRead(blueLED)); flag = 1; } if(key == 5 && !flag){ digitalWrite(redLED, LOW); digitalWrite(greenLED, LOW); digitalWrite(blueLED, LOW); flag = 1; } // если кнопка была нажата и отпущена, разрешаем изменение состояния цвета if(!key && flag) // соответствует if(key == 0 && flag == 1) { flag = 0; } // проверяем состояние каналов светодиода и выводим на индикатор, какой цвет включен if (digitalRead(redLED)) { // соответсвует if (digitalRead(redLED) == 1) lcd.setCursor(0,0); lcd.print("Red"); } else { lcd.setCursor(0,0); lcd.print(" "); } if (digitalRead(greenLED)) { lcd.setCursor(5,0); lcd.print("Green"); } else { lcd.setCursor(5,0); lcd.print(" "); } if (digitalRead(blueLED)) { lcd.setCursor(11,0); lcd.print("Blue"); } else { lcd.setCursor(11,0); lcd.print(" "); } // Функция loop начнет выполняться сначала } //----------------------------------------------------------------------- // Эта функция будет выполнена только когда ее вызвали из программы // Функция читает значение с АЦП, куда подключена аналоговая клавиатура // и сравнивает с калибровочными значениями, определяя номер нажатой кнопки int get_key() { int input = analogRead(A6); int k; for(k = 0; k < NUM_KEYS; k++) if(input < adcKeyVal[k]) return k + 1; return 0; }
В заключение приведем небольшой видеоролик, демонстрирующий описанные опыты.
Как видим, возможности платы расширения набора «Цифровая лаборатория» позволяют удобно, наглядно и быстро осваивать практику работы с Ардуино и подсоединяемыми дополнительными модулями.
В следующей статье мы рассмотрим взаимодействие Ардуино с Андроид-смартфоном по технологии Bluetooth с использованием платы расширения. Программировать смартфон будем с помощью проекта MIT App Inventor, который разработан и поддерживается Массачусетским Технологическим Интститутом.
ссылка на оригинал статьи https://geektimes.ru/post/270714/
Добавить комментарий