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

в 9:34, , рубрики: arduino, diy или сделай сам, азбука электронщика, Блог компании Мастер Кит, лаборатория, мастер кит, Программирование, программирование микроконтроллеров, Электроника для начинающих

В первом материале, рассказывающем об обучающем наборе «Цифровая лаборатория» NR05, мы в общих чертах описали принципы построения, состав набора и плату расширения.

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

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

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

В качестве исполнительного устройства на плате предусмотрено место для установки жидкокристаллического символьного двухстрочного LCD-индикатора с подсветкой. На таком индикаторе можно отобразить достаточно информации как в обучающих целях, так и при применении набора в качестве законченного устройства. В обучающем пособии рассказывается, как выводить символьную информацию на дисплей, как заставить дисплей отображать русские и английские буквы одновременно. Индикатор используется практически во всех описанных в брошюре проектах.

Рассмотрим самое простейшее исполнительное устройство – светодиод. В набор входит трехцветный (RGB – Red, Green, Blue) яркий светодиод. Из трех цветов такого светодиода с помощью изменения интенсивности каждого из них, в силу особенностей человеческого глаза можно получить любой цвет. Такой метод получения цвета называется аддитивным смешением цветов и используется, например, в телевизорах и мониторах. Смешав три цвета в равных пропорциях, мы получим белый цвет.

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

Подключим светодиод к разъему XP15 платы расширения, который дополнительно промаркирован «RGB_LED» с помощью четырех проводов или переходника. Мы применяем светодиод с общим катодом (общим «минусом»), поэтому самый длинный вывод светодиода подсоединяется к контакту GND («Ground»), а остальные выводы светодиода соединяем с контактами RED/D5 (красный), BLUE/D6 (синий), GREEN/D9 (зеленый).

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

D5, D6 и D9 – это цифровые выводы Ардуино, на которых можно получить широтно-импульсную модуляцию (ШИМ) для управления яркостью светодиода. В обучающем пособии приведен необходимый минимум теории ШИМ и способ реализации этой модуляции в Ардуино.

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

Приведем код программы (скетча), управляющей яркостью свечения 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);
}

Теперь рассмотрим пример использования встроенных в плату кнопок.

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

В общем случае каждая кнопка подключается к отдельному цифровому выводу Ардуино и программа последовательно опрашивает эти выводы для того, чтобы определить, какая кнопка нажата. Для экономии выводов Ардуино, которые необходимо задействовать для определения нажатия кнопки в плате расширения набора «Цифровая лаборатория» используется «аналоговая» клавиатура, подключенная всего к одному аналоговому входу Ардуино. Такой способ часто используются в бытовой технике. Программа измеряет выходное напряжение на выходе делителя напряжения, которое зависит от того, какая кнопка нажата. В обучающем пособии рассмотрена теория такого делителя и способ его применения в клавиатуре. Недостатком такого способа является то, что кнопки можно нажимать только по одной, последовательно.

Загрузим в Ардуино соответствующую программу:

Спойлер

//  Подключаем аналоговую клавиатуру и на дисплее выводи номер нажатой кнопки
//-----------------------------------------------------------------------
// Обязательно подключаем стандартную библиотеку 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://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js