qoistoochee128

【ART-Pi】Thermal printer based on ART-Pi +557280A

 
Overview

I. Introduction

1. Function introduction:

Add a thermal printer expansion board to the ART-Pi main control. This expansion board integrates a thermal printer head, 3 LEDs and 3 buttons. Connect your mobile phone to the board WIFI, and you can print Chinese characters through the mobile APP. (Because WIIF is not available, this function is replaced by a serial port.) Information such as QR codes and pictures, LEDs and buttons can prompt operating status and interaction.

2. Brief description:

(Original plan) Configure the WIFI on the baseboard as the server, and the mobile APP as the client to transmit data through the LAN. The printed Chinese characters will be burned into the memory chip in advance, and the entire font library will be burned into the flash, and the font template will be queried and obtained when needed. Use the QR code generation algorithm to convert Chinese characters into QR codes and print them.

3. Display diagram of ART_PI and expansion board

ART_PI display image image.png

Printer expansion board front image.png

reverse side image.png

And ART_Pi connection diagram front image.pngside image.png

Run demo program image.png

2. Apology

I am very grateful to Lichuang EDA and RT_Thread for recognizing my project. I am very honored. However, because I have been working on a Raspberry Pi project during my vacation, the time distribution may be a bit uneven. After the ART_Pi was mailed back, it has been in a state of dust. I feel very sorry. The start of school is approaching, and I feel like the RT_Thread activity is coming to an end. Since they recognize me so much, I feel that I shouldn’t let myself down. So, I was ready to take some time to complete this project.

3. Getting started with ART_PI

I still remember the first time I ran ART_PI. Because I didn’t understand anything, I created an RT_Thread project in RT_Thread. After burning the program, the terminal just didn’t display. I don’t know why. Because my expansion board led out serial port 1, I used serial port 1 as the console after simple modifications, but this was very inconvenient and a bit wasteful. After using it for a period of time, I accidentally found in the group that they were all projects created based on development boards. I thought, this is what it looks like. I am such a pig. Then I created a project based on ART_PI, but after downloading it, nothing appeared, the console was still unusable, and it felt like the program was not programmed. I accidentally heard the term bootloader, searched it, and found out the reason. It turns out that the main control flash of ART_PI is only 128K. If the project is larger than 128K, it must be programmed into the external flash, and the internal flash will be programmed with this bootloader as a boot. After this brief introduction, the cottage suddenly opened up, and then entered RT_Thread studio for a while and reprogrammed the bootloader (available in the sample project based on ART_PI). The original bootloader has been destroyed because I programmed other projects. After programming the bootloader, I programmed the demo project based on the development board. As a result, the console can be used and the lights flash normally. The first step has finally been taken, which is great. As a reminder, projects created in the future must also be improved based on the demo project.

4. The experience of joining ART_PI for the first time

When I used ART_PI for the first time, I had already downloaded the RT_Thread studio development environment, and based on the official documentation, I had a preliminary understanding of the simple use of RT_Thread studio. Because it was my first time to use an operating system, I knew nothing about these concepts, and with my previous thoughts on bare-metal programming, this sudden jump felt too much. Fortunately, there is a magical website called Bilibili. I found the operation video launched by RT_THread in it. It took me a day to go through it all. I still feel confused. I may have understood it, but I still seem to understand nothing. I don’t understand (laughing to death). RT_Thread Video link: Video link What should I do? I’ve watched the video and can’t do anything. I had no choice but to continue looking for information. Which place had the most complete information? It must be the official website. So, I went to the official website to continue learning and exploring. After briefly reading it again, I finally got a general understanding. But it was still not good enough, so I followed the introduction of each chapter on the official website and went through every knowledge point according to the routine (maybe not all), and then I was ready to start the printer project when I seemed to understand something. . RT_Thread official website link: Document link

5. Familiarization stage

In the process of getting familiar with RT_Thread development, I transplanted SPI and QSPI according to the documentation, which are the two external flashes corresponding to the development board, and also wrote the button and LED routines. I briefly recorded it on CSDN.

1. SPI

2. Buttons and LEDs

-------------------------------------------------- ----------------------------------The following is the focus of this chapter, the debugging and implementation of the printer-- -------------------------------------------------- --------------------------

6. Debugging and implementation of printer project

1. Create a demo project

I won’t introduce it here. It is recommended to read the official website documentation.

2. Make and burn font library

Regarding this project, I also wrote a document, which uses the STM32F103 chip and is a bare metal project. You can see the production part. I will introduce the programming part below. Font library production and programming. If you don’t want to make it yourself, you can go directly to my github to download the github link and find image.png the tested fonts. This is what I use.

The following introduces the method of using ART_PI to program the font. There are two steps required to complete this step. One is the transplantation of the serial port, and the other is the transplantation of the W25Q128.

3. Transplantation of W25Q128

If the project is created based on ART_PI, this step is not required. I actually copied the SPI1 driver from cubuMX and put it in the board.c file. (I'm so stupid, I will introduce it later) Open macro definition and enable SPI1 and then mount the device.


/*---------挂载SPI1设备--------------*/
int rt_spi_w25Q128_init(void)
{
  /* 向系统注册SPI1总线上spi10从设备 */
    rt_hw_spi_device_attach("spi1", W25Q128_DEVICE_NAME, GPIOA, GPIO_PIN_4);   // W25Q64的片选连接在PA4上

//    if(RT_NULL == rt_sfud_flash_probe("W25Q128", W25Q128_DEVICE_NAME))  // 检测这个设备
//    {
//        return -RT_ERROR;  // 没有检测到
//    }
    return RT_EOK; // 检测成功
}

Then use the official document's initialization program to read the ID (see the official routine). The data read out is image.png

Then use the command to check whether the SPI10 device is successfully mounted. image.png

Then there are the chip erase, block erase, sector erase, write data and read data functions of W25Q128. (Ported from wildfire routine)

I’ll just post a picture and won’t go into details. The code can be posted below, please check it yourself. image.png During the debugging process, I needed to constantly test to see if the data was burned in, so I wrote a data reading function and added it to the command line.

/* 测试读数据 */
void aa(int argc,char *argv[])
{
    rt_uint16_t i;
    rt_uint8_t * pBuffer;
    rt_uint32_t readAddr = 0; // 读地址
    rt_uint16_t length = 0;

    /* 配置接收的参数 */
    rt_kprintf("read argv[1]:%s 
",argv[1]);
    readAddr = htoi(argv[1]); // 将16进制字符串转化为整形 // 要读的地址
    length = atoi(argv[2]);  // 要读的长度
    rt_kprintf("readAddr:%x length:%d 
",readAddr,length);
    SPI_FLASH_BufferRead(pBuffer,readAddr,length);

   for(i = 0; i< length;i++)
     rt_kprintf("%x ",pBuffer[i]);
}

This function can accept command line parameters to determine the first address of the data to be read and the number of bytes of data to be read. Two functions have to be introduced here

> atoi() This is built-in to convert the numbers of the string into integers > htoi() This needs to be written by yourself. It converts the hexadecimal of the string into an integer, which is very useful here.

The htoi function was found online, thanks to the friend who provided it.

/*---------------------------函数 */
rt_uint16_t tolower(rt_uint16_t c)
{
    if (c >= 'A' && c <= 'Z')
    {
        return c + 'a' - 'A';
    }
    else
    {
        return c;
    }
}

rt_uint32_t htoi(char s[])
{
    rt_uint16_t i;
    rt_uint32_t n = 0;
    if (s[0] == '0' && (s[1]=='x' || s[1]=='X'))
    {
            i = 2;
     }
    else
    {
           i = 0;
     }
    for (; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z') || (s[i] >='A' && s[i] <= 'Z');++i)
    {
            if (tolower(s[i]) > '9')
            {
                 n = 16 * n + (10 + tolower(s[i]) - 'a');
            }
            else
            {
                 n = 16 * n + (tolower(s[i]) - '0');
            }
        }
    return n;
}

Test: Enter aa 0 256 就是从0地址处读256个字节 image.png writing on the command line. I also encapsulated such a function. Due to limited space, the demonstration will not be carried out. At this point, W25Q128 has been transplanted successfully.

4. Transplantation of serial port

Because I need to use the serial port to send the font and then write it to W25Q128, I need to transplant the serial port program. Because my expansion board leads to serial port 1, then I need to transplant serial port 1.

Enable serial port 1 in board.h image.png

I am using the official interrupt routine. I originally wanted to use DMA transmission, but I don’t know why it cannot be used, so there is no other way. Just interrupt when it is interrupted. Simply modify the serial port reception callback function and use an array to save each time. The received data is written to the modified program in flash every 256 bytes received.


/*------串口接收线程入口-----------------*/
void uart1_recv_thread_entry_INT(void *parameter)
{
  char ch;
  rt_uint8_t buf[300];
  rt_uint16_t buf_length = 0;
  rt_uint32_t writeAddr = 0; // 写入flash的首地址
  while(1)
  {
      /* 从串口读取一个字节的数据,然后读取到则等待接收信号量 */
      while(rt_device_read(uart_dev_usart1, 0, &ch, 1) != 1)
      {
          /* 读取不成功,等待获取信号量 一获取信号量就表示有数据接收 */
          rt_sem_take(&rx_sem, RT_WAITING_FOREVER);  // 阻塞等待接收信号量
      }
      /* 读取到的数据通过串口错位输入 */
      //ch = ch + 1;
      //rt_device_write(uart_dev_usart1, 0, &ch, 1);
      /* 把接收到的每一个字符都写入到flash中 */
      buf[buf_length ++] = ch;  // 存储字符到数组
      if(buf_length == 256)  // 一帧数据是256个字节
      {
         // 一帧数据接收完,先写入flash中
         SPI_FLASH_BufferWrite(buf,writeAddr,buf_length);  // 往flash 中写入数据

         writeAddr += 256;
         buf_length = 0;
         rt_memset(buf, 0, 256);  // 清空缓冲区
         rt_kprintf("write 256 byte success!
");
      }
  }
}

Each time 256 bytes are received, "write 256 byte success! " will be printed on the console. In this way, you can also check the running status. Please see the font creation and programming above for the configuration of the serial port assistant. They are the same.

In this way, the serial port configuration is also completed.

Programming: Erase the entire chip first. There is a problem here. I use the command to erase the entire chip to erase the chip. The data read out is also 0xff, but the first two or three blocks cannot write data. , the latter can write data, I don’t know why (if anyone knows, I hope you can give me some guidance). In the end, there was nothing I could do, so I used a loop to erase each block, thus indirectly erasing the entire chip. The effect was good, and data writing was normal.

/*----------用块擦除代替芯片擦除----------  */
/* 一共是16MB  16384KB   一个块64KB   一共是256个块
 * 一个块的起始地址和结束地址范围是  0-65536B  也就是0-FFFF
 * 0-FFFF  10000-1FFFF 20000-2FFFF ...
 * */
void SPI_FLASH_BlockFormat(void)
{
    rt_uint16_t i;
    rt_uint32_t BlockAddr = 0; // 地址
    rt_kprintf("SPI_FLASH_BlockFormat start !
");
    for(i = 0; i< 256;i++)  // 一共擦除256个块
    {

        SPI_FLASH_WriteEnable(); // 写使能
        SPI_FLASH_WaitForWriteEnd(); // 等待写完成
        // 写入4个字节的数据  不接收
        W25Q128_Send_Buf[0] = W25X_BlockErase; // 擦除块指令
        W25Q128_Send_Buf[1] = (BlockAddr & 0xFF0000) >> 16; // 块地址
        W25Q128_Send_Buf[2] = (BlockAddr & 0xFF00) >> 8;
        W25Q128_Send_Buf[3] = BlockAddr & 0xFF;
        rt_spi_send(spi_dev_w25q128,W25Q128_Send_Buf,4);
        SPI_FLASH_WaitForWriteEnd(); // 等待写完成

        BlockAddr += 10000;  // 一次加10000,也是一个块的首地址
    }
    rt_kprintf("SPI_FLASH_BlockFormat complish !
");
}
MSH_CMD_EXPORT(SPI_FLASH_BlockFormat,SPI_FLASH_BlockFormat); // 添加到命令行

In this way, the font writing is successful.

Verification: I also wrote a function to read the number of bytes in the font to see if the data is consistent. The code is too long, please post a picture image.png

image.png

Execute and test the entire command on the command line, which will take out the data of your font. Here is a 33*32 font, a total of 132 bytes. image.png You can verify the correctness with winhex. It is introduced in font production and programming. , not much to say here.

In this way, the font programming is completed.

Printer driver migration

Briefly introduce the pins of the printer. 4 pins control the operation of the motor, 6 pins are responsible for heating, one pin LAT is responsible for latching data (to put it bluntly, it is chip select), one SCK, and one DI (can form an SPI). , you only need to configure 4 click pins and 6 heating pins as PIN outputs, LAT, SCK and DI to configure an SPI device to transmit data, so it can be driven.

Regarding the issues required during the configuration process, I configured the SPI2 driver from CubeMX as usual, and then transplanted it to the board.c file. I also enabled SPI2, and the SPI20 device was also recognized in the console, but the final result It means that SPI transmission failed. I was delayed at this step for a long time, doing various tests, looking for errors, and even tested it with a logic analyzer. There were no waveforms at all, and I had no clue. Finally, after reading the online documentation, I realized that I was wrong from the beginning. (It would not be unfair to say that I am a pig.) For a project created based on the development board, it is useless for us to add the transplanted driver in board.c. We need to

image.png

To configure this file, I opened this file and found the SPI initialization, which contains SPI1 and SPI4 drivers. This also explains why my first step W25Q128 can drive successfully, but my SPI2 fails to transmit data. After I transplanted the SPI2 program image.png

Sure enough, the transmission was normal.

Test motor rotation: To test motor rotation, you only need to make 4 pins output levels in sequence, that is, drive the stepper motor. I wrote a rotation test,

/* 测试打印机转动 */
void testPrinterRight(void)
{
    rt_uint16_t i;
      for(i = 0;i < 40; i++)
      {
          printer_right(50,2);
      }
      rt_kprintf("testPrinterRight success
");
}
MSH_CMD_EXPORT(testPrinterRight,testPrinterRight);

Just enter testPrinterRight on the command line and the motor will rotate a certain distance.

Then write the program for printing Chinese characters, letters, and the program for printing pictures. After unremitting efforts, the first stage is completed.


Attach the renderings: image.pngimage.png

The Chinese characters feel okay, but the pictures are a bit terrible.

It will continue to be improved in the future.



Second phase 2021-3-22

This is the second phase of development and testing. Because I have several projects in hand now, I cannot develop this project wholeheartedly. I can only complete this project indirectly by taking some time. (Therefore, many functions have not been developed yet, please forgive me, but I will keep developing them)

1.Added functions

On the effect of the first stage, further modifications were made,

1. Improved the situation of unclear printing of Chinese characters 2. Added the possibility of multi-line printing (originally only supported single-line printing) 3. Added the ability to display Chinese characters on the screen, and then click on the corresponding Chinese characters to print

Originally, I wanted to add an APP or use the screen to spell Chinese characters directly for printing, but I was interrupted due to some difficult factors and turned to this very inconvenient method.

Because I used to use esp8266 for WIFI development. Now I have never been exposed to the WIFI template on the ART_pi board, and I am not very familiar with it. I haven’t studied it yet. I will do it when I have time. In that case, APP can be developed. used.

Screen typing is because I am not very familiar with pinyin input method typing, and I have not learned it systematically. I searched online and it seems that it is not very complicated. I haven’t adjusted it yet. I hope this function will be added in the future.

That’s it for now, I’ll definitely come back and tidy it up when I have time (definitely).

Printing effect

Various fonts.jpgMultiple fonts1.jpg Recognized QR code QR code.jpgIdentify QR code.jpg

See the attachment for test results.

参考设计图片
×
 
 
Search Datasheet?

Supported by EEWorld Datasheet

Forum More
Update:2025-06-23 13:03:11

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
community

Robot
development
community

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号