Эксперименты на основе набора «Цифровая лаборатория»

от автора

В первом материале, рассказывающем об обучающем наборе «Цифровая лаборатория» 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *