Многофункциональный шилд работает с платформой Arduino, имеет стандартный форм-фактор, и подключается к Arduino UNO, MEGA, Leonardo и их клонам. На шилде имеется все необходимое для ознакомления и изучения различных датчиков и периферии. Данный шилд можно использовать не только для обучения, но и в готовых конструкциях. Отсутствие проводов облегчает работу новичкам и ускоряет обучение. На Multi-function Shield можно попрактиковаться по управлению светодиодами, кнопками, семисегментном дисплее, сдвиговом регистре, датчиками температуры, инфракрасном датчике и другими модулями. Он не требует дополнительного питания.
Многофункциональный шилд обладает широким спектром функций, что делает его идеальным для начинающих ардуинщиков. Он может быть полезен для продвинутых пользователей, поскольку он имеет встроенные компоненты общего назначения:
Характеристики:
Unit | PIN # |
4 светодиода LEDs | D10, D11, D12, D13 |
3 тактовые кнопки reset button | A1, A2, A3 |
Потенциометр (10 kOм) | A0 |
4-разрядный 7-семисегментный LED индикатор на 2-х сдвиговых регистрах 74HC595 | Latch 4, Clock 7, Data 8 |
Звуковой излучатель (Зуммер) | D3 (digital On/Off) |
Разъем для подключения инфракрасного датчика (remote control) | D2 |
Разъем для подключения аналогово LM35 или цифрового DS18B20 датчиков температуры (Джампер J1 подключает или отключает резистор 10 кОм для правильной работы этих датчиков) | A4 |
Разъем APC220 для подключения модулей (Bluetooth, голосового модуля и др.) | GND, +5v, D0, D1 (rx/tx) |
Свободные пины (с ШИМ (pwm)), например для сервоприводов и др. | D5, D6, D9, A5 |
Кнопка Сброс (Reset) | |
Размеры: | 69 х 53,5 мм |
Напряжение питания: | 5 В |
Для работы с Multi-function Shield необходимо установить следующие библиотеки:
TimerOne, Software I2C, Multi-function shield library
Схема шилда:
Рассмотрим несколько примеров без использования этих библиотек:
- Поморгаем светодиодами.
Четыре светодиода подключены к следующим пинам: D10, D11, D12, D13
Как видите, аноды светодиодов (D1, D2, D3, D4) подключены к +5, а катоды подключены к пинам Arduino через резисторы 510 Ом (R1, R2, R3, R4). Светодиоды загораются, когда на соответствующий пин подается низкий уровень 0 (LOW) и гаснут – когда подаем 1 высокий уровень (HIGH).
Скетч:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | void setup(){ pinMode(10, OUTPUT);//устанавливаем вывод 10 как выход pinMode(11, OUTPUT);//устанавливаем вывод 11 как выход pinMode(12, OUTPUT);//устанавливаем вывод 12 как выход pinMode(13, OUTPUT);//устанавливаем вывод 13 как выход } void loop(){ //==========зажигаем и гасим все 4 светодиода с паузой 1 сек.=============== digitalWrite(10, LOW); //включаем LED (pin 10) digitalWrite(11, LOW); //включаем LED (pin 11) digitalWrite(12, LOW); //включаем LED (pin 12) digitalWrite(13, LOW); //включаем LED (pin 13) delay(1000); //пауза 1 секунда digitalWrite(10, HIGH); //выключаем LED (pin 10) digitalWrite(11, HIGH); //выключаем LED (pin 11) digitalWrite(12, HIGH); //выключаем LED (pin 12) digitalWrite(13, HIGH); //выключаем LED (pin 13) delay(1000); // пауза 1 секунда //==========зажигаем и гасим 4 светодиода по очереди с паузой 1 сек.=============== digitalWrite(10, LOW); //включаем LED (pin 10) delay(1000); //пауза 1 секунда digitalWrite(11, LOW); //включаем LED (pin 11) delay(1000); //пауза 1 секунда digitalWrite(12, LOW); //включаем LED (pin 12) delay(1000); //пауза 1 секунда digitalWrite(13, LOW); //включаем LED (pin 13) delay(1000); //пауза 1 секунда digitalWrite(10, HIGH); //выключаем LED (pin 10) delay(1000); //пауза 1 секунда digitalWrite(11, HIGH); //выключаем LED (pin 11) delay(1000); //пауза 1 секунда digitalWrite(12, HIGH); //выключаем LED (pin 12) delay(1000); //пауза 1 секунда digitalWrite(13, HIGH); //выключаем LED (pin 13) delay(1000); // пауза 1 секунда } |
- Поморгаем светодиодами с использованием цикла for():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | int LEDPIN = 10 ; //Задаем переменную, с подключением 1-ого светодиода к Pin10 int NUMB = 4; //задаем количество светодиодов void setup(){ for (int i = LEDPIN; i < LEDPIN + NUMB; i ++) //изменяем переменную i на единицу в заданном диапазоне pinMode(i, OUTPUT); //Устанавливаем вывод i цифрового ввода/вывода как выход } void loop(){ for (int i = LEDPIN; i < LEDPIN + NUMB; i ++) //изменяем переменную i на единицу в заданном диапазоне { digitalWrite(i, HIGH); //на цифровом выходе i устанавливаем 1. Гасим светодиод. delay(300); //пауза 300мс секунд } for (int i = LEDPIN; i < LEDPIN + NUMB; i ++) //изменяем переменную i на единицу в заданном диапазоне { digitalWrite(i, LOW); //на цифровом выходе i устанавливаем 0. Включаем светодиод. delay(300); //пауза 300мс секунд } } |
- Кнопки
Multi-function Shield имеет 3 пользовательских кнопок A1, A2, A3 и кнопку Сброс.
Эти 3 кнопки подключены через подтягивающие резисторы 10 кОм к напряжению +5в. Т.е. на пинах A1, A2, A3 находится высокий уровень 1 (HIGH), а при нажатии на кнопку низкий уровень 0 (LOW).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | //зажигаем светодиоды кнопками int ledpin1 = 10; //задаем переменную ledpin1 и подсоединяем к выводу 10 int ledpin2 = 11; //задаем переменную ledpin2 и подсоединяем к выводу 11 int ledpin3 = 12; //задаем переменную ledpin3 и подсоединяем к выводу 12 int inpin1=A1; //задаем переменную inpin1 и подсоединяем к выводу A1 int inpin2=A2; //задаем переменную inpin2 и подсоединяем к выводу A2 int inpin3=A3; //задаем переменную inpin3 и подсоединяем к выводу A3 int val;//задаем переменную val void setup(){ pinMode(ledpin1,OUTPUT);//устанавливаем вывод 10 как выход pinMode(ledpin2,OUTPUT);//устанавливаем вывод 11 как выход pinMode(ledpin3,OUTPUT);//устанавливаем вывод 12 как выход pinMode(inpin1,INPUT);//устанавливаем вывод A1 как вход pinMode(inpin2,INPUT);//устанавливаем вывод A2 как вход pinMode(inpin3,INPUT);//устанавливаем вывод A3 как вход } void loop(){ val=digitalRead(inpin1);//считываем данные порта в переменную val if(val==LOW) //выполняем условие, если в переменную записан 0, то гасим светодиод { digitalWrite(ledpin1,LOW);} else //иначе, включаем { digitalWrite(ledpin1,HIGH);} val=digitalRead(inpin2);//считываем данные порта в переменную val if(val==LOW) //выполняем условие, если в переменную записан 0, то гасим светодиод { digitalWrite(ledpin2,LOW);} else //иначе, включаем { digitalWrite(ledpin2,HIGH);} val=digitalRead(inpin3);//считываем данные порта в переменную val if(val==LOW) //выполняем условие, если в переменную записан 0, то гасим светодиод { digitalWrite(ledpin3,LOW);} else //иначе, включаем { digitalWrite(ledpin3,HIGH);} } |
Следующий скетч позволяет использовать кнопку пользователя для генерации звука через встроенный зуммер.Зуммер на этом многофункциональном шилде достаточно громкий, он подключен к транзистору Q1. Этот p-n-p-транзистор подает звуковой сигнал, когда на пине D3 низкий уровень 0 (LOW). В техническом описании вы можете увидеть схему подключения.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #define ON LOW //задаем включение зуммера #define OFF HIGH //задаем выключение зуммера #define BUZZER 3 //подключаем зуммер к пину 3 #define KEY1 A1 //подключаем кнопку к пину А1 void setup(){ /* конфигурируем выводы*/ pinMode(KEY1, INPUT); //кнопка А1 как вход pinMode(BUZZER, OUTPUT); //зуммер 3 как выход digitalWrite(BUZZER, OFF);//выключаем звук зуммера } void loop(){ if( digitalRead(KEY1)==ON ) //нажимаем кнопку KEY1 { digitalWrite(BUZZER, ON); //зуммер включен } else{ digitalWrite(BUZZER, OFF); //зуммер выключен } } |
- Потенциометр
Данный переменный резистор сопротивлением 10 кОм средней ножкой подключен к аналоговому входу А0. Сглаживающий конденсатор С1 уменьшает помехи.
Считываем значение потенциометра на аналоговом входе в порт, крутим потенциометр и смотрим, как меняются показания от 0 до 1023.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #define Pot A0 //Определяем вывод А0 как вход потенциометра int Val = 0; //задаем переменную Val void setup(){ Serial.begin(9600); } void loop(){ Val = analogRead(Pot); //считываем данные в переменную val Serial.print("Pot = ");//пишем в порт текст Serial.println(Val);//отправляем значение переменной Val в порт. Крутим потенциометр и смотрим, как меняются показания от 0 до 1023. delay(500); //пауза 500мс } |
- Потенциометр и управление яркостью светодиодов.
Посмотрим как будет меняться яркость светодиодов. При вращении потенциометра значение будет менятся от 0 до 255. Запишем в скетч только два светодиода, подключеные к пинам D12 и D11. Контакт D11 имеет ШИМ (Широтно-импульсная модуляция), поэтому яркость этого светодиода будет менятся плавно. А контакт D12 не имеет ШИМ (PWM). И яркость этого светодиода будет меняться скачком 0 или 1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | int potpin=A0;//задаем вывод потенциометра A0. int ledpin=12;//задаем переменную ledpin и подсоединяем к выводу 12(без ШИМ) int ledpin1=11;//задаем переменную ledpin1 и подсоединяем к выводу 11(с ШИМ) int val=0;// задаем переменную Val void setup(){ Serial.begin(9600); } void loop(){ val=analogRead(potpin);// считываем данные порта в переменную val Serial.println(val);//отправляем значение переменной Val в порт.(от 0 до 1023) analogWrite(ledpin,val/4);// при вращении потенциометра на ledpin значение будет менятся от 0 до 255. Яркость светодиода меняется скачком 0 или 1.(нет ШИМ(PWM)) analogWrite(ledpin1,val/4);// при вращении потенциометра на ledpin1 значение будет менятся от 0 до 255. Яркость светодиода меняется плавно.(есть ШИМ(PWM)) delay(100);//пауза 100мс } |
- 4-разрядный 7-семисегментный LED индикатор на 2-х сдвиговых регистрах 74HC595
Схема:
Сдвиговый регистр 74HC595 c SPI интерфейсом. Это один из самых простых регистров, который преобразует последовательную шину в параллельную. Микросхема принимает на вход последовательность 8-битных данных, которые затем преобразует в логические состояния на 8-пиновом выходе. В данном случае используется две микросхемы. Одна отвечает за данные разрядов, вторая – за данные чисел.
— Ножка 14 микросхемы подключена к контакту D8. Это линия передачи данных(SDI). В скетче обозначаем DATA_DIO.
— Ножка 11 микросхемы подключена к контакту D7. Это линия тактирования (SFTCLK). В скетче обозначаем CLK_DIO.
— Ножка 12 микросхемы подключена к контакту D4. Это линия синхронизации данных, защелка (LCHCLK). В скетче обозначаем LATCH_DIO.
Запишем числа 5, 6, 7, 8 в наш дисплей:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // Определяем контакты сдвигового регистра,используемые для семисегментного дисплея #define LATCH_DIO 4 //линия синхронизации данных, защелка (LCHCLK) #define CLK_DIO 7 //линия тактирования (SFTCLK) #define DATA_DIO 8 //линия передачи данных(SDI) /* байты чисел от 0 до 9 */ const byte SEGMENT_MAP[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90}; /* Байт-карты для выбора разряда дисплея от 1 до 4 */ const byte SEGMENT_SELECT[] = {0xF1,0xF2,0xF4,0xF8}; void setup (){ /* Установите выходы DIO как выходы */ pinMode(LATCH_DIO,OUTPUT); pinMode(CLK_DIO,OUTPUT); pinMode(DATA_DIO,OUTPUT); } void loop(){ /* Обновить дисплей с текущим значением счетчика */ WriteNumberToSegment(0 , 5);//записываем в нулевой (старший) разряд 5 WriteNumberToSegment(1 , 6);//записываем в 1 разряд 6 WriteNumberToSegment(2 , 7);//записываем в 2 разряд 7 WriteNumberToSegment(3 , 8);//записываем в 3 разряд 8 } /* отправляем десятичное число от 0 до 9 в один из четырех разрядов дисплея */ void WriteNumberToSegment(byte Segment, byte Value) { digitalWrite(LATCH_DIO,LOW); shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_MAP[Value]); shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_SELECT[Segment] ); digitalWrite(LATCH_DIO,HIGH); } |
- Цифровой датчик температуры DS18b20
Будем использовать библиотеку для Multi-function Shield, про которую я упоминал выше.
TimerOne, Software I2C, Multi-function shield library
Она упрощает работу с дисплеем и с датчиками.
Схема подключения датчика DS18b20 на шилде:
NOTE: джампер J1 необходимо включить в shield, для корректной работы датчика DS18b20.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | //подключаем необходимые библиотеки #include <TimerOne.h> #include <MultiFuncShield.h> #include <OneWire.h> #include <DallasTemperature.h> OneWire oneWire(18); // вход датчиков 18b20, А4. DallasTemperature ds(&oneWire); // NOTE: джампер J1 необходимо включить shield, для корректной работы датчика 18b20. void setup() { Timer1.initialize(); //инициализация таймера MFS.initialize(&Timer1); // инициализация multi-function shield library Serial.begin(9600); ds.begin(); // инициализация } void loop() { ds.requestTemperatures(); // считываем температуру с датчика MFS.write(ds.getTempCByIndex(0) , 1); // отправляем значение температуры на дисплей с 1-м знаком после запятой. Serial.println(ds.getTempCByIndex(0)); delay(100); } |
- Аналоговый датчик температуры LM35
Этот датчик подключается в тот же разъем, что и DS18b20. Он имеет обратную цоколевку.
NOTE: джампер J1 необходимо убрать из shield, для корректной работы датчика LM35.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // NOTE: джампер J1 необходимо извлеч из shield, для корректной работы датчика LM35. //подключаем необходимые библиотеки #include ; #include ; #include ; void setup() { Timer1.initialize(); //инициализация таймера MFS.initialize(Timer1); // инициализация multi-function shield library // Инициализация с использованием фильтра нижних частот. // Выберите либо: SMOOTHING_NONE, SMOOTHING_MODERATE or SMOOTHING_STRONG MFS.initLM35(SMOOTHING_MODERATE); } void loop() { int tempCentigrade = MFS.getLM35Data(); // считываем данные в переменную умноженные на 10. MFS.write((float)tempCentigrade / 10, 1); // выводим на дисплей температуру в гр.цельсия (/10) и с одним знаком после запятой. delay(100); } |
- Потенциометр и библиотека Multi-function shield library.
Выведем значение потенциометра на дисплей:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //подключаем необходимые библиотеки #include ; #include ; #include ; void setup() { Timer1.initialize(); //инициализация таймера MFS.initialize(Timer1); // инициализация multi-function shield library } void loop() { MFS.write(analogRead(POT_PIN)); //считываем температуру с потенциометра непосредственно в дисплей delay(100); //пауза 100 мс } |
- Цифровые часы с будильником
Этот скетч демонстрирует цифровые часы с будильником. После включения и загрузки программы дисплей начинает мигает, пока пользователь не установит время. Удерживайте кнопку 1, чтобы установить время. Последовательно начинают мигать часы, затем минуты. Кнопкой 3 устанавливаем нужное значение.
Удерживая одновременно кнопки 1 и 2 также можно установить будильник.
Удерживая кнопку 3 можно включить или выключить будильник. При этом загорается светодиод 1 (D13).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | #include ; #include ; #include ; /* button 1 : удерживайте, чтобы установить время button 2 : нажмите, чтобы посмотреть время будильника button 3 : установкв времени, при удержании: вкл/откл будильника LED1 : on = будильник включен */ volatile unsigned int clockMilliSeconds = 0; volatile byte clockSeconds = 0; volatile byte clockMinutes = 0; volatile byte clockHours = 12; volatile byte clockEnabled = 1; byte alarmMinutes = 30; byte alarmHours = 6; volatile byte alarmEnabled = false; byte alarmTogglePressed = false; enum displayModeValues { MODE_CLOCK_TIME, MODE_CLOCK_TIME_SET_HOUR, MODE_CLOCK_TIME_SET_MINUTE, MODE_ALARM_TIME, MODE_ALARM_TIME_SET_HOUR, MODE_ALARM_TIME_SET_MINUTE }; byte displayMode = MODE_CLOCK_TIME; //------------------------------------------------------------------------------- void setup(){ Timer1.initialize(); MFS.userInterrupt = clockISR; MFS.initialize(Timer1); MFS.blinkDisplay(DIGIT_ALL); //MFS.beep(500); } void loop(){ byte btn = MFS.getButton(); switch (displayMode) { case MODE_CLOCK_TIME: displayTime(clockHours, clockMinutes); if (btn == BUTTON_2_PRESSED){ MFS.beep(0); // cancel the alarm. displayMode = MODE_ALARM_TIME; } else if (btn == BUTTON_1_LONG_PRESSED) { MFS.blinkDisplay(DIGIT_ALL, OFF); MFS.blinkDisplay(DIGIT_1 | DIGIT_2); displayMode = MODE_CLOCK_TIME_SET_HOUR; clockEnabled = false; clockMilliSeconds = 0; clockSeconds = 0; } else if (btn == BUTTON_3_LONG_PRESSED !alarmTogglePressed) { alarmTogglePressed = true; alarmEnabled = !alarmEnabled; MFS.writeLeds(LED_1, alarmEnabled); } else if (btn == BUTTON_3_LONG_RELEASE) { alarmTogglePressed = false; } break; case MODE_CLOCK_TIME_SET_HOUR: if (btn == BUTTON_1_PRESSED) { MFS.blinkDisplay(DIGIT_1 | DIGIT_2, OFF); MFS.blinkDisplay(DIGIT_3 | DIGIT_4); displayMode = MODE_CLOCK_TIME_SET_MINUTE; } else if (btn == BUTTON_3_PRESSED || btn == BUTTON_3_LONG_PRESSED) { clockHours++; if (clockHours = 24) { clockHours = 0; } displayTime(clockHours, clockMinutes); } break; case MODE_CLOCK_TIME_SET_MINUTE: if (btn == BUTTON_1_PRESSED) { MFS.blinkDisplay(DIGIT_3 | DIGIT_4, OFF); displayMode = MODE_CLOCK_TIME; clockEnabled = true; } else if (btn == BUTTON_3_PRESSED || btn == BUTTON_3_LONG_PRESSED) { clockMinutes++; if (clockMinutes = 60) { clockMinutes = 0; } displayTime(clockHours, clockMinutes); } break; case MODE_ALARM_TIME: displayTime(alarmHours, alarmMinutes); if (btn == BUTTON_2_SHORT_RELEASE || btn == BUTTON_2_LONG_RELEASE) { displayMode = MODE_CLOCK_TIME; } else if (btn == BUTTON_1_LONG_PRESSED) { MFS.blinkDisplay(DIGIT_ALL, OFF); MFS.blinkDisplay(DIGIT_1 | DIGIT_2); displayMode = MODE_ALARM_TIME_SET_HOUR; alarmEnabled = false; } break; case MODE_ALARM_TIME_SET_HOUR: if (btn == BUTTON_1_PRESSED) { MFS.blinkDisplay(DIGIT_1 | DIGIT_2, OFF); MFS.blinkDisplay(DIGIT_3 | DIGIT_4); displayMode = MODE_ALARM_TIME_SET_MINUTE; } else if (btn == BUTTON_3_PRESSED || btn == BUTTON_3_LONG_PRESSED) { alarmHours++; if (alarmHours = 24) { alarmHours = 0; } displayTime(alarmHours, alarmMinutes); } break; case MODE_ALARM_TIME_SET_MINUTE: if (btn == BUTTON_1_PRESSED) { MFS.blinkDisplay(DIGIT_3 | DIGIT_4, OFF); displayMode = MODE_CLOCK_TIME; alarmEnabled = true; MFS.writeLeds(LED_1, ON); } else if (btn == BUTTON_3_PRESSED || btn == BUTTON_3_LONG_PRESSED) { alarmMinutes++; if (alarmMinutes = 60) { alarmMinutes = 0; } displayTime(alarmHours, alarmMinutes); } break; } } void displayTime (byte hours, byte minutes) { char time[5]; sprintf(time, "%03d", (hours * 100) + minutes); MFS.write(time, 1); } //-------------------------------------------------------------------------------- void clockISR () { // Perform ripple count for all time components. if (clockEnabled) { clockMilliSeconds++; if (clockMilliSeconds = 1000) { clockMilliSeconds = 0; clockSeconds++; if (clockSeconds = 60) { clockSeconds = 0; clockMinutes++; if (clockMinutes = 60) { clockMinutes = 0; clockHours++; if (clockHours = 24) { clockHours = 0; } } //Если текущее время совпадает с временем будильника, а сигнал тревоги включен, включите будильник. if (alarmEnabled (clockMinutes == alarmMinutes) (clockHours == alarmHours)) { MFS.beep( 10, // период вкл 5, // период выклциклов 100, // количество витков цикла 50 // задержка между витками цикла ); } } } } } |
Здравствуйте . Не могли бы Вы исправить скетч -Цифровые часы с будильником — при загрузке в ардуино он не работает . Есть утверждение на форумах что в нём нет треугольных скобок и амперсандра … Внесите пожалуйста ясность в этот вопрос . В чём я ошибаюсь ?