На сегодняшний день микроконтроллеры являются неотъемлемой частью практически любого электронного устройства. Они используются в самых простейших бытовых приборах и в невероятно сложных научных исследованиях.
Данная работа будет представлять собой разработку одного из самых популярных устройств – калькулятора. Проект будет реализован на базе микроконтроллера Arduino Uno, также будут сделаны структурные и блок схемы устройства, написан программный код. Для создания проекта достаточно обладать базовыми знаниями микропроцессорной техники. Для симуляции устройства использовался пакет программ для автоматизированного проектирования электронных схем (САПР) Proteus 8 версии.
Видео работы устройства в Proteus 8
Обзор аналогов на базе других микроконтроллеров
Калькулятор является очень распространённым электронным прибором, очевидно поэтому способов его реализации на других микроконтроллерах также очень много, ниже будут приведены некоторые альтернативные решения.
Калькулятор на базе микроконтроллера PIC16F873
Микроконтроллер DD1 работает от внутреннего тактового RC-генератора (это позволяет отказаться от кварцевого резонатора). Резистор R2 — частотозадающий для этого генератора, а резистор R1 предотвращает случайный нежелательный перевод микроконтроллера в исходное состояние электромагнитными наводками. Микроконтроллер работает по программе, которую необходимо занести в его память с помощью программатора. Вводимые числа, результаты вычислений и пояснительные надписи отображаются на табло буквенно-цифрового ЖКИ HG1 со встроенным контроллером HD44780. Резистор R4 ограничивает ток подсветки индикатора.
Клавиатура представляет собой прямоугольную матрицу из сорока кнопок SB1— SB40. Диоды VD1—VD8 предотвращают замыкание линий порта B в микроконтроллере при одновременном нажатии на несколько кнопок. Для линий порта А, соединенных с клавиатурой, подобная защита не требуется.
Обмен информацией с ЖКИ ведется по восьмиразрядной двунаправленной шине данных с задействованным флагом занятости BF. Шина использует порт B микроконтроллера совместно с клавиатурой. Для предотвращения конфликтов, возникающих при нажатиях на кнопки во время обращения микроконтроллера к ЖКИ, программа конфигурирует на время таких обращений линии порта А как входные. Это исключает возможность замыкания линий порта B на общий провод через диоды VD1—VD8 и выходные буферы порта А.
Калькулятор на базе Arduino Mega
При нажатии на клавиши калькулятор показывает предупреждение, запрашивающее пользователя выбрать правильную операцию.
После выбора задачи калькулятор дает пользователю ввести первую цифру первого числа. Затем должен быть напечатана вторая цифра. У калькулятора 99999 — наибольшее число, т.е. возможно ввести только 5 цифр на число. При вводе 5-значного числа калькулятор переключается на следующий шаг. Если длина числа меньше 5 знаков, то оно подтверждается кнопкой «OK», а затем пишется второе число. Этой же клавишей подтверждается окончания набора второго числа.
Результат расчета отображается на ЖК-дисплее, пока пользователь не нажмет клавишу DEL.
Нажатие клавиши DEL прерывает текущую операцию и возвращает к начальному экрану. Удаление последнего номера или цифры не допускается
Калькулятор на базе микроконтроллера Н1806ВМ2
Используется:
· МК Н1806ВМ2
· Микросхема М1801РР1 и КР537РУ11
· Индикатор буквенный АЛС363 (или похожие аналоги из серии АЛС)
· Интегральные схемы ЭКФ1564
Для ввода используется 2 линий порта опроса клавиатуры, для вывода — 1 бит (самый младший) звукового 4-бит ЦАП. Значения выводятся на матричный 5x7 дисплей АЛС363. Клавиатура состоит из 18 клавиш (10 цифровых и 8 операционных).
Все приведенные выше аналоги имеют недостатки по сравнению со схемой и элементами, рассматриваемыми в данном проекте:
Микроконтроллер PIC16F873 сложен в программировании по сравнению с ATMega328. Хоть оба МК и используют один язык программирования C, но код, написанный в среде Arduino, интуитивно более понятен чем код на MPLAB. Стоит отметить, что IDE MPLAB имеет намного больший и мощный функционал по сравнению с IDE Arduino, однако он избыточен для такого проекта.
Калькулятор на базе Arduino Mega почти схож с тем, что рассматривается в данном проекте, однако мощности Arduino Uno вполне достаточно для реализации проекта, к тому же, масса и габариты плат не в пользу Arduino Mega.
Микроконтроллер Н1806ВМ2 на сегодняшний день является устаревшим. Схема калькулятора на его основе очень сложная в реализации и требует множество электронных компонентов для работы.
Исходя из вышеописанного следует вывод, что реализация калькулятора на базе Arduino Uno является самым сбалансированным: плата доступна в свободной продаже, простой и понятный IDE позволяет быстро освоить его программирование, достаточная мощность для комфортной работы устройства.
Разработка структурной схемы
Для реализации калькулятора не требуется множество функциональных блоков т.к. вся полезная работа устройства происходит в самом микроконтроллере, поэтому необходимы лишь блоки для управления устройством человеком:
Клавиатура
Экран
Сама структурная схема очень проста и приведена на рисунке ниже
Устройство состоит всего из 3 блоков. Первый - клавиатура, с нее мы вводим необходимые данные. Второй - плата Arduino UNO, которая обрабатывает поступающие данные. Третий - ЖК дисплей, который выводит поступающие на плату данные и выводит конечный результат.
Разработка схемы электрической принципиальной
Разработка электрической схемы производилась в САПР Proteus 8. Программа имеет все необходимые компоненты для построения схемы и ее симуляции:
Плата Arduino UNO
LCD дисплей LM016L
Клавиатура 4x4
Библиотеки для симуляции работы микроконтроллеров AVR.
Сама схема с распиновкой представлена на рисунке ниже.
Выбор компонентов устройства
Выбор микроконтроллера
Для реализации устройства была выбрана платформа Arduino UNO на базе микроконтроллера ATmega328. Платформа имеет 14 цифровых вход/выходов (6 из которых могут использоваться как выходы ШИМ), 6 аналоговых входов, кварцевый генератор 16 МГц, разъем USB, силовой разъем, разъем ICSP и кнопку перезагрузки. Для работы достаточно подключить платформу к компьютеру посредством кабеля USB, либо подать питание при помощи адаптера AC/DC или батареи. Arduino Uno может получать питание через подключение USB или от внешнего источника питания. Источник питания выбирается автоматически.
Характеристики Arduino UNO
Микроконтроллер: ATmega328
Рабочее напряжение: 5 В
Входное напряжение: 7-12 В
Входное напряжение: 6-20 В
Цифровые Входы/Выходы: 14 (6 из которых могут использоваться как выходы ШИМ)
Аналоговые входы: 6
Постоянный ток через вход/выход: 40 мА
Постоянный ток для вывода 3.3В: 50 мА
Флеш-память: 32 Кб (ATmega328) из которых 0.5 Кб используются для загрузчика
ОЗУ: 2 Кб
EEPROM: 1 Кб
Тактовая частота: 16 МГц
Внешнее питание (не USB) может подаваться через преобразователь напряжения AC/DC (блок питания) или аккумуляторной батареей. Преобразователь напряжения подключается посредством разъема 2.1 мм с центральным положительным полюсом. Провода от батареи подключаются к выводам Gnd и Vin разъема питания. Платформа может работать при внешнем питании от 6В до 20 В. При напряжении питания ниже 7 В, вывод 5V может выдавать менее 5 В, при этом платформа может работать нестабильно. При использовании напряжения выше 12В регулятор напряжения может перегреться и повредить плату. Рекомендуемый диапазон от 7В до 12 В.
Микроконтроллер ATmega328 располагает 32кБ флэш памяти, из которых 0.5кБ используется для хранения загрузчика, а также 2кБ ОЗУ (SRAM) и 1Кб EEPROM. (которая читается и записывается с помощью библиотеки EEPROM).
На платформе Arduino Uno установлено несколько устройств для осуществления связи с компьютером, другими устройствами Arduino или микроконтроллерами. ATmega328 поддерживают последовательный интерфейс UART TTL (5 В), осуществляемый выводами 0 (RX) и 1 (TX). Установленная на плате микросхема ATmega8U2 направляет данный интерфейс через USB, программы на стороне компьютера "общаются" с платой через виртуальный COM порт. Прошивка ATmega8U2 использует стандартные драйвера USB COM, никаких стороних драйверов не требуется, но на Windows для подключения потребуется файл ArduinoUNO.inf. Мониторинг последовательной шины (Serial Monitor) программы Arduino позволяет посылать и получать текстовые данные при подключении к платформе. Светодиоды RX и TX на платформе будут мигать при передаче данных через микросхему FTDI или USB подключение (но не при использовании последовательной передачи через выводы 0 и 1).
Библиотекой SoftwareSerial возможно создать последовательную передачу данных через любой из цифровых выводов Uno.
ATmega328 поддерживает интерфейсы I2C (TWI) и SPI. В Arduino включена библиотека Wire для удобства использования шины I2C.
Платформа программируется посредством ПО Arduino. Из меню Tools>Board выбирается «Arduino Uno» (согласно установленному микроконтроллеру).
Микроконтроллер ATmega328 поставляется с записанным загрузчиком, облегчающим запись новых программ без использования внешних программаторов. Связь осуществляется оригинальным протоколом STK500
Имеется возможность не использовать загрузчик и запрограммировать микроконтроллер через выводы ICSP (внутрисхемное программирование).
В Arduino Uno встроен самовосстанавливающийся предохранитель (автомат), защищающий порт USB компьютера от токов короткого замыкания и сверхтоков. Хотя практически Хотите добавить подпись к фотографии? Нажмите значок настройки. все компьютеры имеют подобную защиту, тем не менее, данный предохранитель обеспечивает дополнительный барьер. Предохранитель срабатывает при прохождении тока более 500 мА через USB порт и размыкает цепь до тех пока нормальные значения токов не будут восстановлены.
Длина и ширина печатной платы составляют 6.9 и 5.3 см соответственно. Малые габариты являются одним из достоинств этой платы для реализации устройства.
Выбор дисплея
ЖК дисплей LM016L на основе микроконтроллера HD44780 является наиболее часто используемым в электронике. Его можно встретить в кофейных автоматах, часах, копирах, принтерах, роутерах и т.п.
ЖК дисплей представляет из себя модуль, состоящий из микроконтроллера HD44780 разработанный фирмой Hitachi и непосредственно самим ЖК дисплеем. Микроконтроллер принимает команды и обрисовывает соответствующие символы на ЖК дисплее.
Характеристики LCD дисплея LM016L
Размеры: 80 x 36мм
Рабочая температура: 0 - 50°C
Подсветка: голубая
Цвет символов: белый
Размер символа: 4.35 x 2.95мм
Формат: 16 x 2
Размеры точки: 0.5 x 0.5мм
Интерфейс: HD44780
Видимая область: 64.5 x 13.8мм
Питание: 5В
Существует огромное количество разновидностей данного ЖК модуля, он может быть 1, 2, 4 - строчный с различным числом символов на строке, с подсветкой или без, с различным цветом подсветки и т.п. Объединяет их всех наличие микроконтроллера HD44780, зная команды которого можно без проблем использовать в своих проектах ту или иную модификацию.
Преимуществом данного дисплея является наличие библиотеки «LiquidCrystal» в среде программирования Arduino IDE, что значительно упрощает работу с ним.
Выбор цифрового блока
Для работы с устройством используется программируемая матричная 4x4 клавиатура с цифровыми клавишами от 0 до 9, клавишами для выполнения простых математических операций (сложение, вычитание, умножение, деление) и кнопкой включения и выключения. Все клавиши программируемы, при необходимости для каждой из них можно задать определенную функцию.
Для реализации устройства можно использовать любую матричную клавиатуру 4x4 в среде. В данном случае используется готовая клавиатура в САПР Proteus 8 со специально обозначенными клавишами математических операций, это позволяет удобно работать с устройством.
Программная часть
Разработка алгоритма работы устройства
Блок-схема устройства максимально проста и представлена ниже.
Код
Язык программирования большинства устройств основан на низкоуровневом C/C++, от чего он является довольно сложным в освоении. Однако для Arduino этот язык скомпилирован с библиотекой AVR Libc, что значительно упрощает его в освоении и позволяет использовать любые функции Arduino.
#include <LiquidCrystal.h> // Подключение библиотеки для дисплея
#include <Keypad.h> // Подключение библиотеки для клавиатуры
const byte ROWS = 4; // Инициализация константы «столбцы»
const byte COLS = 4; // Инициализация константы «строки»
char keys[ROWS][COLS] = {
{'7','8','9','D'},
{'4','5','6','C'},
{'1','2','3','B'},
{'*','0','#','A'}
}; // Инициализация матрицы кнопок клавиатуры
byte rowPins[ROWS] = { 0, 1, 2, 3 }; // Соединение ROW0, ROW1, ROW2, ROW3 к пинам
byte colPins[COLS] = { 4, 5, 6, 7 }; // Соединение COL0, COL1, COL2 к пинам
Keypad kpd = Keypad(makeKeymap(keys),rowPins,colPins,ROWS,COLS); // Создание клавиатуры
const int rs = 8, en = 9, d4 = 10, d5 = 11, d6 = 12, d7 = 13; // Пины к которым подключен ЖК дисплей
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // Настройка пинов дисплея
long Num1,Num2,Number; // Создание переменных для чисел
char key,action; // Создание переменных для клавиш
boolean result = false; // Создание логической функции result
void setup() { // Настройка
lcd.begin(16, 2); // Выбор строки и столбца на дисплее для вывода
lcd.print("Loading"); // Вывод надписи «Loading» на дисплей
lcd.clear(); // Очистка дисплея
}
void loop() { // Основная часть программы
key = kpd.getKey(); // Запись значения нажатой кнопки в переменную
if (key!=NO_KEY) // Проверка условия нажатия
DetectButtons(); // Оператор нажатия кнопок
if (result==true) // Проверка логического условия
CalculateResult(); // Оператор расчета результата
DisplayResult(); // Оператор вывода на дисплей
}
void DetectButtons() // Начало подпрограммы нажатия кнопок
{
lcd.clear(); // Очистка дисплея
if (key=='*') // Если нажата клавиша «*»
{Serial.println ("Button Cancel"); Number=Num1=Num2=0; result=false;} // Вывод «*» при нажатии
if (key == '1') // Если нажата кнопка «1»
{Serial.println ("Button 1"); // Вывести «1»
if (Number==0) // Если нажата переменная равна 0
Number=1; // Присвоить переменной 1
else // Иначе
Number = (Number*10) + 1; // Два нажатия (1=>11 и т.п.)
}
if (key == '4') // Если нажата клавиша «4»
{Serial.println ("Button 4"); // Вывести «4»
if (Number==0) // Если переменная равна 0
Number=4; // Присваивание переменной 4
else // Иначе
Number = (Number*10) + 4; // Добавление младшего разряда
}
if (key == '7') // Если нажата клавиша «7»
{Serial.println ("Button 7"); // Вывести «7»
if (Number==0) // Если переменная равна 0
Number=7; // Присваивание переменной 7
else // Иначе
Number = (Number*10) + 7; // Добавление младшего разряда
}
if (key == '0') // Если нажата клавиша «0»
{Serial.println ("Button 0"); // Вывести «0»
if (Number==0) // Если переменная равна 0
Number=0; // Присваивание переменной 0
else // Иначе
Number = (Number*10) + 0; // Добавление младшего разряда
}
if (key == '2') // Если нажата клавиша «2»
{Serial.println ("Button 2"); // Вывести «2»
if (Number==0) // Если переменная равна 0
Number=2; // Присваивание переменной 2
else // Иначе
Number = (Number*10) + 2; // Добавление младшего разряда
}
if (key == '5') // Если нажата клавиша «5»
{Serial.println ("Button 5"); // Вывести «5»
if (Number==0) // Если переменная равна 0
Number=5; // Присваивание переменной 5
else // Иначе
Number = (Number*10) + 5; // Добавление младшего разряда
}
if (key == '8') // Если нажата клавиша «8»
{Serial.println ("Button 8"); // Вывести «8»
if (Number==0) // Если переменная равна 0
Number=8; // Присваивание переменной 8
else // Иначе
Number = (Number*10) + 8; // Добавление младшего разряда
}
if (key == '#') // Если нажата клавиша «#»
{Serial.println ("Button Equal"); // Вывести «#»
Num2=Number; // Присваивание переменной Num2 значение Number
result = true; // Логическая функция истина
}
if (key == '3') // Если нажата клавиша «3»
{Serial.println ("Button 3"); // Вывести «3»
if (Number==0) // Если переменная равна 0
Number=3; // Присваивание переменной 3
else // Иначе
Number = (Number*10) + 3; // Добавление младшего разряда
}
if (key == '6') // Если нажата клавиша «3»
{Serial.println ("Button 6"); // Вывести «3»
if (Number==0) // Если переменная равна 0
Number=6; // Присваивание переменной 3
else // Иначе
Number = (Number*10) + 6; // Добавление младшего разряда
}
if (key == '9') // Если нажата клавиша «3»
{Serial.println ("Button 9"); // Вывести «3»
if (Number==0) // Если переменная равна 0
Number=9; ; // Присваивание переменной 3
else; // Иначе
Number = (Number*10) + 9; // Добавление младшего разряда
}
if (key == 'A' || key == 'B' || key == 'C' || key == 'D') // Поиск кнопок в 4 столбце
{
Num1 = Number; // Num1 присвоить значение Number
Number =0; // Number присвоить 0
if (key == 'A') // Если нажата клавиша «А»
{Serial.println ("Addition"); action = '+';} // Вывести «+»
if (key == 'B') // Если нажата клавиша «В»
{Serial.println ("Subtraction"); action = '-';} // Вывести «-»
if (key == 'C') // Если нажата клавиша «С»
{Serial.println ("Multiplication"); action = '*';} // Вывести «*»
if (key == 'D') // Если нажата клавиша «D»
{Serial.println ("Devesion"); action = '/';} // Вывести «/»
delay(100); // Задержка 100 мс
}
}
void CalculateResult() // Подпрограмма расчетов
{
if (action=='+') // Если выполняется сумма
Number = Num1+Num2; // Сложить Num1 и Num2
if (action=='-') // Если выполняется разность
Number = Num1-Num2; // Вычесть из Num1 Num2
if (action=='*') // Если выполняется произведение
Number = Num1*Num2; // Умножить Num1 и Num2
if (action=='/') // Если выполняется деление
Number = Num1/Num2; // Разделить Num1 на Num2
}
void DisplayResult() // Подпрограмма вывода результата расчетов
{
lcd.setCursor(0, 0); // Выставить курсор по координатам 0,0
lcd.print(Num1); lcd.print(action); lcd.print(Num2); // Вывести уравнение
if (result==true) // Проверка условия
{lcd.print(" ="); lcd.print(Number);} // Вывести «=» и ответ рядом с уравнением
lcd.setCursor(0, 1); // Выставить курсор по координатам 0,1
lcd.print(Number); // Вывести ответ
}
Моделирование
Для моделирования и проверки устройства использовалась САПР Proteus 8. Пакет представляет собой систему схемотехнического моделирования, базирующуюся на основе моделей электронных компонентов, принятых в PSpice. Отличительной чертой пакета PROTEUS VSM является возможность моделирования работы программируемых устройств: микроконтроллеров, микропроцессоров, DSP и проч. Библиотека компонентов содержит справочные данные. Дополнительно в пакет PROTEUS VSM входит система проектирования печатных плат. Вместе с программой устанавливается набор демонстрационных проектов для ознакомления.
Видео примера работы прикреплено в начале поста.
Заключение
Сегодня мы рассмотрели разработку устройства расчета простейших математических операций на базе Arduino. Устройство удовлетворяет всем техническим параметрам: благодаря использованию платформы Arduino UNO калькулятор имеет малые габариты и массу, при том, что элементная база платформы позволяет полностью покрыть все потребности проекта; все компоненты устройства доступны в свободной продаже по приемлемой стоимости; плата программируется самым популярным языком программирования C/C++ и совместимо со всеми современными компонентами, что позволяет модифицировать устройство в будущем; сама платформа Arduino имеет множество легко подключаемых библиотек и поддержку во многих современных САПР, где постоянно обновляется.
мне кажется, это лучший калькулятор на ардуино, из тех что я видел
Ставьте лайки, подписывайтесь, рассказывайте друзьям.