现在玩了一年多,总算大概知道一些基础知识了,这里整理一下分享给同样开始想使用贴片元件进行电子 DIY 的朋友们。
PS. 我作为一个新入门电子 DIY 玩家,以下都是从一个初学者的角度整理的,并且主要介绍我使用过,稍微了解一点的元件,如有错误还请指正。
在使用成品模块,或者分立元件时,一般都不用太考虑封装,它们的引脚可能本身就符合万用板上的引脚间距。
但是在使用 PCB 和贴片元件时,就需要了解每个元器件的封装了,一般画 PCB 时有一个重要的步骤就是给 PCB 中所使用的元器件画封装。幸好立创 EDA 结合立创商城,给大多数元器件已经画了封装,在立创 EDA 中可以直接使用。
元件封装(Footprint)或称为元件外形名称,其功能是提供电路板设计用,换言之,元件封装就是电路板的元件。 封装主要分为DIP双列直插和SMD贴片封装两种。
对于常用元器件,例如电阻、电容,这些都是使用的 0805、0603、0402 这样的数字来表示封装大小,这里面的数字都是英制单位,例如一个 0805 封装的电阻就表示这个电阻的尺寸大约为 0.08 inch 0.05 inch,对应到公制单位大概是 2.0mm 1.25mm。
另外一些元器件也会使用公制单位来表示封装尺寸,例如晶振中的 3225 表示大小为 3.2mm * 2.5mm 的晶振。
以上两种封装的更多尺寸可以参考这个帖子: https://www.digikey.cn/zh/forum/t/topic/440 。
芯片一般会有更多引脚,这个时候就会接触到例如 SOP-8、QFN-48、QFP-48 这样的封装,其中 SOP 还有相应的更密集引脚的变种 SSOP。这类封装名称后面跟着的数字用来表示这个芯片拥有多少引脚,例如 QFN-48 就表示这个芯片有 48 个脚本,通常会是四边,每边 12 个引脚。
SOP 和 QFP 这两种封装都有对应的引脚在芯片外面,而 QFN 则是在封装侧面分布着一排焊盘,焊接难度比较 SOP、QFP 可能会更高一些。
这种封装一般会用在高速芯片上,因为这种芯片体积小,但是拥有更多引脚,通过像 QFN 这样的封装已经没办法放下足够多的引脚了,又或者因为芯片本身设计需要,需要将引脚按内部模块分布。
在接触到高速电路例如 USB 3.0、SoC 之后,会碰到此类芯片,例如全志 H616、DDR 内存颗粒、eMMC 存储芯片等,这些芯片的焊接相比上面几种又增加了难度,可能需要失败几次才能掌握 。
关于更多芯片封装可以参考这个文章: http://www.ccmchip.com/20201019-88990.html 。
电阻在电路通常用来限流、分压等用途,是比较常用的元件了。
在原理图中,电阻的位号通常使用 R 开头。
插件电阻
在以前的分立元件电路中比较常用,现在用上 PCB 就可以不用了,不过有个好处就是一般功率比贴片电阻大。
贴片电阻
用来代替插件电阻的,现在 PCB 设计中最常用的元件之一了。
采样电阻
在电流采样电路中会使用到,一般阻值是豪欧级别,例如 5 豪欧、10 豪欧,这样即使在有大电流时,也不会产生太大的功耗。
大功率电阻
像水泥电阻、铝壳电阻什么的,可以做到很大体积,并且承受比较大的功率,例如 5 欧 50W 的电阻,就可以承受一段时间持续 10A 的电流。
对于贴片电阻,常用的封装就是 0805、0603、0402 等等,对于手工焊接玩家来说,0805、0603 是比较适合手工焊接的,0402 在熟练的情况也可以使用,不过这个也是我个人的极限了,再小也没有尝试过。
一般电阻封装可以根据功耗去选择,通常封装更大的电阻,拥有更高的功率支持,如果不是需要通过大电流,可以往小了并且手工焊接友好的封装的方向选择,我现在通常会选择 0603 封装的贴片电阻。
对于电阻选型来说,可以从功率、精度两个方面来考虑。
功耗
在非高功率电路中,一般不会有特别高的电流,贴片电阻常见的 125mW 的功率已经足够使用了,例如在 5V 电路中使用 1K 的电阻给 LED 限流,电阻消耗的功率为 0.001A * 5V = 0.005W,远低于 125mW。
精度
电阻常见精度有 5%、1%、0.1% 等,有一些精密电路,例如 USB 芯片的某些引脚会比电阻精度有要求,但是一般也就是要求 1% 的精度,只有比较少的场合会使用到 0.1% 精度的电阻,一般来说 5% 和 1% 精度的电阻价格没有差别太大,在购买时我都直接选择 1% 精度的电阻。
电容通常是用来稳压、去耦、滤波等用途,有些时候在电路中使用量可能比电阻还要大,例如像 SoC、DDR 等场景,在它们的背面都是密密麻麻的电容。
在原理图中,电容的位号通常使用 C 开头。
贴片电容
使用 PCB 贴片元件之后,最常用的电容封装了,没有极性区分,不过一般容量不会太大,价格便宜,在 PCB 上用量应该是最多的一种。
钽电容
体积小,容量一般比贴片电容大一些,有正负极区分,接反了可能会爆,价格相比贴片电容要贵很多,一般在电源模块中用得比较多。
铝电解电容
体积大,容量更大,价格便宜,插件和贴片的封装都有,另外铝电解电容会有老化的问题,时间长了会容量下降。
固态电容
体积跟铝电解电容差不多,容量也类似,性能参数相比铝电解电容更好,并且不存在铝电解电容的老化问题,现在很多主板好不好就会宣传用了多少固态电容。
当然固态电容价格要比一般铝电解电容要高上很多了,如果不是极致需求的场合,还是就用一般的铝电解电容吧 。
固态电容的优点可以参考这篇文章: https://www.szlcsc.com/info/13572.html 。
当然并不是只有上面三种,还有更多其他类型的电容,但是目前我在做电子 DIY 的时候,还没有使用过,也并不了解,这里就不过多介绍了。
贴片电容
贴片电容的封装跟电阻一样,一般就是 0805、0603 等,贴片电容的容量大小、耐压值都会影响封装大小,一般越大的容量、越高的耐压值,会要更大的封装。
铝电解电容和固态电容
这类电容一般外形都是圆柱体,因此封装一般使用 *直径高度* 的方式表示,例如 6.3mm7mm 就表示这个电容的直径为 6.3mm,高度为 7mm。跟贴片电容一样,这个体积也是跟电容的容量和耐压值相关的。
钽电容
钽电容一般封装会用 A、B、C、D、E、P 这种字母表示,例如 B 型就是 3528,尺寸为 3.5mm*2.8mm。
更多钽电容封装信息可以参考这个文章: http://www.yznfc.com/tdrzs/1.html 。
容量
电容的容量一般都需要根据它所使用的场景去选择,并且一般对应场景会有对应的容量选择,例如以下几种常见的:
一般电路上使用的芯片,它提供的数据手册都会有相关的电容容量参考建议,直接按手册来就行。
更多电容去耦、滤波相关知识可以参考这篇文章: https://www.cnblogs.com/deliweier-wangshuping/p/16127284.html 。
耐压值
电容不像电阻,它是有耐压值的,如果超过它的额定电压,可能就会“点亮”一颗电容 。一般来说,使用是使用 USB 供电的电路,最高电压就 5V,一般也不用太注意这个,大部分贴片电容的耐压值都会在 5V 之上的,低一点的常见也是 6.3V。
但是对于一些有高电压的电路来说,就特别需要注意电容的耐压值了,比如 USB PD 充电电源模块,输入和输出最高可能都会到 20V,这个时候就需要选择耐压值高一点的电容了,一般可以按实际电压的 1.5~2 倍来选择,低一点问题也不是特别大,之前在做 SW3536 快充模块时,输出 20V 的电容就选择了 25V 耐压,使用下来问题也不大。
ESR、ESL
电容还有两个参数,就是 ESR 和 ESL,分别是等效串联电阻(ESR)和等效串联电感(ESL),其中 ESR 会影响在使用过程中电容本身的发热情况,ESL 会影响使用过程中信号的稳定性,通常这两个值越低越好。
另外这两个值也会影响到实际滤波时的效果,这就涉及到一些模电的知识,还没有深入去学习过,只能说目前没有特别关注这两个参数的情况下,也没有太大问题 。
更多 ESR、ESL 知识可以参考这篇文章: https://www.yuden.co.jp/cs/product/support/faq/q007.html 。
我不是太懂电感的作用,它主要用在电源相关的电路中,例如升降压模块。
在原理图中,电感的位号通常使用 L 开头。
贴片电感
体积比较小的电感,一般比较少用,额定电流一般比较小。
工字电感/磁胶电感
价格一般比较便宜,各种规格额定电流的都有,应该算是非屏蔽类型或半屏蔽类型的电感。
一体成型电感
一般比较体积大,可以有比较大的额定电流,全屏蔽封装,通常在主板或显卡的供电部分可以看到,作为一个外行人,觉得这种类型的电感看着比较专业。
磁环电感
一般就是直接一个磁芯再加上绕制的线圈,体积巨大,不过好像额定电流会比较大,发热也比较小。
小型贴片电感也跟贴片电阻一样,有 0805、0806 等尺寸的封装。
像工字电感、磁胶电感、一体成型电感,通过会直接使用公制单位来表示尺寸,例如 0420 表示长和宽是 4mm 4mm,高度是 2mm 的电感,对于更大一些的电感,例如像 22uH 7A 的一体成型电感,在立创商城的封装选择中,会直接显示为 SMD, 13.6mm 12.8mm。
对于磁环电感来说,就是看一下两个引脚的间距,来确定是否符合 PCB 安装需求了。
电感的几个主要参数就是电感量、DCR、额定电流和饱和电流,在选型的时候可以根据这几个参数来决定,另外封装形式还会影响 PCB 布线时的一些内容,需要额外考虑一下。
电感量
电感的单位一般用 uH 来表示,电路中的电感需要使用多少电感量,一般直接根据芯片的手册来决定,在手册中通常会给出一个电感量的计算公式,根据工作电压、工作电流等参数计算出来需要使用的电感量。
例如像 TP5400 这个锂电池充放电芯片,手册推荐的电感量就是 3.3~22uH,我一般直接配合 10uH 的电感来使用。
直流电阻(DCR)
这个就相当于电感在通过电流时的电阻值,根据已知电流、电阻时的功率计算公式 P = I2 * R 可以发现,如果电感的 DCR 值越高,那么在通过大电流时,发热会更严重,这个在大电流电源模块中需要特别注意。之前在做 SW3536 充电模块时,如果持续 100W 满功率运行,电感的温度也会上升得很快。
额定电流和饱和电流
这个参数在有大电流需求时需要关注,同样以 SW3536 充电模块为例,最高功率 100W 时,电流为 5A,如果所选择电感的额定电流和饱和电流不够高,就会导致电感量下降以及电感本身发热比较严重。
更多电感相关知识可以参考这篇文章: https://www.dianyuan.com/eestar/article-2265.html 。
屏蔽和非屏蔽电感
对于屏蔽和非屏蔽电感,在 PCB DCDC 电路布线时,需要额外考虑一下焊盘中间是否需要禁止铺铜,防止电感对电路中电压产生影响。
更多内容可以参考这篇文章: https://zhuanlan.zhihu.com/p/478688078 。
这篇文章是从一个电子 DIY 爱好者的角度去介绍了电阻、电容、电感三种元件的一些相关知识,大概了解之后,在 EDA 中去绘制原理图和 PCB 布局布线时,也能避免手足无措的情况,可以快速上手。
以及这也是一些入门相关的知识,具体每种元件的特性,还需要在后续的使用中继续深入学习和掌握,才能让整个电路更加稳定。
等到焊接 PCB 所需要的元器件都到手之后,就可以将我们的 PCB 组装起来了。
PS. 我也还是一个初学者,如果文章中有一些错误或不足,还请多多指教。
在采购元器件前,我们可以先在立创 EDA 中将物料清单(俗称 BOM)导出,在立创 EDA 中使用 导出》物料清单(BOM)... 菜单就可以导出 BOM。
物料清单 (BOM),也称为产品结构,是构建、制造或维修产品或服务所需的所有物料的列表。物料清单充当集中式源,包含从原材料阶段制造产品所需的所有信息。
BOM 导出后是一个 Excel 文件,打开后就可以看到它包含了这块 PCB 所需要的全部相关元器件:
如果直接在立创商城购买这些元器件,可以在导出 BOM 对话框中选择 元件下单,这样就会将 BOM 上传到立创商城,并开启 BOM 配单服务,可以自动根据 BOM 表中的内容匹配到合适的元器件,省去了一个一个查找并添加到购物车的过程。
当然立创商城购买元器件的价格并不一定是最优的,淘宝上很多商家也提供配单服务。不过立创商城的东西比较齐全,对于一些低价元器件,还是可以考虑直接在立创商城一站配齐的,对于差价比较大的元器件,我也都是选择在淘宝上购买。
例如这个 USB 电流表项目中,CH32V003F4P6 和 INA219,淘宝上的价格都更有吸引力一点。
另外立创商城的元器件品质相对而言更有保障一点,如果在其他项目中,某些元器件的假货比较多的话,还是建议直接在立创商城购买,毕竟焊接完翻车再返回浪费时间不值得。
在准备将元器件摆放在 PCB 上之前,还需要先将 PCB 刷上锡膏,如果没有钢网,对于这样简单并且元件尺寸不是很小的项目,也可以直接使用针筒锡浆,每个焊盘挤一点。
如果没有下单钢网,有激光雕刻机的话,也可以参考我之前这篇文章:将节省进行到底,使用激光雕刻机和牛皮纸 DIY SMT 钢网,做一个廉价版钢网。
刷完锡膏或者挤完锡浆之后,就可以开始将元器件一个一个摆放上 PCB 了。
顺便提一下,立创 EDA 有一个很方便的工具用来辅助手工焊接 PCB,通过 PCB 编辑器的 工具》焊接辅助工具... 来打开。
在焊接辅助工具中,可以很方便地将元器件和它实际在 PCB 上的位置对应起来,这样即使在焊接一个没有带丝印的 PCB 时,也可以很准确地将元器件摆放在正确的位置。
我在使用过程中有两个习惯来提升摆放元器件效率:
摆放元器件是一个枯燥的过程,不过摆放完成之后,就可以愉快地铁板烧啦,都已经上 PCB 了,还是建议上一个加热台,效率相比使用电铬铁更高,一般购买一个 10x10cm 的加热台就足够使用了,毕竟免费打样也只能 10x10cm 的 PCB 。
因为我一般使用低温锡,因此加热台将温度设置在 180 度就可以了,即能很好的熔化焊锡,也不会因为温度高时间长导致 PCB 或者元器件损坏。
在加热过程中,建议随时观察元器件引脚之间是否有连锡,可以随时使用助焊剂或镊子来调用元器件的位置,或者将连锡划开。
小技巧:USB Type-C 母座焊接的一个小技巧,可以先等 PCB 上的锡膏熔化之后,查看是否存在焊锡过多导致连锡等情况发生,如果有的话,用先镊子处理好,保证每个焊盘之间都是独立的,并且焊锡量都没有太多之后,再将 USB Type-C 母座放上去。
最近再使用电铬铁将 12864 OLED 模块焊接上去,因为这个 USB 电流表比较高的元器件,可以仅靠 2.54mm 排针的塑料座就可以将屏幕和 PCB 隔离开,因此可以直接将屏幕焊接在 PCB 上,使用排母连接反而会使得这个 USB 电流表变得太厚。
另外,这里为了防止屏幕下边掉下去碰到 PCB,也焊接了两个 2.54mm 排针来垫高。
当然一开始为了测试,防止贴片元件焊接有问题,可以用 2.54mm 排母先连接屏幕,测试没问题之后,再将屏幕焊接在 PCB 上。
热腾腾的 PCB 到手,等它凉了之后,就可以测试一下基本的连通性有没有问题了。
因为我们现在还没有编写固件,可以简单测试一下是否存在短路:
基本测试没有问题之后,就可以继续进行后续的开发工作啦。
至此,这款 DIY USB 电流表的硬件部分已经基本完工,只需要注入灵魂“单片机固件”就可以使用了。当然,作为一个完整的 USB 电流表,还需要进行外壳设计和面板设计,来让它看起来更像一个完整的产品。
这个 USB 电流表已经在立创开源平台开源,访问以下地址即可查看相关文件:
https://oshwhub.com/wandaeda/ji-yu-ch32v003-de-usb-dian-liu-biao
如果还没有完成 PCB 设计,可以参考前两篇文章:
PS. 我也还是一个初学者,如果文章中有一些错误或不足,还请多多指教。
得意于 PCB 板厂间的竞争,现在有不少板厂提供了免费打样服务,例如嘉立创、捷配等。有了这些提供免费打样服务的 PCB 板厂,作为电子 DIY 爱好者也可以低成本的拥有一块正经生产出来的 PCB 来完成一些产品了,而不是只能使用万用板和飞线来制作。
我现在用过两家板厂的免费打样服务,分别是嘉立创和捷配,目前两家的规则差不多,都是一个月内有两次免费打样机会。
嘉立创是我用过最多的免费打样服务板厂了,他的免费打样服务范围相当广,FR-4 2、4、6 层板,FPC 柔性电路板,铝基板等都可以进行免费打样,结合立创 EDA,整体下单流程很顺畅。
另外嘉立创 PCB 阻焊油墨除绿色外的颜色也是可以免费使用的,PCB 生产时间相比绿色会多一两天,但是可以拥有红色、蓝色、紫色、黑色 PCB,还是相当值得的。
嘉立创免费打样一般都是给 5 片 PCB。
嘉立创要使用免费打样,需要先在下单后台的优惠券中心领取优惠券,可以在需要打样时再领取,优惠券的有效期是按领取时间来算的,比如在 10 号领取的优惠券,可以在下个月 10 号前使用,一般直接领取 1-4 层喷锡专用券就可以了,如果有 FPC 或者 6 层板需求,需要领取对应类型的优惠券。
捷配在之前也实施过一段时间的免费打样,不过是需要消费后次月才可以获得免费券,然后 2023 年又重新改了规则,可以每月免费领取 2 张免费打样券,现在看规则,也是 2-6 层板都可以免费打样了。
相比嘉立创,捷配可选的板材稍微少一点,另外 2 层板只给 3 片 PCB,可以作为嘉立创的后备方案。
捷配目前也是领取优惠券的方式来实现免费打样,在上面的打样规则说明页面就可以完成领取。捷配的优惠券有效期是领取当月,因此要在月底前用掉。
在将 PCB 设计文件给到板厂进行制造之前,还有一些准备工作需要做,例如在 PCB 设计中使用的工艺是否符合板厂的条件等。
每个板厂的生产工艺都会有一些差别,例如最小钻孔直径、最小线宽线距等,在将 PCB 文件交给板厂免费打样之前,最好先检查一下 PCB 设计中使用的这些工艺是否符合板厂免费打样的要求。这个可以借助于 EDA 的 DRC 功能来实现。
以嘉立创为例,虽然它的工艺说明中,多层板可以最小可以使用 0.15mm 的内径,但是如果需要免费打样,则只能选择 0.3mm 的内径,因此在导出 Gerber 文件之前,需要将过孔改成符合规则的大小。
嘉立创工艺参数: https://www.jlc.com/portal/vtechnology.html
最小过孔/焊盘
单双面板:0.3mm(内径)/0.5mm(外径)
多层板:0.15mm(内径)/0.25mm(外径)
① 外径必须比内径大0.1mm,推荐大0.15mm以上
② 最小孔推荐0.2mm以上
③ 双面板过孔塞孔的,最小孔0.15mm(同多层板)
以下是我使用过程中两家板厂需要注意的点:
可以看到捷配的线宽线隙要求会大一点,如果在做单双面板时,需要额外注意一下 EDA 里面的参数是否设置正确。
为了防止下单时才出现错误,可以在一开始进行 PCB 布线时就在 EDA 软件中设置好对应的规则,这样在布线过程中,EDA 会帮我们规范过孔和布线时的线宽线隙等参数。
例如在立创 EDA 中,就可以在 PCB 设计面板中,通过菜单 设计》设计规则... 来打开设计规则配置面板,然后针对要使用板厂的免费打样规则来定制这里的参数。
线隙规则
过孔规则
DRC 检查结果
例如这里我放置了一个内径为 10mil 的过孔,在进行 DRC 检查时,就会提示有过孔尺寸错误。
在解释中就可以看到对应的说明:
在修正完所有 DRC 错误之后,就可以准备导出 Gerber 给到板厂生产啦。
在完成 PCB 设计的 DRC 之后,就可以导出 Gerber 来给板厂生产了。
Gerber文件格式是印刷电路板(PCB)设计数据传输的实际标准格式,被称为电子制造业的骨干。 所有PCB设计软件都能输出Gerber文件,所有PCB制造软件也都可以处理它们,使PCB专业人员能够安全有效地交换PCB的设计数据。 Gerber文件包含线路层,阻焊层,文字以及钻孔和成型的数据。
在立创 EDA 中,可以通过 导出 菜单完成 Gerber 文件的导出:
这里定义一下输出的 Gerber 文件名,一般直接使用 一键导出 即可,然后点击 导出 Gerber 就可以将 Gerber 保存到本地,后续在嘉立创或捷配下单时就可以上传这个文件了。
当然如果是使用嘉立创免费打样服务的话,可以直接使用这里的 PCB 下单 功能,它会直接将 Gerber 文件上传到嘉立创下单平台,并且可以自动解析 Gerber 文件中的内容,在下单可以自动填写一些字段,例如 PCB 尺寸和层数等。
PS. 嘉立创现在有彩色丝印服务,如果需要的话,一定要在这里勾选 生成彩色丝印制造文件,要不然在嘉立创下单平台没办法选中彩色丝印服务。
这里以嘉立创下单平台为样例说明一下 PCB 下单过程常见参数的用途和如何选择。
基本信息
PCB 工艺
个性化服务
这里的选项,大部分保持默认就可以了,只有几个选项会影响最终效果需要注意一下。
交期和 SMT
这里交期一般都选默认的就可以了,如果是绿色油墨的话,使用嘉立创小助手下单,可以选择 24-48 小时免费加急,网页下单就没有了。
另外 SMT 贴片和开钢网都可以不需要,自己玩 DIY 用 SMT 成本还是有点高,钢网的话可以上淘宝找卖家做,打样尺寸的钢网要便宜很多,或者也可以参考我用激光雕刻机做钢网:将节省进行到底,使用激光雕刻机和牛皮纸 DIY SMT 钢网。
完成下单界面的一堆选项之后,就可以提交订单啦,在板厂审核通过之后,就会开始生产,根据工艺参数不一样,一般坐等 3-5 天就可以收到板厂寄来的 PCB 了。
生产力的发展让电子 DIY 爱好者也能享受科技的进步,虽然还不能和最前沿的 PCB 生产工艺相提并论,但是和以前使用万用板和飞线来说,已经是一个巨大的进步了,这里还是要感谢各家提供了 PCB 免费打样的厂家,让玩家也能享受到高质量的 PCB 生产服务。
这个 USB 电流表已经在立创开源平台开源,访问以下地址即可查看相关文件:
https://oshwhub.com/wandaeda/ji-yu-ch32v003-de-usb-dian-liu-biao
CodeGeeX2 是多语言代码生成模型 CodeGeeX (KDD’23) 的第二代模型。不同于一代 CodeGeeX(完全在国产华为昇腾芯片平台训练) ,CodeGeeX2 是基于 ChatGLM2 架构加入代码预训练实现,得益于 ChatGLM2 的更优性能,CodeGeeX2 在多项指标上取得性能提升(+107% > CodeGeeX;仅60亿参数即超过150亿参数的 StarCoder-15B 近10%)
不过因为手上只有一个笔记本用的 Nvdia 显卡,型号是 3070,并且显存还只有 8G,因此在运行过程中相对更高显存的显卡会碰到一些坑,这里就记录一下整个安装过程、踩的坑和解决方法。
我的笔记本安装了 Windows 10 系统,并且还没有安装 WSL,因此就直接在 Windows 系统中来安装和部署 CodeGeeX2 了。
软件和硬件环境:
并且后续所有模型和测试相关文件,都会放到 E:\AI\CodeGeeX2
目录中。
cd AI\CodeGeeX2
# 创建 VirtualEnv
python -m venv .venv
# 激活 VirtualEnv
.venv\Scripts\activate
# 安装依赖
pip install protobuf cpm_kernels torch>=2.0 gradio mdtex2html sentencepiece accelerate modelscope
这里可以直接使用 modelscope 的镜像,速度会比从 GitHub 克隆要快一些:
# 注意这里需要在 E:\AI\CodeGeeX2 目录中
git clone https://www.modelscope.cn/ZhipuAI/CodeGeeX2-6B.git
本来以为需要使用量化版本 codegeex2-6b-int4,但是后来在使用时,量化版本反而加载会出错,使用原始版本反而没问题。
这个需要重新安装一个特定版本的 transformers
包来解决
pip uninstall transformers
pip install transformers==4.33.2
参考 issue:https://github.com/chatchat-space/Langchain-Chatchat/issues/1835
这是默认使用 pip 安装的 torch 包并没有包含 CUDA 支持,需要根据要安装的操作系统和 CUDA 版本,在 PyTorch 网站获取指定的安装命令来解决。
对于 Windows + Python + CUDA 11.8,可以使用以下命令来安装:
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
通常这个错误发生时,打开任务管理器可以看到显存已经爆了,会直接冲到 8G 然后掉回去。
这个时候需要使用 8bit 量化方式运行模型,安装 accelerate
和 bitsandbytes
这两个包。
pip install accelerate
pip install bitsandbytes
在安装完后还是会提示找不到相关的 dll,需要下载预编译 dll 和修改一下 bitsandbytes
的源代码。
下载 libbitsandbytes_cuda116.dll
在 https://github.com/DeXtmL/bitsandbytes-win-prebuilt 下载预编译的 libbitsandbytes_cuda116.dll,并将它放到以下文件夹中:
.venv\Lib\site-packages\bitsandbytes
在这个目录中已经有其他版本的 so 等文件,注意这个 dll 文件的文件夹和 要修改的源代码并不在同一个目录。
修改 evaluate_cuda_setup
文件路径:.venv\Lib\site-packages\bitsandbytes\cuda_setup\main.py
先找到 return libbitsandbytes_cpu.so
,把这一行注释掉,并替换为以下内容:
if torch.cuda.is_available(): return 'libbitsandbytes_cuda116.dll', None, None, None, None
需要注意 Python 代码的缩进要和上一行对齐。
修改 run_cuda_setup
文件路径:.venv\Lib\site-packages\bitsandbytes\cuda_setup\main.py
这个修改和上面是在同一个文件中。
在文件里搜索 ct.cdll.LoadLibrary(binary_path)
,这个有两处,都将它们替换为以下内容:
self.lib = ct.cdll.LoadLibrary(str(binary_path))
同样需要注意对齐缩进。
参考文章:
测试代码 test.py
from modelscope import AutoTokenizer, AutoModel
tokenizer = AutoTokenizer.from_pretrained("E:\AI\CodeGeeX2\CodeGeeX2-6B", trust_remote_code=True)
model = AutoModel.from_pretrained("E:\AI\CodeGeeX2\CodeGeeX2-6B", trust_remote_code=True).quantize(8).cuda()
model = model.eval()
# remember adding a language tag for better performance
prompt = "# language: Python\n# 用python写一个冒泡排序算法,并用中文逐行注释\n"
inputs = tokenizer.encode(prompt, return_tensors="pt", padding=True, truncation=True).to(model.device)
outputs = model.generate(inputs, max_length=256, top_k=1)
response = tokenizer.decode(outputs[0])
print(response)
运行测试代码
在命令行中通过 python test.py
就可以运行测试代码:
同时可以在任务管理器看到 GPU 显存占用逐渐就几乎到达 100%:
输出结果代码
# language: Python
# 用python写一个冒泡排序算法,并用中文逐行注释
def bubble_sort(alist):
"""
冒泡排序
:param alist: 需要排序的列表
:return: 排序后的列表
"""
for i in range(len(alist) - 1, 0, -1):
for j in range(i):
if alist[j] > alist[j + 1]:
alist[j], alist[j + 1] = alist[j + 1], alist[j]
return alist
if __name__ == "__main__":
print(bubble_sort([5, 2, 4, 6, 1, 3]))
使用测试文件来测试就是会导致每次运行的时候都需要重新加载一次模型,这个过程还是比较费时间的,因此可以通过 FastAPI 来运行一个 API 服务器,这样就可以通过 HTTP 请求的方式来生成代码,避免每次都要重新加载模型文件。
API 服务器测试文件 api_test.py
from fastapi import FastAPI, Request
from modelscope import AutoTokenizer, AutoModel
import uvicorn, json, datetime
import torch
app = FastAPI()
@app.post("/")
async def create_item(request: Request):
global model, tokenizer
json_post_raw = await request.json()
json_post = json.dumps(json_post_raw)
json_post_list = json.loads(json_post)
prompt = json_post_list.get('prompt')
inputs = tokenizer.encode(prompt, return_tensors="pt", padding=True, truncation=True).to(model.device)
outputs = model.generate(inputs, max_length=256, top_k=1)
response = tokenizer.decode(outputs[0])
now = datetime.datetime.now()
time = now.strftime("%Y-%m-%d %H:%M:%S")
answer = {
"response": response,
"status": 200,
"time": time
}
log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr(response) + '"'
print(log)
return answer
if __name__ == '__main__':
tokenizer = AutoTokenizer.from_pretrained("E:\AI\CodeGeeX2\CodeGeeX2-6B", trust_remote_code=True)
model = AutoModel.from_pretrained("E:\AI\CodeGeeX2\CodeGeeX2-6B", trust_remote_code=True).quantize(8).cuda()
model = model.eval()
uvicorn.run(app, host='127.0.0.1', port=7860, workers=1)
运行 API 服务器
在命令行中通过 python api_test.py
来运行 API 服务器,会提示已经 在 http://127.0.0.1:7860
这个地址上运行起来:
通过 API 请求获取结果
这个时候使用像 Reqable 的 API 测试工具,就可以发送一个请求给到服务器,来获取对应的代码生成结果了。
上面这个返回的 API 响应就跟之前使用单次测试生成的结果一样了。
小显存跑大语言模型还是比较多坑的,配置跑模型的 Python 环境也比较复杂,感谢网上诸多已经踩过坑的前辈给出的各种解决方案。
另外使用了 GPU 加速的大语言模型,比单纯用 CPU 跑还是快很多的,这次只是使用 CodeGeeX2 简单测试一下代码生成能力,还没有深入使用,后续再深入使用了有经验之后再分享给大家。
PS. 我也还是一个初学者,如果文章中有一些错误或不足,还请多多指教。
通过立创 EDA 的 设计>更新/转换原理图到PCB 菜单,就可以将原理图中所有元件放置到 PCB 设计页面中,并且已经都将每个元件的网络配置且连接好。
我们首先需要做的就是将元件根据用途大概放置到对应的区域,先来根据目标的形态绘制一个草图。
首先使用放置板框功能,画一个 PCB 的边框,可以根据实际预期 PCB 大小,将板框设置成那个尺寸,例如这里先设置成 45mm*70mm。
这里可以使用立创 EDA 的交叉选择功能,在原理图中选择对应功能区域的元件,然后按 Shift+X,就可以在 PCB 设计页面中选择对应的元件,方便将归属于同一功能的元件都选中,然后放置到目标位置去。
这样就可以大概将整体布局确定下来,后续就可以在这个基础上进行布线了,当然最终效果会比这个紧凑很多,可以在布线过程中不断调整。
在初步确定布局之后,就可以根据每个模块的功能,将它们目标的布局确定下来,例如这里 DC-DC 模块,就可以根据一般 DC-DC 模块布局的需求,先把相关电阻、电容、电感的位置放置完毕,再进行最后的布线。
像 MCU 和 INA219 的去耦电容,在这一步也可以就近放到它们的电源引脚附近。
在经过这一步调整布局后,整体 PCB 的尺寸又可以根据新的元件布局调整一下了,这里就可以调整到 30mm*55mm。
对于 USB 电流表这种低速通信项目,也可以尝试一下自动布线。立创 EDA 自带了一个自动布线功能,通过菜单 布线>自动布线... 就可以打开。
不过立创 EDA 的自动布线功能并不是太实用,大多数时候可能没办法完成需求,之前尝试过几次,只能在网络更简单的情况下可以完成,可以看到在这个项目中,有一些网络它没办法连通,整体布线也是不可用状态。
既然自动布线不可行,就只能手工布线了,整体来说,这个项目的布线不算很复杂,只是两个 USB Type-C 直通那一块比较多需要使用过孔来完成交叉的连接,其他地方都可以直接走通。
PCB 正面
这里为了方便手工焊接,所有元件都放在了 PCB 正面,这样通过加热台可以一次性焊接完成。
因为 PCB 正面已经放满了元件,已经没有空间走 USB 的 VBUS 信号,因此把 VBUS 通过过孔到 PCB 背面走线。
PCB 反面
另外因为这个 USB 电流设计最高支持 USB PD 100W 的检测,在这个时候电流最高会到 5A,为了保障整个 PCB 不会因为高电流出现严重发热的问题,USB VBUS 通过十几个过孔到背面,并且走线加宽到了近 8mm。
同时为了减小采样电阻的发热,采样电阻使用了 10mΩ 的阻值,并且也是通过很多过孔连接到 PCB 背面的走线上。
在完成布局布线之后,就可以通过立创 EDA 的预览功能,看到最终设计完成的 PCB 效果图了,可以分别查看 2D 效果和 3D 效果,2D 效果图就是拿到生产完成 PCB 的样子,3D 效果图则是带了 3D 元件样子。
2D 预览效果图
3D 预览效果图
在完成 PCB 布局布线之后,可以使用立创 EDA 自带的 检查DRC 功能来检查 PCB 的布线是否存在问题。
设计规则检查(Design Rule Check, DRC) 是利用AD软件进行PCB设计时的重要检查工具,系统会根据设计工程师之前设计好的规则设置,对PCB设计的各个方面进行检查校验,比如导线宽度、安全距离、元件间距、过孔类型等这些需要检查的规则,DRC是PCB板设计正确性和完整性的重要保证。
如果检查结果有错误,就可以在 DRC 结果中看到对应的错误分类和错误列表:
如果检查没有错误,就会显示 0,这个时候就可以选择下单生产啦。
当然如果有些时候在设计其他 PCB时,故意留的一些 DRC 错误也可以忽略,直接下单生产。
在完成 PCB 布局布线之后,就可以将 PCB 设计文件导出成 Gerber 交给板厂生产啦,目前提供免费打样的板厂也不少,例如可以直接使用立创 EDA 在嘉立创下单打样。
DIY USB 电流表的 PCB 设计部分就分享到这里啦。
本项目已经在立创开源平台发布,可以直接打开以下地址查看并且复刻。
https://oshwhub.com/wandaeda/ji-yu-ch32v003-de-usb-dian-liu-biao
作为电子 DIY 爱好者,做一个自己的 USB 电流表也是一件顺理成章的事。这里把之前已经开源的一个 USB 电流表的原理图来添加一些详细说明,对于初学者来说可以大概搞明白一个简单设备的原理图该怎么画。
当然我也还是一个初学者,如果文章中有一些错误或不足,还请多多指教。
电压、电流、功率、容量界面
功率历史图表界面
在最开始搞一个入门 DIY 的产品,还是不要搞太复杂,尽量从简单的开始,先确定一下需求范围,降低整体开发难度,一方面减少原理图绘制之类的工作量,另外一方面,也可以增加成功率,防止半路弃坑 。
作为一个 USB 电流表,主要功能就是电流、电压等指标的采集,以及作为现在已经普及度非常高的 USB Type-C 接口和 USB PD 充电都需要支持一下,然后再通过屏幕展示出来采集的数据就可以了。
因此根据需求大概确定以下功能点:
之前做一些 DIY 产品的时候,一直都使用的 ESP32 系列 MCU,但是对于 USB 电流表这样一个简单的产品,并且不准备加上 Wi-Fi 或蓝牙数据传输功能,因此就需要选择另外一款 MCU 产品。
在一个 DIY 群里聊天的时候看到有推荐 WCH 这款 RISC-V 的低功耗 MCU CH32V003,就是它了,尝试一下。
CH32V003 官网:https://www.wch.cn/products/CH32V003.html
CH32V003系列是基于青稞RISC-V2A内核设计的工业级通用微控制器,支持48MHz系统主频,具有宽压、单线调试、低功耗、超小封装等特点。CH32V003系列内置1组DMA控制器、1组10位模数转换ADC、1组运放比较器、多组定时器以及标准通讯接口USART、IIC、SPI等。
CH32V003 主要参数
对于本项目来说,使用 12864 OLED 以及 INA219 需要 I2C 接口,按键需要使用普通 GPIO,UART 用于调试信息输出,SDIO 用于烧录,对比之后发现,TSSOP20 封装的 CH32V003F4P6 更适合,它相比使用 SOP8 封装的 CH32V003J4M6 拥有更多 GPIO,并且 UART 和 SDIO 也没有复用,可以更好地满足本项目的需求。
作为一个 USB 电流表,最重要的当然是电压、电流的检测,这个可以通过运放来完成,也可以直接选用现成的芯片,这里为了简单,直接选用现成的芯片,因为之前用过 TI 的 INA219,就直接选用这款了。
INA219 官网:https://www.ti.com.cn/product/cn/INA219
INA219 是一款具备 I2C 或 SMBUS 兼容接口的分流器和功率监测计。该器件监测分流器电压降和总线电源电压,转换次数和滤波选项可通过编程设定。可编程校准值与内部乘法器相结合,支持直接读取电流值(单位:安培)。通过附加乘法寄存器可计算功率(单位:瓦)。I2C 或 SMBUS 兼容接口 具有 16 个可编程地址。
INA219 的电压最大量程为 26V,在 PD2.0 100W 中,最大 20V 是足够使用的,但是如果碰到支持 PD3.1 140W,使用 28V 供电时,就会超量程了。但是目前看支持 140W 的充电器和设备都比较少,暂时不纠结这个问题。后续可以考虑使用 INA226 来代替,它具备更高的量程。
因为本项目中的 USB 电流表需要支持 USB PD 并且会有最高 100W 的检测需求,在这时 USB 接口中的 VBUS 电压会最高到达 20V,而项目中使用的 CH32V003 和 INA219 并不支持在这样的高电压下工作,因此需要使用一款 DC-DC 芯片来将 VBUS 降压到 3.3V 供 MCU 以及 INA219 使用。
LGS5145:https://item.szlcsc.com/5718438.html
LGS5145 是一种带内部开关的降压 DC/DC 稳压器,具备SKIP 控制模式,将低静态电流与高开关频率相结合,可在广泛的负载电流范围内实现高效率。 SKIP 模式使用短的“突发"周期通过内部功率 MOSFET 切换电感电流,然后是休眠周期,在休眠周期中,电源开关关闭,负载电流由输出电容器提供。在轻负载时,突发周期占总周期时间的一小部分,使平均电源电流最小化,大大提高了轻负载时的效率。
LGS5145 具有 4.5V~55V 的宽输入电压范围,从而最大限度地减少对外部浪涌抑制组件的需求。使其成为宽输入电源范围工业和高电池节数电池组应用的理想选择。LGS5145 具有集成式低阻值 0.6Ω 高侧功率 MOSFET ,可提供至少 0.6A 的输出电流能力,具有出色的负载和线路瞬态响应。
在立创商城搜索了一下之后,选择了这款体积比较小的 DC-DC 电源芯片,使用 SOT-23 封装,并且支持最高 40V 输入电压,可以应对 USB PD 最高 20V 输入电压的降压需求。
作为一款简易 USB 电流表,直接用最常用的 12864 OLED 屏幕就足够用了,另外为了降低制作难度,这里直接用了现成的 OLED 屏幕模块,省去焊接屏幕以及它的一堆外围元件。
同时为了开发简单,复用开源项目中的 I2C 通信代码,这里也选用了四针 I2C 接口的 12864 OLED 屏幕模块。
最终我们选定的元件如下:
为了保持电流表体积小巧,因此没有添加 USB Type-A 接口,输入输出均使用了 USB Type-C 接口。
并且因为需要支持 USB PD 供电,用电设备和充电器之前需要使用 CC1 或 CC2 配置线进行协商,因此 USB Type-C 母座均使用了使用了 16P 的版本。
两个母座的 VBUS 网络,一个使用的 VBUS,另外一个使用的是 VBUS_OUT,是因为这两个母座中间需要连接一个采样电阻,因此需要使用不一样的网络名称。
为了让用电设备和充电器之间可以正常进行 USB PD 协议协商,因此需要将输入输出的 CC1、CC2 引脚直接连通。
USB Type-C 的其它引脚在 PD 协议中并无实际使用场景,不过其他协议例如 QC 或 APPLE 2.4A 还是会用到 D+、D- 等引脚,因此为了保证兼容性,也将其他引脚都直接连接。
这样使用有两点需要注意:
又因为两边的 USB Type-C 接头是直通的,因此其实不存在哪头用于输入哪头用于输出的情况,随便哪一边接充电器侧都可以。
原理图直接根据 LGS5145 数据手册绘制,一般来说大部分芯片都会提供典型应用电路,按照数据手册中的说明来绘制原理图通常没有什么大问题。
图中 R5、R6、R7 为分压反馈电阻,从数据手册中 设定输出电压 一节可以看到分压电阻计算公式:
根据公式可以算出实际输出电压为 Vout = 0.812 * (40K / 10K) = 3.428V,高出一点点,在 MCU 和 INA219 的输入电压允许范围,问题也不大。选用这些阻值主要是因为手上有 10K 以及 20K,不想再买额外的电阻了,如果没有复用需求的话,可以直接按数据手册建议的购买电阻。
C6 为前馈补偿电容,通常是为了增加 DC-DC 输出电流变化时的响应速度,可以不加。
整个 DC-DC 最终输出网络为 V3.3。
另外,为了指示 DC-DC 是否正常工作,在 DC-DC 这部分也添加了一个 LED 指示电源工作状态,并使用 10K 的限流电阻。
CH32V003 这块,供电 3.3V,加上 100nF 去耦电容,I2C 总线加了 10K 上拉电阻。
网络用途和说明如下:
INA219 也不需要太多外围元件,只需要给供电添加一个去耦电容,并将 VIN+ 和 VIN- 连接到采样电阻两端即可。
A0 和 A1 用于决定 MCU 和 INA219 通信时使用的地址,这里都将它们接地,最终 INA219 将使用 0x40 作为 I2C 通信时的地址。
R2 为采样电阻,INA219 就是通过采集采样电阻两端电阻的差并结合欧姆定律来计算出实际通过电路中的电流。
另外这个 USB 电流表项目,为了能测量比较高的电压,并且避免较大的发热,这里使用 10mR 的采样电阻,这样即使在 100W 20V 5A 时,功耗也只有 0.25W,实测 100W 长时间运行也不发烫。
SDA 和 SCL 连接到网络 I2C_SDA 和 I2C_SCL,用于 MCU 和 INA219 通信。
这个 USB 电流表使用的 0.96 寸 12864 OLED 屏幕作为显示设备,为了制作方便直接用的成品模块,这里只需要放一个 4 针 2.54mm 排母就可以了,为了定位屏幕的位置,额外放了一个 12864 屏幕模块的符号,方便在 PCB 设计的时候确定排母位置。
这里只需要根据屏幕模块引脚顺序,确定到排母的网络符号就可以了。
另外还有两个按键,用于操作 USB 电流表的切换页面以及数据清零,这里采用低电平触发的方式,因此每个按键都使用了 10K 上拉电阻连接到 3.3V,然后按键的另一对引脚连接到 GND。
这里的 UART 接口用来调试使用,方便在编写代码时直接使用日志来输出当前变量值,这里只保留了 TXD、RXD、GND,没有放置 V3.3,因为 USB 电流表在使用时一般肯定会有外部供电。
下载接口使用了 CH32V003 定义的 SWDIO 和 NRST,使用 WCH Link-E 编程器即可对 CH32V003 进行刷写程序,和 UART 接口一样,如果已经连接了外部供电,在连接编程器的时候也可以只连接 GND 和 SWDIO。
至此我们已经完成了这个 USB 电流表项目的所有原理图绘制,在立创 EDA 中使用 设计>更新/转换原理图到PCB 菜单就可以将原理图更新到 PCB 编辑器中,可以开始布线啦。
本项目已经在立创开源平台发布,可以直接打开以下地址查看并且复刻。
https://oshwhub.com/wandaeda/ji-yu-ch32v003-de-usb-dian-liu-biao
]]>自从有了嘉立创 PCB 免费打样之后,我玩电子 DIY 基本上都是直接上 PCB 而不是洞洞板 + 模块了。在打样完 PCB 之后,一般都是选择手工焊接元件,以前都是直接使用针筒式锡膏点锡的方式来进行上锡,然后再用电铬铁或者加热台完成手工焊接操作。
但是在面临越来越复杂的 PCB,并且使用了 0603 甚至 0402 封装的元件之后,针筒式锡膏就很难控制挤出量了,并且一块板子几百个焊盘需要点锡的话,工作量实在太大了。
这个时候就可以按照 SMT 标准流程,使用钢网刷锡膏的方式来给焊盘上锡了。最开始也是使用了嘉立创的钢网服务来配备钢网,但是他们的费用还是比较高的,不管板子大小,一个钢网就需要 50 元,打样都已经白嫖的,再花 50 元似乎不太值。
后来再在淘宝上找到了一些钢网制作店铺,可以针对打样的 PCB 大小制作钢网,价格就便宜不少,加上运费在 15 元左右,这个价格也还算实惠了。
不过在 B 站看到一些视频使用 3D 打印机制作钢网的视频之后,启发了我,想到闲置的那台激光雕刻机,似乎也可以用激光雕刻机来完成钢网的制作。
最终在尝试几次之后,选择了 90 克覆膜牛皮纸来作为制作钢网的材料,毕竟一般激光雕刻机的功率并不够用来雕刻钢片。
对于使用 X、Y 轴移动方式来雕刻的激光雕刻机,它的固件也是直接使用的 Gcode 进行激光雕刻操作,因此我们首先需要准备激光雕刻用的 Gcode 文件。
立创 EDA 专业版中提供了将 PCB 焊盘导出为 DXF 文件的操作,这刚好是 LaserWeb 支持的文件格式,我们首先将 PCB 焊盘导出为 DXF 文件。
直接在立创 EDA 专业版的导出菜单中,找到 DXF...:
在导出界面中,导出层选择对应需要导出焊盘的层,例如这里使用了 Miyoo PCB 作为示例,它主要的元件在底层,这里就在导出层选择了底层。
然后在导出对象中选择底层焊盘和多层焊盘,有些带引脚的贴片元件需要使用多层焊盘,例如 USB Type-C 母座的四个脚需要用这个多层焊盘导出。
这里可以新建一个配置将这些选项保存下来,这样下次再导出的时候可以直接选择对应的预设了。
选择完成后,点 导出DXF 就可以获取对应底层焊盘的 DXF 文件了。
LaserWeb 是一个支持从 DXF/SVG/BITMAP/JPG/PNG 等文件格式来生成用于激光雕刻或 CNC Gcode 文件的软件。
- generating GCODE from DXF/SVG/BITMAP/JPG/PNG files for Lasers and CNC Mills (= CAM Operations)
- controlling a connected CNC / Laser machine (running one of the supported firmwares)
对比过其他的激光雕刻生成软件,LaserWeb 支持的文件格式多,使用比较简单易懂,并且还是跨平台的,对于 macOS 用户相当友好。
配置 LaserWeb 参数
这里使用 LaserWeb 生成 Gcode 的步骤如下:
配置 PCB 位置
默认情况下,预览视图中的位置是根据 EDA 编辑器 PCB 的位置是一致的,同样根据 PCB 原点位置来摆放焊盘位置,如果 PCB 编辑器中原点位置跟 PCB 实际位置不一致的话,这里预览视图中焊盘位置也是离原点位置比较远的。
为了便于上激光雕刻机时确定摆放牛皮纸的位置,建议把原点修改为 PCB 焊盘范围的左上角,这样在摆放牛皮纸时,只需要确定左上角就可以了。
在浮动工具栏中,将 Min 的位置修改为 X 是 0,Y 为负的 PCB 高度左右就可以,这里改成 -50。
特别注意:底层的焊盘的方向在导出时,是从顶面看过去的方向,而不是实际刷锡膏时的方向,因此在生成 Gcode 时,需要在 LaserWeb 中将焊盘水平镜像一下。
生成 Gcode 并保存
最后点击侧边工具栏中的 Generate 按钮就可以生成 Gcode 了,预览视图也可以看到激光运行轨迹,点右侧的保存图标就可以将生成的 Gcode 保存为文件,供激光雕刻机使用。
将 Gcode 文件上传到激光雕刻机的控制器上,摆上牛皮纸,就可以开始雕刻了,记得戴上护目镜保护眼睛安全哦~
最后雕刻完的牛皮纸钢网
之前忘记拍照了,拍个干净一点的反面吧。
拿到牛皮纸钢网之后,就可以开始刷锡膏了。
将钢网对准 PCB,拿小铲子刷一遍就可以了。
另外建议锡膏不要回收使用,刷完了剩余的锡膏直接丢了或者放到专用的回收罐子里,要不然会导致原来的锡膏也会干掉,非常不利于后续刷锡膏的效果。
我使用的刮板是以前买覆膜相册时送的这种,用来刮锡膏刚好合适。
整体效果:
整体来说,效果还是符合预期的,0603 和 0402 封装的焊盘基本上不需要特别处理可以直接摆放元件。
USB Type-C 16P 母座效果:
16P 的 USB Type-C 母座锡膏量还是会有点多,在铁板烧的时候,建议先化锡,确定没有连锡后再摆放元件。
0603 封装以及 QFN 效果:
0603 封装元件基本没有大问题,直接摆放元件即可,但是有中间焊盘的 QFN 元件焊锡量肯定多了,会导致 QFN 元件浮起,离 PCB 有一段距离,这个可以在铁板烧的时候,用镊子将 QFN 元件往下压一下,挤出多余的焊锡,然后铁板烧完之后, 再使用电铬铁处理一下。
FPC 0.5mm 连接器效果:
0.5mm 的 FPC 连接器焊锡量也比较多,建议跟 16P USB Type-C 母座一样,先确定没有连锡再放元件。
刷完锡膏就可以把大部分元件摆上去了,又是一个体力活。
摆好元件之后,就可以将 PCB 放上加热台加热了,在加热过程中,需要注意比较小的电阻电容有没有偏移位置,如果在偏移可以使用镊子重新摆正一下。
另外对于 USB Type-C 母座和 FPC 连接器这种有密集引脚的元件,确定焊盘没有连锡之后,就可以放上去了。这个时候可以先把元件放在 PCB 预热一下,防止元件温度太低放上去直接把焊锡固化了。
当然有条件还是直接上钢网吧,使用牛皮纸制作的钢网基本上也是一次性的,放了一段时间之后上面没有擦干净的锡膏会严重影响第二次使用。
其中一些项目不光是固件方面的程序,也包含了对应的硬件设计,可以当作一个电子 DIY 入门的学习项目。
项目地址:https://github.com/agucova/awesome-esp
一个国外爱好者收集的 ESP32/ESP8266 开源项目集合,主要偏完整的固件应用。
这里是一些完整的固件开源项目,通常也会包含一个完整的硬件项目,不管是用来学习硬件开发,还是学习嵌入式软件开发,都是很好的例子。
项目地址:https://github.com/esphome/esphome
算是最流行的开源智能家居固件之一了,通过编写 YAML 配置文件的方式来快速集成各种传感器、开关、屏幕等设备到一个固件中,并且内置了 Home Assistant 等智能家居平台的支持,可以一键添加到这些平台中。
要使用 ESPHome,基于上只需要了解大概的 GPIO 知识,I2C 以及 SPI 总线的概念就可以上手了,传感器或者其他外设的驱动都已经包含在固件中,并且官方文档也包含了详细的配置教程。
之前就使用 ESPHome 快速搭建了两个应用:
超简单 DIY - AirCube 空气检测站
使用 ESPHome + INA219 模块构建一个简易功率计
项目地址:https://github.com/arendst/Tasmota
另外一个支持 ESP32/ESP8266 的智能家居固件,但是配置方式和 ESPHome 不太一样。ESPHome 是基于配置文件去编译每个设备需要的固件,Tasmota 是基于它的 WebUI 去配置所需要使用的外设,相对而言,可能对于不喜欢写配置文件的用户来说,Tasmota 用起来更方便。
项目地址:https://github.com/SmallPond/X-Knob
基于 smartknob 和 X-Track 的一个开源无刷电机旋钮固件,相比原版的自定义绘制界面,X-Knob 使用 LVGL 渲染界面,扩展性和开发的便捷性要好很多,并且作者也搭建了一套 UI 生命周期管理,在页面管理上更加舒适。
项目地址:https://github.com/Aircoookie/WLED
开源的 WS2812B 灯带控制固件,配套有 App 和 Web 控制界面,可以提供各种灯光切换效果,使用流水灯、彩虹灯之类,并且固件还提供了 API 来控制灯带,理论上淘宝上随便买一个滴胶 WS2812B 灯带再加上一个 NodeMCU/ESP8266 开发板,就可以代替 YeeLight 那些卖得巨贵的灯带了。
项目地址:https://github.com/awtrix/AWTRIX2.0-Controller
网红像素钟,包含了各种应用,天气预报、空气质量、时间、日期、各个平台粉丝数等,我复刻了两个版本,一个直接使用淘宝上购买的 32x8 WS2812 像素屏,使用的 5050 封装灯珠,体积比较大,另外一个就是自己画板子做了个小尺寸的,使用 3528 封装的灯珠。
AWTRIX 配套的服务器功能还挺强大的,不光可以安装应用,还支持画图标等,也有 API 来推送通知,这样可以拿 AWTRIX 像素钟当一个通知中心。
这个项目是使用 ESP8266 的,目前已经停止维护了,作者新开了一个坑使用的 ESP32,不过功能和生态并不如旧版强大,主要是可以单机运行,不再需要单独部署一个服务端,但是如果想要扩展更多功能,还是需要例如 Home Assistant 或者 NodeRED 这样的服务端程序。
AWTRIX Light: https://github.com/Blueforcer/awtrix-light
项目地址:https://github.com/ClimbSnail/HoloCubic_AIO
由稚晖君在很早的时候推出的透明小电视,算是一个很不错的桌面小摆件。这个项目是第三方在原版硬件基础之上推出的独立固件,相比原版包含了更多功能,还有上位机程序可以控制小电视。
项目地址:https://github.com/cesanta/mongoose-os
一个面向 IoT 设备使用的固件,集成了很多 IoT 设备常用的功能,例如 OTA 固件更新以及远程管理等,并且内置了很多大平台的 IoT 能力支持,例如 AWS IoT、Google IoT Core、Microsoft Azure。
这个固件的另外一大特色就是,它可以使用 JavaScript 来编写业务代码,对于熟悉 JavaScript 的工程师来说,可以完全不关心固件是如何编译、打包的,只需要专注于业务逻辑的编写。
项目地址:https://github.com/Nihiue/open-ip-kvm
一个开源的 IP-KVM,类似于 Pi-KVM,但是 Pi-KVM 的使用成本太高了,这个开源项目使用了 Arduino Leonardo 开发板模拟 HID 设备,并使用 MS2109 采集卡来采集目标设备的 HDMI 输出画面,最终使用 nodejs + Web 的方式给用户提供操作界面。
整个项目还是比较完整的,相比 Pi-KVM,整体搭建成本可以低一个数量级。
项目地址:https://github.com/bblanchon/ArduinoJson
对于带网络请求的应用来说,JSON 的解析和生成是必不可少的,基本上大多数接口都使用 JSON 来作为 HTTP API 的请求和响应格式。
ArduinoJson 支持静态和动态分配内存,在 ESP32 上,基本上不太用担心内存占用问题,解析速度也还不错,使用静态解析时,需要注意对象是否在引用有效范围内,否则可能会出现数据错乱的情况。
项目地址:https://github.com/nanopb/nanopb
Protobuf 在一些长连接通信的场合也是一种经常使用的通信格式,体积小、解析速度快、向前兼容性好使得它的应用范围相当广泛,在嵌入式应用中,可能有一些场合也需要解析 Protobuf,使用 Nanopb 就可以用于解析这些数据。
项目地址:https://github.com/mr-glt/Arduino-SHA-1-Hash
对比过几个库之后觉得比较好用的 SHA-1 Hash 生成库,通常用于 API 请求生成签名。
项目地址:https://github.com/intrbiz/arduino-crypto
测试过比较好用的 AES 加解密以及 SHA256-HMAC 生成库,在有些需要使用 HMAC 的场合时,就可以使用这个库。
项目地址:https://github.com/janLo/EspArduinoExceptionDecoder
对于 ESP32 应用,在出现 crash 的时候,通常只会给一个包含了各种代码地址的 coredump,这个时候就可以使用这个工具,结合本地编译的固件映像,将那一堆十六进制的代码地址转换为实际源代码中的位置,从来更方便地排查异常是怎么发生的。
项目地址:https://github.com/soligen2010/encoder
旋转编码器驱动,支持点击、双击、长按等事件检测,基于计时器,适用性比较好。
项目地址:https://github.com/adafruit/Adafruit_GPS
GPS 协议解析库,支持 NMEA-0183,在 ESP32 上编译比较顺利,其他几个库会有这样那样的问题。
不过需要注意的是,这个库并不支持所有 NMEA 指令,在使用时需要查看实际数据是否符合预期。
项目地址:https://github.com/wollewald/INA219_WE
电流/功率计 INA219 芯片的驱动库,代码比较整洁,并且支持设置采样电阻大小,这样在实际使用过程中,可以通过降低采样精度的方式来增加电流采样范围。
项目地址:https://github.com/S-LABc/MT6701-Arduino-Library
MT6701 磁编码器驱动库,在 smartknob 项目中可以作为 TLV493D 的替代。
项目地址:https://github.com/mathertel/OneButton
支持多种触发方式的按键检测库,以及支持单击、双击、长按等事件的检测。
项目地址:https://github.com/crankyoldgit/IRremoteESP8266
红外遥控协议库,可以用来开发一个万能遥控硬件,支持很多种设备,包含一些国内的家电,例如美的空调,这样可以精确控制空调的温度、风速等选项,而不是只能重放从遥控器获得的红外指令。
项目地址:https://github.com/holgerlembke/ESPxWebFlMgr
可以实现通过网页管理 ESP32/ESP8266 内置 SPIFFS 中文件的库,可以实现下载、删除、重命名等操作,并且可以显示 SPIFFS 中可用空间。
加上这个库就可以实现最简单的文件管理功能了,比如在 SPI Flash 中记录的数据,可以通过这个方式来同步到电脑上。
项目地址:https://github.com/khoih-prog/ESPAsync_WiFiManager
最常用的通过 Web 配置 ESP32 Wi-Fi 连接的库,在没有连接上 Wi-Fi 时,启动一个 Hotspot,用户连接上之后可以设置需要连接的 Wi-Fi 接入点名称、密码等,集成了已知 SSID 扫描等能力。
不过这个库有一个不太好的地方,在默认实现中,即使已经有保存了之前连接过的网络,还是会扫描一次已知网络,并去跟之前连接过的 BSSID 进行匹配,这导致在启动时连接速度不太理想。这个时候可以直接调用 ESP32 官方库的 WiFi.begin 方法来绕开这个过程,实现更快的连接速度。
项目地址:https://github.com/arduino-libraries/NTPClient
对于 ESP32 系列来说,如果不想加一个 RTC 芯片来保存时间,使用 NTP 获取时间是一个不错的选择,这个库就可以用于同步 NTP 时间并且获取当前时间,使用也比较简单。
项目地址:https://github.com/Links2004/arduinoWebSockets
需要连接 WebSocket 服务端时,可以使用这个库,对比了其他几个库,这个算比较好用的。
项目地址:https://github.com/arduino-libraries/ArduinoHttpClient
相对内置的 HTTPClient,这个库可以支持更多方法去发送 HTTP 请求,封装也比较好,并且支持设置 Header、支持 Basic Auth 等。
项目地址:https://github.com/plerup/espsoftwareserial
ESP32 只有 2 个 UART 可用,如果想要连接更多 UART 外设,这个时候可以使用软件模拟的 UART,这个库算是比较常用的了。
项目地址:https://github.com/suculent/esp32-http-update
ESP32 Arduino 内置了 OTA 支持,但是只能使用 HTTPS 地址,不支持 HTTP URL,如果要使用 HTTPS 地址,对于 ESP32 来说,需要配置一堆证书以及网站签名等信息,使用起来比较麻烦,这个库支持直接通过 HTTP URL 更新固件,固件的完整性可以通过其他 HTTPS API 来传递 MD5 等签名来验证。
项目地址:https://github.com/ZinggJM/GxEPD2
SPI 接口电子墨水屏驱动库,支持很多尺寸的 SPI 接口电子墨水屏,使用比较简单。
项目地址:https://github.com/neu-rah/ArduinoMenu
通过配置的方式来生成多级菜单,支持菜单包含设置项,以及支持通过编码器来完成设置,并且可以配置多个输出,在调试的时候也比较方便,比如同时在 0.96 OLED 和 Serial 中输出菜单。
项目地址:https://github.com/Bodmer/TFT_eSPI
TFT LCD 驱动库,支持常见 ST7789V、GC9A01 等主控。
项目地址:https://github.com/lvgl/lvgl
跨平台 GUI 框架,内置了相当多的控件,例如 Tab、输入框、下拉框等,以及包含了软键盘等,并且可以集成多种输入设备,例如鼠标、键盘、编码器等,可以用来实现一个完整的嵌入式设备界面程序。
Arduino 还是一个比较方便的开发框架,配置 ESP32 强大的性能和自带联网的特性,开发一些联网设备应用还是很方便的,希望这些开源项目对大家进入电子 DIY 有所帮助。
]]>相比去年,今年在电子 DIY 上又学习了一些新东西,再来总结一下在 2023 年得到的经验。当然这些都是我作为一个新手村玩家得到的经验,只能说在 DIY 这个领域,可以用来应付一些需求,与实际商业化产品开发过程中需要的经验,还是会有比较大的距离,因此这些经验也仅供大家参考。
经过这一年,看见什么数码产品,都想着自己能不能做一个,找找开源项目,找找对应芯片,然后搞出一个半成品 。
作为一个新手,2023 年整体还是以复刻为主,得益于立创硬件开源平台,总是可以看到各种很有意思的项目,这其中有一些算是玩具,有一些是开发相关的,有一些则是实际生活中会使用到的数码产品。
在复刻项目过程中,现在能更多地去理解原理图,知道每个部分的作用是什么,以及在它的基础上,是否可以做出一些符合自己需求的修改,例如以下这些基础的修改:
在经历过几个开源项目的复刻过程后,会逐渐对硬件项目的构成有一个更清晰的概念,也能对硬件项目中可能包含的功能模块了解更多一点,例如电源模块、充电模块、电机驱动等。
在知道和了解了硬件项目中的这些模块之后,在后续想要做自己的项目时,就可以参考和使用了,这跟在软件项目中使用开源库的原理也差不多。
项目地址:https://github.com/scottbez1/smartknob
关键词:无刷电机,SimpleFOC,PID,ESP32,TMC6300,磁编码器,SK6812
SmartKnob 是一个国外工程师使用无刷电机来模拟各种旋钮手感的带屏旋钮项目,通过 PID 控制电机的位置和旋转力度,就可以模拟像齿轮、段落开关、无级调节等各种效果,可以用在智能家居控制等场景,或者作为电脑的智能副屏使用,可以显示状态以及控制音乐播放等。
现在淘宝上也有一些类似的带屏旋钮,但是应该都是固定类型手感,而不是像这个项目通过 PID 控制无刷电机,可以根据控制场景的不同,去模拟不同的手感。
通过这个项目可以学习到无刷电机的控制 SimpleFOC、磁编码器 TMC6300 等功能模块的使用。
项目地址:https://oshwhub.com/iqirtryi/pkb16x4-atmega32a
关键词:QMK,vial,ATmeta32A,客制化键盘,Planck
复刻这个项目是想学习一下键盘的制作,毕竟客制化键盘这么火,不如从头自己做一把。
通过这个项目可以了解到键盘的扫描矩阵大概是怎么一回事,以及在和 QMK 固件的配置中,去如何将按钮与行线、列线对应起来。
另外这个开源项目使用了 ATmega32A,默认的 bootloader 不支持 USB 烧录,需要先烧录一个增加 USB 支持的 bootloader,这一步相比使用 ESP32 等模块开发就麻烦了一些,当然也可能是因为之前一起在使用 ESP32 系列,配合 CH340 USB2TTL 芯片已经很熟悉了。
在刷入新的 bootloader 之后,ATmega32A 用起来就比较方便了,在 macOS 上也有对应的 App 进行固件烧录,不需要进入 Windows。
当然这个键盘在复刻完之后并没有用起来,键盘还是太难适应了……以后再看看能不能做一把 ErgoDox 看看,试试更符合人体工程学的键盘。
项目地址:https://oshwhub.com/ftwtwzy/snaillpi_copy
关键词:嵌入式 Linux,以太网,USB OTG,V3S,Device Tree,DDR
我是通过这个项目开始接触到 SoC 这一块的内容,之前没想到 20 几块人民币就可以买一个 V3S 这样配备了 1.2GHz CPU、64MB DDR 内存的 SoC,能直接跑 Linux,作为了一个标准的电脑主机来使用。
对比起来,一个 ESP32-S3 N16R8 模块也要 20 几块,只有双核 240MHz 以及 512KB SRAM 和 8M PSRAM,虽然 ESP32-S3 集成了 Wi-Fi 以及蓝牙功能,但是 V3S 能跑 Linux 还是有很大吸引力的。
通过这个项目,可以了解到 Linux 嵌入式开发,包括 Deivce Tree 配置、u-boot、rootfs 等,也可以大概了解常用外设如何在 Linux 中驱动起来,例如 SPI 屏幕、I2C 设备、UART 通信等。
在掌握了 Linux 嵌入式开发之后,可以玩的东西就很多了,现在有很多价格便宜性能强大的 ARM 类 SoC,也有 RISC-V 类 SoC,基本上都拥有 1GHz 以上 CPU 以及 64MB 以上 DDR 内存,再贵一点,就可以上到多核以及 512MB 内存的 SoC 了,这类 SoC 已经可以跑 Linux 桌面或者 Android 系统了,例如这个 基于全志 A133 的一款平板 项目,就可以开发出自己的平台。
原作视频:https://www.bilibili.com/video/BV1PE411p7F8/
开源项目地址:https://oshwhub.com/xyzDIY/tpa6120-zhuo-mian-er-fang
关键词:模拟电路,运算放大器,TPA6120,NJM4580
这个项目算是模拟电路的项目了,对这块内容并不熟悉,以前的模拟电路也没有学好,到现在也没有掌握运放的使用,复刻这个项目主要就是体验一下,使用电脑直接推耳机,跟使用耳放推会有什么不同。
然而实际听下来并不能听出区别……木耳实锤了。
项目地址:https://oshwhub.com/wqlll/sw3538
关键词:快充,USB Power Delivery 协议,USB Type-C,智融,DC-DC Buck,SW3538,SW3536
现在使用 USB Type-C PD 充电的设备越来越多,之前看到过另外一个项目 大功率微型桌面充电坞,本来想复刻一个,但是它设计得有点复杂,理解起来比较困难,在后来看到这个 140W 的单芯片充电模块的时候,就决定复刻一个来学习一下 PD 快充模块的开发。
SW3538 是智融出品的一个支持多种快充芯片的充电管理芯片,支持 PD、QC、VOOC 等公开或私有快充协议,这个本身只支持降压,也就是输入电压需要高于输出电压,例如如果想要支持 PD 20V5A 充电,输入电压就需要大于 20V。
其实 SW3538 芯片本身跟常用的 DC-DC Buck 电路区别不是很大,它更多是支持通过 CC1、CC2 数据线来与充电设备通信,从而自动的调整充电电压、电流,理论上如果通过单片机实现 PD 协议的处理,也可以自己实现一个 PD 充电器,但是在有专用芯片的情况下,也没有必要这么做了。
在复刻完单个快充模块之后,直接将几个模块拼起来,搞了个桌面充电站,1x140W + 3x65W,配上一个大功率开关电源,就可以满足常见充电需求了。
不过复刻的快充模块最后还是碰到点问题,在持续满功率运行的时候,电感和 MOS 管都发热厉害,查了半天也没弄明白什么原因,可能是 MOS 管 Gate 信号存在振铃导致的,但是并不能确认,后来复刻 SW3526 这款内置了 MOS 管的快充芯片时,也存在同样发热大的问题,终究还是没有太能深入理解到模拟电路的原理。
项目地址:https://oshwhub.com/xyzdiy/nvme-type-c-ying-pan-he
关键词:ASM2362,NVME,PCI-E,高速电路,USB Type-C MUX,USB 3.0
之前买了个零刻 SER 7 小主机,另外买了块 2T NVME 装上了,自带的 NVME 就闲置下来,刚好在立创开源平台看过几个 NVME 硬盘盒项目,最后找了个基于 ASM2362 支持 USB 3.1 Gen 2 10Gbps 的方案,整体 PCB 体积相比另外基于 JMS583 以及 RTL9210 的更小,更符合匹配商业化产品的想象,配合这个 PCB 再 3D 打印一个盒子直接当成品用也不是不行。
选择这个项目也为后来调试埋了一些坑,这个项目更多采用了 USON、DFN、QFN 类型封装的芯片,这导致在焊接的时候出现了较多返工,中间碰到 SSD 主供电 3.3V 一直没有出来,排查半天以为芯片损坏,直接从主控供电飞了根线来测试,最后发现还是焊接问题。
回头再看这个项目,其实没有特别难的地方,主控芯片几乎包办了所有功能,USB Type-C 的 MUX 也由 ASM2362 完成了,不需要额外的 MUX 芯片,例如 VL160。仅有的几个外部模块就是供电以及 SPI FLASH 了,供电其实可以根据元件库存替换为 EA3036 或者其他类似单路供电 DC-DC 芯片,但是不想花更多时间就没有做更多修改,直接使用原版工程打样了。USB 应用中,类似芯片的功能都相当强大,差不多都是 All in 1,因此整体电路不会特别复杂,复刻起来还是比较简单的。
总的来说,还是需要多练习一下 QFN 类芯片的焊接技术,之前也出现过好几次焊接不良导致的问题排查。
最终使用英睿达 P3 Plus 测试,读写也基本符合预期吧。
项目地址:https://oshwhub.com/gloomyghost/yuzukih616
关键词:全志,H616,DDR,eMMC,AXP313,高速电路,BGA 封装
前面所有项目中,只有 ASM2362 硬盘盒算是涉及到高速线路,其他几个都没有比较高速线路布线的需求,因此为了让 2023 能感觉到 DIY 水平的提升,在末尾的时候选择了挑战一下这块 6 层板全志 H616 开发板。
这块块的难点在于,作者使用了大量 0402 的元件,以及包含了好几个 BGA 封装的芯片,这在手工焊接的时候就会有一定的挑战。不过经过一年的练习,现在对于 0402 封装的阻容,已经可以比较轻松应对了,反而是从来没有碰过的 BGA 封装翻车了。
一开始拿加热台 + 热风枪焊接内存,加热了大概 90 秒,芯片本身已经固定住了取不下来,上电也没有短路大电流,觉得没啥问题了,就把 H616 也一起焊接了上去。上电之后,发现晶振不起振,这下懵了,查都没法查……
没办法就尝试把内存取下来看看有没有什么问题,也是拆了半天,拆下来之后发现,PCB 焊盘掉了两个点 ,这还没出师就要学习针线活了。然后内存颗粒上的锡球也需要重植,上某宝买了钢网之后拿低温焊锡值了个球重新上热风枪,这回简单多了,感受到了推动芯片再复位的过程。
然而这事还没有结束,在经历了主控找不到 PMIC、给 AXP313 加焊、又给主控加焊、启动 HDMI 还是无信号后再检查发现,H616 的串口输出了内存无法初始化的错误,于是无法判断是 H616 同样由于出厂高温锡球没有熔化导致焊接问题,还是内存颗粒焊盘掉点导致通信问题,只能先放一边了。
这个项目算是 2023 年复刻唯一失败的了,等有空了再去买一套 H616 + AXP313 重新尝试一下 。
在能完成这个项目之后,应该会在新一年继续尝试一些使用 BGA 封装芯片的项目,也去了解一下诸如 eMMC、DDR 这样元件的布线。
当然,复刻并不是单纯为了复刻,复刻一个开源项目是为了去熟悉这个项目中所用到的模块、芯片、线路,以及借助于这些项目的实际应用,来了解在电子 DIY 中可以用到的内容,毕竟不是在学校里学习,正向慢慢从基础打起,而是反向推演,以实际项目来了解在电子 DIY 这个领域中,可以掌握哪些内容,需要了解哪些知识。
除了复刻立创开源平台的项目,在 2023 年也从头设计开发了一些自己用的东西,总是复制粘贴也不能检验学到的知识是否已经实际掌握并运用自如了,所以还是需要从功能设计、元件选型、设计原理图、PCB 布线完整地走一遍,来将复刻开源项目中学到的经验巩固下来。
作为一个新手玩家,从头设计也只能从简单的开始,都是一些功能比较简单的产品,希望明年能做一些更复杂的东西。
项目地址:https://oshwhub.com/wandaeda/dan-pian-ji-esp32-s3-kai-fa-ban
关键词:ESP32-S3,开发板,扩展板,TFT LCD,多功能按键,I2C,SPI,LVGL
作为乐鑫 ESP32-S3 的重度用户,之前一直用淘宝上买的开发板,但是这些购买的成品在使用时总有这样那样的不便,因此作为刚开始准备从头画原理图的新手,准备第一个自主设计项目就拿这个练手了。刚好嘉立创还在搞开发板训练营活动,能白嫖打样 + 元件,妥妥地免费学习了。
作为第一个练手的板子,方便手工焊接,阻容都选择了 0805 封装,除了自动下载的三极管,为了节省整个空间,用了一个 SOT-363 封装的元件,直接集成了 2 个 NPN 和电阻,在极限的面积下能保障了还有 ESP32-S3 的自动下载功能。
因为 ESP32-S3 支持 USB Host & Device,因此双 USB 接口也是必需的了,这样可以在测试 USB Host & Device 功能时,可以同时通过串口进行调试。
通过这个项目可以大概了解到 LDO 的使用,CH340C USB 转串口芯片的使用,总体外围元件相当少,虽然面积比较小,2 层板布线也不是很宽裕,但是总体来说,也还算是一个比较简单的板子。
项目地址:https://oshwhub.com/wandaeda/sl2-1a-usb-hub
关键词:USB 2.0,USB 集线器,高速电路,USB Hub
USB 作为最常用的接口,并且平时经常连接 MCU 这类低速设备,电脑上的 USB 2.0 接口不太够用了,这不得安排上来练习一下制作一个。在立创开源平台对比了好多 USB 2.0 Hub 的芯片,最后选了 SL2.1A 这个芯片,支持 USB 2.0 一分四。
SL2.1A 的使用相当简单,外围电路几乎只需要滤波电容,内部集成了晶振,但是第一次练习,还是尝试使用了一个外置 12MHz 晶振。另外为了使用现有线材来连接 USB Hub,这个 USB Hub 的输入接口选择了 USB Type-C。另外 USB 2.0 标准下每个接口电流供应能力限制为 500mA,因此也额外添加了一个 2A 的保险丝来保障主机接口的安全。
在焊接这个 USB Hub 的时候还踩了一个坑,本想每个口输出接口加上一个电容来给连接设备稳定供电,堆料上了 1000uF 的电容,没想到一接上主机直接提示功率过大了,查了资料才发现这些电容并联之后,在接上电脑的瞬间充电电流会特别大,因此后来都把这个输出稳压电容替换成了 100uF。
最后成品测试了一下,差不多可以跑满 USB 2.0 的带宽,说明阻抗控制、差分对布线啥的应该没问题,基本上可以算是掌握了 USB 2.0 这个速度级别的产品开发能力。
USB 2.0 Hub 也还有不少其他选择,如果不要求更多功能例如 LED 灯什么的,基本上外围电路都很简单,例如 FE2.1、CH334 等,最终选择哪个可以根据实际要几个输出口、PCB 面积等来考虑。
项目地址:https://oshwhub.com/wandaeda/tp5400-li-dian-chi-chong-fang-yi-ti-dai-di-ya-bao-hu-dian-yuan-mo-kuai
关键词:电源管理,电池管理,锂电池充放电,DC-DC
现在锂电池已经是数码产品中不可或缺的部分,如果一个产品以可移动使用的场景去开发,那必然要面临锂电池充电管理的问题。在立创开源平台,常用的充电方案都是使用的 TP4056,但是这个芯片只有充电管理。
在 2022 年复刻其他项目时,已经使用过 TOPPOWER 还有另外一款芯片 TP5400,同时支持单节锂电池充电管理以及 5V 升压支持,在不了解单片机供电特性以及某些元件可能需要 5V 供电的情况下,能带有升压到 5V 从而实现与 USB 供电条件一致可以更能保障最终运行效果。
一开始这个充放电电路只是在另外一个产品中使用,但是在做了 AirCube 之后,也想给这个产品增加移动使用支持。但是因为 AirCube 是一个基于各种功能模块开发的产品,并不是一个全部贴片的 PCB,这就需要一个独立的充放电管理模块来完成锂电池的充电和升压,并且同时支持通过一个 USB 接口同时支持 USB 供电和充电。在淘宝上搜索了一遍之后没有找到特别合适的模块,因此就想到之前用过的 TP5400,并且自己来制作一个小电源模块。
这个基于 TP5400 的电源模块没有特别的地方,基本上是按照官方数据手册的典型应用画的,为了方便手焊也基本上都使用的 0805 封装的元件。
不过这个模块有个特殊的地方,是为了防止锂电池过放增加了一个低电压放电截止电路。至于为什么要加这个电路,是因为 TP5400 典型应用中,在电池电压低于 3V 时,TP5400 的确会保护锂电池然后停止升压,但是锂电池本身还是会通过二极管直接连接到用电端,如果用电端有例如 LED 这样对电压并不敏感的设备,会持续放电,从而导致锂电池过放。
我目前也没有搞清楚为什么锂电池保护板没有起应有的作用,但是为了防止这个情况的发生,就增加了一个电压过低断电的电路,主要借助于 PMOS 打开需要有一定的压差来实现,在 TP5400 不升压时,TP5400 5V 没有输出,电池电压经过分压电路后,PMOS Gate 电压与 Source 电压压差小于 Vgsth,PMOS 关闭,这样后端电路就不会消耗任何电流了。
目前这个模块已经用在了其他的项目中,可以省去不少时间,也算是实现了第一个复用的模块。
项目地址:https://oshwhub.com/wandaeda/ji-yu-ch32v003-de-usb-dian-liu-biao
关键词:INA219,CH32V003,RISC-V,采样电阻,OLED,DC-DC,USB Power Delivery
做这个项目的起因是因为在电子 DIY 爱好者群里看到有人发了 WCH 一个特别便宜的 MCU CH32V003,只要 7 毛钱一颗,16K Flash + 2K RAM,并且有国外爱好者做了一个开源 CH32V003 GameConsole。平时做小东西都是用的 ESP32,但是 ESP32 相对而言体积大、功耗高,而且在有些场景也不是一定需要 Wi-Fi、蓝牙等功能,只是需要一个单片机来完成基本功能,因此就拿 USB 电流表这个已经有一大堆实现的产品来学习一下 CH32V003 的开发。
做一个 USB 电流表,需要的功能也没有特别多,OLED 屏幕驱动、按键检测、I2C 通信,基本上 GameConsole 项目里面都有了,可以直接拿来用,电压电流检测可以使用 INA219,最大支持 26V 电压输入和 3.2A 电流,通过修改采样电阻大小,还可以支持更大电流,对于 USB Type-C PD 充电来说,不考虑 PD 3.1 28V 的情况下,INA219 已经足够使用了,如果想支持更高电压,也可以将 INA219 替换为 INA226。
不同于一般使用 USB 供电的产品,这个 USB 电流表需要支持 USB PD 协议供电,因此有两个问题需要处理:
因为 USB PD 充电在没有协商完成时,是不会供电的,因此这个电流表需要有后端用电设备才能启动,如果想要在没有后端用电设备的情况下也能启动,就需要实现 USB PD 诱骗了,这个比较复杂就不在这个简单的项目里去处理了。
另外后来发现还是有耐高压的 LDO 可以选择,例如 HT7533 这个型号,可以耐压 30V,而 CH32V003 + OLED 屏幕 + INA219 总共耗电大概在 5mA 左右,使用 LDO 供电完全可以负担并且不会发热太大,后续碰到类似场景就可以替换成 LDO,降低电路复杂度。
解决上面这几个问题之后,就是普通的单片机系统开发了,还有一个需要注意的就是 CH32V003 的内存只有 2KB,相对 ESP32 系列的 512KB,使用起来实在是捉襟见肘。并且 CH32V003 并没有硬件浮点功能,每使用一个浮点相关计算,例如乘法、除法,都会编译相关的软件浮点库进入固件,而这些代码就相当占体积了,会迅速占满 16KB 的 Flash 空间。因此在编写固件的时候,需要尽量避免浮点计算,可以选择将整型扩大 1000 倍当浮点数使用来保留三位小数精度。
CH32V003J4P6 使用下来除了 16KB Flash 和 2KB RAM 比较紧张,其他还是相当舒适的,GPIO 够多,也有硬件 I2C、SPI,功耗也不高,最重要是价格便宜,在每个需要代码逻辑的小节点放一个 MCU 都可以。
项目地址:https://oshwhub.com/wandaeda/pd-power-supply-spoofing-based-on-ch32v003-and-ch224k
关键词:INA219,CH32V003,RISC-V,采样电阻,OLED,LDO,彩色丝印,USB PD 诱骗,CH224K,USB Power Delivery
之前在复刻完 SW3536 快充模块之后, 想要测试一下这个模块的持续输出能力,但是买的电子负载仪并不支持直接进行 PD 协商到 20V 5A 进行测试,这个时候就需要一个 USB PD 诱骗模块了。在淘宝上买了两个模块测试之后发现,这些模块本身能支持功率有限制,测试到 25W 左右就会进入保护状态然后直接重启了。因此就想着,不如自己做一个 USB PD 诱骗器。
搜了一个立创开源平台,发现 WCH 也有一款 USB PD 诱骗芯片 CH224K,使用比较简单,支持 USB PD 固定几档电压的诱骗,可以通过单个 GPIO 连接不同阻值的方式来调节,也可以通过多个 GPIO 组合状态来调节,最终就选择这个芯片来进行 USB PD 诱骗操作了。
在完成 USB Type-C 功率表之后,发现 CH32V003J4P6 的 GPIO 数量足够多,再分出 3 个 GPIO 用来操作 CH224K,也可以继续支持 OLED 屏幕显示以及 INA219 电压电流的采集,而且本身结构差不多,刚好可以节省重新设计 PCB 的时间。
这次为了精简整体电路,就将 DC-DC 降压电路换成了支持高压输入的 LDO,这样在电源输入部分可以更精简。
由于 CH224K 接管了与上游 USB PD 供电端的通信,因此这里的 LDO 就可以在连接到 USB PD 供电端就可以获得电压输入,从而直接对单片机进行供电,在没有连接到下游 USB PD 用电设备时,也可以通过按键来调节输出电压。
为了能测试大功率,PCB 在布线时也加宽了 VBUS 的走线,制作完成后,实测 20V 5A 测试 10 分钟整体 PCB 也只是温热,完全可以胜任长时间的 USB PD 100W 诱骗测试任务。
在这个项目制作完成后和淘宝上的一些产品对比后发现,好像成本上也没有特别大的优势,功能还是人家的更丰富,有空再去研究研究这些产品用的是什么方案。
熟悉了硬件的一些基础知识之后,从头设计一个简单的硬件产品也不是很难,主要是找到适合的芯片,根据芯片的数据手册去画出它的原理图,根据模块之间的通信方式,例如 UART、I2C 或者 SPI 等,将各个芯片模块组合起来就可以了。
对于一般项目来说,掌握几种供电方式、电池管理、主控使用、外设连接之后,基本就可以拼凑出来完整的 PCB 了。
ESP32-S3 扩展板示例工程,Type-C 诱骗器,Type-C 功率计
嵌入式项目不光是硬件,还需要有对应的软件系统开发,2023 年除了继续熟悉使用 Arduino,还尝试了解了一下 FreeRTOS 以及祼机开发和使用寄存器。
在 2022 年开发嵌入式项目时,都是用的 Arudino 框架,直接使用了 arduino-esp32 封装的各种现成库,并且都是直接将业务逻辑写在 setup、loop 函数中,没有多任务处理,没有高级界面绘制,基本还是停留在修修改改开源代码状态。
在 2023 年,逐渐开始了解到 FreeRTOS,也了解到 ESP32 官方框架是基于 FreeRTOS,是可以直接使用 FreeRTOS 相关的方法,也开始尝试去通过 FreeRTOS 实现多任务运行,不再是一个死循环写到黑。
在这过程中主要学习了 WiFiManager 这个库的代码,并且尝试修改了一下来符合自己的需求,网上开源的 WiFiManager 基本上都是阻塞方式执行,在进行配网时,就无法执行自己的代码。在仔细学习了一下这些个 WiFiManager 库的代码之后,使用 FreeRTOS 的 xTaskCreate 来创建异步任务去执行配网任务,并且通过 Lambda 来回调配置进度,同时还可以在 loop 函数中执行自己的界面绘制代码,这样就可以随时展示当前配网进度。
从一个软件工程师的角度来看,这些库的代码质量不算高,主打一个功能实现就好,整体代码结构、封装程序都不算好,修改起来比较费劲,并且多个示例或者不同使用方法都是通过复制代码来实现的,很难看明白逻辑是如何处理的,要将多个例程中的功能合并在一起使用时就需要彻底理解整个库的逻辑。
当然还是要感谢这些开源库的作者,像我这样的新手能快速搭建一个像模像样的产品出来,并且能具备一个产品基础的功能。
在搞完 ESP32-S3 最小开发板之后,刚好通过 SmartKnob 另外一个类似项目接触到 LVGL 这个跨平台的 GUI 开发框架,对于需要有界面的产品来说,这个框架使用起来还是相当方便的,对资源要求不高,并且还有相当多成熟的控件可以使用,如果不喜欢写代码,还有一些可视化编辑器可以使用,例如 NXP 推出的 GUI Guider。
对于一款开发板来说,如果要验证一些功能,光有 MCU 部分也是不够的,还是需要一些常用外设,这样在验证想法的时候,可以直接使用现成的外设而不用再去用面包板或者杜邦线连接各种外设,费心费力不说,还容易出错,万一出错短路就更不好了。因此在做完 ESP32-S3 最小开发板之后,就再根据这个开发板做了对应的扩展板, 包含各种常用外设和总线,例如屏幕、SD/TF 读卡器、多功能按钮、WS2812 LED 等。
通过开发这个扩展板的示例工程,就可以用来熟悉一下 LVGL 开发、屏幕驱动、SD/TF 卡文件存取等常见需求的开发了,这样以后在碰到类似需求时,就可以快速上手,如果产品本身需要的外设和这个扩展板一致,甚至都可以直接复用 PCB 和代码了。
LVGL 整体封装挺完善的,接入各种按键驱动、鼠标驱动也比较方便,但是对于控件还需要具体场景使用过后才能进一步熟悉,当然了解到框架整体思路之后,使用起来就是阅读文档的过程了,并不会太高的门槛。
但是 LVGL 本身还是主要面向过程的,对于各个界面生命周期的管理并不如像 iOS 开发那样简单,也有一些项目,例如 X-Track 码表项目,就封装了一套 MVC 的框架,后续想要更快速的完成一个带屏项目,可能也需要去封装一套更好用的 MVC 框架。
在大多数项目都使用 ESP32-S3 这个系列 MCU 的时候,都不用怎么关心 MCU 资源是否足够,毕竟最低 4M Flash + 512KB SRAM,在单片机这个场景怎么着也是够用的,但是在使用 CH32V003 这种低端 MCU 时,就开始需要仔细掂量各种资源的使用了。
在使用 CH32V003 开发 USB Type-C 电流表时,一开始想使用 Arduino 框架,GitHub 上已经有爱好者针对 CH32V003 封装好了常用的函数和库,例如 GPIO 操作、I2C 总线、UART 操作等,但是等到实际使用时才发现,光启用 GPIO + Serial.print 之后,就已经占了十几 K 的 Flash 空间,再一加 SSD1306 屏幕驱动,Flash 空间直接爆了。
因此这个时候只能考虑使用官方 SDK 进行开发了,刚好开源项目 GameConsole 算是使用了官方 SDK 进行开发的,甚至有一些部分比官方 SDK 还简单,是直接操作寄存器的。USB Type-C 电流表整体外设与 GameConsole 差不多,刚好可以借用它的代码框架。
但是就跟上面复刻项目时介绍的那样,CH32V003 没有硬件浮点支持,因此所有使用了浮点计算的代码都得想办法改成整型计算,并且还需要特别注意,在计算过程中是否会超过 32 位整型有效范围,要不然最后显示出来的结果又是不准确的。
为了调试以及屏幕输出数字,都还不能直接使用系统自带的 printf,要不然一不小心 Flash 空间又超了,因此需要自己封装对应的 printf 来将数字输出到 UART 以及 OLED 屏幕。
另外在实现功率、电压历史记录时,每种数据按一屏统计需要记录 128 个点,一个点使用 2 字节存储,这样一个历史曲线就需要 256 字节,但是 CH32V003 的 SRAM 只有 2KB,因此在开发完其他功能后,剩余 SRAM 已经不多,剩余 SRAM 的空间只够保存一个历史曲线,最终只能选择保留功率曲线。
在开发过程中,通过 PlatformIO 的 Inspect 功能可以快速分析整个项目的 Flash 占用、内存占用,我也是通过这个功能才发现浮点计算需要占用大量 Flash 空间,最终通过删除所有浮点计算代码来节省 Flash 空间。
虽然对于现代 PC 软件项目来说,系统资源不再是考虑的重点,Electron 这类框架大行其道,但是对于嵌入式领域而言,由于成本限制,资源还是相当紧张的,因此在软件开发上所受的限制也相当大。
不过由于半导体工艺的发展,现在很多 MCU 的资源也越来越夸张,像 ESP32-S3 只需要 20 多块钱有 4M Flash 和 512KB RAM,甚至像 V3S 也只要 20 多块钱,有 64MB 内存,可能以后在成本没有特别敏感的场合,嵌入式开发也不用考虑太多资源限制,只有在极致成本考量的情况下,才会去祼机编程。
2023 年,复刻了一些项目,原创了一些项目,虽然并不是什么复杂的项目,还是将其中一些在立创开源平台开源了,希望能对同样是新手村的朋友们有所帮助。
其中 AirCube 算是最敷衍的一样项目了,但是应该算是最实用的项目了,在几个开源项目中被查看的次数最多,在新的一年,也希望能把这个项目再次更新一下,优化一下布线,增加一下 TVOC 检测,以及优化一下外壳,使用一下立创面板定制服务,让它变得更像一个正经的产品。
作为一个没有太多创意的人,还是很喜欢 B 站上各种 DIY UP 主以及立创开源平台上的作者们,这些平台和项目让我有了在软件开发领域中通过 GItHub 学习开发的感觉,可以快速实现自己的想法,从虚拟的软件世界,到真实的硬件世界,从虚拟的二进制字节流,变成看得见摸得着的硬件产品,这种感觉还是很棒的。
在 2023 年的电子 DIY 项目,相比 2022 年最大的区别就是多了很多高速电路相关的内容,从使用低速 UART、I2C 以及 SPI,到使用 USB 2.0、USB 3.0、PCI-E 以及 DDR 这些高速通信总线,也在慢慢接近现代的计算机体系。
在 2022 年时,尝试复刻过一个 MS2130 USB 3.0 视频采集卡以及基于 VL817 的 USB 3.0 Hub,但是总是失败,一直没办法触发 USB 3.0 连接,只能通过 USB 2.0 使用,这导致我一直对 USB 3.0 有一些恐惧,觉得这是一个很大的门槛,在这一年都没有再去接触过相关的内容。
但是 2023 年,逐渐开始了解到高速电路中的等长、等距、阻抗等概念,也逐渐了解了什么是差分布线,看了好多视频,总算知道当初使用 GPS 模块时,GPS 天线布线要求 50 欧姆阻抗匹配是什么意思,也开始慢慢尝试去复刻一些相关的硬件。
大概掌握这些知识之后,就开始尝试复刻 SL2.1 USB 2.0 Hub,制作完成并且测试之后,速度也能跑满 USB 2.0 480Mbps 的最高速率,在这之后,总算觉得应该是入门了,扯下了高速电路的第一层面纱。
在这里不得不提嘉立创的 阻抗计算神器,使用嘉立创的 PCB 打样服务,配合这个阻抗计算神器,就可以在立创 EDA 里使用这些参数去给高速电路布线了,验证下来也基本上没有什么问题。
这也算是一个祛魅的过程,逐渐不会觉得高速电路是一个可望不可及的目标,也更有意愿去尝试一些更有难度的项目了,例如使用了 DDR 的 H616 开发板。
另外也感受了现代硬件通信协议的健壮性,可能 PCB 板材、布线参数等原因会导致实际指标达不到预期水平,但是主机芯片、从机芯片等还是能正常通信,只是不能跑满带宽,感谢全世界的大牛们打下这样坚实的基础,让我这样的新手也能摸一摸 10Gbps 的通信 。
在了解了高速电路的基础知识,并且也大概通过一些开源项目验证了 USB 2.0 之后,在 2023 年尾声的时候,终于重新尝试了 USB 3.0 的 Hub 以及 USB 3.0 的 NVME 硬盘盒。
这次 USB 3.0 Hub 使用了最新的 VL822 芯片,并且使用了 VL160 来实现 USB Type-C 接口的正反插识别,除了 VL160 整体外围电路只有电源供电,经过几次 QFN 焊接经历也能比较熟练的把 QFN 封装芯片焊接完成,最终测试下来这个 USB 3.0 Hub 连接了一个 RTL9210 NVME 硬盘盒,读取速度可以跑到 800MB/s,直接硬盘盒读取速度是 900MB/s,速度有一点损失,整体速率超过了 5Gbps 但是离 10Gbps 还差一点,不过也算是满足预期了。
另外这个焊接 USB 3.0 Hub 的过程中还踩了一个小坑,作者在画原理图的时候,忘记将 VL160 的供电连接了,导致在测试的时候在总线上一直无法显示 USB 3.0 Hub,在对比了另外一个 USB 3.0 Hub 之后才发现 VL160 没有供电,最后直接通过一根飞线解决了,也算是小小地体验了一把硬件 Debug。
另外一个就是基于 ASM2362 的 NVME 硬盘盒,同样是支持 USB 3.1 Gen 2 10Gbps 的芯片,相比 VL822 更省事,外围电路只有供电,连 USB Type-C 的正反插识别都已经内置了。虽然中间也因为焊接问题导致设备不识别排查了好久,但是最终也算是完成了。
另外就是 H616 开发板了,因为第一次焊接 BGA 导致验证失败,也没有再继续了,等今年再空些的时候,就继续把它验证完成吧。
10Gbps 级别的高速线路不再神秘之后,就想来综合做点东西了,准备在新的一年,看看能不能用这几个验证过的芯片,去 DIY 一个自己的 USB 3.0 扩展坞出来,毕竟之前写过一篇《六款便携 4K60Hz USB Type-C 扩展坞横向对比评测》,总觉得这些扩展坞有这样那样的不满意。
在 2023 年,嘉立创服务群仍然是最大的帮手,立创开源平台,立创 EDA,PCB 打样、立创商城、SMT 等服务,包含了一个硬件产品从设计、开发、制造全流程的服务,并且清晰透明的价格,让个人电子 DIY 爱好者也能享受现代工业生产的强大。
自从开始接触更复杂的电路,逐渐在立创 EDA 里面更多地使用 4 层板,立创 EDA 专业版也能提供比较好的支持,虽然立创 EDA 在 macOS 上的性能兼容性总存在一些问题,但是在反馈后也能持续改进,并且还是免费使用的。希望后续在接触到 6 层板之后,立创 EDA 的性能能更近一步优化,让 PCB 布线更顺畅。
最值得一提的是,立创商城的面板打印服务,结合立创 EDA 专业版中的面板设计工具,可以很方便地去可视化设计亚克力面板,并且价格透明,没有起订门槛,实在是一个让产品显得更专业的好服务。
在双 11 的时候,终于将服役一年多的创想三维 Sermoon V1 替换成了拓竹 P1S Combo,习惯高速 3D 打印机之后真的再也回不去了,以前需要晚上打印早上再查看结果的 3D 模型验证,现在可以晚上就打两次样来验证结构设计是否合理,大大提高了生产力。
结合拓竹 AMS,即使不使用多色打印的情况下,将它作为 3D 打印材料管理工具也是相当方便的,可以常年放置 4 卷不同材质或者颜色的材料在 AMS 中,在切片时选择需要的颜色或材质,完全不需要手动操作换料,节省了大量时间。
另外相比 Sermoon V1,拓竹 P1S 打印 PETG 的成功率也要高上很多,很多需要韧性的结构件,就可以选择使用 PETG 了。
自从用上嘉立创 PCB 打样服务,越来越多使用贴片元件之后, 手工焊接使用针管锡膏来点锡的方式效率也越来越跟不上需求。这个时候使用钢网刷锡膏是一个好选择,但是嘉立创开钢网费用比较高,某宝上卖家制作钢网要便宜不少,但是经常打样的话,光钢网费用也是一笔不小的支出了。
在 B 站上也学习过使用 3D 打印一个钢网,但是实验之后,这个精度实在难以控制,不管是厚度,还是后续要贴 0603、0402 封装的元件,都难以应付。
但是这个用法也启发了我,想起来之前买的 3020 CNC,同时配了一个激光头,再找个合适的材料通过激光雕刻的方式,就可以在家制作一个钢网了。
这种配的激光头并不足矣切割钢片,因此没办法实现真正的钢网,但是用来切割纸片足够了,在试验了很多次之后, 选择了 100g 的牛皮纸,使用下来厚度和精度都还算能接受,对于 0603、0402 封装的元件可以比较轻松的完全刷锡膏操作,对于一些引脚比较密集的元件,相邻引脚的开孔会连接到一起,最终形成一块连续的区域。不过这个问题也不大,使用加热台时加一些助焊剂来辅助焊接就可以了。
使用这种方式焊接贴片元件大大提升了效率,虽然摆元件这件事还是有点费眼睛,只能期待一下以后桌面贴片机能降价和减小体积了。
电子 DIY 这个业余爱好,从 2022 年重搭,2023 年又折腾一年,感觉仍然还是在新手村打转,基本上还停留在复制粘贴的程度,但是相比 2022 年,从只会复制粘贴,到能看懂原理图,从 PCB 只能原版打样,到能改改符合自己需求,还是有一些进步。
在软件开发上,能逐渐突破 Arduino 的限制,了解到更底层的技术,开始去理解 MCU 运行的内部逻辑,掌握基础的嵌入式 OS 使用,例如 FreeRTOS,以及大概明白所谓的寄存器编程是怎么样一回事,毕竟从一个应用软件开发的角度来说,这些东西本来就应该是库存在的。
2023 年也有一些小小的遗憾,没有能完整的做一个产品出来,之前参考 TickrMeter 做的墨水屏产品,也因为 PCB 设计和固件开发问题,一直没能正式上线,坐等新的一年填坑了。
在新的一年,先挖好坑吧:
突然发现这个流水账已经两万字了,就这样吧,记录一下 2023 年的电子 DIY 历程,希望对同样有兴趣玩电子 DIY 的朋友们有所帮助。
]]>这一次我们就来看看如何给 Monaco Editor 增加代码块折叠功能。
在 Monaco Editor Playground 的 Folding Provider Example 示例中,可以看到如何给一个自定义语言添加代码折叠支持:
monaco.languages.registerFoldingRangeProvider("foldLanguage", {
provideFoldingRanges: function (model, context, token) {
return [
// comment1
{
start: 5,
end: 7,
kind: monaco.languages.FoldingRangeKind.Comment,
},
// ...
]
}
});
可以看到,只需要在注册自定义语言后,再注册一个 foldingRangeProvider 即可,在 provicdeFoldingRanges callback 中,将可以折叠的代码区块,以 start 和 end 行号圈定范围,返回给到 Monaco Editor 即可。
在示例中,它是通过硬编码起始和结束行号的方式来提供可折叠范围的,但是在实际使用过程中,我们不可能预见可以支持代码折叠的范围,这里需要使用编码的方式来动态生成可折叠范围。
在开发 MermaidEditor 的代码编辑器时,在部分图表中,代码块会有一些层级关系,为了有更好的编辑体验,我们就需要给代码编辑器加上代码块折叠功能。
目前 Monaco Editor 并没有提供官方的 LSP(Language Server Protocol) 支持,我们需要使用其他方式来实现代码折叠的逻辑。
通过观察,我们可以发现,对于不同层级的代码块来说,它们通常拥有不同数量的缩进,因此我们可以通过缩进来判断代码行是否属于同一个代码块。
获取编辑区内容
在 provideFoldingRanges 函数中有一个参数 model,通过这个变量我们可以获得当前编辑区中的所有文本内容,通过遍历每一行的内容,可以获取到每一行的前置空白字符数量,从而根据空白字符数量来判定代码块折叠范围。
// 用于匹配每一行空白字符的正则表达式
const pattern = /^(\s*)(.+)/;
// 遍历编辑区内容中的每一行代码
for (var i = 1, count = model.getLineCount(); i <= count; i++) {
const line = model.getLineContent(i);
// 获取每一行代码中的前置空白字符
const matches = pattern.exec(line);
if (matches) {
// 获取当前行的空白长度,用于匹配后续代码行是否属于这一区块
const indentLen = matches[1].length;
}
}
匹配代码折叠区域
在遍历每一行代码后,我们需要判断它后续的代码行,是否属于可折叠代码区块,这里判断的标准是,后续代码行的前置空白字符长度大于当前行的前置空白字符数量,因此所有缩进长度大于当前行的代码区域,都可以被包含进来 。
// 从下一行开始搜索
let endLine = i + 1;
let lastNotEmptyLine = i;
// 遍历到编辑区内容末尾
while (endLine <= count) {
const lineContent = model.getLineContent(endLine);
// 获取后续行的前置空白字符长度
const subMatches = pattern.exec(lineContent);
if (subMatches != null) {
// 如果前置空白字符长度大于起始行,就将它包含进折叠区域
if (subMatches[1].length > indentLen) {
lastNotEmptyLine = endLine;
} else {
break;
}
}
endLine++;
}
请注意,这里额外忽略了空白行,是为了防止空白行会中断折叠区域的判断,这样在处理同等缩进的代码块中,如果出于代码格式考虑添加的空白也不会导致折叠区域判断错误,提前结束折叠区域的判定。
返回代码块折叠区域
if (lastNotEmptyLine > i) {
ranges.push({
start: i,
end: lastNotEmptyLine,
kind: monaco.languages.FoldingRangeKind.Region,
});
}
这里返回 Monaco Editor 可以使用的代码块折叠区域数据结构。
monacoEditor.languages.registerFoldingRangeProvider("foldLanguage", {
provideFoldingRanges: function (model, context, token) {
const ranges = [];
const pattern = /^(\s*)(.+)/;
for (var i = 1, count = model.getLineCount(); i <= count; i++) {
const line = model.getLineContent(i);
const matches = pattern.exec(line);
if (matches) {
const indentLen = matches[1].length;
let endLine = i + 1;
let lastNotEmptyLine = i;
while (endLine <= count) {
const lineContent = model.getLineContent(endLine);
const subMatches = pattern.exec(lineContent);
if (subMatches != null) {
if (subMatches[1].length > indentLen) {
lastNotEmptyLine = endLine;
} else {
break;
}
}
endLine++;
}
if (lastNotEmptyLine > i) {
ranges.push({
start: i,
end: lastNotEmptyLine,
kind: monaco.languages.FoldingRangeKind.Region,
});
}
}
}
return ranges;
},
});
可以看到,最终 Monaco Editor 正确显示了代码块折叠标记,并且有嵌套的折叠,也能正确识别。