Освой Arduino играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Термопринтер с интерфейсом TTL

Рассмотрим примеры с термопринтером с интерфейсом TTL.

Thermoprinter

Популярной библиотекой для работы с принтером является библиотека adafruit/Adafruit-Thermal-Printer-Library. Устанавливайте через менеджер библиотек в Arduino IDE.

Будем использовать программную шину UART. Мы можем назначить функции TX и RX шины для любых выводов Arduino UNO. Выводы назначаются при объявлении объекта библиотеки SoftwareSerial:


SoftwareSerial   mySerial(5, 6); // mySerial(RX, TX)

Примеры

Библиотека снабжена несколькими примерами для показа всех основных возможностей принтера: A_printertest, B_charsets, C_barcodes, bitmapImageConvert. Немного видоизменённые примеры представлены ниже.

Основные настройки текста


#include <SoftwareSerial.h>
#include <Adafruit_Thermal.h>

// Объявляем объект библиотеки SoftwareSerial,
// указывая выводы Arduino: RX = 5 (зелёный), TX = 6 (синий). Можно назначить другие выводы Arduino
#define RX_PIN 5
#define TX_PIN 6

SoftwareSerial mySerial(RX_PIN, TX_PIN);

// Объявляем объект библиотеки Adafruit_Thermal, указывая ссылку на созданный объект mySerial
Adafruit_Thermal printer(&mySerial);

void setup() {
  //  Инициируем передачу данных по программной шине UART на скорости 9600.
  // Функцию следует вызвать до вызова функции printer.begin!
  mySerial.begin(9600);

  // Инициируем работу с термопринтером.
  // В качестве параметра можно указать время нагрева пикселей от 3 (0,03 мс) до 255 (2,55 мс),
  // чем выше тем темнее пиксели. Значение по умолчанию = 120 (1,20 мс)
  printer.begin();
  printer.setSize('L');      //  Устанавливаем крупный размер шрифта 'L' (Large)
  printer.println("Large");  //  Выводим текст
  printer.setSize('M');      //  Устанавливаем средний размер шрифта 'M' (Medium)
  printer.println("Medium"); //  Выводим текст
  printer.setSize('S');      //  Устанавливаем маленький размер шрифта 'S' (Small) - используется по умолчанию
  printer.println("Small");  //  Выводим текст

  printer.justify('R');       //  Устанавливаем выравнивание текста по правому краю 'R' (Right)
  printer.println("Right");   //  Выводим текст
  printer.justify('C');       //  Устанавливаем выравнивание текста по центру 'C' (Center)
  printer.println("Center");  //  Выводим текст
  printer.justify('L');       //  Устанавливаем выравнивание текста по левому краю 'L' (Left) - используется по умолчанию
  printer.println("Left");    //  Выводим текст

  printer.inverseOn();        //  Устанавливаем инверсию цвета текста.
  printer.println("Inverse"); //  Выводим текст
  printer.inverseOff();       //  Отменяем инверсию цвета текста.

  printer.doubleHeightOn();          //  Устанавливаем удвоенную высоту текста.
  printer.println("Double Height");  //  Выводим текст
  printer.doubleHeightOff();         //  Отменяем удвоенную высоту текста.

  printer.doubleWidthOn();           //  Устанавливаем удвоенную ширину текста.
  printer.println("Double Width");   //  Выводим текст
  printer.doubleWidthOff();          //  Отменяем удвоенную ширину текста.

  printer.boldOn();                  //  Устанавливаем полужирное начертание текста.
  printer.println("Bold");           //  Выводим текст
  printer.boldOff();                 //  Отменяем полужирное начертание текста.

  // Устанавливаем подчёркивание текста линией в 1 пиксель.
  // Равнозначно вызову функции с параметром 1: printer.underlineOn(1);
  printer.underlineOn();
  printer.println("Underline 1px");  //  Выводим текст
  printer.underlineOn(2);            //  Устанавливаем подчёркивание текста линией в 2 пикселя.
  printer.println("Underline 2px");  //  Выводим текст
  printer.underlineOff();            //  Отменяем подчёркивание текста.

  // Межстрочный интервал в 2,5 мм.
  // В качестве параметра можно указать интервал от 24 (2,4 мм) до 32767. По умолчанию 30 (3,0 мм)
  printer.setLineHeight(25);
  printer.println("1\r\n2\r\n3");    //  Выводим 3 строки текста
  printer.setLineHeight(60);         //  Устанавливаем межстрочный интервал в 6,0 мм.
  printer.println("4\r\n5\r\n6");    //  Выводим 3 строки текста
  printer.setLineHeight();           //  Устанавливаем межстрочный в значение по умолчанию (3,0 мм)

  // Устанавливаем межсимвольный интервал в 10 пикселей.
  // В качестве параметра можно указать интервал от 0 до 32767 пикселей. По умолчанию 0
  printer.setCharSpacing(10);
  printer.println("CharSpacing");    //  Выводим текст
  printer.setCharSpacing();          //  Отменяем межсимвольный интервал. Равнозначно вызову printer.setCharSpacing(0);

  printer.tab();                     //  Устанавливаем отступ (табуляцию).
  printer.println("<- Tabulation");  //  Выводим текст
  
  // Прокручиваем ленту на 10 пикселей. В качестве параметра можно указать от 0 до 255 
  printer.feedRows(10);              пикселей.

  if (printer.hasPaper()) {         //  Если кассовая лента установлена (есть бумага), то ...
    printer.println("Paper OK");    //  Выводим текст
  } else {                          //  Если нет бумаги, то ...
    //  Что-то делаем, например, включаем светодиод или звуковой сигнал
  }

  // Устанавливаем настройки принтера по умолчанию.
  // Функцию удобно использовать, если хотите быть уверены что на него не повлияют ранее установленные размеры или начертания.
  printer.setDefault();
  printer.feed(3);                 //  Прокручиваем ленту на 3 строки
}

void loop() {}

Печать русских символов

В первый день пример работал, а на следующий день почему-то перестал. Я не разбирался в проблеме, оставил на всякий случай.


#include         <SoftwareSerial.h>
#include         <Adafruit_Thermal.h>

#define RX_PIN 5
#define TX_PIN 6

SoftwareSerial mySerial(RX_PIN, TX_PIN);

Adafruit_Thermal printer(&mySerial);

// Объявляем функцию перевода русских символов из кодировки UTF-8 в кодировку CP866
char* RUS(char*);

void setup() {
  mySerial.begin(9600);
  printer.begin();
  printer.setDefault();
  printer.setCodePage(CODEPAGE_CP866);              //  Устанавливаем кодовую таблицу CP866 с поддержкой русского языка

  printer.println(RUS("Hello Kitty - Привет киска")); //  Выводим текст на принтер. Функция RUS преобразует русские символы, а остальные вернёт как есть

  char text1[] = "Текст в переменной text1";        //  Определяем переменную text1
  RUS(text1);                                       //  Функция RUS преобразует русские символы переменной text1 и сохранит их в той же переменной
  //printer.println(text1);                           //  Выводим преобразованный текст на принтер
  //  Вывод из переменной text2:
  char text2[] = "Текст в переменной text2";        //  Определяем переменную text2
  //printer.println(RUS(text2));                      //  Функция RUS преобразует русские символы переменной text2

  //printer.feed(3);                                  //  Прокручиваем ленту на 3 строки
}                                                     //
//  Вы можете применять различные стили начертания и размеры шрифта при выводе его на термопринтер.
void loop() {}

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)
}

Вывод штрих-кодов


#include <SoftwareSerial.h>
#include <Adafruit_Thermal.h>

#define RX_PIN 5
#define TX_PIN 6

SoftwareSerial mySerial(RX_PIN, TX_PIN);
Adafruit_Thermal printer(&mySerial);

void setup() {
  mySerial.begin(9600);
  printer.begin();

  // Выводим название формата, затем сам штрих-код
  // В данном формате используются 12 цифр
  printer.print(F("UPC-A:"));                       
  printer.printBarcode("123456789012", UPC_A);      

  // Выводим название формата, затем сам штрих-код
  // Штрих-код EAN-13, аналогичен формату JAN-13. В данном формате используются 13 цифр
  printer.print(F("EAN-13:"));
  printer.printBarcode("1234567890123", EAN13);     

  // Выводим название формата, затем сам штрих-код
  // Штрих-код EAN-8, аналогичен формату JAN-8. В данном формате используются 8 цифр
  printer.print(F("EAN-8:"));
  printer.printBarcode("12345678", EAN8);

  // Выводим название формата, затем сам штрих-код
  printer.print(F("CODE 39:"));
  // Штрих-код CODE 39. Можно использовать от 2 до 255 цифр и заглавных латинских букв
  printer.printBarcode("ARDUINO", CODE39);   

  // Выводим название формата, затем сам штрих-код
  // Штрих-код CODE 93. Можно использовать от 2 до 255 цифр, заглавных латинских букв, пробелы, и знаки *.:$%/+-
  printer.print(F("CODE 93:"));
  printer.printBarcode("ARDUINO", CODE93); 

  // Выводим название формата, затем сам штрих-код
  // Штрих-код ITF. Можно использовать от 2 до 255 цифр
  printer.print(F("ITF:"));
  printer.printBarcode("1234567890", ITF);

  // Выводим название формата, затем сам штрих-код
  // Штрих-код CODABAR. Можно использовать от 2 до 255 цифр, заглавных латинских букв, и знаки .:%/+-
  printer.print(F("CODABAR:"));
  printer.printBarcode("1234567890", CODABAR);      

  // Выводим название формата, затем сам штрих-код
  // Выводим штрих-код CODE 128. Можно использовать от 2 до 255 символов
  // коды которых лежат в диапазоне от 0 до 127 таблицы символов ASCII
  printer.print(F("CODE128:"));
  printer.printBarcode("iArduino", CODE128);        

  printer.feed(2);       //  Прокручиваем ленту на 3 строки
  printer.setDefault();  //  Восстанавливаем стандартные настройки
  
}

void loop() {}

Графика

Принтер позволяет печатать простенькую графику. Но делать это очень неудобно. Сначала нужно с помощью сторонних программ (LCDAssistant) сконвертировать изображение в чёрно-белый вариант, затем преобразовать её в набор байтов, а потом уже посылать на принтер. Я решил пока не заморачиваться в этом направлении. Обойдёмся без картинок.

Дополнительные материалы

Описание функций библиотека Adafruit Thermal Printer Library

Реклама