输入设备


概述

本节介绍输入设备的设计与实现,重点是传感器集成和微控制器编程,属于 Lucio Pentagna 的 Fab Academy 2020 项目。

小组项目

个人项目


学习成果


你是否:

本周流程

学习 Neil 的输入板 → 决定输入类型 → 设计原理图/电路板 → 铣削电路板 → 焊接元件 → 调试 → 编辑并发布网站


使用的工具


使用的软件


文件

  1. 文件(Eagle)
  2. 文件(G-code)
  3. 文件(代码)

小组作业

查看小组作业页面了解更多详情。


个人项目

本周我专注于测试热敏电阻,这对我的孵化器项目来说必不可少,用来测量和控制温度。

我选择的热敏电阻是 B57560G0104。根据数据手册,它在 25 摄氏度时电阻为 100K。

热敏电阻的阻值随温度升高而下降。由于芯片的 ADC 引脚读取的是电压而不是电阻,所以需要分压电路来推算它的阻值。

我把热敏电阻与一个电阻串联后接到 VCC。热敏电阻的一端接地,另一端接在串联电路里。

我的电路板和温度传感器的展示照 我的电路板和温度传感器的展示照


参考资料

就像我在第 6 周做的那样,我先回顾了 Neil 的电路板。我重新设计的是可见光输入板。

Neil 教授的温度板 Neil 教授的温度板


用 Arduino 做实验

这个实验的目的是理解和测试热敏电阻与代码。虽然能工作,但温度读数不太准确。没有精确的校准仪器,我就烧开水,确保温度大约在 100 摄氏度。

用烙铁烧水。热敏电阻浸在液体里。

热敏电阻和温度探头放在一起的细节。 热敏电阻和温度探头放在一起的细节。


用 USBasp 给 ATtiny 编程

ATtiny45 上的 USBasp 编程器ATtiny45 上的 USBasp 编程器

下面的视频展示了编程过程。

YouTube 上的高清视频


用我设计的电路板做实验

我的电路板和温度传感器的展示照 我的电路板和温度传感器的展示照


设计电路板(PCB)

ATtiny45 引脚图 ATtiny45 数据手册(点击这里)

因为我通常用 Arduino IDE 编程,所以不仅要有数据手册,还要有一张把引脚从一个编程平台对应到另一个平台的图,这很有用。

快速看一眼就能发现,Arduino 有 4 个模拟引脚。它们都有模数转换器(ADC0、ADC1、ADC2、ADC3),所以也可以和引脚 1、0、2 一起当作数字引脚使用。

这次作业我需要 1 个模拟引脚和 2 个数字引脚。模拟引脚用来接热敏电阻,数字引脚用于串口通信。

板上会有一个 ISP 编程器排针,两侧各有 2 个排针,方便按需使用和测试所有引脚,还会有一个 LED,用来显示已经通电。

Autodesk Eagle 是我的首选工具,但我会用 pcb-gcode 插件生成 G-code。

电阻计算

为了计算电阻值,我查看了下面的数据手册,以下是我做的计算和观察:

蓝色 LED

数据手册摘录 数据手册摘录

电阻计算 电阻计算

下面是我设计的原理图:

带 ATtiny45 的电路板原理图

ATtiny45 电路板的原理图

带 ATtiny45 的电路板设计

带 ATtiny45 的输入设备板

热敏电阻板

在我的热敏电阻板上,我用了:

  1. Vishay Dale NTHS1206N01N1003KE NTC 100KOHM 3964K 1206,数据手册在这里。
  2. 一个 100k 电阻作为下拉电阻

NTC 热敏电阻的阻值随温度升高而下降,反之亦然。为了计算阻值,用一个已知电阻来测量电压降。ATtiny45 不直接测量电阻,所以程序里用的公式是:RT = ((VCC*R-R*VRT)/VRT)

热敏电阻板原理图

热敏电阻板原理图

热敏电阻板设计

热敏电阻板设计

ATtiny45 的代码

这次作业我用了三组代码:

  1. 软件串口的参考资料:来源 1 来源 2

    因为 ATtiny 不能用普通的硬件串口,所以我加入了一个库来实现这个功能:

    #include "SoftwareSerial.h"
    SoftwareSerial Monitor(1, 0);
    
    void setup() 
    {
        Monitor.begin(9600);
        pinMode(0, OUTPUT);
        pinMode(1, INPUT);
    }
                

    打印要用另一种方式:

    Monitor.println(whatever you want to print here);
                
  2. 用 Arduino 读取温度

    Arduino 实验中使用的代码来自 Arduino Project Hub:How Easy Is It to Use a Thermistor?!,作者 Marcazzan_M:

    //Thermometer with thermistor
    
    /*thermistor parameters:
     * RT0: 10 000 Ω
     * B: 3977 K +- 0.75%
     * T0:  25 C
     * +- 5%
     */
    
    //These values are in the datasheet
    #define RT0 10000   // Ω
    #define B 3977      // K
    //--------------------------------------
    
    #define VCC 5    //Supply voltage
    #define R 10000  //R=10KΩ
    
    //Variables
    float RT, VR, ln, TX, T0, VRT;
    
    void setup() {
      Serial.begin(9600);
      T0 = 25 + 273.15;                 //Temperature T0 from datasheet, conversion from Celsius to kelvin
    }
    
    void loop() {
      VRT = analogRead(A0);              //Acquisition analog value of VRT
      VRT = (5.00 / 1023.00) * VRT;      //Conversion to voltage
      VR = VCC - VRT;
      RT = VRT / (VR / R);               //Resistance of RT
    
      ln = log(RT / RT0);
      TX = (1 / ((ln / B) + (1 / T0))); //Temperature from thermistor
    
      TX = TX - 273.15;                 //Conversion to Celsius
    
      Serial.print("Temperature:");
      Serial.print("\t");
      Serial.print(TX);
      Serial.print("C\t\t");
      Serial.print(TX + 273.15);        //Conversion to Kelvin
      Serial.print("K\t\t");
      Serial.print((TX * 1.8) + 32);    //Conversion to Fahrenheit
      Serial.println("F");
      delay(500);
    }
                
  3. 我的代码版本把软件串口和 Marcazzan 的部分代码合在一起,因为 ATtiny 无法同时编译软件串口和对数计算。编译后代码必须限制在 4k 以内。

    代码在这里

    #include "SoftwareSerial.h"
    #define VCC 5    //Supply voltage
    #define R 100000  //R=100KΩ
    
    float RT,VRT,VR;
    
    SoftwareSerial Monitor(1, 0);
    
    void setup() {
        Monitor.begin(9600);
        pinMode(0, OUTPUT);
        pinMode(1, INPUT);
    }
    
    void loop() {
        VRT = analogRead(3);              //Acquisition analog value of VRT
        VRT = (5.00 / 1023.00) * VRT;      //Conversion to voltage
        VR = VCC - VRT;
        RT = ((VCC*R-R*VRT)/VRT);               //Resistance of RT
    
        // Monitor.println("Voltage Read:");
        // Monitor.print(VRT,10);
        // Monitor.println("Voltage drop:");
        // Monitor.print(VR,10);
        Monitor.print("Resistance:");
        Monitor.println(RT);
       
        delay(1000);
    }
                

    原来用来求阻值的公式对我不适用,因为在我的板上热敏电阻和电阻的位置是互换的:热敏电阻接 VCC,100k 电阻接地。我把公式改成了:

    RT = ((VCC*R-R*VRT)/VRT);               //Resistance of RT
                

设计和制作 PCB

改进了工作流程后,我把它更新为使用 PCB-Gcode ULP 和 Autoleveller 软件。


在 Autodesk Eagle 中设计

原理图准备好后,按以下步骤操作:

  1. 点击 SCH/BRD 打开对话框。
  2. 在对话框里点击 yes,把元件放到电路板区域旁边。

Eagle 设计,第 1 步

元件会放在代表电路板的正方形旁边;电路板稍后会调整尺寸。

Eagle 设计,第 2 步

输入“move”并按回车,然后点击每个元件,把它拖到电路板里面。

Eagle 设计,第 3 步

这里我开始把 ATtiny45 拖进电路板的边界内。逐个点击元件时不需要再次输入“move”,除非按了“esc”或用了别的命令。

Eagle 设计,第 4 步

所有元件都拖好了,上边界也用“move”命令拖动并调整了尺寸。移动元件的另一种方法是输入“info”,然后用左键点击元件,这样可以直接输入元件的坐标,而不用拖动。

Eagle 设计,第 5 步

“rotate”命令可以把元件转到便于高效布线的理想方向。黄线表示原理图中创建的连接。

Eagle 设计,第 6 步

这里我用“polygon”命令创建一个轮廓。轮廓闭合时会弹出一个对话框。

Eagle 设计,第 7 步

多边形画完后,对话框会打开。输入“GND”会把多边形连到地。

Eagle 设计,第 8 步

输入“ratsnest”或点击它的图标,会用接地层填满整个电路板区域。现在,输入“autoroute”或使用“route”命令,就可以连接各个元件。

Eagle 设计,第 9 步

在给元件布线之前,进入 edit → design rules 设置各元素之间的间距。

Eagle 设计,第 10 步

在“sizes”选项卡中设置走线的最小宽度。根据我的经验,0.2mm 效果很好。

Eagle 设计,第 11 步

“clearance”选项卡设置 PCB 各元素之间的距离。我现在所有信号都用 0.3mm。

Eagle 设计,第 12 步

所有设计规则设好后,输入“autorouter”或点击它的图标,就会开始连接各个元件。

Eagle 设计,第 13 步

一个重要的设置是点击名为“bottom”的框,如果你不想要双面板就选择 N/A。然后按下去就会开始处理。

Eagle 设计,第 14 步

然后选择其中一个选项,点击“evaluate”或“end job”返回电路板布局。

我用黄色圈出了电路板的底层,它是蓝色的。我不想要这个,所以下一步会重做电路板。

Eagle 设计,第 15 步

这里可以看到“ratsnest”命令的效果。这个命令会用接地层填满所有没有被过孔占用的空间。

Eagle 设计,第 16 步

因为我希望自动布线器重新做一遍,所以我输入了“ripup”并全选,这样所有布线都被撤销。

Eagle 设计,第 17 步

然后重新做自动布线。

Eagle 设计,第 18 步

这里布线完成了,但还没应用“ratsnest”。

Eagle 设计,第 19 步

这里已经应用了“ratsnest”。

Eagle 设计,第 20 步

这一步我挪动元件,把电路板缩小了一点。这是用“move”命令完成的。如果你想移动多个元件,先选中它们并输入“group”,然后输入“move”,再用右键点击它们来移动整组。

Eagle 设计,第 21 步


ratsnest 的两难

下面可以看到一块有“ratsnest”和一块没有“ratsnest”的板。

第一块板应用了“ratsnest”,看起来会乱一些。一个优点是散热:更大的铜面积有助于电路板冷却,也能提高导电性,尤其是在双面板上,一面可以是地,另一面是 VCC,几乎整个表面都能用于传输电能。第二块板看起来更干净。

带 ratsnest 的电路板

现在我喜欢做没有“ratsnest”的板,因为手工焊接可能不精确,短路很容易发生,而“ratsnest”会增加这种风险。

在“milling”层画出的粗浅蓝色轮廓会被 pcb-gcode ULP 用来生成 G-code 铣削轮廓。软件用它来创建边界,这个切割可以用来把电路板从覆铜板上分离下来。多边形的厚度决定铣刀尺寸。

不带 ratsnest 的电路板


电路板物料清单(BOM)

数量 位置 Digikey 或 Mouser 编号 制造商编号 说明
1 U1 ATTINY45V-10SU-ND ATTINY45V-10SUR 8 位 MCU 集成电路,4KB Flash,8SOIC 封装
2 R1 311-10.0KFRCT-ND RC1206FR-0710KL 贴片电阻 10K 欧姆 1% 1/4W 1206
1 R2 311-100FRCT-ND RC1206FR-07100RL 贴片电阻 100 欧姆 1% 1/4W 1206
1 D3 160-1169-1-ND LTST-C150GKT 绿色透明贴片 LED 1206
1 C1 445-1423-1-ND C3216X7R1H105K160AB 陶瓷电容 1UF 50V X7R 1206
1 FTDI 6 针排针
2 1X4P 排针

PCB-Gcode

前一段时间,我开始使用一个叫 PCB-Gcode 的 User Language Program(ULP)。它是一个很棒的程序,有很多设置,我一部分通过阅读文档、一部分通过反复尝试才弄明白。

下面展示我如何设置它,以便顺利生成 G-code。

  1. 点击 file
  2. 然后点击 Run ULP
  3. 接着点击 pcb-gcode-setup

PCB-Gcode 设置,第 1 步

我自定义的设置是:

  1. 我选择只生成顶层轮廓和顶层钻孔:第一个是生成把电路板从板材上切下来的 G-code;第二个是电路板可能有的孔。铣刀或钻头的直径在 machine 选项卡中选择。
  2. 这里可以设置电路板厚度。我的板子用 1.72mm 的切割就能很好地分离,在“num Slices”里我选了 6,也就是分 6 次切下电路板。
  3. 定位钻孔是在蚀刻过孔和电路板设计的所有特征时留下的浅标记。它们用来对准钻孔用的钻头,防止钻头在板上滑动。我选的是 0.055mm,和蚀刻用的深度一样。
  4. 隔离是最重要的设置之一。如果最大值设得太高,这个设置可能会让电脑变得很慢。对我有效的是:最小 0.0254mm(默认);最大 1.5mm;步进 0.05mm。最后一项和最大值一起,能保证走 30 遍,确保走线之间没有残留铜,并且充分隔离,降低短路风险。这些数字可能有点夸张,但效果非常好,我做出来的板子很漂亮。以后我可能会减小最大值或增大步进。

PCB-Gcode 设置,第 2 步

在 Machine 选项卡中选择切深、单位、进给速度和刀具直径等设置。

  1. Z high 设为 12.7(默认),这个设置应该给可能挡路的夹具留出间隙;Z up 是机器从一个位置移动到另一个位置时离开电路板的高度;Z down 是切割深度。这个数值对我来说很重要,因为我用的是 10 度 V 型刀。如果切得太深,就会切得比应该的更多;如果太浅,就会切得不够。当然,10 度不算太陡,比更陡的蚀刻刀更能容忍深度误差;钻孔深度是通孔的深度,通常应该比空白 PCB 的厚度稍大一点,以补偿瑕疵;Drill dwell 是每个孔之间的停顿,它让钻头冷却,我保持默认值。
  2. 这里我把单位设为 mm
  3. 我所有的蚀刻进给速度都是默认值
  4. 我用的刀具直径是 0.1 mm

PCB-Gcode 设置,第 3 步

G-code style 选项卡用来选择后处理器。我用的是 Mach3。

PCB-Gcode 设置,第 4 步

这是 ULP 生成的 G-code 可视化。可以用方向键在图像中移动,也可以用加号和减号。

PCB-Gcode 可视化

会生成四个文件:

  1. *.bot.mill.gcode:是底层铣削(轮廓),我不用这个文件。
  2. *.top.drill.gcode:是钻孔的 G-code
  3. *.top.mill.gcode:是顶层轮廓的文件,这些文件可以用来把 PCB 分离下来。
  4. 最后,*.top.etch.gcode 是 PCB 蚀刻的 G-code,包含所有设计好的特征。

在 PCB-Gcode 中生成文件

下面是热敏电阻板隔离路径的可视化。

热敏电阻板隔离路径的可视化


Autoleveller

Autoleveller 是一款很棒的软件。它先探测空白 PCB,然后用生成的文件调整 G-code 的切割深度,确保铣床能跟随空白 PCB 的起伏。我通过运行可执行文件启动 Autoleveller;在 Linux 上不需要安装。接着点击 File,再点击 Original GCode File(OGF):这样就可以在程序里加载原始 G-code。

Autoleveller 设置,第 1 步

点击原始 G-code。

Autoleveller 设置,第 2 步

点击 yes,让设置基于已加载的文件。

Autoleveller 设置,第 3 步

接着点击窗口右下角的 Generate PFG。这会生成一个包含一系列指令的 G-code。它会:-先探测 Z 0;-再探测电路板区域内的多个点;-然后询问保存原始文件的位置,之后会用这个文件生成自动调平的 G-code。

Autoleveller 设置,第 4 步

这里正在保存 PFG 文件。然后把这个 G-code 加载到 CNC,并按照 G-code 区域的说明操作。

Autoleveller 设置,第 5 步

现在该把空白 PCB 固定到 CNC 工作台上了。我不再使用双面胶,因为它不如夹具有效,而且之后还得清理残留的胶带。

把 PCB 固定到 CNC 工作台

我在 CNC 上事先铣了一个凹槽,让电路板有固定位置,这有助于固定空白板。

为 PCB 铣出的凹槽

在 CNC 上加载 PFG 后,按照屏幕上的说明连接探针。

在 CNC 上连接探针

这里我把探针接到电路板表面,把鳄鱼夹接到铣刀上。

连接探针和鳄鱼夹

这个视频展示了探测过程。

探测完成后,保存原始文件,拿到 Autoleveller 里加载。

把原始文件加载到 Autoleveller

把探测得到的原始文件重新加载到 Autoleveller。

加载探测得到的原始文件

最后,点击屏幕右下角的 Autolevel 保存调整后的 G-code。保存文件,拿到 CNC 上开始铣削。

保存调整后的 G-code

加工视频

蚀刻(铣削)过程的慢动作视频。

最终结果在这里。有时我会用 1000 目砂纸让它表面更好。

铣削的最终结果

现在我来展示电路板边缘的切割。

铣削电路板边缘

结果

焊接前的热敏电阻板 焊接前的热敏电阻板。

焊接后的热敏电阻板 焊接并用异丙醇清洁后的热敏电阻板。

ATtiny45 板和热敏电阻板的最终结果 ATtiny45 板和热敏电阻板,已经可以工作了。

脚注

avrdude -Cavrdude.conf -v -pattiny45 -cusbasp -Pusb -e -Uefuse:w:0xff:m -Uhfuse:w:0xdf:m -Ulfuse:w:0xe2:m

串口监视器:YouTube 视频

ATtiny 风扇控制器项目:Robot Room

用 Arduino 和 NTC 热敏电阻读取温度:Circuit Digest

配置 Arduino 022:High-Low Tech

回流焊炉项目:Pleasant Software

上拉电阻(RES SMD 10K OHM 1% 1/4W 1206),从 RST 到 VCC

去耦电容(CAP CER 1UF 50V X7R 1206),从 VCC 到 GND,用于降低噪声

← (3月25日) 嵌入式编程 · 所有周 · 应用与影响 (4月15日) →