Andrew Ross / Adafruit_Thermal_Printer

Dependents:   Thermal_HelloWorld

Fork of AdafruitThermalPrinter by Ashley Mills

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AdafruitThermal.cpp Source File

AdafruitThermal.cpp

00001 /*************************************************** 
00002   This is a library for the Adafruit Thermal Printer
00003   
00004   Pick one up at --> http://www.adafruit.com/products/597
00005   These printers use TTL serial to communicate, 2 pins are required
00006 
00007   Adafruit invests time and resources providing this open source code, 
00008   please support Adafruit and open-source hardware by purchasing 
00009   products from Adafruit!
00010 
00011   Written by Limor Fried/Ladyada for Adafruit Industries.  
00012   MIT license, all text above must be included in any redistribution
00013  ****************************************************/
00014  
00015 // Ported to mbed by Ashley Mills
00016 /** Documentation by Andrew Ross - NOTE: printBitmap not ported, nothing tested **/
00017 
00018 #include "mbed.h" 
00019 #include "AdafruitThermal.h"
00020 
00021 
00022 AdafruitThermal::AdafruitThermal(PinName RX_Pin, PinName TX_Pin) {
00023   _RX_Pin = RX_Pin;
00024   _TX_Pin = TX_Pin;
00025 }
00026 
00027 void AdafruitThermal::begin(int heatTime) {
00028   _printer = new Serial(_RX_Pin, _TX_Pin);
00029   _printer->baud(9600);
00030 
00031   // The printer can't start receiving data immediately
00032   // upon power up -- needs a moment to initialize.  If
00033   // Arduino & printer are powered from the same supply,
00034   // they're starting simultaneously.  Need to pause for
00035   // a moment so the printer is ready for commands.
00036   // (A more robust approach might be to wait in a loop
00037   // issuing status commands until valid response.)
00038   wait(0.5);
00039   
00040   reset();
00041 
00042   // Description of print settings from page 23 of the manual:
00043   // ESC 7 n1 n2 n3 Setting Control Parameter Command
00044   // Decimal: 27 55 n1 n2 n3
00045   // Set "max heating dots", "heating time", "heating interval"
00046   // n1 = 0-255 Max printing dots, Unit (8dots), Default: 7 (64 dots)
00047   // n2 = 3-255 Heating time, Unit (10us), Default: 80 (800us)
00048   // n3 = 0-255 Heating interval, Unit (10us), Default: 2 (20us)
00049   // The more max heating dots, the more peak current will cost
00050   // when printing, the faster printing speed. The max heating
00051   // dots is 8*(n1+1).  The more heating time, the more density,
00052   // but the slower printing speed.  If heating time is too short,
00053   // blank page may occur.  The more heating interval, the more
00054   // clear, but the slower printing speed.
00055 
00056   writeBytes(27, 55);   // Esc 7 (print settings)
00057   writeBytes(20);       // Heating dots (20=balance of darkness vs no jams)
00058   writeBytes(heatTime); // Library default = 255 (max)
00059   writeBytes(250);      // Heat interval (500 uS = slower, but darker)
00060 
00061   // Description of print density from page 23 of the manual:
00062   // DC2 # n Set printing density
00063   // Decimal: 18 35 n
00064   // D4..D0 of n is used to set the printing density.  Density is
00065   // 50% + 5% * n(D4-D0) printing density.
00066   // D7..D5 of n is used to set the printing break time.  Break time
00067   // is n(D7-D5)*250us.
00068   // (Unsure of the default value for either -- not documented)
00069 
00070   const int
00071     printDensity   = 14, // 120% (? can go higher, text is darker but fuzzy)
00072     printBreakTime = 4;  // 500 uS
00073   writeBytes(18, 35); // DC2 # (print density)
00074   writeBytes((printBreakTime << 5) | printDensity);
00075 }
00076 
00077 // reset printer
00078 void AdafruitThermal::reset() {
00079   writeBytes(27, 64);
00080 }
00081 
00082 // reset formatting
00083 void AdafruitThermal::setDefault(){
00084   online();
00085   justify('L');
00086   inverseOff();
00087   doubleHeightOff();
00088   setLineHeight(32);
00089   boldOff();
00090   underlineOff();
00091   setBarcodeHeight(50);
00092   setSize('s');
00093 }
00094 
00095 void AdafruitThermal::test(){
00096   write('h');
00097   write('e');
00098   write('l');
00099   write('l');
00100   write('o');
00101   write('!');
00102   write('\n');
00103   feed(2);
00104 }
00105 
00106 void AdafruitThermal::print(char *string) {
00107     while(*string!=0) {
00108         write(*string);
00109         string++;
00110     }
00111     feed(2);
00112 }
00113 
00114 void AdafruitThermal::testPage() {
00115   writeBytes(18, 84);
00116 }
00117 
00118 // this is the basic function for all printing, the rest is taken care of by the
00119 // inherited Print class!
00120 size_t AdafruitThermal::write(uint8_t c) {
00121   if (c == 0x13) return 0;
00122 
00123   if (c != 0xA)
00124     linefeedneeded = true;
00125   else
00126     linefeedneeded = false;
00127 
00128   //DBG(" 0x");
00129   //DBG(c, HEX);
00130   //DBG(" ("); 
00131   
00132   PRINTER_PRINT(c);
00133 
00134   return 1;
00135 
00136 }
00137 
00138 void AdafruitThermal::setBarcodeHeight(int val){
00139   //default is 50
00140   writeBytes(29, 104, val);
00141 }
00142 
00143 void AdafruitThermal::printBarcode(char * text, uint8_t type) {
00144   int i;
00145   uint8_t c;
00146 
00147   delay(1000); // Need these delays else barcode doesn't always print. ???
00148   writeBytes(29, 107, type); // set the type first
00149   delay(500);
00150   // Copy string, not including NUL terminator
00151   for(i=0; (c = text[i]); i++) PRINTER_PRINT(c);
00152   delay(500);
00153   PRINTER_PRINT(c); // Terminator must follow delay. ???
00154 
00155   delay(3000); // For some reason we can't immediately have line feeds here
00156   feed(2);
00157 }
00158 
00159 void AdafruitThermal::writeBytes(uint8_t a) {
00160   PRINTER_PRINT(a);
00161 }
00162 
00163 void AdafruitThermal::writeBytes(uint8_t a, uint8_t b) {
00164   PRINTER_PRINT(a);
00165   PRINTER_PRINT(b);
00166 }
00167 
00168 void AdafruitThermal::writeBytes(uint8_t a, uint8_t b, uint8_t c) {
00169   PRINTER_PRINT(a);
00170   PRINTER_PRINT(b);
00171   PRINTER_PRINT(c);
00172 }
00173 
00174 void AdafruitThermal::writeBytes(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
00175   PRINTER_PRINT(a);
00176   PRINTER_PRINT(b);
00177   PRINTER_PRINT(c);
00178   PRINTER_PRINT(d);
00179 }
00180 
00181 // === Character commands ===
00182 
00183 #define INVERSE_MASK (1 << 1)
00184 #define UPDOWN_MASK (1 << 2)
00185 #define BOLD_MASK (1 << 3)
00186 #define DOUBLE_HEIGHT_MASK (1 << 4)
00187 #define DOUBLE_WIDTH_MASK (1 << 5)
00188 #define STRIKE_MASK (1 << 6)
00189 
00190 void AdafruitThermal::setPrintMode(uint8_t mask) {
00191   printMode |= mask;
00192   writePrintMode();
00193 }
00194 void AdafruitThermal::unsetPrintMode(uint8_t mask) {
00195   printMode &= ~mask;
00196   writePrintMode();
00197 }
00198 
00199 void AdafruitThermal::writePrintMode() {
00200   writeBytes(27, 33, printMode);
00201 }
00202 
00203 void AdafruitThermal::normal() {
00204   printMode = 0;
00205   writePrintMode();
00206 }
00207 
00208 void AdafruitThermal::inverseOn(){
00209   setPrintMode(INVERSE_MASK);
00210   //writeBytes(29, 66, 1);
00211 }
00212 
00213 void AdafruitThermal::inverseOff(){
00214   unsetPrintMode(INVERSE_MASK);
00215   //writeBytes(29, 'B', 0, 10);
00216   //writeBytes(29, 66, 0);
00217 }
00218 
00219 void AdafruitThermal::upsideDownOn(){
00220   setPrintMode(UPDOWN_MASK);
00221 }
00222 
00223 void AdafruitThermal::upsideDownOff(){
00224   unsetPrintMode(UPDOWN_MASK);
00225 }
00226 
00227 void AdafruitThermal::doubleHeightOn(){
00228   setPrintMode(DOUBLE_HEIGHT_MASK);
00229 }
00230 
00231 void AdafruitThermal::doubleHeightOff(){
00232   unsetPrintMode(DOUBLE_HEIGHT_MASK);
00233 }
00234 
00235 void AdafruitThermal::doubleWidthOn(){
00236   setPrintMode(DOUBLE_WIDTH_MASK);
00237 }
00238 
00239 void AdafruitThermal::doubleWidthOff(){
00240   unsetPrintMode(DOUBLE_WIDTH_MASK);
00241 }
00242 
00243 void AdafruitThermal::strikeOn(){
00244   setPrintMode(STRIKE_MASK);
00245 }
00246 
00247 void AdafruitThermal::strikeOff(){
00248   unsetPrintMode(STRIKE_MASK);
00249 }
00250 
00251 void AdafruitThermal::boldOn(){
00252   setPrintMode(BOLD_MASK);
00253 }
00254 
00255 void AdafruitThermal::boldOff(){
00256   //unsetPrintMode(BOLD_MASK);
00257   //writeBytes(27, 69, 0);
00258   //  if (linefeedneeded)
00259   //      feed();
00260 
00261     //linefeedneeded = false;
00262 }
00263 
00264 void AdafruitThermal::justify(char value){
00265   uint8_t pos = 0;
00266 
00267   if(value == 'l' || value == 'L') pos = 0;
00268   if(value == 'c' || value == 'C') pos = 1;
00269   if(value == 'r' || value == 'R') pos = 2;
00270 
00271   writeBytes(0x1B, 0x61, pos);
00272 }
00273 
00274 // Feeds by the specified number of lines
00275 void AdafruitThermal::feed(uint8_t x){
00276   // The datasheet claims sending bytes 27, 100, <x> will work
00277   // but it feeds much much more.
00278   while (x--)
00279     write('\n');
00280 }
00281 
00282 // Feeds by the specified number of rows of pixels
00283 void AdafruitThermal::feedRows(uint8_t rows) {
00284   writeBytes(27, 74, rows);
00285 }
00286 
00287 void AdafruitThermal::flush() {
00288   writeBytes(12);
00289 }
00290 
00291 void AdafruitThermal::setSize(char value){
00292   int size = 0;
00293 
00294   if(value == 's' || value == 'S') size = 0;
00295   if(value == 'm' || value == 'M') size = 10;
00296   if(value == 'l' || value == 'L') size = 25;
00297 
00298   writeBytes(29, 33, size, 10);
00299   // if (linefeedneeded)
00300   //  println("lfn"); //feed();
00301   //linefeedneeded = false;
00302 }
00303 
00304 // Underlines of different weights can be produced:
00305 // 0 - no underline
00306 // 1 - normal underline
00307 // 2 - thick underline
00308 void AdafruitThermal::underlineOn(uint8_t weight) {
00309   writeBytes(27, 45, weight);
00310 }
00311 
00312 void AdafruitThermal::underlineOff() {
00313   underlineOn(0);
00314   //writeBytes(27, 45, 0, 10);
00315   //Writing text with underline will work but seems to be a problem printing after turning off underline
00316 }
00317 
00318 /*
00319 void AdafruitThermal::printBitmap(int w, int h, const uint8_t *bitmap) {
00320   if (w > 384) return; // maximum width of the printer
00321   for (int rowStart=0; rowStart < h; rowStart += 256) {
00322     int chunkHeight = ((h - rowStart) > 255) ? 255 : (h - rowStart);
00323     delay(500); // Need these delays else bitmap doesn't always print. ???
00324     writeBytes(18, 42);
00325     writeBytes(chunkHeight, w/8);
00326     delay(500);
00327     for (int i=0; i<((w/8)*chunkHeight); i++) {
00328       PRINTER_PRINT(pgm_read_byte(bitmap + (rowStart*(w/8)) + i));
00329     }
00330     delay(500);
00331   }
00332 }
00333 
00334 
00335 void AdafruitThermal::printBitmap(int w, int h, Stream *stream) {
00336   if (w > 384) return; // maximum width of the printer
00337   for (int rowStart=0; rowStart < h; rowStart += 256) {
00338     int chunkHeight = ((h - rowStart) > 255) ? 255 : (h - rowStart);
00339     delay(500); // Need these delays else bitmap doesn't always print. ???
00340     writeBytes(18, 42);
00341     writeBytes(chunkHeight, w/8);
00342     delay(500);
00343     for (int i=0; i<((w/8)*chunkHeight); i++) {
00344       PRINTER_PRINT((uint8_t)stream->read());
00345     }
00346     delay(500);
00347   }
00348 };
00349 
00350 void AdafruitThermal::printBitmap(Stream *stream) {
00351   uint8_t tmp;
00352   uint16_t width, height;
00353 
00354   tmp = stream->read();
00355   width = (stream->read() << 8) + tmp;
00356 
00357   tmp = stream->read();
00358   height = (stream->read() << 8) + tmp;
00359 
00360   printBitmap(width, height, stream);
00361 };
00362 */
00363 
00364 // Take the printer offline. Print commands sent after this will be
00365 // ignored until `online` is called
00366 void AdafruitThermal::offline(){
00367   writeBytes(27, 61, 0);
00368 }
00369 
00370 // Take the printer back online. Subsequent print commands will be
00371 // obeyed.
00372 void AdafruitThermal::online(){
00373   writeBytes(27, 61, 1);
00374 }
00375 
00376 // Put the printer into a low-energy state immediately
00377 void AdafruitThermal::sleep() {
00378   sleepAfter(0);
00379 }
00380 
00381 // Put the printer into a low-energy state after the given number
00382 // of seconds
00383 void AdafruitThermal::sleepAfter(uint8_t seconds) {
00384   writeBytes(27, 56, seconds);
00385 }
00386 
00387 // Wake the printer from a low-energy state. This command will wait
00388 // for 50ms (as directed by the datasheet) before allowing further
00389 // commands to be send.
00390 void AdafruitThermal::wake() {
00391   writeBytes(255);
00392   delay(50);
00393 }
00394 
00395 ////////////////////// not working?
00396 void AdafruitThermal::tab(){
00397   PRINTER_PRINT(9);
00398 }
00399 void AdafruitThermal::setCharSpacing(int spacing) {
00400   writeBytes(27, 32, 0, 10);
00401 }
00402 void AdafruitThermal::setLineHeight(int val){
00403   writeBytes(27, 51, val); // default is 32
00404 }