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

    В первом материале, рассказывающем об обучающем наборе «Цифровая лаборатория» 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, который разработан и поддерживается Массачусетским Технологическим Интститутом.
    Мастер Кит 39,34
    Полезная электроника
    Поделиться публикацией
    Похожие публикации
    Комментарии 5
    • +1
      Для тех, кому понравился набор, похожий собирается из
      arduino uno — $3
      sensor shied — $2
      lcd 1602 keypad — $3
      Датчики — $2-5
      • +1
        Видел такие наборы в «Чип и Дип» (да, да, эти ребята тоже знают толк в ценах).
        И, что хочу сказать — новичку лучше начинать с развития навыка заказа комплектующих из Китая.
        • +1
          Описано понятно и интересно, хотя уже и много раз было. Непонятно одно — зачем тут "цифровая лаборатория".
          Попробуйте написать какой-то нибудь пример, в котором она будет реально востребована и, скажем, заменит с десяток других компонентов.
          • 0
            А ничего, что у вас на все три анода идет одинаковый резистор в 270 Ом, хотя падение напряжения на каждом переходе разное?
            • 0
              Ничего :) Я в своих проектах ВСЕ светодиоды (5 мм) спокойно подключаю через 100-240 Ом и ни разу проблем не было. Всё работает как надо, даже светодиодные кубики.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое