2
\$\begingroup\$

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.

Clipped Sine wave

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
    // HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 1);
    adc_val = HAL_ADC_GetValue(&hadc1);
    adc_buf[i]=adc_val;
    if(i>999)
        i=0;
    adc_plot(adc_buf[i]);   // ploting the data from buffer
    i++;
    #endif}

Any idea how can I improve this?

\$\endgroup\$
7
  • \$\begingroup\$ In your adc_plot() function you do LinePixels[j]=0x0f. Why? What effect does this have on the printed output? \$\endgroup\$
    – brhans
    May 17 at 11:50
  • \$\begingroup\$ 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);? \$\endgroup\$
    – brhans
    May 17 at 11:55
  • \$\begingroup\$ Do you have a link to the programming manual for the printer? \$\endgroup\$
    – brhans
    May 17 at 11:57
  • \$\begingroup\$ 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 \$\endgroup\$
    – Shubham
    May 17 at 11:59
  • \$\begingroup\$ 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. \$\endgroup\$
    – Shubham
    May 17 at 12:05

1 Answer 1

6
\$\begingroup\$

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.

\$\endgroup\$
4
  • \$\begingroup\$ 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. \$\endgroup\$
    – Shubham
    May 17 at 12:11
  • \$\begingroup\$ link of the datasheet mouser.in/datasheet/2/164/ftp_628dcl_dsl_30x-1149348.pdf \$\endgroup\$
    – Shubham
    May 17 at 12:16
  • \$\begingroup\$ 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). \$\endgroup\$
    – jcaron
    May 17 at 12:42
  • \$\begingroup\$ 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 \$\endgroup\$
    – Shubham
    May 17 at 16:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.