Hey,
I'm using a thermal printer (http://www.adafruit.com/products/597) to print a black circle that's 384 x 384 pixel, by printing each row of the circle individually using the Adafruit Thermal Printer Library.
The problem I am getting is that this streaky stuff http://imgur.com/YBOrnKy. Any tips for making this go away? I gather there's some way to change the print density and all that.
Printing Big Black Images with Thermal Printer
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
-
- Posts: 7
- Joined: Tue Jan 14, 2014 12:50 pm
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Printing Big Black Images with Thermal Printer
One problem you may be running into is power. Being a thermal printer, it needs more current to heat the pins in the print-head if there is a lot of black in the line. Judging from the way it starts off nice and black and fades as the width increases, I'd suspect that the power supply can't keep up and the voltage is dropping.
To confirm that, try measuring the supply voltage as you are printing and see if it drops noticeably as you print the circle.
To confirm that, try measuring the supply voltage as you are printing and see if it drops noticeably as you print the circle.
-
- Posts: 7
- Joined: Tue Jan 14, 2014 12:50 pm
Re: Printing Big Black Images with Thermal Printer
Thanks. How might one go about doing that?
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Printing Big Black Images with Thermal Printer
Do you have a multimeter? If so, set it to read voltage and touch the probes to the + and - power connections.
If you are using the adapter shown in the tutorial, you can just touch the probes to the two terminal screws.
http://learn.adafruit.com/mini-thermal- ... first-test
If you are using the adapter shown in the tutorial, you can just touch the probes to the two terminal screws.
http://learn.adafruit.com/mini-thermal- ... first-test
-
- Posts: 7
- Joined: Tue Jan 14, 2014 12:50 pm
Re: Printing Big Black Images with Thermal Printer
The voltage seems to consistently stay at 5v.
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Printing Big Black Images with Thermal Printer
Is the image you are printing supposed to be just a plain uniform black circle? I see some streaks as well as some more regular looking crescent and banding patterns. What exactly is the output supposed to look like?The problem I am getting is that this streaky stuff
-
- Posts: 7
- Joined: Tue Jan 14, 2014 12:50 pm
Re: Printing Big Black Images with Thermal Printer
It should just be a uniform black circle of radius 192 pixels.
- pburgess
- Posts: 4161
- Joined: Sun Oct 26, 2008 2:29 am
Re: Printing Big Black Images with Thermal Printer
Is this using the Arduino or the Python library?
-
- Posts: 7
- Joined: Tue Jan 14, 2014 12:50 pm
Re: Printing Big Black Images with Thermal Printer
This is using the Arduino library.
I've been trying to mess around with the variables in the printer.begin function, and have been getting some different results, but there always seems to be some degree of streaky distortion to the images, like in the picture I posted above.
I've been trying to mess around with the variables in the printer.begin function, and have been getting some different results, but there always seems to be some degree of streaky distortion to the images, like in the picture I posted above.
- adafruit_support_mike
- Posts: 67454
- Joined: Thu Feb 11, 2010 2:51 pm
Re: Printing Big Black Images with Thermal Printer
That has to be numerical. The errors seem to be a fixed width in each row.
What code are you using to generate the image?
What code are you using to generate the image?
-
- Posts: 7
- Joined: Tue Jan 14, 2014 12:50 pm
Re: Printing Big Black Images with Thermal Printer
Here's the code. Let me know if you have any questions.
Code: Select all
const float pi = 3.14159;
#include "SoftwareSerial.h"
#include "Adafruit_Thermal.h"
int printer_RX_Pin = 5; // This is the green wire
int printer_TX_Pin = 6; // This is the yellow wire
Adafruit_Thermal printer(printer_RX_Pin, printer_TX_Pin); //setup printer
void setup()
{
Serial.begin(9600);
printer.begin();
for (int y = 0; y < 384; y++)
{
uint8_t row_data[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int curve_start = round(sqrt(square(192)-square(y-192))*cos(2*pi*1/2)) + 384/2;
int curve_end = sqrt(square(192)-square(y-192)) + 192;
for (int pixel=0; pixel < 384; pixel++) //generate the pixels
{
if (pixel >= curve_start && pixel<=curve_end)
{
row_data[pixel/8] += (1 << ((pixel+8)/8)*8-pixel-1);
}
} //end generation
for (int i=0; i < 48; i++)
{
Serial.println(row_data[i], BIN);
}
printer.printBitmap(384,1,row_data,false);
}
}
void loop()
{
}
- adafruit_support_mike
- Posts: 67454
- Joined: Thu Feb 11, 2010 2:51 pm
Re: Printing Big Black Images with Thermal Printer
Okay, no obvious signs of trouble there.
Try reducing the radius of the circle to 190, then 100, then 40. Let's see how the printer responds to different line widths. Also try printing a row of all zeros between rows of data. Maybe there's some relationship between the problem and the amount of time the print head has been able to rest.
Try reducing the radius of the circle to 190, then 100, then 40. Let's see how the printer responds to different line widths. Also try printing a row of all zeros between rows of data. Maybe there's some relationship between the problem and the amount of time the print head has been able to rest.
- pburgess
- Posts: 4161
- Joined: Sun Oct 26, 2008 2:29 am
Re: Printing Big Black Images with Thermal Printer
I can confirm the phenomenon happens; it's not peculiar to your printer, nor a defect of the code.
One unfortunate bit with these receipt printers is that even with a datasheet they're still, to a large degree, a black box...there's very little information on how exactly all the thermal parameters work and what's going on internally. Think I have an idea what's going on here...
It appears the printer can only heat a limited number of dots per line at any one time, and despite any settings the upper limit is less than the full width of 384 pixels. To print more dots than this, it prints the scanline in sections...the default as the code is set, if my math is right, is 168 pixels. The max appears to be 248 pixels...still less than the full printable width. What happens when a line has more 'set' pixels than this is that the first N dots are heated, then the remainder (up to N) dots (and in the default case, a third pass at such). Due to the finite available power available at any given instant, the two (or three) sections won't appear the same density.
Workarounds are limited. First, in the library source file Adafruit_Thermal.cpp, you can change line 166:
This can be changed to '30', which reduces (but does not eliminate) the banding -- it's now in two sections instead of three. This is the absolute upper limit, despite what the datasheet may say; any higher and the printer reverts to the default (64 dots).
When doing this, you'll probably need to lower the heat setting when calling printer.begin() to avoid stiction, e.g.:
Second then, is to fake out the bitmap so that no more than 248 pixels are set on a line. With the circle, this could be done by setting only odd-numbered, columns:
The resulting circle is much lighter, but appears contiguous now; no weird crescenting.
As long as you know for certain there won't be any solid black lines, you can boost the heat setting back to the default so it prints a little darker:
Victory...not flawless, but I think the best that can be hoped for from something really designed for receipts:
One unfortunate bit with these receipt printers is that even with a datasheet they're still, to a large degree, a black box...there's very little information on how exactly all the thermal parameters work and what's going on internally. Think I have an idea what's going on here...
It appears the printer can only heat a limited number of dots per line at any one time, and despite any settings the upper limit is less than the full width of 384 pixels. To print more dots than this, it prints the scanline in sections...the default as the code is set, if my math is right, is 168 pixels. The max appears to be 248 pixels...still less than the full printable width. What happens when a line has more 'set' pixels than this is that the first N dots are heated, then the remainder (up to N) dots (and in the default case, a third pass at such). Due to the finite available power available at any given instant, the two (or three) sections won't appear the same density.
Workarounds are limited. First, in the library source file Adafruit_Thermal.cpp, you can change line 166:
Code: Select all
writeBytes(20); // Heating dots (20=balance of darkness vs no jams)
When doing this, you'll probably need to lower the heat setting when calling printer.begin() to avoid stiction, e.g.:
Code: Select all
printer.begin(100);
Code: Select all
if ((pixel >= curve_start && pixel<=curve_end) && (pixel & 1))
As long as you know for certain there won't be any solid black lines, you can boost the heat setting back to the default so it prints a little darker:
Code: Select all
printer.begin();
-
- Posts: 7
- Joined: Tue Jan 14, 2014 12:50 pm
Re: Printing Big Black Images with Thermal Printer
Thank you for all your help! I wasn't able to get this to work with my printer though - I ended up setting the heating dots to 15, using a checkered pattern on every other pixel, and decreasing the width down to 288. But, I definitely wouldn't have been able to pull it off without this advice! Thanks!
Please be positive and constructive with your questions and comments.