[Thermal Printer] Printing images as Stream over serial from processing

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
peek
 
Posts: 23
Joined: Sat Jan 14, 2012 6:17 am

[Thermal Printer] Printing images as Stream over serial from processing

Post by peek »

Hi there,

I'm trying to print images larger in size than my Arduino duemilanove progmem can handle.
So I thought I could use the printBitmap(Stream *stream) function for this and stream image data from a processing sketch.

•Has anyone made a sketch that accomplishes this yet?

•Should I use image_to_file or image_to_byte to prepare the image data?

•It does work directly via serial, no need for sd card or ethernet shield?

Best,
p
Last edited by peek on Sun May 12, 2013 5:49 pm, edited 1 time in total.

peek
 
Posts: 23
Joined: Sat Jan 14, 2012 6:17 am

Re: [Thermal Printer] Printing images as stream over serial from processing

Post by peek »

Okay, based on some research I got a feeling it should work over serial.
I also know more about streams now:
http://arduino.cc/en/Reference/Stream

On to figure this out,
p

peek
 
Posts: 23
Joined: Sat Jan 14, 2012 6:17 am

Re: [Thermal Printer] Printing images as Stream over serial from processing

Post by peek »

How can i use input from serial as Stream?
I guess I have to construct a Stream object first, but I don't know how.

This example uses a file:

Code: Select all

// open the file.
myFile = SD.open("test.bmp", FILE_READ);

// cast the file to a stream (note, your width and height may be different)
printer.printBitmap(384, 205, dynamic_cast<Stream*>(&myFile));
How can I do something like this:
printer.printBitmap(384, 205, Serial.read());[/code]

Please help, thanks!
p

scrubbl3r
 
Posts: 21
Joined: Sat Jul 13, 2013 6:26 pm

Re: [Thermal Printer] Printing images as Stream over serial from processing

Post by scrubbl3r »

Hi Peek,

did you ever figure this out? I've seen your other post about this. In fact I've dredged up every single piece of information on the topic [printing from a stream] with the Adafruit Thermal printer. Really? no one has ever figured it out?

Best,
G

User avatar
technerdchris
 
Posts: 46
Joined: Sun Nov 25, 2012 4:08 am

Re: [Thermal Printer] Printing images as Stream over serial from processing

Post by technerdchris »

Right now, I'm in the same boat. :P I've got a thermal printer and trying to dynamically write a bitmap to it. I can't get their own example to print from a byte * array declared with the sketch. If I could figure out how to feed that into a stream object, it would probably work.

Only now I learn you cannot alter PROGMEM, so I have no idea how to actually print something I have in an array that matches the format of their "Processing" .h output.

So frustrating...

User avatar
technerdchris
 
Posts: 46
Joined: Sun Nov 25, 2012 4:08 am

Re: [Thermal Printer] Printing images as Stream over serial from processing

Post by technerdchris »

I just had an "oh duh" moment. One of the printBitmap() constructors has a 4th argument, fromProgMem. Earlier today, I realized that program memory is static; the static bytes of large arrays, fonts, and strings can be written to the flash for program memory and are not a part of SRAM.

So earlier when I saw the fromProgMem argument, I thought, well that's no good, I'm trying to write from a byte array. It didn't occur to me that program memory is accessed a whole different way than normal. Sure enough, I open up the library cpp file, find

Code: Select all

void Adafruit_Thermal::printBitmap(
 int w, int h, const uint8_t *bitmap, bool fromProgMem) {
... and a few lines below, the smoking gun:

Code: Select all

        PRINTER_PRINT(fromProgMem ? pgm_read_byte(bitmap + i) : *(bitmap+i));
Bingo! Now, I'm able to print from the

Code: Select all

uint8_t bitmap_data[] = {
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,
  .
  .
  .
... which I have declared as a global variable, using this as the function call:

Code: Select all

        unsigned int IMGSIZE = 128;
	printer.printBitmap(IMGSIZE, IMGSIZE, bitmap_data, 0 );
Now to figure out how to deal with each x and y pixel ... then draw lines between them or something... :P

User avatar
technerdchris
 
Posts: 46
Joined: Sun Nov 25, 2012 4:08 am

Re: [Thermal Printer] Printing images as Stream over serial from processing

Post by technerdchris »

I was totally successful at creating an image array as a variable with a mega2560... but I am limited by SRAM to somewhere near 200x200 pixels.

THAT is why all the sample sketches use PROGMEM as there's plenty of non-writable (during program run time) storage space there. From http://arduino.cc/en/Tutorial/Memory :
The ATmega328 chip found on the Uno has the following amounts of memory:
Flash 32k bytes (of which .5k is used for the bootloader)
SRAM 2k bytes
EEPROM 1k byte

The ATmega2560 in the Mega2560 has larger memory space :
Flash 256k bytes (of which 8k is used for the bootloader)
SRAM 8k bytes
EEPROM 4k byte
Here's my code:

Code: Select all

#include <SoftwareSerial.h> // core lib
#include <Adafruit_Thermal.h>
#include <avr/pgmspace.h>
// this is the green wire
#define PTR_RX_PIN 3
// this is the yellow wire
#define PTR_TX_PIN 2
Adafruit_Thermal printer(PTR_RX_PIN, PTR_TX_PIN);
static const unsigned int IMGSIZE = 200;
static const unsigned int IMGROWBYTES = IMGSIZE/8;
byte bitmap_data[IMGSIZE*IMGROWBYTES] = {0};

I then directly access this array in a for loop indexing through my dataset:

Code: Select all

void graph2thermal( unsigned int size, int test[], int idxmax ){
	static const unsigned int w=size, h=size, Bpr=w/8;    // Bytes per row, 128/8 = 16
	for(unsigned int idx=0; idx < idxmax-1; idx++  ){
		static const unsigned int y = map(test[idx], TPS_floor[_tps], TPS_max[_tps], 1, w);
		static const unsigned int x = map(idx, 0, idxmax, 0, h-1);
		//  what's our Y offset? 128-45 = 83 : 83*16=1328
		static const unsigned int yoffset =(h-y)*Bpr;   // how many bytes away from start of our array
		// which x byte : 44/8 = 5 whole bytes
		static const unsigned int xoffset = x/8;
		static const unsigned int offset = yoffset+xoffset;
		// now which bit
		//  44%8=4 : 0x80 >> 4 = 0x08
		static const unsigned int shifty = x%8;
		static const unsigned int _pixel = 0x80 >> shifty;
		bitmap_data[offset] = bitmap_data[offset] | _pixel;
	printer.printBitmap(w, h, bitmap_data, 0 );
	printer.feed(3);
}
All of the static const unsigned int's are in the weak hopes it buys me a little more room in SRAM... I think it did... the Arduino went from not even trying to start up with 256px to starting up and then having screwy values. :P

Given that the Byte array's size is Height*(Width/8), here are a few values of note:

Code: Select all

px	Byte array size
128	2048
192	4608
200	5000
208	5408
216	5832
224	6272
232	6728
240	7200
248	7688
256	8192
280	9800
288	10368
384	18432
An UNO's SRAM in its entirety is the size of a 128x128 monochrome bitmap array! And my Seeeeduino Mega's SRAM is the exact size of a 256px bitmap. I can't wait until the Goldilocks UNO is available with its smoking hot 16k of SRAM.

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”