您尚未登录。

楼主 # 今天 16:45:53

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

好久没上坛子了,对不住兄弟们,此楼敬晕哥

离线

楼主 #1 今天 17:02:10

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

先介绍下当前的实验环境:

软件环境:
   XSTAR开发环境,由原先的XBOOT分离而来.。XBOOT计划分离出两个独立项目,一个XSPARK,聚焦bootloader;另一个就是XSTAR,跨操作系统纯C版APP开发框架。

硬件环境:
   因为有了XSTAR加持,所以就可以不上任何SOC了,直接用PC搞定,为了让PC拥有控制IO的能力,这里用沁恒微的CH347F这款USB口扩展芯片,其可以扩展出I2C,SPI,GPIO,UART,JTAG功能
   打印机直接采用常用的384点,57mm的普通热敏打印机,因为打印机所需IO较多,这里采用了PCF8574这款I2C接口的芯片来扩展GPIO,一颗PCF8574可以扩展8个GPIO口,可以满足打印机模块的核心功能驱动,辅助性的功能,就需额外扩展了,比如温度检测,纸张检测,切刀等等。

离线

楼主 #2 今天 17:17:14

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

打印机驱动本身,并不复杂,一个2相4线步进电机,每走两步,算一个像素,两根串行数据传输线,就是SPI里面的MOSI以及CLK,还有锁存线,以及至少1根加热控制线,加热控制线的加热时间通常是2ms左右,这里需要考虑热扩散效应,最好建立一个跟历史数据,并跟当前打印黑点数相关联的模型,动态调整加热时间,以达到最优加热效果。

这里在控制加热时有个坑,还得注意,从省事的角度,384个点一股脑传输进来再一起加热是最简单的,但是,但是,就怕但是,如果这384个点里面绝大部分是黑色,也就是需要加热,那么第一你的电源顶不住,第二,即使你的电源顶得住,打印头也顶不住,一般最多同时打印点数在128点左右,不然,你期望的黑色线条变成白茫茫一片,所以这里需要做点处理,当然也不复杂,超过了极限分批次处理就可以了。

还有一个影响体验的就是IO速度了,之前因为用的纯gpio模拟,打印速度太慢了,慢得无法忍受。这里在数据传输时需要上纯硬件SPI接口,来个10MHZ基本就快起来了,当然GPIO模拟慢,这里要批评一下沁恒微,I2C连续读写之间有固定的的延迟,这个延迟严重制约GPIO的速度,这里还看官方是否能改进吧,不然这些桥接芯片在高速场景就无法满足需求了。

离线

楼主 #3 今天 17:33:02

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

关于字体渲染,这里走了点弯路,开始研究的是MSDF技术,这种技术由SDF扩展而来,就是多通道有符号距离场,其优势是高质量缩放,很容易实现发光,阴影,空心字等特效,其存储方式类似于传统的点阵字体,但表现能力要强很多,这种技术主要是用在3D游戏领域,本以为应该也适合嵌入式,但综合评估下来,还是不太适合。
1,字库偏大,一个3000字的中文字库,在24像素大小时需要仅10MB
2,为了达到高质量缩放,必须采用更大像素尺寸的字库,这里字库体积会急剧膨胀
3,渲染效率这一块,虽然渲染代码不多,仅需10来行,但需要实现浮点型双线性插值,对于纯CPU渲染来说,代价偏大

研究成果我打个包丢这里,敢兴趣的可以研究研究,备注,对于嵌入式而言,此方案是歧路。

# MSDF字体生成工具

这是一个用于生成MSDF(多通道有符号距离场)字体的工具集,包含字体纹理生成和C代码转换功能。

## 使用方法

### 1. 生成MSDF字体纹理

使用 `msdf-atlas-gen.exe` 从TTF字体文件生成MSDF纹理:

#### Windows环境:
```bash
# 生成PNG格式纹理
.\msdf-atlas-gen.exe -font Roboto-Regular.ttf -type mtsdf -minsize 24 -emrange 0.2 -yorigin top -format png -imageout roboto_regular.png -json roboto_regular.json
```

#### Linux环境(使用Wine):
```bash
# 生成PNG格式纹理
wine msdf-atlas-gen.exe -font Roboto-Regular.ttf -type mtsdf -minsize 24 -emrange 0.2 -yorigin top -format png -imageout roboto_regular.png -json roboto_regular.json
```

#### 备注:
- **Kerning 支持**:如果TTF字体未能导出kerning信息,需要通过FontForge重新导出支持kern的字体。使用FontForge打开字体文件,确保包含kerning表,然后重新导出为TTF格式。

- **字体规范**:字体必须满足OpenType规范,无异常交集(overlapping contours)。可以使用FontForge检查和修复字体中的轮廓交集问题,确保字形路径正确且无自交。

- **字符集**:如果需要按需来生成字符,请使用-charset参数,所需字体存储在一个txt文本里,用双引号括起来,也在文件里指定unicode范围,用方括号描述,具体请参考chinese目录的中文字符集。

### 2. 转换为C头文件

使用Python脚本将生成的纹理和元数据转换为C头文件:

```bash
python3 msdfgenc.py <png_file> <json_file> <font_name>
```

#### 参数说明:
- `png_file`: 输入的PNG纹理文件
- `json_file`: 输入的JSON元数据文件
- `font_name`: 输出字体名称(用于生成的文件名和变量名)

#### 示例:
```bash
python3 msdfgenc.py roboto_regular.png roboto_regular.json roboto
```

## 依赖要求

- msdf-atlas-gen.exe
- Python 3.x
- wine (Linux平台)

mtsdf-0.0.0.7z

最近编辑记录 xboot (今天 17:35:39)

离线

楼主 #4 今天 17:39:24

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

关于字体渲染,最后还是回到了传统的ttf字体,质量好,字库小,这是最优解决方案。
附图是不同字号下的渲染效果。
2_20260119-1738.jpg

1_20260119-1738.jpg

离线

楼主 #5 今天 17:44:32

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

有了文字打印,当然少不了图片打印,以及二维码打印,这些都是轻车熟路,简单拓展下api就可以了。

下面是打印接口函数,既支持低阶接口也支持高阶打印接口,其中文字支持多语言混排,图片也支持抖动算法,自动二值化。

void printer_print(struct printer_t * p, unsigned char * buf, unsigned int len);
void printer_feed(struct printer_t * p, int lines);
void printer_cut(struct printer_t * p);
void printer_standby(struct printer_t * p);

void printer_print_hr(struct printer_t * p, int black, int white);
void printer_print_text(struct printer_t * p, enum printer_align_t align, const char * family, enum font_style_t style, int size, const char * fmt, ...);
void printer_print_qrcode(struct printer_t * p, enum printer_align_t align, int pixsz, const char * fmt, ...);
void printer_print_vision(struct printer_t * p, enum printer_align_t align, struct vision_t * v);
void printer_print_surface(struct printer_t * p, enum printer_align_t align, struct surface_t * s);

3_20260119-1741.jpg

离线

楼主 #6 今天 18:03:55

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

关于抖动算法,常用的有floyd-steinberg,jarvis-judice-ninke,stucki,atkinson,这里采用atkinson,这个算法会大面积留白,有点艺术性,适合打印场景。

对于这种普通的热敏打印机是否能灰度化打印,理论上是可行,原理也不复杂,就是将加热时间进行分片,比如需要实现16灰度打印,原始图像数据位8bit灰度图,只需将总时间除以16用于基本加热时间片,然后加加热一次,对应的灰度值减去16,直到减至0,就不再加热。这里假设了打印灰度跟加热时间是线性关系。

实际测试下来,靠加热时间控制很难实现16灰度等级的打印,即使理论上的16灰度等级,实际上最多也就4灰度等级,这个结论仅限于我当前的实验条件,线性化假设,以及这种国产的普通热敏打印机。

上面是卡通图像是抖动算法,下面的是灰度打印,可以看出是能表现出一些灰度来的。

为了展现出灰度打印的实际效果,我这里选择了中国传统山水画,再来进一步实验。首图是原始绘图度,下面都是不同打印热密度下的表现。
11.png

12.jpg
13.jpg
14.jpg
15.jpg


最终结论,普通热敏打印机是可以实现灰度打印的,但是效果不敢恭维,基本没有很强的表现力,只能用于赚吆喝,堆参数而已,所有最终还是决定放弃此特性。

离线

楼主 #7 今天 18:10:50

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

打印机的基础工作做到这里,基本算可以结束,但对于应用场景而言,才算刚刚开始,这里可以玩出各种花来。我这里就抛转引玉,如标题所说,就展现两个应用场景,一个AI打印机,另一个作业帮错题打印机。

AI打印机,随便来点展现吧,对话打印,歌词打印,生图打印,拍照动漫化打印等等。。。

背后的核心就是各种模型在加持。

离线

楼主 #8 今天 18:21:41

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

好了,AI打印相关话题就不展开了,毕竟还要恰饭,说点作业帮APP加持吧。

这个作业帮喵喵机其实早就有前人研究过了,里面的传输协议,也整理成档,玩起来的玩家也不少。但是,但是,又来但是了,最新的APP无法支持基于这些协议的自制设备了。为了搞清楚APP究竟哪里限制了,我买来了最早的喵喵机P1,上逻辑分析仪,不管怎么样,你最新的APP不也得支持最老的机器才行?

所以,咸鱼给我送来了温暖。
44.jpg
33.jpg
33.png

这里抓的是ios平台的,后面重点攻克的是android平台,没采用仅供参考。
55.png

离线

楼主 #9 今天 18:37:35

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

有了数据,结合前人研究的协议,我这里分析到问题点了,最新的app不支持,就是因为CRC32的初始化向量变化了,作业帮APP的CRC32初始化向量是随APP走的,理论上要通信成功,需要作业帮APP先发送初始化向量,然后机器接收到后,后面都按此向量来校验以及生成相关数据帧,如果向量不正确,那么你肯定无法生成有效信息,所以APP也不认了。

那APP是如何发送初始化向量的呢,明文吗?这个大概率不是的,那如何解密出初始化向量呢,这个说实话,是有点困难的,特别是在特征信息很少时,根本无法正向解密出来,尽然来不了正向,那就来暴力,CRC32我从0x00000000试验到0xffffffff,只需要几秒钟,暴力代码如下,基于ios数据编写的,仅供参考。

/*
 * start = 0x88f8cf69, crc= 0xbc1eee5a
 */
static int do_test(int argc, char ** argv)
{
	uint8_t buf = 0x01;

	for(uint32_t start = 0; start < 0xffffffff; start++)
	{
		uint32_t crc = xcrc32_sum(start, &buf, 1);
		if((crc == 0xbc1eee5a)/* || (crc == 0x5aee1ebc)*/)
		{
			shell_printf("start = 0x%08x, crc= 0x%08x\r\n", start, crc);
		}
		else
		{
			if((start & 0xffff) == 0xffff)
			{
				//shell_printf("not found start = 0x%08x\r\n", start);
			}
		}
	}
	return 0;
}

可以顺利输出当前CRC初始化向量,而且这个向量是不变化的,是固化在APP里。后面重点在攻克Android系统的APP,暴力出来后,CRC初始化向量是0,不知道是不是因为我的机器是P1,最老款的,进行特殊对待了,不管怎么样,我就模拟P1,当最老款的,也不是未尝不可。

好了,基础工作研究到位了,下面就开始编码验证,App绑定验证了。

需要先购买一个蓝牙透传模拟,支持SPP以及BLE的,然后做一些设定,稍后补充,下面是具体的APP绑定过程。

离线

楼主 #10 今天 18:52:05

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

蓝牙模块使用下图所示的模块,该模块支持双模蓝牙。对于安卓平台,采用SPP进行透明传输;对于IOS平台,采用BLE进行透明传输。
66.png
为了让朱叶邦APP能够识别蓝牙设备并成功绑定,需要对透明传输模块进行一些配置。对于SPP模式,以下项目是必须修改的。
67.png

1, 波特率修改为115200
2,蓝牙设备名称修改为Paperang
3,蓝牙设备地址,从机器复刻
4,对于协议里面的设备名称也必须从机器复刻

MAC必须和设备序列号对应,否则无法顺利绑定。

错题打印效果展示

离线

楼主 #11 今天 18:56:50

xboot
会员
注册时间: 2019-10-15
已发帖子: 704
积分: 437

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

关于XSTAR,没有任何文档,这里直接让AI阅读了整个源码,让AI提炼出工程亮点,可以一阅。

xstar.png

离线

#12 今天 20:14:12

hameyou
会员
注册时间: 2018-04-15
已发帖子: 247
积分: 28.5

Re: 我来玩玩热敏打印机,先实现AI打印机,再顺带赋能作业帮APP

楼主玩的挺溜得,网上能买到吗?

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn


太原小智科技有限责任公司 - 东莞哇酷科技有限公司联合开发