# Smooth wave plotting using 3 inch thermal printer [closed]

I am interfacing 3 inch Fujitsu thermal printer (FTP-638MCL103) with STM32. Character printing is working fine. I am struggling to print smooth sine waves generated from a function generator.

I want to make this dotted waveform smoother.

Here is my code for plotting:

void adc_plot(uint16_t val){

uint8_t j = 36;
uint8_t LinePixels[72]={0};  // total 576 dots (72 * 8 dots)
j=  (int)(val/14)+30;
LinePixels[j]=0x0f;
PrintDots8(LinePixels,72);
PrintDots8(LinePixels,72);
PrintDots8(LinePixels,72);
PrintDots8(LinePixels,72);
PrintDots8(LinePixels,72);
PrintDots8(LinePixels,72);
PrintDots8(LinePixels,72); /* multiple statements to make it darker horizontally */
LinePixels[j]=0x00;}


And code from main.c as follows

  while (1){
#if 1
if(i>999)
i=0;
i++;
#endif}


Any idea how can I improve this?

• In your adc_plot() function you do LinePixels[j]=0x0f. Why? What effect does this have on the printed output? May 17 at 11:50
• And unrelated to your issue, but why do you LinePixels[j]=0x00; at the end of adc_plot()? Why do you bother with putting adc_val into adc_buf[i] when you could just adc_plot(adc_val);? May 17 at 11:55
• Do you have a link to the programming manual for the printer? May 17 at 11:57
• linepixels[72] is the array of dots to be printed horizontally. eg if i set linepixels[1]=0xff; it will print first 8dots of the horizontal line and for linepixels[72]=0xff means last 8 dots of the line. @brhans May 17 at 11:59
• 1. Linepixels[j] need to reset otherwise it will continue printing the same data while rolling. 2. using array for storing data samples of sine waves. of course i can use adc_plot directly. i used the array for comparing two data points and plots. May 17 at 12:05

Without reading the datasheet, it is obvious from these lines that you operate on a number of bits:

uint8_t LinePixels[72]={0};  // total 576 dots (72 * 8 dots)
j=  (int)(val/14)+30;
LinePixels[j]=0x0f;


The problem is that you treat it as a number of bytes. Whatever you're printing you only print 00000000 00001111 00000000 etc.

You need to replace the line LinePixels[j]=0x0f with something that only sets one of the bits, and sets the correct bit based on whatever is left of your division. I suggest something like this (untested):

j = (int)(val/SCALE)+(576/2);
LinePixels[j/8] = 1<<(j%8);


You need to modify the scale depending on your input range, and you may need to correct the shift direction because I don't know the order of the bits your printer expects.

You will probably want to perform the initial scaling in a different way to be able to round correctly, but the general idea holds:

1. Calculate j as a non-negative integer between 0 and 575.
2. Figure out which byte to set: j/8
3. Figure out which bit to set in that byte: j%8

As the commenters point out there are a lot of places you can optimize this, but optimization is a different problem and should be performed after you have a working algorithm.

• i tried to set the single bit for the calculated adc value. but the data is not visible on paper so i set in to 0x0f to get the thckness right. i tried filling the gap between two adc values but it is not perfect though. May 17 at 12:11
• link of the datasheet mouser.in/datasheet/2/164/ftp_628dcl_dsl_30x-1149348.pdf May 17 at 12:16
• I’m not quite sure the printout matches what you expect. One should see spaces between lines being exactly equal to the line width, but that does not seem to be exact. Also, one would probably need to actually draw lines between consecutive points (rather than just repeating multiple times). May 17 at 12:42
• I am trying to draw lines between two adc value which is stored in adc buf But my current algorithm is not working. Any suggestion is appreciated @jcaron May 17 at 16:48