3

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?

JRE
  • 67,678
  • 8
  • 104
  • 179
Shubham
  • 41
  • 6
  • In your `adc_plot()` function you do `LinePixels[j]=0x0f`. Why? What effect does this have on the printed output? – brhans May 17 '22 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);`? – brhans May 17 '22 at 11:55
  • Do you have a link to the programming manual for the printer? – brhans May 17 '22 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 – Shubham May 17 '22 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. – Shubham May 17 '22 at 12:05
  • You don't need to reset `LinePixels[j]` at the end of the function after it's been printed - you're zeroing it out at the start of the function every time with the `uint8_t LinePixels[72]={0};` line. – brhans May 17 '22 at 12:06
  • it was a global variable before. – Shubham May 17 '22 at 12:12

1 Answers1

6

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.

pipe
  • 13,748
  • 5
  • 42
  • 72
  • 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. – Shubham May 17 '22 at 12:11
  • link of the datasheet https://www.mouser.in/datasheet/2/164/ftp_628dcl_dsl_30x-1149348.pdf – Shubham May 17 '22 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). – jcaron May 17 '22 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 – Shubham May 17 '22 at 16:48