This is the Adafruit thermal printer, whose Arduino library is published here: http://www.ladyada.net/products/thermalprinter/. This is a basic port to mbed that needs proper testing. The first printBitmap function is implemented but not fully tested, the stream versions are not ported yet.

Dependents:   SMS_LEDMatrixPrinter

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 hastily to mbed by Ashley Mills - NOTE: printBitmap not ported, nothing tested **/
00016 #include "mbed.h"
00017 #include "AdafruitThermal.h"
00018 /*
00019 #define LPC_UART0             ((LPC_UART0_TypeDef     *) LPC_UART0_BASE    )
00020 #define LPC_UART1             ((LPC_UART1_TypeDef     *) LPC_UART1_BASE    )
00021 #define LPC_UART2             ((LPC_UART_TypeDef      *) LPC_UART2_BASE    )
00022 #define LPC_UART3             ((LPC_UART_TypeDef      *) LPC_UART3_BASE    )
00023 
00024 Set correct UART
00025 
00026 UART3
00027 p9 = P0_0 (tx)
00028 p10 = P0_1 (rx)
00029 
00030 UART1
00031 p13 = P0_15 (tx)
00032 p14 = P0_16 (rx)
00033 
00034 UART2
00035 p28 = P0_10 (tx)
00036 p27 = P0_11 (rx)
00037 
00038 UART0
00039 USBTX = P0_2
00040 USBRX = P0_3
00041 */
00042 
00043 LPC_UART_TypeDef *lpcUart;
00044 
00045 // look at http://mrkindustries.com.ar/files/titan-doxy-html/lpc17xx__uart_8c_source.html
00046 AdafruitThermal::AdafruitThermal(PinName RX_Pin, PinName TX_Pin)
00047 {
00048     _RX_Pin = RX_Pin;
00049     _TX_Pin = TX_Pin;
00050 }
00051 
00052 void AdafruitThermal::begin(int heatTime)
00053 {
00054     _printer = new Serial(_RX_Pin, _TX_Pin);
00055     _printer->baud(19200);
00056 
00057 //    if( TX_Pin == p28 )
00058         lpcUart = ((LPC_UART_TypeDef *)LPC_UART2_BASE);
00059 //    else  if( TX_Pin == p9 )
00060 //        lpcUart = ((LPC_UART_TypeDef *)LPC_UART3_BASE);
00061 
00062     // The printer can't start receiving data immediately
00063     // upon power up -- needs a moment to initialize.  If
00064     // Arduino & printer are powered from the same supply,
00065     // they're starting simultaneously.  Need to pause for
00066     // a moment so the printer is ready for commands.
00067     // (A more robust approach might be to wait in a loop
00068     // issuing status commands until valid response.)
00069     wait(0.5);
00070 
00071     reset();
00072 
00073     // Description of print settings from page 23 of the manual:
00074     // ESC 7 n1 n2 n3 Setting Control Parameter Command
00075     // Decimal: 27 55 n1 n2 n3
00076     // Set "max heating dots", "heating time", "heating interval"
00077     // n1 = 0-255 Max printing dots, Unit (8dots), Default: 7 (64 dots)
00078     // n2 = 3-255 Heating time, Unit (10us), Default: 80 (800us)
00079     // n3 = 0-255 Heating interval, Unit (10us), Default: 2 (20us)
00080     // The more max heating dots, the more peak current will cost
00081     // when printing, the faster printing speed. The max heating
00082     // dots is 8*(n1+1).  The more heating time, the more density,
00083     // but the slower printing speed.  If heating time is too short,
00084     // blank page may occur.  The more heating interval, the more
00085     // clear, but the slower printing speed.
00086 
00087     writeBytes(27, 55);   // Esc 7 (print settings)
00088     writeBytes(20);       // Heating dots (20=balance of darkness vs no jams)
00089     writeBytes(heatTime); // Library default = 255 (max)
00090     writeBytes(250);      // Heat interval (500 uS = slower, but darker)
00091 
00092     // Description of print density from page 23 of the manual:
00093     // DC2 # n Set printing density
00094     // Decimal: 18 35 n
00095     // D4..D0 of n is used to set the printing density.  Density is
00096     // 50% + 5% * n(D4-D0) printing density.
00097     // D7..D5 of n is used to set the printing break time.  Break time
00098     // is n(D7-D5)*250us.
00099     // (Unsure of the default value for either -- not documented)
00100 
00101     const int
00102     printDensity   = 14, // 120% (? can go higher, text is darker but fuzzy)
00103     printBreakTime = 4;  // 500 uS
00104     writeBytes(18, 35); // DC2 # (print density)
00105     writeBytes((printBreakTime << 5) | printDensity);
00106 }
00107 
00108 // reset printer
00109 void AdafruitThermal::reset()
00110 {
00111     writeBytes(27, 64);
00112 }
00113 
00114 // reset formatting
00115 void AdafruitThermal::setDefault()
00116 {
00117     online();
00118     justify('L');
00119     inverseOff();
00120     doubleHeightOff();
00121     setLineHeight(32);
00122     boldOff();
00123     underlineOff();
00124     setBarcodeHeight(50);
00125     setSize('s');
00126 }
00127 
00128 //void AdafruitThermal::printNothing( char ch ) { }
00129 
00130 void AdafruitThermal::test()
00131 {
00132     write('h');
00133     write('e');
00134     write('l');
00135     write('l');
00136     write('o');
00137     write('!');
00138     write('\n');
00139     feed(2);
00140 }
00141 
00142 void AdafruitThermal::print(char *string)
00143 {
00144     while(*string!=0) {
00145         write(*string);
00146         string++;
00147     }
00148 }
00149 
00150 void AdafruitThermal::testPage()
00151 {
00152     writeBytes(18, 84);
00153 }
00154 
00155 
00156 void AdafruitThermal::directPutc( uint8_t c ) {
00157 
00158 /*    do {
00159     } while ((LPC_UART2->LSR & 0x20)==0) ;
00160     //write character to UART
00161     LPC_UART2->THR = c ;
00162 */
00163     do {
00164     } while ((lpcUart->LSR & 0x20)==0) ;
00165     //write character to UART
00166     lpcUart->THR = c ;
00167 
00168 }
00169 
00170 
00171 // this is the basic function for all printing, the rest is taken care of by the
00172 // inherited Print class!
00173 size_t AdafruitThermal::write(uint8_t c)
00174 {
00175     if (c == 0x13) return 0;
00176 
00177     if (c != 0xA)
00178         linefeedneeded = true;
00179     else
00180         linefeedneeded = false;
00181 
00182     //DBG(" 0x");
00183     //DBG(c, HEX);
00184     //DBG(" (");
00185 
00186     PRINTER_PRINT(c);
00187 
00188     return 1;
00189 
00190 }
00191 
00192 void AdafruitThermal::setBarcodeHeight(int val)
00193 {
00194     //default is 50
00195     writeBytes(29, 104, val);
00196 }
00197 
00198 void AdafruitThermal::printBarcode(char * text, uint8_t type)
00199 {
00200     int i;
00201     uint8_t c;
00202 
00203     delay(1000); // Need these delays else barcode doesn't always print. ???
00204     writeBytes(29, 107, type); // set the type first
00205     delay(500);
00206     // Copy string, not including NUL terminator
00207     for(i=0; (c = text[i]); i++) PRINTER_PRINT(c);
00208     delay(500);
00209     PRINTER_PRINT(c); // Terminator must follow delay. ???
00210 
00211     delay(3000); // For some reason we can't immediately have line feeds here
00212     feed(2);
00213 }
00214 
00215 void AdafruitThermal::writeBytes(uint8_t a)
00216 {
00217     PRINTER_PRINT(a);
00218 }
00219 
00220 void AdafruitThermal::writeBytes(uint8_t a, uint8_t b)
00221 {
00222     PRINTER_PRINT(a);
00223     PRINTER_PRINT(b);
00224 }
00225 
00226 void AdafruitThermal::writeBytes(uint8_t a, uint8_t b, uint8_t c)
00227 {
00228     PRINTER_PRINT(a);
00229     PRINTER_PRINT(b);
00230     PRINTER_PRINT(c);
00231 }
00232 
00233 void AdafruitThermal::writeBytes(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
00234 {
00235     PRINTER_PRINT(a);
00236     PRINTER_PRINT(b);
00237     PRINTER_PRINT(c);
00238     PRINTER_PRINT(d);
00239 }
00240 
00241 // === Character commands ===
00242 
00243 #define INVERSE_MASK (1 << 1)
00244 #define UPDOWN_MASK (1 << 2)
00245 #define BOLD_MASK (1 << 3)
00246 #define DOUBLE_HEIGHT_MASK (1 << 4)
00247 #define DOUBLE_WIDTH_MASK (1 << 5)
00248 #define STRIKE_MASK (1 << 6)
00249 
00250 void AdafruitThermal::setPrintMode(uint8_t mask)
00251 {
00252     printMode |= mask;
00253     writePrintMode();
00254 }
00255 void AdafruitThermal::unsetPrintMode(uint8_t mask)
00256 {
00257     printMode &= ~mask;
00258     writePrintMode();
00259 }
00260 
00261 void AdafruitThermal::writePrintMode()
00262 {
00263     writeBytes(27, 33, printMode);
00264 }
00265 
00266 void AdafruitThermal::normal()
00267 {
00268     printMode = 0;
00269     writePrintMode();
00270 }
00271 
00272 void AdafruitThermal::inverseOn()
00273 {
00274     setPrintMode(INVERSE_MASK);
00275 }
00276 
00277 void AdafruitThermal::inverseOff()
00278 {
00279     unsetPrintMode(INVERSE_MASK);
00280 }
00281 
00282 void AdafruitThermal::upsideDownOn()
00283 {
00284     setPrintMode(UPDOWN_MASK);
00285 }
00286 
00287 void AdafruitThermal::upsideDownOff()
00288 {
00289     unsetPrintMode(UPDOWN_MASK);
00290 }
00291 
00292 void AdafruitThermal::doubleHeightOn()
00293 {
00294     setPrintMode(DOUBLE_HEIGHT_MASK);
00295 }
00296 
00297 void AdafruitThermal::doubleHeightOff()
00298 {
00299     unsetPrintMode(DOUBLE_HEIGHT_MASK);
00300 }
00301 
00302 void AdafruitThermal::doubleWidthOn()
00303 {
00304     setPrintMode(DOUBLE_WIDTH_MASK);
00305 }
00306 
00307 void AdafruitThermal::doubleWidthOff()
00308 {
00309     unsetPrintMode(DOUBLE_WIDTH_MASK);
00310 }
00311 
00312 void AdafruitThermal::strikeOn()
00313 {
00314     setPrintMode(STRIKE_MASK);
00315 }
00316 
00317 void AdafruitThermal::strikeOff()
00318 {
00319     unsetPrintMode(STRIKE_MASK);
00320 }
00321 
00322 void AdafruitThermal::boldOn()
00323 {
00324     setPrintMode(BOLD_MASK);
00325 }
00326 
00327 void AdafruitThermal::boldOff()
00328 {
00329     unsetPrintMode(BOLD_MASK);
00330 }
00331 
00332 void AdafruitThermal::justify(char value)
00333 {
00334     uint8_t pos = 0;
00335 
00336     if(value == 'l' || value == 'L') pos = 0;
00337     if(value == 'c' || value == 'C') pos = 1;
00338     if(value == 'r' || value == 'R') pos = 2;
00339 
00340     writeBytes(0x1B, 0x61, pos);
00341 }
00342 
00343 // Feeds by the specified number of lines
00344 void AdafruitThermal::feed(uint8_t x)
00345 {
00346     // The datasheet claims sending bytes 27, 100, <x> will work
00347     // but it feeds much much more.
00348     while (x--)
00349         write('\n');
00350 }
00351 
00352 // Feeds by the specified number of rows of pixels
00353 void AdafruitThermal::feedRows(uint8_t rows)
00354 {
00355     writeBytes(27, 74, rows);
00356 }
00357 
00358 void AdafruitThermal::flush()
00359 {
00360     writeBytes(12);
00361 }
00362 
00363 void AdafruitThermal::setSize(char value)
00364 {
00365     int size = 0;
00366 
00367     if(value == 's' || value == 'S') size = 0;
00368     if(value == 'm' || value == 'M') size = 10;
00369     if(value == 'l' || value == 'L') size = 25;
00370 
00371     writeBytes(29, 33, size, 10);
00372     // if (linefeedneeded)
00373     //  println("lfn"); //feed();
00374     //linefeedneeded = false;
00375 }
00376 
00377 // Underlines of different weights can be produced:
00378 // 0 - no underline
00379 // 1 - normal underline
00380 // 2 - thick underline
00381 void AdafruitThermal::underlineOn(uint8_t weight)
00382 {
00383     writeBytes(27, 45, weight);
00384 }
00385 
00386 void AdafruitThermal::underlineOff()
00387 {
00388     underlineOn(0);
00389 }
00390 
00391 
00392 void AdafruitThermal::printBitmap(int w, int h, const uint8_t *bitmap)
00393 {
00394     if (w > 384) return; // maximum width of the printer
00395     for (int rowStart=0; rowStart < h; rowStart += 256) {
00396         int chunkHeight = ((h - rowStart) > 255) ? 255 : (h - rowStart);
00397         delay(500); // Need these delays else bitmap doesn't always print. ???
00398         writeBytes(18, 42);
00399         writeBytes(chunkHeight, w/8);
00400         delay(500);
00401         for (int i=0; i<((w/8)*chunkHeight); i++) {
00402             PRINTER_PRINT(bitmap[(rowStart*(w/8)) + i]);
00403 //      PRINTER_PRINT(pgm_read_byte(bitmap + (rowStart*(w/8)) + i));
00404         }
00405         delay(500);
00406     }
00407 }
00408 
00409 /*
00410 void AdafruitThermal::printBitmap(int w, int h, Stream *stream) {
00411   if (w > 384) return; // maximum width of the printer
00412   for (int rowStart=0; rowStart < h; rowStart += 256) {
00413     int chunkHeight = ((h - rowStart) > 255) ? 255 : (h - rowStart);
00414     delay(500); // Need these delays else bitmap doesn't always print. ???
00415     writeBytes(18, 42);
00416     writeBytes(chunkHeight, w/8);
00417     delay(500);
00418     for (int i=0; i<((w/8)*chunkHeight); i++) {
00419       PRINTER_PRINT((uint8_t)stream->read());
00420     }
00421     delay(500);
00422   }
00423 };
00424 
00425 void AdafruitThermal::printBitmap(Stream *stream) {
00426   uint8_t tmp;
00427   uint16_t width, height;
00428 
00429   tmp = stream->read();
00430   width = (stream->read() << 8) + tmp;
00431 
00432   tmp = stream->read();
00433   height = (stream->read() << 8) + tmp;
00434 
00435   printBitmap(width, height, stream);
00436 };
00437 */
00438 
00439 // Take the printer offline. Print commands sent after this will be
00440 // ignored until `online` is called
00441 void AdafruitThermal::offline()
00442 {
00443     writeBytes(27, 61, 0);
00444 }
00445 
00446 // Take the printer back online. Subsequent print commands will be
00447 // obeyed.
00448 void AdafruitThermal::online()
00449 {
00450     writeBytes(27, 61, 1);
00451 }
00452 
00453 // Put the printer into a low-energy state immediately
00454 void AdafruitThermal::sleep()
00455 {
00456     sleepAfter(0);
00457 }
00458 
00459 // Put the printer into a low-energy state after the given number
00460 // of seconds
00461 void AdafruitThermal::sleepAfter(uint8_t seconds)
00462 {
00463     writeBytes(27, 56, seconds);
00464 }
00465 
00466 // Wake the printer from a low-energy state. This command will wait
00467 // for 50ms (as directed by the datasheet) before allowing further
00468 // commands to be send.
00469 void AdafruitThermal::wake()
00470 {
00471     writeBytes(255);
00472     delay(50);
00473 }
00474 
00475 ////////////////////// not working?
00476 void AdafruitThermal::tab()
00477 {
00478     PRINTER_PRINT(9);
00479 }
00480 void AdafruitThermal::setCharSpacing(int spacing)
00481 {
00482     writeBytes(27, 32, 0, 10);
00483 }
00484 void AdafruitThermal::setLineHeight(int val)
00485 {
00486     writeBytes(27, 51, val); // default is 32
00487 }