В этом уроке мы создадим дешифратор азбуки Морзе. Датчик звука преобразует звуковой сигнал в электрический и отправит его в Arduino. Arduino дешифрует принятые данные и отправит их, либо в монитор последовательного порта, либо на символьный дисплей LCD1602 I2C, либо в термопринтер UART. В Arduino нужно загрузить один из трёх скетчей, в зависимости от собранного устройства.
Нам понадобится:
- Arduino Uno х 1шт.
- Trema датчик звука x 1шт.
- Trema Shield x 1шт.
В зависимости от собираемой схемы понадобится одно из устройств вывода информации и библиотека:
- Дисплей LCD1602 I2C зелёный или синий x 1шт.
- Библиотека LiquidCrystal_I2C для работы с дисплеем LCD1602 I2C.
- Термопринтер x 1шт.
- Библиотека Adafruit_Thermal для работы с термопринтером.
О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE. Более подробно о работе с LCD дисплеем и термопринтером можно ознакомиться на страницах: WiKi - работа с символьными ЖК дисплеями и Wiki - работа с термопринтерами.
Видео:
Схемы подключения:
Схема подключения зависит от используемого устройства вывода данных.
Вывод данных в LCD дисплей:
Трема датчик звука подключается в аналоговому выводу A3 (номер хранится в константе pinSensor - его можно изменить). LCD дисплей подключается к аппаратной шине I2C.
Вывод данных в термопринтер:
Трема датчик звука подключается в аналоговому выводу A3 (номер хранится в константе pinSensor - его можно изменить). Термопринтер подключается по программной шине UART с назначенными в скетче выводами TX и RX. Номера выводов указываются при объявлении объекта mySerial(RX, TX) библиотеки SoftwareSerial, которая входит в стандартный набор Arduino IDE. В скетче RX объявлен как 5 вывод Arduino (он подключается к зелёному TX выводу принтера), а TX объявлен как 6 вывод Arduino (он подключается к синему RX выводу принтера). Жёлтый вывод (DTR) принтера не используется. Термопринтер запитывается от отдельного источника питания от 5 до 9 В постоянного тока, при этом красный провод подключается к + питания, а черный к - и к выводу GND Arduino.
Вывод данных в монитор последовательного порта:
Трема датчик звука подключается в аналоговому выводу A3 (номер хранится в константе pinSensor - его можно изменить). Дополнительные устройства не подключаются.
Алгоритм работы:
Часть скетча отвечающая за дешифрование сигнала одинакова для каждого устройства:
- В начале создаются три массива:
- chrMorze - содержит символы;
- lenMorze - содержит количество точек или тире для символа;
- varMorze - содержит комбинацию точек и тире для символа (точка = 0, тире = 1);
Пример: возьмем седьмой элемент каждого массива - из массива chrMorze понятно что это символ «G», из массива lenMorze понятно что он состоит из 3 точек или тире, а из массива varMorze понятно, что комбинация равна значению 0x6 = 0b00000110. Берем последние 3 бита - 110, точка = 0, тире = 1, значит в азбуке Морзе это « – – • ». - Так же создаются константы:
- pinSensor - хранит номер вывода к которому подключён датчик звука;
- varVolume - хранит уровень громкости на который требуется реагировать. Чем ниже уровень, тем чувствительнее датчик звука;
- tmrSignal - хранит время в миллисекундах для определения точек и тире (если сигнал был длиннее этого времени - значит это тире, а если короче - значит это точка);
- tmrPause - хранит время в миллисекундах для определения окончания приёма символа (если пауза между сигналами была длиннее этого времени - значит передача символа закончена, а если короче - значит символ еще принимается).
- Декодирование осуществляется в коде loop и состоит из 3 частей: фиксация звука, фиксация паузы, вывод символа.
- Если в первой части зафиксирован звук, то устанавливаем флаг наличия принятого сигнала flgSignal, увеличиваем счетчик точек/тире lenLetter, сохраняем время его фиксациии и входим в цикл while пока звук не исчезнет. После исчезновения звука определяем его длительность вычитая текущее время из ранее сохранённого.
- Если во второй части зафиксирована пауза, то сохраняем время её фиксации и входим в цикл while пока пауза не исчезнет или не пройдёт время tmrPause означающее об окончании приёма символа. После выхода из цикла проверяется причина выхода из него (закончена пауза или истекло время). Если закончена пауза, то опять начинает выполняться первая часть декодирования, иначе устанавливается флаг flgLetter разрешающий переход в третью часть декодирования.
- Третья часть часть декодирования заключается в определении принятого символа (по трём массивам: chrMorze, lenMorze, varMorze) и выводе этого символа в устройство вывода.
Код программ:
Код программы зависит от используемого устройства вывода данных.
Вывод данных в LCD дисплей:
#include <Wire.h> // Подключаем библиотеку для работы с шиной I2C #include <LiquidCrystal_I2C.h> // Подключаем библиотеку для работы с LCD дисплеем по шине I2C LiquidCrystal_I2C lcd(0x27,16,2); // Объявляем объект библиотеки LiquidCrystal_I2C, указывая параметры дисплея (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2) const uint8_t pinSensor = A3; // Определяем константу с номером вывода к которому подключён датчик звука const uint16_t varVolume = 800; // Определяем константу с уровнем громкости сигнала (принимаются только те сигналы, громкость которых выше указанного уровня) const uint32_t tmrSignal = 300; // Определяем константу с указанием длительности сигнала (если сигнал короче - точка, если сигнал длиннее - тире) const uint32_t tmrPause = 500; // Определяем константу с указанием длительности паузы (если пауза между сигналами дольше, значит начинается новое слово) uint32_t tmrSeparator; // Объявляем переменную для определения граничного времени для сигналов и пауз uint8_t varLetter; // Объявляем переменную для хранения принятых точек и тире одного символа (бит 0 - точка, бит 1 - тире) uint8_t lenLetter; // Объявляем переменную для хранения количества точек и тире в принятом символе bool flgSignal; // Объявляем флаг указывающий на то что была принята хотя бы одна точка или тире bool flgLetter; // Объявляем флаг указывающий на то что был принят символ char chrMorze[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.', ';', ',', ':', '?', '!', '-', ' ', '\n', '\r'}; uint8_t lenMorze[] = { 2, 4, 4, 3, 1, 4, 3, 4, 2, 4, 3, 4, 2, 2, 3, 4, 4, 3, 3, 1, 3, 4, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5}; uint8_t varMorze[] = {0x1, 0x8, 0xA, 0x4, 0x0, 0x2, 0x6, 0x0, 0x0, 0x7, 0x5, 0x4, 0x3, 0x2, 0x7, 0x6, 0xD, 0x2, 0x0, 0x1, 0x1, 0x1, 0x3, 0x9, 0xB, 0xC, 0xF, 0x7, 0x3, 0x1, 0x0, 0x10, 0x18, 0x1C, 0x1E, 0x1F, 0x0, 0x2A, 0x15, 0x38, 0x0C, 0x33, 0x21, 0x11, 0x15, 0x0A}; // Массивы: chrMorze - содержит символы, lenMorze - количество точек и тире в символе, varMorze - комбинация точек и тире (бит 0 - точка, бит 1 - тире) void setup(){ // lcd.init(); // Инициируем работу с LCD дисплеем lcd.backlight(); // Включаем подсветку LCD дисплея lcd.setCursor(0, 0); // Устанавливаем курсор в позицию (0 столбец, 0 строка) lcd.print("Detector Morze"); // Выводим текст "Detector Morze" delay(2000); // Ждём 2 секунды lcd.clear(); // Чистим экран lcd.setCursor(0, 0); // Устанавливаем курсор в позицию (0 столбец, 0 строка) flgLetter=varLetter=lenLetter=0; // Сбрасываем флаги и переменные относящиеся к принятому символу } // // void loop(){ // // Если зафиксирован звук: // if(analogRead(pinSensor) > varVolume){ // Если уровень звука считанный со входа pinSensor превышает значение varVolume flgSignal=true; // Устанавливаем флаг указывающий на наличие сигнала lenLetter++; // Увеличиваем счетчик количества точек и тире в принятом символе tmrSeparator = millis()+tmrSignal; // Определяем граничное время сигнала (если сигнал пропадёт до этого времени - значит принята точка, иначе принято тире) while(analogRead(pinSensor) > varVolume){delay(10);} // Ждём пока не пропадёт сигнал varLetter<<=1; varLetter|=tmrSeparator<millis(); // Сдвигаем все биты переменной varLetter (она хранит принятые точки и тире символа) и записываем в последний бит этой переменной «0» или «1» (зависит от длительности сигнала) // Если зафиксирована пауза: // }else{ // Если уровень звука считанный со входа pinSensor меньше или равен значению varVolume (считаем что это пауза) tmrSeparator = millis()+tmrPause; // Определяем граничное время паузы (если пауза пропадёт до этого времени - значит мы продолжаем принимать символ, иначе символ полностью принят) while(analogRead(pinSensor) < varVolume && tmrSeparator>millis()){delay(10);} // Ждём пока не исчезнет пауза, но не дольше чем время указанное в tmrSeparator if(tmrSeparator<millis()){flgLetter=flgSignal; flgSignal=false;} // Если пауза длилась дольше чем указано в tmrSeparator, то устанавливаем флаг flgLetter, но только если установлен флаг flgSignal указывающий что ранее был принят хотя бы один сигнал } // // Если принят символ: // if(flgLetter){ // Если установлен флаг flgLetter значит символ полностью принят, его нужно сравнить и вывести for(uint8_t i=0; i<46; i++){ // Проходим по всем 46 символам массивов if(varLetter==varMorze[i] && lenLetter==lenMorze[i]){ // Если комбинация точек и тире в varLetter совпала с varMorze[i] и количество точек и тире совпало с lenMorze[i], то... if(i==44 || i==45) {lcd.clear(); lcd.setCursor(0, 0);} // Если найденный символ является символом начала '\n' или конца '\r' строки, то чистим экран и устанавливаем курсор в начало else {lcd.print(chrMorze[i]);} // Если найленный символ не является символом начала '\n' или конца '\r' строки, то просто его выводим на экран (позиция символа на экране смещается автоматически) }} flgLetter=varLetter=lenLetter=0; // Сбрасываем флаги и переменные относящиеся к принятому символу, так как мы его уже вывели } // } //
Вывод данных в термопринтер:
#include <SoftwareSerial.h> // Подключаем библиотеку для работы по программной шине UART #include <Adafruit_Thermal.h> // Подключаем библиотеку для работы с принтером SoftwareSerial mySerial(5, 6); // Объявляем объект библиотеки SoftwareSerial, указывая задействованные выводы Arduino (RX=5-зелёный, TX=6-синий) Adafruit_Thermal printer(&mySerial); // Объявляем объект библиотеки Adafruit_Thermal, указывая ссылку на созданный ранее объект библиотеки SoftwareSerial const uint8_t pinSensor = A3; // Определяем константу с номером вывода к которому подключён датчик звука const uint16_t varVolume = 800; // Определяем константу с уровнем громкости сигнала (принимаются только те сигналы, громкость которых выше указанного уровня) const uint32_t tmrSignal = 300; // Определяем константу с указанием длительности сигнала (если сигнал короче - точка, если сигнал длиннее - тире) const uint32_t tmrPause = 500; // Определяем константу с указанием длительности паузы (если пауза между сигналами дольше, значит начинается новое слово) uint32_t tmrSeparator; // Объявляем переменную для определения граничного времени для сигналов и пауз uint8_t varLetter; // Объявляем переменную для хранения принятых точек и тире одного символа (бит 0 - точка, бит 1 - тире) uint8_t lenLetter; // Объявляем переменную для хранения количества точек и тире в принятом символе bool flgSignal; // Объявляем флаг указывающий на то что была принята хотя бы одна точка или тире bool flgLetter; // Объявляем флаг указывающий на то что был принят символ char* RUS(char*); // Объявляем функцию перевода русских символов из кодировки UTF-8 в кодировку CP866 char chrMorze[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.', ';', ',', ':', '?', '!', '-', ' ', '\n', '\r'}; uint8_t lenMorze[] = { 2, 4, 4, 3, 1, 4, 3, 4, 2, 4, 3, 4, 2, 2, 3, 4, 4, 3, 3, 1, 3, 4, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5}; uint8_t varMorze[] = {0x1, 0x8, 0xA, 0x4, 0x0, 0x2, 0x6, 0x0, 0x0, 0x7, 0x5, 0x4, 0x3, 0x2, 0x7, 0x6, 0xD, 0x2, 0x0, 0x1, 0x1, 0x1, 0x3, 0x9, 0xB, 0xC, 0xF, 0x7, 0x3, 0x1, 0x0, 0x10, 0x18, 0x1C, 0x1E, 0x1F, 0x0, 0x2A, 0x15, 0x38, 0x0C, 0x33, 0x21, 0x11, 0x15, 0x0A}; // Массивы: chrMorze - содержит символы, lenMorze - количество точек и тире в символе, varMorze - комбинация точек и тире (бит 0 - точка, бит 1 - тире) void setup(){ // mySerial.begin(9600); // Инициируем передачу данных по программной шине UART на скорости 9600 бот printer.begin(); // Инициируем работу с принтером printer.justify('C'); // Устанавливаем выравнивание по центру printer.setSize('M'); // Устанавливаем средний размер шрифта printer.setCodePage(CODEPAGE_CP866); // Устанавливаем кодовую таблицу CP866 с поддержкой русского языка printer.println("--------------------------------"); // Выводим текст "--------------------------------" printer.println(RUS("Дешифратор азбуки Морзе")); // Выводим текст "Дешифратор азбуки Морзе" через функцию RUS printer.setSize('S'); // Устанавливаем маленький размер шрифта printer.println("iarduino.ru"); // Выводим текст "iarduino.ru" printer.setSize('M'); // Устанавливаем средний размер шрифта printer.println("--------------------------------"); // Выводим текст "--------------------------------" printer.feed(2); // Прокручиваем ленту на две строки printer.setSize('L'); // Устанавливаем большой размер шрифта flgLetter=varLetter=lenLetter=0; // Сбрасываем флаги и переменные относящиеся к принятому символу } // // void loop(){ // // Если зафиксирован звук: // if(analogRead(pinSensor) > varVolume){ // Если уровень звука считанный со входа pinSensor превышает значение varVolume flgSignal=true; // Устанавливаем флаг указывающий на наличие сигнала lenLetter++; // Увеличиваем счетчик количества точек и тире в принятом символе tmrSeparator = millis()+tmrSignal; // Определяем граничное время сигнала (если сигнал пропадёт до этого времени - значит принята точка, иначе принято тире) while(analogRead(pinSensor) > varVolume){delay(10);} // Ждём пока не пропадёт сигнал varLetter<<=1; varLetter|=tmrSeparator<millis(); // Сдвигаем все биты переменной varLetter (она хранит принятые точки и тире символа) и записываем в последний бит этой переменной «0» или «1» (зависит от длительности сигнала) // Если зафиксирована пауза: // }else{ // Если уровень звука считанный со входа pinSensor меньше или равен значению varVolume (считаем что это пауза) tmrSeparator = millis()+tmrPause; // Определяем граничное время паузы (если пауза пропадёт до этого времени - значит мы продолжаем принимать символ, иначе символ полностью принят) while(analogRead(pinSensor) < varVolume && tmrSeparator>millis()){delay(10);} // Ждём пока не исчезнет пауза, но не дольше чем время указанное в tmrSeparator if(tmrSeparator<millis()){flgLetter=flgSignal; flgSignal=false;} // Если пауза длилась дольше чем указано в tmrSeparator, то устанавливаем флаг flgLetter, но только если установлен флаг flgSignal указывающий что ранее был принят хотя бы один сигнал } // // Если принят символ: // if(flgLetter){ // Если установлен флаг flgLetter значит символ полностью принят, его нужно сравнить и вывести for(uint8_t i=0; i<46; i++){ // Проходим по всем 46 символам массивов if(varLetter==varMorze[i] && lenLetter==lenMorze[i]){ // Если комбинация точек и тире в varLetter совпала с varMorze[i] и количество точек и тире совпало с lenMorze[i], то... if(i==44||i==45){printer.feed(2);} // Если найденный символ является символом начала '\n' или конца '\r' строки, то прокручиваем ленту на две строки else {printer.println(chrMorze[i]);} // Если найденный символ не является символом начала '\n' или конца '\r' строки, то просто его выводим на экран (позиция символа на экране смещается автоматически) }} flgLetter=varLetter=lenLetter=0; // Сбрасываем флаги и переменные относящиеся к принятому символу, так как мы его уже вывели } // } // // // Функция перевода русских символов строки str из кодировки UTF-8 в кодировку CP866: char* RUS(char* str){ // Определяем функцию которая преобразует код русских символов из кодировки UTF-8 в кодировку CP866 uint8_t i=0, j=0; // Определяем переменные: i - счетчик входящих символов, j - счетчик исходящих символов while(str[i]){ // Проходим по всем символам строки str, пока не встретим символ конца строки (код 0) if(uint8_t(str[i]) == 0xD0 && uint8_t(str[i+1]) >= 0x90 && uint8_t(str[i+1]) <= 0xBF ){str[j] = (uint8_t) str[i+1]-0x10; i++;}else // Символы «А-Я а-п» (код UTF-8: D090-D0AF D0B0-D0BF) сохраняем в кодировке CP866: код 80-9F A0-AF (символ занимал 2 байта, а стал занимать 1 байт) if(uint8_t(str[i]) == 0xD1 && uint8_t(str[i+1]) >= 0x80 && uint8_t(str[i+1]) <= 0x8F ){str[j] = (uint8_t) str[i+1]+0x60; i++;}else // Символы «р-я» (код UTF-8: D180-D18F) сохраняем в кодировке CP866: код E0-EF (символ занимал 2 байта, а стал занимать 1 байт) if(uint8_t(str[i]) == 0xD0 && uint8_t(str[i+1]) == 0x81 ){str[j] = 0xF0; i++;}else // Символ «Ё» (код UTF-8: D081) сохраняем в кодировке CP866: код F0 (символ занимал 2 байта, а стал занимать 1 байт) if(uint8_t(str[i]) == 0xD1 && uint8_t(str[i+1]) == 0x91 ){str[j] = 0xF1; i++;}else // Символ «ё» (код UTF-8: D191) сохраняем в кодировке CP866: код F1 (символ занимал 2 байта, а стал занимать 1 байт) {str[j] = (uint8_t) str[i];} j++; i++; // Остальные символы оставляем как есть, без преобразования, но их место в строке могло сдвинуться, если до них были встречены русские символы } while(j<i){str[j]=0; j++;} return str; // Так как место занимаемое символами в строке могло уменьшиться, заполняем оставщиеся байты символами конца строки (код 0) }
Вывод данных в монитор последовательного порта:
const uint8_t pinSensor = A3; // Определяем константу с номером вывода к которому подключён датчик звука const uint16_t varVolume = 800; // Определяем константу с уровнем громкости сигнала (принимаются только те сигналы, громкость которых выше указанного уровня) const uint32_t tmrSignal = 300; // Определяем константу с указанием длительности сигнала (если сигнал короче - точка, если сигнал длиннее - тире) const uint32_t tmrPause = 500; // Определяем константу с указанием длительности паузы (если пауза между сигналами дольше, значит начинается новое слово) uint32_t tmrSeparator; // Объявляем переменную для определения граничного времени для сигналов и пауз uint8_t varLetter; // Объявляем переменную для хранения принятых точек и тире одного символа (бит 0 - точка, бит 1 - тире) uint8_t lenLetter; // Объявляем переменную для хранения количества точек и тире в принятом символе bool flgSignal; // Объявляем флаг указывающий на то что была принята хотя бы одна точка или тире bool flgLetter; // Объявляем флаг указывающий на то что был принят символ char chrMorze[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.', ';', ',', ':', '?', '!', '-', ' ', '\n', '\r'}; uint8_t lenMorze[] = { 2, 4, 4, 3, 1, 4, 3, 4, 2, 4, 3, 4, 2, 2, 3, 4, 4, 3, 3, 1, 3, 4, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5}; uint8_t varMorze[] = {0x1, 0x8, 0xA, 0x4, 0x0, 0x2, 0x6, 0x0, 0x0, 0x7, 0x5, 0x4, 0x3, 0x2, 0x7, 0x6, 0xD, 0x2, 0x0, 0x1, 0x1, 0x1, 0x3, 0x9, 0xB, 0xC, 0xF, 0x7, 0x3, 0x1, 0x0, 0x10, 0x18, 0x1C, 0x1E, 0x1F, 0x0, 0x2A, 0x15, 0x38, 0x0C, 0x33, 0x21, 0x11, 0x15, 0x0A}; // Массивы: chrMorze - содержит символы, lenMorze - количество точек и тире в символе, varMorze - комбинация точек и тире (бит 0 - точка, бит 1 - тире) void setup(){ // flgLetter=varLetter=lenLetter=0; // Сбрасываем флаги и переменные относящиеся к принятому символу Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бит/сек Serial.println("Детектор азбуки Морзе"); // Выводим текст "Детектор азбуки Морзе" Serial.println("====================="); // Выводим текст "=====================" } // // void loop(){ // // Если зафиксирован звук: // if(analogRead(pinSensor) > varVolume){ // Если уровень звука считанный со входа pinSensor превышает значение varVolume flgSignal=true; // Устанавливаем флаг указывающий на наличие сигнала lenLetter++; // Увеличиваем счетчик количества точек и тире в принятом символе tmrSeparator = millis()+tmrSignal; // Определяем граничное время сигнала (если сигнал пропадёт до этого времени - значит принята точка, иначе принято тире) while(analogRead(pinSensor) > varVolume){delay(10);} // Ждём пока не пропадёт сигнал varLetter<<=1; varLetter|=tmrSeparator<millis(); // Сдвигаем все биты переменной varLetter (она хранит принятые точки и тире символа) и записываем в последний бит этой переменной «0» или «1» (зависит от длительности сигнала) // Если зафиксирована пауза: // }else{ // Если уровень звука считанный со входа pinSensor меньше или равен значению varVolume (считаем что это пауза) tmrSeparator = millis()+tmrPause; // Определяем граничное время паузы (если пауза пропадёт до этого времени - значит мы продолжаем принимать символ, иначе символ полностью принят) while(analogRead(pinSensor) < varVolume && tmrSeparator>millis()){delay(10);} // Ждём пока не исчезнет пауза, но не дольше чем время указанное в tmrSeparator if(tmrSeparator<millis()){flgLetter=flgSignal; flgSignal=false;} // Если пауза длилась дольше чем указано в tmrSeparator, то устанавливаем флаг flgLetter, но только если установлен флаг flgSignal указывающий что ранее был принят хотя бы один сигнал } // // Если принят символ: // if(flgLetter){ // Если установлен флаг flgLetter значит символ полностью принят, его нужно сравнить и вывести for(uint8_t i=0; i<46; i++){ // Проходим по всем 46 символам массивов if(varLetter==varMorze[i] && lenLetter==lenMorze[i]){ // Если комбинация точек и тире в varLetter совпала с varMorze[i] и количество точек и тире совпало с lenMorze[i], то... Serial.print(chrMorze[i]); // Выводим символ из chrMorze[i] в монитор последовательного порта }} flgLetter=varLetter=lenLetter=0; // Сбрасываем флаги и переменные относящиеся к принятому символу, так как мы его уже вывели } // } //
Ссылки:
- Код программы вывод данных в LCD дисплей.
- Код программы вывод данных в термопринтер.
- Код программы вывод данных в монитор последовательного порта.
- Библиотека LiquidCrystal_I2C.
- Библиотека Adafruit_Thermal.
- Wiki - Установка библиотек в Arduino IDE.
- WiKi - Работа с символьными ЖК дисплеями.
- Wiki - Работа с термопринтерами.
- Wiki - Trema Shield.
Обсуждение