我参加了电子设计竞赛...

我参加了电子设计竞赛...

成果

北京市二等奖

方案

我其实对电子电路这块是一窍不通的,也就擅长写写代码调调单片机。然而做电赛软硬兼顾才吃香,要不怎么要求三人组队参赛呢。

经过我们仨人深(一)思(拍)熟(脑)虑(门),就选 F 题了。题目要求,两个金属极板间放若干张纸张,每个极板上仅引出一根线连接到设备上,仅据此就得知道里面夹着多少张纸。(还不如做个电子秤,70g一张纸)

测电容!

两个极板对齐摆放就是一个电容器,里面夹着纸或者其他东西都会改变这个电容器的电容,而我们只需要做两件事情

  • 测出电容
  • 找出电容值与纸张数量的对应关系

感觉这道题最难地方在于

🤕
测量很容易实现,测量准确实属不易

测量值范围预估

(不是我算的我也不知道怎么算反正就是这个样子

题目要求金属极板的面积为 2.5 平方厘米,两个极板间压的足够紧(没有空气)的情况下一张纸的电容约为570 pF ,十张纸的电容约为 57 pF ,20 张纸的电容约为 23.5 pF ,30 张纸的电容约为11.75 pF。

所以,纸越越难区分,设计的最小测量精度为 1.17 pF。

测量电容

“两极板以及极板间的待测纸张构成了一个大电容,容值随着纸张数的不同发生变化。我们将这个大电容接入由 555 计数器构成的多谐振荡器电路中,通过大电容连续的充、放电过程,使得 555 计数器被不断复位、置位,从而输出一定谐振频率的方波,得以将测量纸张数目的问题在转变为测电容之后,再进一步转变为对频率的测量。“

单片机和电容测量电路的桥梁 FPGA

我们需要做一个高频计数器,由于我们选用的是 Arduino Mega2560 作为主控,不管使用什么方法频率计也就在 10K 左右。而 555 输出的是一个方波,周期即电容充放电的周期,通过测量周期长度,也就是测量高频晶振在周期内的震荡次数,以精确测量电容值。

我们利用了一块叫 小脚丫🦶 的FPGA板子,做了个16位计数器,通过16根线和 Arduino Mega2560 相连(谁让它IO口就是多呢),相互不设控制,FPGA每测量一整个周期的计数更新一次16根线的数值,相当于一个计数器+锁存器了。

此外,利用PLL IP核(锁相环) ,我们把 小脚丫🦶 片载的 16Mhz 晶振做了 12 倍频,高达 96Mhz,大大大大大大大大的提高了测量的精度。

如果用单片机实现,这一定是一个既消耗资源,又考验算法性能的工作,但如果换一个方式,就很简单,很简单。也就20行左右的 Verilog 代码。(前提是得接触过 FPGA,数字逻辑课、计组课设课没白上

单片机 Arduino Mega2560

为什么选这块板子呢

  • 不要重复造轮子 (库多随便调,懒癌晚期患者)
  • 丰富的IO接口(要不是为了连上 小脚丫🦶的16根线.....)
  • 简单易用,快速上手(说白了就是菜)

得益于以上优点,让一块OLED屏幕显示英文仅需要4根线和几行代码 😊

测量器

老师好厉害,真的。

印了块电路板,中间腐铜当金属板,我就问问,这谁想的出来!

  • 两块极板精准对接,提高测量精度
  • 一个大夹子直接夹上,提高测量精度
  • 看着美观精巧,实操测量人员心情愉悦,提高测量精度

在这里实名感谢🙏提供夹子的大兄弟,没有你(的夹子)我们不可能走到现在这一步!

动手

(这我就不是很擅长了,虽然我焊接啥的都会!,但就是良品率低,很低很低的那种

我当时怎么就不多拍一些照片呢,也不至于现在找不到图还得靠表情包凑数。之后是再补图吧 2333

编码

PlatformIO + CLion = ❤️

Arduino IDE虽然用着方便,但既不支持代码格式化,又没有智能补全,实属智障IDE。

CLion虽然聪慧过人,但仅支持识别 CMake 这一种构建方式。

brew install platformio  # 安装platformio工具链
platformio lib install 135  # Adafruit SSD1306 屏幕驱动
platformio lib install 188  # Adafruit_GFX 图形库
platformio init --ide clion # 刷新一下对CMake的支持

PlatformIO 有自己的构建方式,生成的 CMakeLists.txt 只是用来打酱油的(让 CLion 可以智能提示和错误检查)

小屏幕

void setup_screen() {
    if (!disp.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
        Serial.println("SSD1306 allocation failed");
        for (;;); // Don''t proceed, loop forever
    }
    disp.setTextSize(1);      // Normal 1:1 pixel scale
    disp.setTextColor(WHITE); // Draw white text
    disp.setCursor(0, 0);     // Start at top-left corner
    disp.setRotation(2);     //屏幕装反了软件来调整
    disp.cp437(true);
}

void disp_menus() {
disp.clearDisplay();
disp.setCursor(0, 0);
disp.println(“Adjust 15 | TEST”);
disp.println(“Adjust 5 | Adjust 25”);
disp.println(“ | (BACK)”);
disp.display();
}

小脚丫 STEP FPGA MX02 V2

module Counter(
    input sig,
    input clk,
    output reg [15:0] out
);

wire clk2;
reg [15:0] cnt;
reg [4:0] ct;

initial begin
out <= 16’’b0000000000000000;
cnt <= 16’’b0000000000000000; // 脉冲计数器
ct <= 4’’b0000; // 对555输出的方波进行分频,提高测量精度
end

pll PLLX(.CLKI(clk),.CLKOP(clk2)); // 调用IP核的倍频器

always @(posedge clk2) begin
if(sig == 1 && ct == 4’’b1111) cnt = 0; // 测完一个测量周期就清空计数器
else cnt = cnt + 1;
end

always @(posedge sig) begin
if(ct == 4’’b1111) begin // 这里相当于一个锁存器,保持out始终为周期完整的测量结果
out = cnt;
ct = 0;
end else ct = ct+1;
end

endmodule

马上就要封箱了!

赛事DDL前,应该做些什么?

印象中是2019年8月10日晚上8点就要停止比赛,不管做得怎么样,都要把作品和设计报告装在一个箱子里,贴上封条,静待专家测试。

那8月10日的下午,就是一个很关键的时间段。

是应该多做一些,还是应该少做一些,以及要保持一个怎样的心态,才算良好。

当时我们已经能精准测量并识别1~30张纸了,使用的是查表法,预先将不同数量厚度的纸张的读数值记录下来,写在程序中,再次测量的据此得出纸张数量。考虑到周围环境以及不同品牌纸张对结果的影响,我们也做了分点校准程序(我们假设误差对于不同数量的纸张的影响是相同的)。

于是,我们是进一步提高1~30张纸的对应表的精度,还是测量并记录更大范围的对应表呢?

对于第一件事情,提高精度的方法无非多次测量取平均,完整测量一次大约需要1小时的时间。

对于第二件事情,亦是测量更多的数据。

这两件事情的决策,即在提高作品稳定性和提高作品分数上之间二选一。想了想,跟高中数学考试快交卷的时候,把这剩余的时间用来检查前面做过的题,还是再攻克攻克难题,很相似。

实际上,这两件事情哪个都没有做 23333

现在回过头来想想,似乎做什么对结果影响都不大。

现场测试

(不让用手机,照片肯定是莫得了

紧张什么的就不说了,都这样。其他组做的也挺有意思的,我看见前一个组,用按着两个金属板,读数后,人工查阅一张打印出来的对应表。

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×