分类目录归档:Arduino小组

PIR传感器相关知识

PIR传感器跟其他的传感器比起来可能要更加复杂(像光电池,避震器,湿度传感器),因为其中有许多影响传感器输入和输出的变量。我们会使用这个不错的图解来开始解释一个基本的传感器是如何工作的。

PIR传感器上有两个插槽,每个插槽由特殊的对红外信号敏感的材料做成。这里使用的镜头不会真的做这么多,所以我们可以看到两个插槽可以“看到”过去的一段距离。(基本上是传感器的敏感性)。当传感器没有工作时,两个传感器检测到同样数量周围环境,比如房间,墙壁或者室外辐射出来的的红外信号。当一个有温度的物体,比如一个人或只动物经过,物体一开始会挡住一半的传感器,这会在传感器两边产生微小的正向电势差。当有温度的物体离开传感器所能探测到的区域,传感器电势差就会发生反转,进而能够产生负向的电势差。这就是传感器检测到的脉冲变化。

1

PIR传感器

PIR传感器被封装在一个密封的金属盒中。在金属盒上有一个用能传递红外信号的材料做成(比较典型的是硅,因为红外线可以很容易就通过硅。)的窗口,用来保护传感器的感应部分。在窗口后面是两个平衡传感器。

2

3

你可以在上面的上面展示的图像中看到窗口的组成—两片传感材料。

4

这张图展示了传感器的内部结构,在里面有一个低噪音的结晶型场效应晶体管(一种晶体管),并将传感器的极高的阻抗缓冲到低成本的的芯片上(比如BIS0001)

透镜

PIR传感器是通用的,而且大部分的价格和灵敏度都不同。大部分的魔术都是通过光来实现的,这对于制造来说是个不错的主意:PIR传感器和电路是固定的,并且成本为几美元。而镜头只需几美分,同时很容易改变宽度,范围和感应模式。

在上图中,透镜只是一块塑料,但这意味着检测区域仅仅是两个矩形。通常我们想要一个更大的检测区域。为了做到这一点,我们使用了一个简单的镜头,比如相机里的那些镜头:他们把一个大的区域(如风景)浓缩成一个小的(在胶片上或CCD传感器上)。由于这些原因很快就会显现出来,我们想要使PIR镜头变得小巧而薄,并且可以从廉价的塑料中进行模塑,尽管它可能会增加变形。由于这个原因,传感器实际上是菲奈尔透镜:

5

菲勒透镜凝聚了光,为传感器提供了更大范围的红外线。

6

 

现在我们有了一个更大的范围。然而,请记住,我们实际上有两个传感器,更重要的是,我们不想要两个真正大的矩形区域,而是多个小区域的散射。所以我们要做的是把镜头分成多个部分,每个部分都是菲勒尔透镜。

7

在这里你可以看到多面部分

8

这一宏观的镜头在每个方面展示了不同的法伦镜头!

不同的面部和副透镜产生了一系列的检测区域,相互交错。这就是为什么镜头中心在上面的部分是“不一致的”——每一个都指向不同的PIR传感元件。

11

10

 

连接一个PIR传感器

11

大部分的PIR模块在两侧或者底部有一个3个引脚的接口。模块之间的输出引脚可能会有所不同,所以对于输出引脚要检查3次。位于接口右边的输出引脚经常是丝网印刷成的(至少我们的是)其中一个引脚会接地,另一个是信号输入,最后一个是接入电源。输入电压经常是3-5V的直流电压但有时会达到12V。在接地。有电源和两个开关连接的情况下有些大的模块没有直接输出,而是通过一个继电器进行操作。

一些继电器的输出是集电极,这说明该继电器需要一个上拉电阻。如果你的输出不可改变,请确保能够在信号引脚和电源引脚之间添加一个10K欧的上拉电阻。

当连接端口的间隔是0.1秒时,一个关于原型PIR传感器的简单方法就是将其连接到面包板上。一些PIR传感器上面已经有数据头了。来自adafruitde PIR有一个三引脚的便于连接导线的接线头。

12

我们的PIR传感器的红色线连接电源正极,黑线接负极,黄线是信号输出。要确保像上面展示的一样连接好线头。如果你反过来接,虽然不会损坏传感器,但是传感器不会工作。

 

测试一个PIR红外传感器

1

2

 

在当PIR传感器检测到人的动作,输出引脚就会上“升”到3.3V,然后点亮LED灯。

如果你手上有已经连好线的面包板,将电池接入之后,为了使PIR“稳定”下来,要先等待30到60秒。在这期间LED灯可能会闪烁。等到LED灯完全熄灭后,为了让灯再次亮起来,我们可以在传感器面前来回走动,挥手等等。

重触发

你手上的PIR传感器有两种选项。首先我们将会探索“重触发”选项。

当你使LED灯闪烁时,观察PIR传感器背面并确保跳线像下面展示的一样连接在L接口。

3

4

现在再次搭建好测试板电路,你可能会注意到当像上面一样连接好PIR传感器时,如果在LED灯面前移动,灯不会保持点亮,而是大约每一秒点亮和熄灭一次。这被叫做“非重触发”。

5

现在将跳线转接到H接口,如果你再次搭建好测试电路,你会注意到如果有物体移动时,灯会一直亮着。这被叫做“重触发”。

6

对于大多数的应用,“重触发”(跳线像上面展示的一样被接到H接口)模式一般会更好。

7

如果你需要将传感器连接到一些边缘触发的装置,你可能会选择将其调节至“非重触发”模式(跳线被连接到L接口)。

改变灵敏度

Adafruit PIR传感器在背部有一个调节灵敏度的微调筒。如果你的PIR传感器太灵敏或者太迟钝,你可以调整这个微调筒—顺时针调节会让传感器更加灵敏。

8

改变脉冲时间和超时时长

在PIR传感器上有两个“超时设定”。其中一个是“Tx”设定:传感器检测到动作后LED灯会点亮多久—由于有电位计,调整Adafruit PIR传感器将会变得很简单。

第二个是决定没检测到动作时LED灯会熄灭多久的“Ti”超时设定。这个设定可能没那么容易去改变,可如果你用电焊去操作,这将变得可行。

首先让我们再看下电路数据

Tx=输出引脚(V0)触发后保持高电平的时间。

Ti=在周期中,触发被抑制,仔细观察时间表。

Tx≈24576×R10×C6;  Ti≈24×R9×C7(参考原理图)

Adafruit PIR传感器,有一个标记着时间的调整电位器。这是一个被串联到一个10 k欧电阻器的1兆欧可调电阻器。同时C6的值为0.01Uf,所以

Tx=24576×(10K)×0.01uF=2.5秒(约等于)

如果Rtime电位器从顺时针方向转到1兆欧电阻,则

Tx=24576×(1010K)×0.01uF=250秒(约等于)

如果Rtime位于中间,那结果将会大概是120秒(2分钟),所以你可以尽可能的开足马力。比如说如果你想通过一个人的动作去打开一个风扇至少1分钟,将Rtime电位器调整至一圈的1/4位置。

对于较旧的或者其他PIR传感器

如果你拿到的是一个没有可调整的电位器的PIR传感器,你可以像这样找出调整电阻

9

判断R10和R9并不是很难,可惜这个PIR传感器时贴错标签的(似乎将R9和R17调换了位置),你可以通过查找BISSOO1数据表来查探引脚,然后找出分别是什么引脚—R10和引脚3连接,R9和引脚7连接,而区别电容会有点难,但是你可以通过“逆向工程”的方法并对传感器记录时间,从而得到解决。

例如;

Tx=24576*R10*C6= ~1.2秒

R10=4.7K,R10=10nF

同样

Ti=24*R9*C7=~1.2秒

R9=470K,R7=0.1Uf

你可以通过交换不同的电阻或电容来改变时间。

 

使用一个PIR传感器

将PIR传感器与微控制器连接起来非常简单。PIR是一个数字输出,所以你所需要做的就是侦听引脚来变成高电平(有检测到)或低电平(未检测到)。

很可能你会想要重新开始,所以一定要把跳线连接到H接口!用5V电压连接传感器并将其接地。然后将输出连接到数字针上。在本例中,我们将使用2引脚。

14

代码很简单,基本上就是跟踪输入2的输入是高还是低。它还会跟踪大头针的状态,这样当运动开始和停止时它就会打印出一条信息。、

  1. /*
  2. * PIR sensor tester
  3. */
  4. int ledPin = 13; // choose the pin for the LED
  5. int inputPin = 2; // choose the input pin (for PIR sensor)
  6. int pirState = LOW; // we start, assuming no motion detected
  7. int val = 0; // variable for reading the pin status
  8. void setup() {
  9. pinMode(ledPin, OUTPUT); // declare LED as output
  10. pinMode(inputPin, INPUT); // declare sensor as input
  11. Serial.begin(9600);
  12. }
  13. void loop(){
  14. val = digitalRead(inputPin); // read input value
  15. if (val == HIGH) { // check if the input is HIGH
  16. digitalWrite(ledPin, HIGH); // turn LED ON
  17. if (pirState == LOW) {
  18. // we have just turned on
  19. Serial.println(“Motion detected!”);
  20. // We only want to print on the output change, not state
  21. pirState = HIGH;
  22. }
  23. } else {
  24. digitalWrite(ledPin, LOW); // turn LED OFF
  25. if (pirState == HIGH){
  26. // we have just turned of
  27. Serial.println(“Motion ended!”);
  28. // We only want to print on the output change, not state
  29. pirState = LOW;
  30. }
  31. }
  32. }

不要忘记有些时候你不需要一个微控制器。一个PIR传感器可以连接到一个继电器(也许是一个晶体管缓冲区),而无需微管

创建你需要的Frizting元件

什么是Fritzing?

Fritzing Logo

Fritzing是一个强大的开源工具让任何一个人用于教学,分享和模仿他们的电子项目! 它允许你设计原理图,因此设计一个部件,然后可以添加到非常专业的接线图。 你甚至可以设计自己的PCB,并从你设计的文件制造。 在SparkFun,我们在教室中使用Fritzing,我们的连接指南,以及任何其他地方,我们需要展示如何将我们的电路板连接到其他硬件。

Fritzing Hookup Example

一个利用Frizting将INA169连接到Arduino的例子

Fritzing的令人敬畏的事情是,你可以为你的项目制作自己的Fritzing零件,并在社区中分享! 本教程将从头开始一步步介绍如何在Fritzing(新)零件编辑器中创建自定义Fritzing零件,

你是否需要做一个自定义的Fritzing零件?

Fritzing在软件安装的时候就带有大量的电子元件。 SparkFun还有一个Fritzing Github库,用于我们在Fritzing中尚未创建的零件。 在创建自己的零件之前,请仔细检查我们的零件是否在自带的元件库或者Github上已经有,或者如果另一个Fritzing用户已经在Fritzing论坛上创建了你所需要的零件。 如果零件已经创建,它将为你节省大量时间! 但是,如果你确定你需要的零件在Frizting里面还没有,请继续阅读!

建议阅读

本教程假设你已经熟悉Adobe Illustrator,Inscape或两者。 使用这些程序超出了本教程的范围。 如果你需要更多的信息,如何使用这些程序的eithwer,他们各自的网站有很多教程和指南,如何开始矢量图形。 如果失败,总是有Google。

这里是其他相关的教程,你阅读这个教程前可能想查看:

下载和安装

你需要下载和安装Frizting软件,并跟着教程来制作你自己的Frizting零件

请注意:如果你只需要做一个基本的IC,Frizting(新)部件编辑器让你轻松制作自定义IC,你不需要下载矢量图形编辑器。但你仍然可以往下阅读,因为本教程将在Frizting(新)零件编辑器中构建一个自定义的IC。

Fritzing

Frizting官网(可能需要科学上网)的下载页面,为你的操作系统下载最新的Frizting版本,找到你要将Fritzing安装在硬盘驱动器上的位置,然后在该位置解压缩Fritzing文件夹。

矢量图形编辑器

有很多不同类型的矢量图形编辑器。我们在SparkFun使用的矢量图形编辑器是Adobe Illustrator和Inkscape。选择你最熟悉和用起来最舒服的。如果你没有一个矢量图形编辑器,Inkscape是一个强大的开源软件选择,并且它是免费的。

Inkscape

Inkscape Logo

Inkscape下载页面,并为你的计算机下载相应的正式发行包。

Windows用户:双击可执行文件。 按照Inkscape设置向导。

Mac OS X用户:按照Inkscape网站上的最新说明进行操作。

Adobe Illustrator

Adobe Illustrator Logo

Adobe Illustrator不是免费的,但如果你已经有Adobe Creative Cloud,你可以下载它。 你还可以购买Illustrator每月会员资格。

请注意:我们与Adobe没有任何关系,只是宣传Illustrator,因为它是一个强大的软件,对在本教程中很有帮助。

Other Downloads其它需要下载的东西

Fritzing字体和模板

Fritzing使用OCR-A字体作为IC使用。 对于所有其他零件,你可以使用OCR-A和Droid Sans fonts字体。 Fritzing具有可在其网站上下载的字体和模板。 你将需要下载Fritzing的图形标准来遵循本教程。 转到他们的模板下载页面,并下载Fritzing的图形标准文件夹。 下载其zip文件后,你需要解压zip文件夹,并放置在计算机上你将要在计算机上安装字体的位置。

SparkFun Fritzing示例模板

本教程将引用很多SparkFun Fritzing示例模板。 如果你正在为SparkFun板制作Fritzing零件或想要一个起点,请从SparkFun Fritzing零件Github库中下载这组示例模板。 SparkFun Fritzing模板将具有本教程的示例,SparkFun T5403气压计SVG,要比较和处理的文件。

面包板视图

当Fritzing启动时,你将会进入欢迎界面,并且你将要转到面包板视图。

breadboard view

在面包板视图中你需要做两个重要的步骤,首先,创建你的面包板SVG,然后上传。 Fritzing更倾向于使用SVG格式,所以你的图像看起来很棒,当你放大和缩小! 其次,你需要改变连接器针脚。

请注意:如果你只制作一个基本的IC,你可以跳到本教程的编辑面包板视图部分。

Fritzing图形标准

在Fritzing网站上,有很多图形标准要遵循。 这是一个很好规范,因为遵循图形标准,你的零件可以匹配其他Fritzing零件。

模板

当你制作零件时,建议从模板开始。 有一个要引用的零件的图像,因此,当制作你的SVG文件时,该过程会更快。

提示:如果你在为EAGLE中设计的板制作自定义Fritzing零件,则可以下载ULP将板转换为SVG格式。 这样,你可以有一个准确的SVG的EAGLE板作为参考。 你可以在Cadsoft网站上找到EAGLE ULP。

现在是时候为你的面包板视图制作你的图形!

 

创建新元件

在本教程中,我们将会为SparkFun T5403气压计创建一个Frizting新零件。

T5403 Breakout Image

SparkFun T5403的EAGLE图

打开Fritzing应用程序。 你应该在程序顶部看到欢迎,面包板,示意图和PCB的选项卡。 单击面包板按钮以确保你目前在面包板视图中。

Breadboard Button

检查库中自带元件

如果你只是在Fritzing中更新一个板,首先检查是否有一个与你想要创建的Fritzing部分相接近或相关的零件。你可以在搜索栏中键入零件的名称。

Search for Part

搜索栏可以在零件窗口的顶部找到

你也可以在Fritzing的零件窗口的不同部分查看类似的零件。

Parts Window

寻找SparkFun火焰并点击可以看到一个巨大的SparkFun Fritzing零件库

从绘制IC开始

如果没有一个零件像你想要的,使用IC作为基础是一个好的开始。 单击零件窗口中的CORE选项卡。 向下滚动,直到看到IC。 在ICs部分下,单击并拖动IC图标到Breadboard窗口。

Core Tab

自定义IC很简单,因为Fritzing可以改变引脚和IC封装的数量

Dragging IC on breadboard window

更改IC的名称

 

查看右侧的“查看栏”中IC的属性。 将IC的名称更改为元件名。 然后,更改引脚部分中模块或元件的引脚数。 对于SparkFun T5403气压计,我们需要8个引脚。 你将在“面包板”视图中看到模块中IC更改后的名称。

Changing name

Fritzing(新)元件编辑器

右键单击面包板窗口中的IC,然后选择编辑(新元件编辑器)。Fritzing(新)元件编辑器弹出。

Go to Parts Editor

Fritzing(新)零件编辑器有6个主要部分,你需要在其中进行更改。那些是:

  • 面包板
  • 示意图
  • PCB
  • 图标
  • 元数据
  • 连接器

真的没有你需要遵循的命令。在做了几个不同的自定义部件后,你可能会最终在一个视图开始之前的其他工作。在本教程中,我们只是去一个个讲述教程。

作者注释:我发现,对于具有大量引脚的板,从连接器视图开始的板可以节省更多的时间,因为你可以在列表中更快地命名连接器引脚。

在继续之前,最好先保存为新零件。如果你需要在制作自定义部件时随时停止,你可以在将来再次使用。转到文件。然后,选择另存为新零件

Save as new Part

如果需要,你可以选择命名前缀


让我们继续面包板视图!

自定义面包板SVG

创建文件

打开矢量图形编辑器并创建一个新文件。文件的图像大小应与你的开发板的大小相同。SparkFun T5403气压计爆破尺寸为1“x 0.650”。你将要使用一个好的命名约定保存文件,因为在创建Fritzing部分时最终需要3个不同的svg文件。

Illustrator用户: 你可以通过转到文件 – >另存为,保存为SVG,然后点击保存保存。

对于此示例,面包板SVG命名为:SFE_T5403_Barometer_Breakout_breadboard.svg

使用模板作为参考

要比较不同的图层和组,你可以打开Fritzing BreadboardViewGraphic_Template.svg文件,该文件位于先前下载的Fritzing Fonts and Template文件夹中。你还可以从SparkFun Fritzing Parts Github仓库打开示例SparkFun T5403晴雨表分线板SVG模板文件。

你可以看到示例模板如何保持图层的组织。对于SparkFun T5403气压计,有一个“面包板”组。在面包板组内,它将具有一组部件,铜层,丝印组和板路径。

制作你的自定义面包板图形的提示

你现在可以创建自定义零件的面包板图形。这里有一些有用的提示!

遵循Fritzing图形标准

Here are some main color standards for Breadboard images:

这里是面包板图像的一些主要颜色标准:

为了符合Fritzing图形标准,你将要使铜触点成为铜/镀锡颜色。

Copper Green

HEX: 9A916C, RGB: 154 145 108

如果你的板上有任何部件的引脚,使用的颜色是灰色的。

Leg Grey

HEX: 8C8C8C, RGB: 140 140 140

SparkFun红色是:HEX:E62C2E,RGB:230 44 46

把事情简单化

Fritzing的伟大之处在于,你可以使你的板子变得简单或你想要的结果。由于SparkFun总是试图使我们的产品更好的修订和有很多的板,更容易和更快的我们不包括某些细节,如痕迹或每个组件,在我们的板子上。如果电路板有新的变化,如电阻值的变化,我们不必在Fritzing部分进入和更改该电阻。更多地关注重要的组件,如IC,可能这是个更好的方式来投入你的时间。它仍然会看起来不错,但工作量少!

使用已经存在的组件

如果你需要在板上的使用已经在Fritzing有的SMD LED,请继续使用它!这将节省你的时间,并保持所有的Fritzing部分具有相同的标准。如果你创建一个自定义的板子,其他人可以使用的组件,你可以在Fritzing网站上分享,让其他人也可以使用!确保在你正在使用的矢量图形编辑器中组织好组件图形,因此在以后的的板子上使用时很容易找到这些部件。

铜组中的名称连接器引脚

Naming your connectors will be a huge time saver. For the SparkFun T5403 Barometer Breakout example, under the copper group, each connector is named connector#pad.

命名你的连接器将是一个巨大的节省时间。对于SparkFun T5403气压计示例,在铜组下,每个连接器命名为连接器#垫。

Copper Layers

示例在Illustrator中。如果你使用Inkscape,你仍然需要确保连接器已正确命名。

使用ORC-A或Droid Sans字体。

坚持Fritzing字体保持所有Fritzing部分看起来一样。建议标准字体大小为5pt。然而,有时候,你不会有空间更小的板。你最好不要低于3pt,因为它开始变得更难看到,而不放大。在Fritzing的网站,他们提到使用黑色作为字体颜色。无论你的丝印颜色往往看起来更好。对于这个例子,我们使用白色,因为这是分线板的丝印颜色,它更容易阅读红色背景。

创建复合路径以制作板开口

Illustrator用户:在PCB的大小中创建路径。对于SparkFun T5403气压计,你可以使用矩形工具制作1“x 0.650”的矩形。然后,在你的板子有开口的路径。例如,你可以使用椭圆形工具,在矩形工具下,制作完整的圆形,其中有支座和连接器针脚的开口。选择所有的开孔层和底部PCB层。

Select All

确保选择底部PCB层

接下来转到Object-> Compound Path-> Make。你现在应该有一个复合的路径,你将能够看到通过Fritzing的开口。

Final Breadboard Image

最终面包板图形

保存

确保在创建自定义板后再次另存为SVG!现在,你可以继续编辑面包板视图。

面包板视图 – 零件编辑器

加载图像

创建自定义面包板图像后,你将需要在Fritzing(新)零件编辑器中加载面包板SVG。首先,返回到Fritzing(新)零件编辑器,然后单击面包板按钮进入面包板视图。转到文件 – >加载图像的视图。

Load graphic

接下来,你将选择刚刚创建的面包板SVG,然后单击打开。图形现在应该在Fritzing(新)零件编辑器中。

连接器

在Fritzing应用程序中,你可以使用彩色线连接不同的Fritzing零件,以显示零件如何连接。为了使Fritzing知道板或部件上的连接器引脚,你需要告诉Fritzing这些连接器在哪里。

连接器引脚的名称和说明

对于面包板视图,连接器窗口将位于Fritzing(新)零件编辑器的右侧。选择一个引脚以更改引脚的名称并添加描述。

Select Pin

选择任何连接器针脚进行编辑

Change Connector Pin Name

选择连接器针脚的图形

单击连接器针脚名称右侧的选择图形按钮。然后,单击连接器针脚的图形。这将设置锚点。锚点是电线连接到该连接器的位置。默认情况下,终点将显示在所选图形的中间。如果要移动终点,你可以单击终点并按住以移动。你也可以通过在连接器窗口中单击“中心”,“W”,“N”,“S”或“E”来更改终端点。

Example Terminal Placement

你可以看到更改终端点时导线位置的差异

更改连接器类型

在“连接器”窗口中更改连接器的类型。你可以选择公头,母头或焊盘。对于SparkFun T5403气压计,所有连接器针脚都是母头。

Set Connector Type

在下图中,你可以看到将连接器类型设置为公头和母头之间的差异。

Different Connector Type

顶板的连接器类型设置为公头。底板的连接器类型正确设置为母头。

对所有连接器针脚重复此操作

名称,选择适当的图形,并更改所有连接器引脚的连接器类型。你还可以在“连接器”窗口中设置“内部连接”。

原理图

自定义原理图SVG

回到Illustrator,Inkscape或你正在使用的矢量图形编辑器。在下载的字体和模板文件夹中打开Fritzing的SchematicViewGraphic_Template.svg。你还可以从SparkFun Fritzing零件Github仓库打开示例SparkFun T5403气压计原理图SVG模板文件。

当编辑原理图以匹配电路板时,你需要确保显示每个连接器引脚。你将需要更改引脚标签以匹配连接器引脚名称。根据你的部件,你可能需要调整模板原理图的大小。确保主零件符号正方形和外销的边缘之间有0.1“的空间。

Schematic Example

确保删除0.1“维度帮助程序框,因此它不会显示在最终的Fritzing原理图图形中

保存SVG

你需要确保保存为一个新的SVG。记住要有一个命名约定,很容易说明为Fritzing部分创建的其他SVG文件之间的区别。

在零件编辑器中编辑原理图视图

加载SVG

返回零件编辑器,点击原理图按钮进入原理图视图。转到文件 – >加载图像的视图。接下来,你将选择刚刚创建的原理图SVG,然后单击打开。零件现在应该在Fritzing(新)零件编辑器中。

设置连接器引脚

如果你看看右侧的连接器窗口,你会注意到你的引脚名称已经存在。当你更改连接器引脚的名称和描述时,在面包板,原理图,PCB或连接器视图中,零件编辑器将自动更改其他视图的连接器引脚名称和描述。此外,连接器类型(公头,母头或焊盘)将仍然相同。

就像在面包板视图中所做的那样,你仍然需要为每个引脚选择一个图形。点击“选择图形”按钮,并为该引脚选择适当的图形。对于示意图视图,你将要更改终端点,因此连接线在最远点连接。

最简单的方法是确保连接器引脚的图形仍然被选中,并更改连接器窗口中的终端点。对于GND图形,通过单击“S”将终点移动到南端。

Terminal Point

对所有连接器重复此操作

在更新所有连接器针脚后,你可以继续在PCB视图中编辑。

PCB视图

制作自定义PCB SVG

回到Illustrator,Inkscape或你正在使用的矢量图形编辑器。当制作自定义PCB SVG时,你需要的主要图像组是铜(其将具有所有连接器焊盘)和丝印。

创建PCB图形

你可以在创建PCB SVG,修改自定义面包板SVG或在下载的字体和模板文件夹中编辑Fritzing的PCBViewGraphic_Template.svg时重新启动。对于此示例,修改了自定义面包板SVG,并将该文件另存为一个名为SFE_T5403_Barometer_Breakout_PCB.svg的新SVG。

确保有两个铜组

设置图层时,请确保有两个铜组。所有连接器层都应在铜组中。当你这样做时,Fritzing将知道该组件在PCB的两侧都有铜连接器。

Example of PCB Layers

有两个铜组的Illustrator示例

确保连接器引脚的间距准确

重要的是让PCB连接器引脚与你的电路板精确匹配,并在引脚之间留出适当的间距。Fritzing提供PCB Fab服务。如果你或其他Fritzing用户想要使用你的自定义部件使用该服务,你将需要确保你的PCB视图是准确的。

图形标准

代替连接器引脚是铜/镀锡绿色,PCB视图连接器引脚是“铜”颜色:

Copper Color

Hex: F7BD13 RGB: 247 189 19

自定义面包板SVG的主要变化是主要的组是铜和丝网印刷。丝网仍然是白色的。

Final PCB Graphic

最终PCB图形

在零件编辑器中编辑PCB视图

返回零件编辑器,点击PCB按钮进入PCB视图。转到文件 – >加载图像的视图。接下来,你将选择刚创建的PCB SVG,然后单击打开。零件现在应该在Fritzing(新)零件编辑器中。

更新连接器引脚

为每个连接器针脚选择适当的图形,就像在面包板和示意图视图中所做的那样。

图标视图

重复使用过去的图形

转到Fritzing(新)零件编辑器,然后单击图标按钮进入图标视图。关于Icon视图的一个伟大的事情是,你可以重用你的面包板,原理图或PCB SVG的图标图像,所以没有必要做一个新的图像!所有你需要做的是去文件,并选择你想要重用的图像。对于SparkFun T5403气压计,Icon视图重新使用面包板图像。面包板图像应显示。

Reuse Past Graphic

伟大的斯科特!你现在完成了图标视图!

元数据

转到元数据视图

转到零件编辑器,然后单击元数据按钮进入元数据视图。元数据是你将添加关于你的部件的所有重要信息的地方!

元数据视图中的不同部分

标题:很自然的。这将是你的部分的名称。

日期:在Fritzing中锁定日期条目。日期应显示你创建零件的日期。如果你稍后在道路上更新部件,日期将更改为上次更新的当前日期。

作者:你会想把你的名字在这里,所以,如果你与Fritzing社区分享你的一部分,他们知道谁是谁的部分。

说明:说明应包括对电路板重要的任何事项,例如工作电压。

标签:标签显示在示意图视图中,可以更容易地识别你选择的部件。对于SparkFun T5403气压计突破,标签将更改为零件。原因是,因为Part相当小,SparkFun T5403气压计名称已经在原理图图形本身。它取决于你想要标记你的部分!

URL:考虑张贴零件的网址,这样任何人都可以获得有关零件的更多信息。

家庭:如果你有一个部分有不同的颜色,芯片包等,你会希望他们在同一个家庭。例如,如果你有一个通孔LED有不同的颜色,同一个LED的所有不同的颜色将在同一个家庭。

变体:创建全新零件时,你要确保变体是1.当你以后进行修订时,如果变体2在同一系列中,则会将下一个修订版本更改为变体2。

属性:一个放置重要细节(如零件号,针脚间距等)的地方。

标签:使用可以找到更容易和最好描述你的部分尽可能少的单词的标签。

Metadata

觉得信息有点缺乏?你可以稍后再更新此内容,当你掌握了更多信息

连接器视图

转到连接器视图

转到零件编辑器,然后单击连接器按钮进入连接器视图。在“连接器”视图中,你可以执行以下操作:

  • 更改连接器数量
  • 设置连接器类型
  • 将连接器针脚设置为通孔或SMD
  • 名称连接器引脚
  • 添加连接器引脚描述

Connectors view

你不需要更改“连接器”视图中的任何内容,因为你已经填写了其他视图中的所有信息。如果你需要做任何最后一分钟的变化,现在你可以。请记住,如果你更改此处的连接器数量,则需要返回并更新面包板,原理图和PCB视图。

保存

 

现在你可以保存你的部分!转到文件>保存

继续导出部件!

导出新零件

Fritzing应用程序中的质量检查

现在是时候在主Fritzing应用程序中检出你的新Fritzing部分。当你在Fritzing(新)零件编辑器中保存为新零件时,零件将自动显示在Fritzing主应用程序中的MINE选项卡的My Parts标签下。

在导出新的自定义零件之前,你需要检查每个视图是否看起来不错。确保你在主Fritzing应用程序,而不是Fritzing(新)零件编辑器。通过单击顶部的面包板按钮,转到面包板视图。在零件窗口中,在右侧,确保你在MINE选项卡。你应该看到你的新部分。在面包板视图上单击并拖动板。

MINE Tab

仔细检查引脚是否命名正确,并且工作正常。在原理图和PCB视图中执行相同操作。一旦进行了质量检查,就可以导出零件。

导出零件

右键单击我的零件窗口中新零件的图标,然后选择导出零件。保存你的Fritzing部分。

Export Part

恭喜你,你做了自己的Fritzing零件!

更多信息和资源

贡献Fritzing

现在你已经完成了你的任务,你可以连接其他Fritzing零件。你可以在Fritzing网站上分享你的部分或项目教程。还有更多的方法来帮助Fritzing社区!查看Fritzing Support Us页面,了解更多支持Fritzing的方法。

大批量的Fritzing零件?

如果你是使用EAGLE的开发人员或投入大量时间来制作Fritzing零件的开发人员,Fritzing团队已经开放了一个工具包,从EAGLE .brd文件制作SVG文件。强烈建议你检查是否正在创建批处理的SVG板文件准备Fritzing。他们在Fritzing Google代码页上有源代码


cc

原始文章采用CC BY-SA 4.0,您可以自由地:

  • 演绎 — 修改、转换或以本作品为基础进行创作
  • 在任何用途下,甚至商业目的。
  • 只要你遵守许可协议条款,许可人就无法收回你的这些权利。

本文由翻译美国开源硬件厂商Sparkfun(火花快乐)的相关教程翻译,原始教程采用同样的CC BY-SA 4.0协议,为便于理解和方便读者学习使用,部分内容为适应国内使用场景稍有删改或整合,这些行为都是协议允许并鼓励的。

原始文章及相关素材链接:

https://learn.sparkfun.com/tutorials/make-your-own-fritzing-parts

串行外围设备接口(SPI)

简介

串行外围设备接口 (SPI) 是一种总线系统,一般用在MCU与小型外设之间,使他们以串行通信。外围设备包括位移寄存器、 传感器和SD卡等。 它一般使用分别独立的时钟线、数据线以及从机通信选择线。

普通串行端口有什么问题?

一般只含RX(接收)线和TX(传送)线的串行端口,我们会称它作异步串口。因为该类串口无法很精确地保证数据在通讯两端实现同步传收。这是由于计算机系统的一切操作都由标准时间源信号驱动(计算机的晶振源),则如果两个系统的标准时间系统由稍微偏差,它们之间的通讯就会出问题。

为了解决这个问题,异步串口通讯系统在每一帧数据里额外增加了起始位和结束位,以保证接收端对每一帧的数据完整接收。另外,在通信两端,都必须设同样的通讯速率(如9600波特率)。起始位和结束为的设定下,保证了即使帧与帧之间的时间间隔有稍微不一,也能实现正常通讯。

Asynchronous serial waveform

(另外,如上图所示,所发送的“11001010” 实际上不等于0x53,因为在串口通讯中一般会首先从数据的最低位开始发送,因此最左端的实际是数据的最低位。所以低半字节实际是0011 = 0x3,高半字节是0101 = 0x5。)

异步通讯纵然好,但它在每帧数据的起始位与结束位上浪费太多信息空间,并且对通讯端的硬件要求较高。另外,当你发现在你的项目中,通讯端之间的传输速率不一,那么传输的数据必然会严重失真。这是因为异步通信里,接收端只能在特定的时间点里对数据线进行采样(如上图虚线处)。否则,接收端会采集到错误的数据。

一个同步的解决方案

SPI 的工作原理有一点不同。它是一种“同步”的数据总线系统,这意味着它额外的增加了一个通讯线共享时钟源,以实现传输同步。这时钟源是一种震荡信号,用来告知接收端对数据线的正确采样时间点。这有可能是时钟信号的上升沿(电平由低到高)或下降沿(电平由高到低);这可以在硬件的数据手册查询。接收端一检测到时钟线的电平变化,就会对数据线进行采样一,以获得一位新的数据(如下图虚线处)。由于每一位数对应着据时钟越变信号,数据就不需要用很精准的速率传输,不过传输端还是会以最高速传输。(我们接着会讨论选择适合的时钟沿以及传输每一位数据的速度。)

alt text

SPI这么受欢迎的原因之一是它对接收端的硬件要求不高,一个位移寄存器就能实现接收。它比使用UART(全双工异步串口通信端)的硬件更简单和便宜。

如何接收数据

你可能会想,这听起来这么棒的通信系统是怎样把数据发送到另一端的呢?这原理就稍微有点复杂。

在SPI,只有一个端口发生时钟源信号(时钟源端一般简写为CLK、SCK),发送时间源信号的硬件叫主机,另一端则叫从机。在一个SPI通信系统里,只有一个主机(一般是MCU),从机则会有多个。

当数据从主机传到从机时,该数据传输线称MOSI(“Master Out / Slave In”),从机传发送数据到主机由另外一条数据线负责,叫MISO(“Master In / Slave Out”),以上两个过程中,主机产生时钟脉冲信号,对应每一位的数据传输,从机则按照时钟脉冲信号,把每一位数据按次序存储或输出。

alt text

由于主机一直操控时钟线,因此它会预先知道从机将会返回多少位数据。以上特点与异步串口通信很不一样,它的接收端接收来自发送端的数据时间上是相对随机的。在SPI通讯中,信息是以特殊的数据格式和协议来传输。例如,MCU对传感器发出“读数据”的指令,传感器一般会按通信协议返回两位字节数据。(如果,你想要一个完整原始的数据,你可以先让传感器先返回一或两个字节声明该原始数据的长度,然后再传输原始数据。)

注意SPI是“全双工”总线系统(拥有分别独立的发送线和接收线)因此,在实际情况下,你可以同时实现数据的发送和接收(例如,实现发送要求对一个传感器读数据的命令,同时接收另外一个传感器回传的数据)。硬件的数据手册会告诉你这是可行的。

从机通讯选择 (SS)

这是SPI总线系统里最后一个你需要关注的线,它叫SS(Slave Select)。这根线是用来激活主机所需通讯的从机。

alt text

SS在空闲时为高电平,即断开从机与主机之间的SPI通讯。(即所说的低电平有效断你会经常在能使断看到类似的应用。)在数据传输之前,要拉低所需通讯从机的SS端。当你不与该从机通讯,则将它的SS端拉高。这相当于一个位移寄存器里的锁存端。

多从机工作

要是有两个或以上从机连在同一根SPI总线系统上:

  1. 一般来说每一个从机都要独立分配一个SS线I。当要与指定的从机通讯时,你将对应的SS端拉低,其它从机的则保持高电平(你不会想同时让两个从机被激活,否则这两个从机就会同时在MISO端与主机通讯,造成数据的相互干扰失真)。每一个从机对应一条独立的SS线。如果你的主机输出口不够,可以用译码器扩展。alt text
  2. 在另一方面,若是要环形传输数据,一个从机的MISO连到下一个从机的MOSI。则要把所有的从机激活通讯。只要数据传输完成,就要把对应的SS端拉高,以防多个从机同时激活。这类结构经常用在位移寄存器和可寻址LED硬件里。

 

 

alt text

注意在这设计里,当数据流从一个从机到另一个,至到任意一个,你将需要传输足够多的数据来推动这个数据流。同样,要注意你传出去的第一分数据是留给最后一个从机的。

这类型的设计通常用在单一输出的情况下,就如LED模块,工作时它并不会返回任何的数据。这样情况你便可以省去MISO端。另外,要是有数据返回,你可以选择环形总线结构来返回数据(上图蓝线所示)如果你选择这类结构。当你接收端来自从机1的数据时,则说明它的数据已经流过所有的从机。所以,为了接收到你所需的数据,你要传输足够多的接收命令。

SPI的程序

许多的MCU已经内置了SPI的硬设,来应对所需高速传输数据的所有要求。而且,对你们来说,按SPI的通讯协议配置相应的I/O口去传输数据是十分简单的。(一个很好的例子在维基百科的SPI。)

如果你想在一个Arduino实现SPI与其他硬件通讯,这有两种方法:

  1. 你可以用shiftIn()shiftOut() 指令。这是基于软件的指令,你可以用任何的引脚作为输出,但这样传输速度会比较慢。
  2. 或者你可以用SPI Library,是集成到MCU的SPI模块。它比指令方法快多了,但它只能按特定的引脚输出。

在通讯之前,你要设置一些相关选项。这些设置必须要和你所通讯的外设相匹配;查阅它们的资料手册,看通讯时需要什么配置要求。

  • 在通讯时可以先发送最高有效位(MSB)或最低有效位(LSB)。在Arduino的SPI库里,这由 setBitOrder() 函数控制。
  • 从机会在时钟脉冲信号上升沿或下降沿读取数据。另外,要注意时钟线在空闲时时高电平还是低电平。在Arduino的SPI库里,这由 setDataMode() 函数控制。
  • SPI可以高速传输数据(几兆每秒),这对于一些外设来说太快了。为了适应这些设备,你可以调节传输速度。在Arduino的SPI库里,这由setClockDivider() 函数来实现,它会将主机的输出时钟频率(对于大多Ardunio是16MHz)分频(8MHz (/2)到125kHz (/128)之间。
  • 如果你用SPI库,你只能用它所指定提供的SCK, MOSI and MISO 引脚。另外,还有一条指定的SS端(对于SPI硬件模块来说,必须至少有一根SS端),不过你也要分配其他的端口作SS端,分别控制每一个从机。
  • 在旧版的Arduino,你需要额外写程序控制相应SS端,让其在通讯前拉低,在通讯结束时拉高。在新版的Ardunio,如Due 可以自动控制每一个SS端,详情见 Due SPI documentation page

更多相关资源

提示和技巧由于

  • 由于SPI传输的是高速信号,它只能进行短距离通讯(仅几英尺)。如果你要远距离通讯,则要降低时钟脉冲频率,并加专用的驱动芯片
  • 如果SPI的传输情况不符合你的预期设想,用逻辑分析仪去排误是一个不错的选择。智能分析仪如Saleae USB Logic Analyzer,可以译码并显示和记录所测量的数据。

alt text

SPI的优点:

  • 它比异步串口通讯要快
  • 就收器的硬件要求较低,如位移寄存器er
  • 支持多从机通讯

 SPI的缺点:

  • 相比其他通讯方案,它需要的信号线较多I
  • 要制定通讯协议(你不可以随意发一堆数据)T
  • 只能有主机控制所有的通讯(从机之间不能直接通讯)
  • 它需要额外分配SS线对应每一个从机,如果多众多从机,这将是个大问题。

扩展阅读

查阅  SPI的维基百科, 那有很多关于SPI的信息以及一些同步串口通讯的资料。

这篇博客 展现了更多关于基于嵌入式硬件建立SPI通讯的正确方法,示例是用 Arduino

许多SparkFunA的产品支持SPI通讯。如 Bar Graph Breakout kit

其他通讯方案:

现在你是SPI的支持者之一了,以下有一些其他教程来练习你的新技能:

 


cc

原始文章采用CC BY-SA 4.0,您可以自由地:

  • 演绎 — 修改、转换或以本作品为基础进行创作
  • 在任何用途下,甚至商业目的。
  • 只要你遵守许可协议条款,许可人就无法收回你的这些权利。

本文由翻译美国开源硬件厂商Sparkfun(火花快乐)的相关教程翻译,原始教程采用同样的CC BY-SA 4.0协议,为便于理解和方便读者学习使用,部分内容为适应国内使用场景稍有删改或整合,这些行为都是协议允许并鼓励的。

原始文章及相关素材链接:

https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi?_ga=1.36860256.1133118399.1488205103

串联和并联电路

串联电路和并联电路

简单的电路(只有几个元件)通常很适合让新手入门。但是,当有新的元件加进来时,事情就不那么简单了。电流是怎么流动的?电压在干什么?可以将这些简化而令人更容易明白吗?恐怕不能。

在这片文章,我们首先会讨论串联电路和并联电路,电路中只有最基础的元件——电阻和电池——来呈现两种电路的不同之处。当你将不同的元件(比如电容器和电感器)结合在串联或并联电路中时,我们会探索一下串联或并联不同的结果。

本文章的内容

  • 串联电路和并联电路是什么样子的?
  • 在两种电路中,元件会如何运作。
  • 在两种电路中,电源电压会对耗能元件有什么影响。

建议阅读

在继续阅读本教程前,建议你阅读以下文章:

串联电路

节点和电流

在我们深入学习本章节之前,我们要提一下什么是节点。这并不是什么有趣的东西,就是连接的两个元件之间的线路。

Node example schematic

四种不同颜色的节点

了解这个,我们学习串并联电路的不同之处就完成一半了。我们还要理解电流是怎么流过电路的。电流从电压高的地方流向电压低的地方。电流会找尽办法流向电压最低的地方(也就是地端)。以上面的电路作为一个例子,这里表明了电流如何从电源正极流向电源负极:

Example of current flow through circuit

电流(用蓝色,橙色,粉色的线表示)在电路中流动。不同的电流用不同的颜色表示。

注意有些节点(就像R1和R2之间的)的电流在进来和出去后都是一样的。在其他节点(特别是R2,R3,R4这三路)干路电流被分成不同的两部分。这就是串并联电路不同的关键。

串联电路的定义

如果两个元件在同一线路上,并且流经它们的电流是同一路电流,那么就说这两个元件串联。这里是三个串联电阻的电路:

Schematic: Three resistors in series

在此电路中,电流只能有一条路线。从电源正极开始,电流首先流过R1。然后直接流过R2,然后R3,最终回到电源的负极。这里只有一条路径让电路流过。这些元件是串联的。

并联电路

并联电路的定义

如果元件之间有不同的节点,它们就是并联的。这里是三个并联电阻的例子:

Schematic: Three resistors in parallel

电流中电源正极出发,然后分别流过R1,R2和R3。将R1和电源连起来的节点也和其他电阻相连。其它电阻也类似地连接在一起。并最终和电源负极相连。这种情况下的电阻的就是并联。

串联电路中的电流处处相等,并联电路中的元件两端的电压相等。

串联和并联同时工作

以下是串联和并联共存的电路。电流从电源正极出来,首先经过R1,然后被分流,经支线流过R2和R3,最后又回到干线上,最终流回电源负极。

Schematic: Series and Parallel Resistors

在这个例子里,R2和R3并联,R1和R2,R3组成的并联电路串联。

计算串联电路中的等效电阻

这里有一些对你来说特别有用的信息。当我们在串联或并联电路中这样放置电阻,我们可以改变流过它们的电流的大小。例如,如果我们有一个10V的电源,一个10kΩ的电阻。依据欧姆定律我们得到1mA的电流。

Schematic: Single Resistor in series with battery

如果在电流中在加一个10kΩ的电阻,还是原来的电源,我们就使电流减少了一半,因为电阻变成原来的两倍了。

Schematic: Two series resistors in series with a battery

换一句话,我们的电路只有一条路径可以让电流流过,我们只不过是使电流流通的条件变得更艰难了。有多艰难呢?10kΩ+10kΩ=20kΩ。这就是我们计算串联电路电阻的方法——直接将它们相加

为了让这个方程更直观:电阻的数量是N——N是任意的值——电阻总值就是每一电阻相加。

Schematic snippet: N resistors in series

Equation: Rtot = R1+R2+...+R(N-1)+RN

计算并联电路中的等效电阻

串联电路中的电阻是怎样的呢?这回稍微复杂一点,但不会太多。回顾一下我们刚才10V电源和10kΩ电阻的例子,这一次我们增加一个10kΩ的电阻和原来的电阻并联。现在电流有两条路径可以走了。因为电压是不变的,在欧姆定律中,第一个电阻的电流仍然是1mA,那么同样的第二只电阻的电流也是1mA,我们就可以得到干路中的电流是2mA。这意味我们使电路中的电阻减半了。

Schematic: Two parallel resistors in parallel with a battery

我们可以很简便得得出10kΩ||10kΩ=5kΩ(||代表并联),但是电阻中不会只有两个电阻的。遇到更多的电阻怎么办呢?

求任意数量并联电阻总阻值的公式是:

1/Rtot = 1/R1 + 1/R2 + ... + 1/R(N-1) + 1/RN

If reciprocals aren’t your thing, we can also use a method called “product over sum” 如果你不喜欢倒数,我们还有一个方法——积除以和,当然是只有两个电阻的时候可以用这个公式:

R1||R2 = R1*R2/(R1+R2)

通过计算R1||R2的总电阻,我们可以将这条方程扩展到多个电阻的情况。但是用倒数相加的方法可能效率更高。

实验时间——第一部分

你需要的器材:

我们做一个简单的实验以验证我们对于串并联电路的理论。

首先,我们将几个10kΩ的电阻串联起来。参照下图,在面包板插一个10kΩ的电阻,并用万用表测量阻值。是的,我们已经知道之前电阻的阻值是10kΩ,但是确保严谨我们还是要测量一下电阻。当我们看到电表的指针稳定下来后,将另一个电阻接在面包板上,并确保和第一个电阻电气相连,然后用万用表测量两个电阻的总阻值。万用表的值大约是20kΩ。

你可能注意到你测量的电阻的阻值和你预想的值并不完全一样。电阻的实际阻值是有一个误差范围的,会与标明的阻值误差几个百分点。因此你可能读到9.99kΩ或10.1kΩ。只要这个读数和正确的数值接近就好,一切都会顺利工作。

Multimeter Fritzing Diagram

Experiment Time – Part 2

现在我们来处理并联电路的情况。如下图左下角那样安置两个电阻,确保它们的引脚是电气相连的。在用万用表测量它们的总阻值之前,你可以先计算一下它们的总阻值(提示:结果是5kΩ)。如果你测到的是接近5kΩ的值,这是好的。如果不是,检查一下连接有没有问题。

Experiment: Measure parallel resistors with a multimeter

分别用3个、4个、5个电阻重复实验。测量到的值分别是3.3kΩ,2.5kΩ和2kΩ。一切事情都按照计划进行吗?如果不是,检查一下连接是否出错。

串、并联电路电阻第一规则

有许多情况需要我们连接多个电阻。例如,你可能想要建立一个特殊的参考电压,你一定需要一系列的电阻,而且这些电阻的值也会比较特殊。既然我们电阻的阻值精度够高,我们就可以用多个不同阻值的电阻组合成我们需要的阻值。

提示1:并联电路中的等价电阻。

并联电路中的N个阻值(R)相同的电阻,那么总的电阻就是R/N。比如说我们需要一个2.5kΩ的电阻,但我们只有10kΩ的电阻。将四个这样的电阻串联起来,我们就会得到2.5kΩ的电阻。

Four 10kΩ Resistors in parallel can be used to create a 2.5kΩ one!

贴士2:精确度(tolerance)

确定你需要的精确度。例如,如果你需要3.2kΩ的电阻,你可以并联3个10kΩ的电阻。你得到的是3.3kΩ的电阻,和你预想中的阻值误差了4%。但是,如果你需要误差小于4%,你可以测量那些“10kΩ”的电阻,挑选测量值小于10kΩ的电阻并联在一起,你就可以得到更接近3.2kΩ的阻值了。理论上,如果我们的10kΩ电阻误差不超过1%,我们只能得到3.3kΩ的阻值。但是一些成品误差会大一些,需要我们耐心点找它出来。

贴士3:串、并联电路的功率

串、并联电路中的电路同样会有功率。比如说有一个100Ω,功率是2W,但我们只有1kΩ,0.25W电阻。你可以将十个1kΩ的电阻并联起来得到100Ω的阻值,总功率是10*0.25W,也就是2.5W。

但我们并联阻值不相同的电阻时,我们要更小心地处理总电压和总功率的值。

贴士4:并串联电路中的不同电阻

并联电路的总阻值一定会小于阻值最小那个电阻。

贴士5:并联电路中能量的损耗。

如果并联电路中的电压值不相同,那么支路中的电能损耗是不一样的,因为电流并不相同。用前面的例子(1kΩ||10kΩ),我们会发现1kΩ电阻的电流是10kΩ电阻电流的10倍。欧姆定律告诉我们功率=电压*电流,就可以推导出1kΩ电阻电功率是10kΩ电阻电功率的10倍。

最后,当我们处理电阻值不同的并联电路时,我们要时常想起贴士4贴士5.如果电阻值是相同的,贴士1和贴士3就变得很好用了。

串联电路和并联电路中的电容

将电容联合起来就像将电阻联合起来……只不过结果刚好相反。为什么会这样呢?

电容器是两块分开但是间隔非常近的导体板,它的主要功能是容纳一定量的电荷。电容器的容值越大,它越能容纳更多的电荷。如果增加导体的面积,电容值会变大,因为容纳电荷的物理面积变大了。如果导体板的距离变大了,电容值就会减小,因为距离使它们之间的场强减弱了。

我们将两个10uF的电容串联在一起,并假设它们都充满电了并准备放电。

Capacitors in series

记住在串联电路中电流只有一条路可以走。也就是说在下面的电容放出的电量和在顶部放出的电量是相等的。因此电容器的总容量并没有增加。

事实上,情况会更糟糕。通过串联电容器,我们只不过是将导体板隔离得更远了。我们得到的不是20uF,或者甚至是10uF。而只是5uF。这个结论的得出和我们计算并联电路的电阻一样,同样都是用“乘除以积”的方法。

Capacitors in series schematic/equation

这看起来似乎没有串联电容的用武之地。但是应该指出,我们得到的是多倍的电压。就像电池一样,我们将电容器串联起来就使电压增加了。

并联电路中的电容相加就像将串联电路中的电阻相加:直接将各部分的值加起来就可以了。为什么是这样呢?将电容器并联起来就像将电容器导体板的面积增加了。更大的面积意味着更大的电容。

Capacitors in parallel schematic/equation

实验时间——第三部分

你会需要:

让我们看看实际中一些串联和并联的电容器。这一部分比电阻那一部分稍微麻烦一点,因为电容器的容量不能直接用万用表测量出来。

让我们首先看看从0开始慢慢增加电容器两端的电压会怎样。如果电容器的电阻为0,电流就会很大。电容器会一直放电,直达它的电压和供应电压相等。

如果电容器的电阻为零,那么放电的速度非常快,电流很大,而充电的速度也会很快(微秒级甚至更少)。在这个实验中,我们想看看一个电容器是怎样充满电的。我们将使用一个10kΩ的电阻,将充电的速度减慢下来,使我们能够比较容易的观察现象。但是首先我们要谈谈什么是RC时间常量。

Tau = R*C

上面的公式是是说一个时间常量的长度(单位:秒)等于电阻(单位:欧姆)乘以电容(单位:法拉)。简单吗?我们将在下一页阐释这个公式。

实验时间——第三部分(继续……)

在本实验的第一部分,我们会用10kΩ的电阻和一个100uF(即0.0001F)的电容.这两者相乘得出一秒的时间常量:

Tau = 10kOhm * 100uF = 1 second

通过一个10kΩ的电阻为100uF的电容器充电,我们可以预测在一个时间常量内(也就是1秒),电容器的电压上升到了供应电压的63%。在5个时间常量后,电容器的电压是供应电压的99%,这是符合以下的曲线的:

Capacitor charge time graph

既然我们已经知道这个规律,我们将要将电路是图案联系起来(请确保不要搞错电容器的两极。)

Fritzing diagram, power off, cap in series with resistor, battery

用万用表测电池包的输出电压。输出电压测量值应该在4.5V附近(如果是新
电池,电压会稍微大一点)。现在连接电路,要注意在和面包板连接前把电
源开关打到OFF位置。同时,红线和黑线不要接错了。你可以用鳄鱼夹将被
测电容和万用表探头连接起来(你可以将线头拉长一点,使连接变得容易)

只要我们对电路的连接满意了,就可以将电池包的开关打到ON。在五秒钟后
,万用表的读数应该和电源的电压接近,这意味着公式是正确的。现在把开
关关了。万用表的读数并没有变化。这是因为电流已经无路可走了,电容器
不会放电,这是一种开路的情况。为了给电容器放电,你可以用10kΩ的电阻
与之并联。在5秒后,电表读数将接近0。

实验时间——第三部分(再继续……)

在本实验的第一部分,我们会用10kΩ的电阻和一个100uF(即0.0001F)的电容.这两者相乘得出一秒的时间常量

C = 100uF*100uF/(100uF+100uF) = 50uF

时间常量会是怎样的呢?

Tau = 0.5 seconds

Experiment 3.2 fritzing diagram

记住这些结果,增加一个电容器,与第一个串联(如上图),确保电表的值
是0V。将滑动开关滑到“ON”。电压表的读数从0变成电源电压值是不是用了原
来一半稍微多的时间呢?这是因为电容器比原来多了一
倍。总的电容值变小了,所以将它充满电需要更少的时间。我们建议用第三
个电容器来证明这一点。

现在我们尝试并联电容器,记住我们说过这就像将电阻串联。于是我们得到
的总容量就是200uF。时间常量就变成:

Tau = 2 seconds

这就意味着如果我们用4.5V的电压给电容器充电,我们大约需要10秒。

Frizing diagram: caps in parallel

为了证明这一点,我们用原先10kΩ和100uF串联的电路,并在这实验中参考
第一个实验那张图。我们已经知道充满电容器需要5秒。现在增加第二个电
容器与之并联。请确保电表的读数是0V(如果不是,就用一个10kΩ的电容器
放电),然后将电池开关打到“ON”。充电时间会久一点,不是吗?我们将电
容器的容量扩大了,当然需要更多时间将它充满电。你可以自己证明它,用
第三个100uF的电容器,并观察它充电的时间。

串联和并联电感器

串联和并联电感器

在电路中串联电感器的情况是很罕见的,但并非没有听说过。我们可以这样
做完成特殊任务。

简而言之,它们就像电阻那样,就是说如果串联,它们的值简单相加,如果
并联,就用“乘积除以和”的值。棘手的部分是,如果它们靠得太近,就会或
多或少产生互相干扰的磁场。为此,只用一个电感比用两个或更多要好,
虽然大部分电感器都包装成可以阻碍磁场。

在任何情况下,说它们像电阻那 样增加是恰当的。关于电感器的更多内容超出了本教程的范围。

资源与深入学习

现在你已经熟悉了串并联电路,为什么不搜索一下这些文章呢?

  • Voltage Dividers (电压驱动器)- 最基础的一种循环电路就是电压驱动器。这是一个建立在本教 程概念之上的电路。
  • What is an Arduino?(什么是Arduino?) -现在你肚子里已经有了电路的基础知识,你可以直接学习 最受欢迎的一种微控制器开发平台:Arduino
  • Switch Basics(开关基础) – 我们在本教程里已经谈论了一些电路基础知识,但还不包括这一 种。开关是每种电路都必需包含的部件。在这篇教程里学习关开关的所有 内容吧。
  • Sewing with Conductive Thread(缝合导电线) – 电路不是只有能在面包上拉电线. E纺织品使用导电线将电灯 缝如衣服或其他纺织物。

    cc

    原始文章采用CC BY-SA 4.0,您可以自由地:

    • 演绎 — 修改、转换或以本作品为基础进行创作
    • 在任何用途下,甚至商业目的。
    • 只要你遵守许可协议条款,许可人就无法收回你的这些权利。

    本文由翻译美国开源硬件厂商Sparkfun(火花快乐)的相关教程翻译,原始教程采用同样的CC BY-SA 4.0协议,为便于理解和方便读者学习使用,部分内容为适应国内使用场景稍有删改或整合,这些行为都是协议允许并鼓励的。

    原始文章及相关素材链接:

    https://www.sparkfun.com/search/results?term=DC+AC

电阻

简介

电阻是最常见的电路元件。在每个电路中它们是至关重要的一部分。在我们喜爱的欧姆定律中,电阻是主角。

resistors

在电阻这一部分,我们涉及以下内容:

  • 什么是电阻?
  • 电阻的单位
  • 电阻的符号
  • 串联、并联电路中的电阻
  • 电阻的不同种类
  • 解读颜色编码
  • 解读表面安装式电阻
  • 电阻应用举例

相关阅读

本文章中一些概念是建立在重要的电学知识上的。在继续阅读本文章之前,建议阅读(起码要浏览)以下文章:


电阻基础

电阻是拥有电抵抗力的电路元件。电阻能够限制流过电路中的电流。

它们是消极的元件,因为它们只能消耗能量(不能产生)。电阻通常在运算放大器、位控制器和其他集成电路中充当活跃的一部分。通常电阻被用来限流、分压上拉IO口

电阻单位

电阻抵抗电流的能力用欧姆来表示。欧姆的符号是希腊字母Ω。1Ω的定义是电阻两端的电压为1V时,流过电阻的电流是1A的阻值。

电阻抵抗电流的能力用欧姆来表示。欧姆的符号是希腊字母Ω。1Ω的定义是电阻两端的电压为1V时,流过电阻的电流是1A的阻值。
SI单位制中,更大或更小的欧姆值可以加上前缀千、兆、吉,这样使比较大的值更容易阅读。像千欧(KΩ)和兆欧(MΩ)是非常常见的电阻单位,百万欧(mΩ)是比较少见的单位。例如,4700Ω和4.7KΩ是相等的,5600000Ω可以写成5600KΩ或5.6MΩ。

符号

所有电阻都是有两极的,电阻的两端都要连接在电路中。电阻的符号有以下两种形式:

Resistor schematic symbols

两种常见的电阻符号。R1是美国式的1KΩ电阻,R2是国际式的47KΩ电阻。

电阻的两端是波浪线(或矩形)伸展出来的线。这两端要和电路的其余部分相连。

电阻的符号通常会由阻值和名字强调出来。以欧姆为单位的阻值,对于估测并实际建造电路是至关重要的。电阻的名字通常由字母R和紧跟着的数字组成。电路中每一个电阻的名字都必须独一无二。举个例子,这里是555定时器电路中的一些电阻:

Example schematic with resistors - a 555 timer

在这个电路中,电阻扮演了设置555定时器输出频率的重要角色。另一个电阻(R3)限制了流过LED的电流大小。


电阻类型

电阻有各种各样的形状和大小。它们可能是穿孔安装或表面安装。穿孔安装通常被缩写成PTH(plated through-hole),表面安装通常被缩写成SMD/SMT(surface-mount technology or device)。

终端和安装

PTH电阻具有长而柔软的引脚,可以插进面包板或手工焊接到测试板或PCB板上。有时候你不想焊接又薄又小的SMD电阻,这些PTH电阻对于使用面包板或其他测试板就显得特别有用了。PTH电阻的引脚又细又长,这就意味着它们比起SMD电阻要更多存储空间。比较普遍的PTH电阻采用轴式包装。电阻的大小和它的功率相关。一个常见的0.5瓦特的电阻长9.2mm,而0.25的电阻长6.3mm。

1/4 and 1/2 watt resistors

一个0.5瓦特的电阻(上)和0.25瓦特的电阻(下)

SMT电阻外形是薄而黑的矩形,两端是更小的铮亮的银色导体边缘。这些电阻一般被安装在PCB板的顶部,与其他元件焊接在一起。因为这些电阻太小了,通常要用机器把它们放在热箱里进行熔焊,并固定在特定的地方。

SMD resistor on a quarter

一个0603外形的330Ω电阻

SMD电阻有标准的大小:通常是0805(0.8mm长,0.5mm宽),0603或0402.它们有利于生产大量的电路板,而且特别节省空间。虽然它们在焊接时需要熟练而精确的焊接技术。

电阻的组成

电阻可以是各种各样的材料。最普遍流行的电阻通常用碳、金属或金属氧化物制成。在这些电阻里,一个薄薄的导体片被绝缘材料弯弯曲曲地包裹着。大多数穿孔式安装的电阻是由碳片或金属片组成的。

Peeled away view of carbon-film resistors

看一看碳片电阻的内容。电阻的阻值(从上到下):27Ω,330Ω,3.3MΩ。在电阻里其他PTH电阻会用超薄的金属片制造。这些电阻通常贵一些。一些高端产品,例如大范围的温度计会选择使用这些电阻。

SMT电阻既有薄的也有厚的。厚的一类通常便宜些但阻值没有薄的那么精确。在两种电阻类型中,一片小小的具有阻值的金属合金被夹在陶瓷基架上,最外层由玻璃或环氧树脂覆盖,然后与两端的导体边连接。

电阻封装种类

电阻有许多特殊的封装类别。有些电阻由四到五个内置电阻排成阵列封装而成,外头引出每个电阻的引脚。在这些阵列的电阻可能共同使用同一个引脚,或者被设置成分压器。

Resistor Network

5个330Ω的电阻阵列,每个电阻的一端都连接在一起。
电阻的阻值不一定是恒定不变的。变阻器的电阻就是可变的,这是一种可以将阻值在一定范围内调整的电阻。和变阻器相似的有电位计。两个电阻在内部串联起来,中间的接头可以调节出适合分压器。这些可变电阻通常用于调节输入电压,比如音量旋钮。

A smattering of potentiometers

一些零散的电位计。


解读颜色带

虽然阻值并没有在电阻上直接标明,但是电阻会用标记来表示阻值。PTH电阻有颜色编码系统,SMD有自己的值标记系统。

解码颜色带

穿孔式安装的轴式电阻通常使用颜色带系统来表示阻值。大多数这类电阻组会有四条环带。

Resistors showing their stripes

前面两条带表示电阻值的两位最重要的数字。第三条带是数字的权重,使这两位数以十的倍数变化。

最后的环带表示电阻的阻值误差范围。误差范围表明了表明的阻值的浮动范围。没有一个电阻是完美的,不同的制作工艺使电阻有不同的精确度。例如,一个误差范围是5%的1KΩ电阻,它的实际阻值在0.95KΩ到1.05KΩ之间。

你怎样分辨那一条环带排在第一呢?最后要说的是,公差带通常很明显地与表示阻值的环带隔离,它通常是金色或银色的。

这里是一张颜色-阻值对应表:

颜色 数值 倍率 倍数 误差范围
黑色 0 100 1
褐色 1 101 10
红色 2 102 100
橙色 3 103 1,000
黄色 4 104 10000
绿色 5 105 100,000
蓝色 6 106 1,000,000
紫色 7 107 10,000,000
灰色 8 108 100,000,000
白色 9 109 1,000,000,000
金色 ±5%
银色 ±10%

这是一个有四条颜色带的4.7kΩ的电阻:

Close-up of a 4.7kOhm resistor

W在解读电阻的颜色带时,最好查阅一张颜色编码表。在前两条颜色带中,找到颜色对应的数字。4.7kΩ的有黄色和紫色的颜色带,分别对应数字4和7。第三条颜色带是红色的,表明47要乘十的二次方,也就是4700!

如果你尝试记住颜色编码表,口诀可能对你有帮助。这里有一个口诀,可以帮助你记住电阻阻值颜色编码。以下是好用的一个,将黑色和褐色的拼写区分开来了:

Big brown rabbits often yield great big vocal groans when gingerly snapped.”

如果你记得“ROY G.BIV”,去掉了靛青色(可怜的靛青色,总会被人遗忘)将黑色和褐色添加在前面,灰色、白色在后面,这就就是典型的彩虹颜色顺序。

颜色代码计算

如果你有一定的数学能力或拿着一部计算器,可以尝试计算一下

 

Band 1 Band 2 Band 3 Band 4
Value 1 (MSV) Value 2 Weight Tolerance

Resistance:

1,000 Ω ±5%

解读SMT电阻阻值

像0603或0805这样的SMT电阻,有它们独特的表示电阻的方式。这里有一些常见的表示阻值的方式。通常有三到四个符号——数字或字母,被打印在电阻上面。
如果你看到的三个符号都是数值,你很可能看到的是以E24方式标记的电阻。这种标记方法和PTH电阻的颜色编码法有几分类似。前两个数字代表了电阻最重要的两个基数,最后一个数字代表的十的次方数。

Examples of E-24 marked SMD resistors

在上面的例图中,电阻上标志着104,105,205,751和754.104标志100kΩ,105表示1MΩ,205表示2MΩ,751表示750Ω,754表示750kΩ。

另一种编码方式是E96,这是一种最隐晦的方式。E96有三个符号,包括在前面的两个数字和一个在后面的字母。前面的两个数字告诉你电阻值的三位数字,这张查阅表对应了并不那么明显的数字关系。

CODE VALUE CODE VALUE CODE VALUE CODE VALUE CODE VALUE CODE VALUE
01 100 17 147 33 215 49 316 65 464 81 681
02 102 18 150 34 221 50 324 66 475 82 698
03 105 19 154 35 226 51 332 67 487 83 715
04 107 20 158 36 232 52 340 68 499 84 732
05 110 21 162 37 237 53 348 69 511 85 750
06 113 22 165 38 243 54 357 70 523 86 768
07 115 23 169 39 249 55 365 71 536 87 787
08 118 24 174 40 255 56 374 72 549 88 806
09 121 25 178 41 261 57 383 73 562 89 825
10 124 26 182 42 267 58 392 74 576 90 845
11 127 27 187 43 274 59 402 75 590 91 866
12 130 28 191 44 280 60 412 76 604 92 887
13 133 29 196 45 287 61 422 77 619 93 909
14 137 30 200 46 294 62 432 78 634 94 931
15 140 31 205 47 301 63 442 79 649 95 953
16 143 32 210 48 309 64 453 80 665 96 976

后面的字母表示倍数关系,在这张表有匹配值

LETTER MULTIPLIER LETTER MULTIPLIER LETTER MULTIPLIER
Z 0.001 A 1 D 1000
Y or R 0.01 B or H 10 E 10000
X or S 0.1 C 100 F 100000

Resistors marked with E-96 codes

因此01C电阻就是10KΩ,01B就是1kΩ,01D就是100kΩ。这些比较容易计算,但其他就不一定了。85A是750Ω,30C实际上是20kΩ.


功率

电阻功率是一个比较隐藏的值。然而这个值是重要的,当我们选择电阻类型时更是如此。

功率是能量形式转换的速率,它的单位是瓦特(W)。例如一个电灯泡能将电能转换成光能。但是一个电阻只能将电能转换成热能。在电路中,热能不是一个友善的小伙伴。太多热量会导致冒烟,然后是火星,然后是火焰!

每一个电阻都有其最大功率。为了不让电阻变得太热,将电阻的实际功率限制在最大范围之内显得尤其重要。电阻的单位是瓦特,电阻的功率通常在0.125W到1W之间。功率大于1W的电阻通常是耗能电阻,它们的能力主要表现为消耗电能。

找到电阻的功率

一个电阻的功率通常可以根据包装外形大小来推断。标准的穿孔式电阻功率通常为0.25W或0.5W。一些耗能电阻会直接将功率值标在电阻上。

Some examples of power resistors

一个耗能电阻在爆炸之前能够消耗许多能量。从右上角到左下角,电阻的功率依次是:25W,5W和3W,阻值分别是2Ω,3Ω,0.1Ω和22Ω。比较小的耗能电阻通常用来感应电流。

表面安装型电阻的功率通常可以通过外形大小来判断。0420和0603的电阻通常是1/16W,0805是1/10W。

计算电阻的功率

功率通常表示成电压和电流的乘积。但是,通过应用欧姆定律,我们也可以用电阻的阻值来计算功率。如果我们知道经过过电阻的电流大小,我们可以这样计算功率

P=I^2*R

或者,我们知道电阻两端的电压值,我们可以这样计算功率:

P=V^2/R


串联、并联电路中的电阻

电阻总是在串联或并联电路中成群结队地出现。在混联电路中的电阻产生的总阻值可以用一个或两个公式计算出来。为了方便了解电阻的总阻值是如何组成的,你需要设计一些特殊的阻值。

串联电阻

串联电路中的电阻阻值之和是各部分电阻阻值的简单相加。

Schematic of resistors in series

Equation for adding resistors in series

串联电路中的N个电阻。总阻值是所有电阻阻值之和

举个例子:如果你想要12.33KΩ的电阻,找到12kΩ和330Ω的电阻,将它们串联起来就可以了。

并联电阻

计算并联电阻中的阻值大小并不是一件容易的事情。并联电路中的N个电阻的总阻值的倒数是所有电阻阻值的倒数之和。

Schematic of resistors in parallel

Equation for adding resistors in parallel

并联电路中的N个电阻。为了计算总阻值,将每一部分阻值取倒数,将它们加起来,然后再将和倒过来,就是总阻值。

阻值的倒数实际上叫传导系数,所以可以更简洁地说:并联电路的传导系数是每一部分电阻传导系数之和。

如果只有两个电阻在并联电路中,总阻值可以用这样的等式计算:

Equation for calculating two resistors in parallel

例如,两个10kΩ的并联电阻的总阻值是5KΩ。

可以用一个符号表示两个并联的电阻:||。如果R1和R2并联,可以记作R1||R2。

电阻网络

为了教授学生计算总阻值,电学老师总是喜欢让学生计算那个疯狂的U型电路的阻值。

一个乏味的求电阻网络总阻值的问题可能是这样的:从A端到B端电路的总阻值是多少?

An example of a resistor network

为了解决这个问题,我们从电路后面的弯道开始,慢慢地简化A到B端的电路。在这里R7,R8,R9是串联在一起的,可以将阻值相加。这三个电阻和R6并联,所以这四个电阻可以记作R6||(R7+R8+R9),得到新的电路图:

Resistor network simplified

现在右边的四个电阻又可以继续简化。R4,R5以及R6-R9联合电阻是串联的,可以相加。现在又可以得到新的电路图:

Resistor network further simplified

现在AB端只有三个串联的电阻。将它们相加起来,那么电路中的总电阻就是:R1+R2+R3 || (R4+R5+R6 || (R7+R8+R9)).


应用举例

电阻出现在每个电路中。这里有几个深度依赖电阻的电路例子。

LED电流限制

在接通电源时,为了确保LED不会爆炸,电阻就显得非常重要。通过将电阻和LED串联,流过两个元件的电路会限制在一个安全的范围内。

Current limiting resistor schematic

当寻找合适的电阻时,可以参考LED的两个电气特性:工作电压和极大电流。工作电压是让LED正常发光的电压。它的范围(通常是1.7V和3.4V)取决于LED的颜色。普通LED的极大电流电流通常是20mA。连续流过LED的电流应该等于或小于极大电流。

只要你掌握了这两个数值,你就能利用以下等式计算限流电阻阻值:

Current limiting resistor = (Vs-Vf)/If

Vs是电源电压:通常是电池的工作电压。VF 和IF是led的工作电压以及点亮它需要的电流。

举个例子,你有一个9V的电池。如果LED是红色的,它的工作电压可能是1.8V。如果你想将电流限制在10mA,用一个720Ω的串联电阻。

Current limiting example equation R=(9-1.8)/.010

分压器

分压器是一种能够将电压值变小的电路。只要使用两个串联电阻,输出的电压是输入电压的分数。

这里有一个分压器电路:

Voltage divider circuit

串联的两个电阻R1和R2,电源电压是Vin,从Vout到地的电压值可以这样计算:

Voltage divider equation

串联的两个电阻R1和R2,电源电压是Vin,从Vout到地的电压值可以这样计算:

分压器对于电阻式传感器非常有用, 比如 photocells(光电池), flex sensors(柔性传感器), and force-sensitive resistors(力敏电阻). 分压器的一半是传感器,另一半是恒阻值电阻。两个元件之间的输出电压可以用微控制器上的模数转换器来阅读。

A photocell and resistor make a light sensor

电阻R1和光电管组成一个分压器,产生可变的输出电压。

上拉电阻

当你需要设置微控制器的输入引脚为宜特定状态时,可以使用上拉电阻。电阻的一端与单片机的引脚相连。另一端与高电压相连(5V或3.3V)。

没有上拉电阻,微控制器的输入就悬浮了。不能保证浮空的引脚是高电平或低电平。

上拉电阻通常被用在按钮或开关的接口。上拉电阻可以使输入引脚的状态在开始时处于某一确定值。当开关断开时,它可以保护电路以免短路。

A resistor pulling up a button input

在上面的电路中。当开关断开,微控制器通过电阻与5V电源相连。当开关闭合,输入引脚直接与地相连。

一个上拉电阻不需要有什么特殊的。但是它的阻值必须能让5V的电源不要耗费太多电压。通常阻值是10kΩ就可以了。


资源和深入学习

现在你是电阻方面的小小专家,探索更多的电学基础概念怎样呢?电阻并不是我们在电学中唯一使用的元件,它们还有:

或者你想更深入地了解电阻的应用

  • Voltage Dividers(分压器)
  • Pull-up Resistors(上拉电阻)

    cc

    原始文章采用CC BY-SA 4.0,您可以自由地:

    • 演绎 — 修改、转换或以本作品为基础进行创作
    • 在任何用途下,甚至商业目的。
    • 只要你遵守许可协议条款,许可人就无法收回你的这些权利。

    本文由翻译美国开源硬件厂商Sparkfun(火花快乐)的相关教程翻译,原始教程采用同样的CC BY-SA 4.0协议,为便于理解和方便读者学习使用,部分内容为适应国内使用场景稍有删改或整合,这些行为都是协议允许并鼓励的。

    原始文章及相关素材链接:

    https://www.sparkfun.com/search/results?term=DC+AC

电容器

简介

电容是有两个终端的电子元件。连同电阻、电感器,这三者是我们使用的最基础的耗能元件。你很难找到一个没有电容器的电路。

Capacitor variety hour

让电容特殊的是它的储电能力。它们像一个充电电池。电容在电路中拥有各种各样至关重要的应用。一般的应用包括储存能量,电压滤波,以及复杂信号的滤波。

本教程内容

在本文章中,我们会探讨有关电容器的话题,包括:

  • 如何制造一个电容
  • 电容器如何工作
  • 电容的单位
  • 电容的种类
  • 如何分辨电容
  • 串联、并联电路中的电容总和
  • 电容器的应用

建议阅读

本文章的一些概念建立在一些重要的电学概念基础之上。在你继续阅读本文章之前,建议阅读(至少浏览)以下相关文章:


符号和单位

电路符号

有两个表示电容器的符号。它们通常有两端,这两端要与电路中的其他部分连接。一种符号是两根较粗且不弯曲的平行直线。两条平行直线靠得很近但不接触。这实际上已经说明了如何制造一个电容器,但是描述起来很难,画图更直截了当:

Capacitor circuit symbols

(1)和(2)是标准的电容器电路符号。(3)是电容器应用在电压调控电路中的例子。

有曲线的符号(图2)表示电容器是有极性 的。本文章中的大部分电容器都用这种符号表示。

每个电容符号都要有一个名字,比如C1,C2等,以及一个值。这个值是指电容器的电容大小。也就是电容是多少法拉。(电容单位是法拉(F))

电容单位

不是所有电容器的电容值都一样的。每个电容器都拥有自己的电容值。电容值是指一个电容器能储存多少电量的能力,电容值越大,储电能力越强。电容的标准单位是法拉,可以简写成F。

1F是非常大的电容值,即使是0.001F(1mF)也是一个巨大的电容值。通常你看到的电容单位是pF(10-12)到mF(10-6)。

 

名称 符号 量级 与法拉相比
皮法 pF 10-12 0.000000000001 F
纳法 nF 10-9 0.000000001 F
微法 µF 10-6 0.000001 F
毫法 mF 10-3 0.001 F
千法 kF 103 1000 F

当你遇到法拉甚至是千法拉级的电容时,你遇到的是一种特殊的超级电容。


电容理论

接下来的部分不一定要初学者全部明白,直到文章后面,这一步分都是比较复杂的。我们建议阅读《如何制造一个电容器》这一章节,如果其他内容让你感到头痛,你可以忽略它们。

如何制造一个电容器

电容的符号实际上已经暗示了它是如何制造的。两块平行金属板之间有一个叫电介质的绝缘材料。两块金属板间隔非常近,但是中间的绝缘电解质保证它们不会互相接触。

Internal capacitor view

标准的电容器夹层:两块金属板被一块绝缘电介质分隔

电解质可以是各种各样的材料:纸,玻璃,橡胶,陶瓷,塑料或者是其他能让电流流过的材料。

两片材料是导体金属:铝,钽,银,或其他金属。两片金属都连着导线,两条线最终和电路的其他元件相连。

电容器的电容值——具有多少法拉——取决于它是如何制造的。更大的电容值意味着更大的电容器。两金属片之间重叠的部分越多,电容器的电容值越大,而金属片之间的距离越,电容值则越小。电解质也对电容有影响。电容可以用以下公式来计算:

C=er*A/(4*pi*d)

εr 是电解质的 介电常数(一个由电解质材料决定的常数), A是两块金属片的重叠面积,d是金属片之间的距离。

电容器如何工作

电荷的流动就是电流,电流使电灯点亮,使风扇转动,使任何电器能工作。当电流通到电容器时,它们不能穿越两块金属板,因为它们中间的电解质是绝缘的。电子——带负电的粒子——充满了其中一块金属板,这块板也就带满了负电。带负电的金属板将另一块金属板上等量的负电荷排斥走了,使另一块带正电。

Charged Cap Drawing

带正电和带负电的金属板互相吸引,因为异号电荷互相吸引。但因为中间的电解质,它们无法结合在一起,而电荷也会一直保持在金属片中。金属片上稳定的电荷创造了电场,影响了电势能和电压。当电容器的电量增长起来,电容器就像电池那样储存了电能。

充电和放电

充电就是使电容的两片金属板分别带上正电和负电。电容器能够保持电场——保留电量——因为每一片金属板都带上正电或负电,而它们永不接触。

在一定程度上,电容的电量已经多到不足以容纳更多的电荷了。其中一片金属板已经有足够的电子,这些电子会排斥任何想加入进来的电子。这就是电容器的储电能力,以法拉衡量,这告诉你一个电容器能带的最大电量是多少。

如果电路通路了,会使电量找到通向另一金属片的路径,使电容器的电量中和,这就是放电

例如,在下面的电路中,一个电池组可以用来在电容器两端产生电势。这会使电容器两金属板上带上等量异号的电量,知道电容器不能容纳更多的电荷。一个和电容串联的LED和电容形成通路,电容器中储存的能量可以用来点亮LED。

capacitor charge/discharge example

计算电量,电压,电流

一个电容器的电容——有多少法拉——告诉你它们储存多少的电量。一个电容器的储存的电量取决于电容器两端的电压。电量,电容,电压的关系可以用以下方程来描述:

Q=CV

电容器的电量Q是电容值和电压V的乘积

电容器的电容值是一个已知常量。因此我们可以调成电压大小来增加或减小电容器的电量。更大的电压就有更多的电量,较小的电压电量就比较少。这个方程提供我们定义法拉的好方法。1F就是在1V电压的情况下容纳1C电量的能力。

计算电流

我们要深入探索电量、电压、电容的关系式,找到电容和电压是如何影响电流的,因为电流是电荷的流动速度。电容中电压和电流的关系的主要内容是:电容器的电流取决于电压增加或减少的速率。如果电容两端的电压迅速增加,就会产生带正号的电流。电压改变的速率小,电流也随之变小。如果电容器的电压稳定不变,就不会有电流。

(这条方程有点丑,因为有微分在里面。如果觉得困难,可以跳过这部分)这个方程是:

i=Cdv/dt

dV/dt这部分是电压对时间的导数,这等价于:在这一瞬间电压增加或减少的速率。如果电压是稳定的,那么导数的结果就是0,也就是电流也是0.这就是为什么两端带有稳定直流电压的电容器不能产生电流。


电容器的种类

电容器有不同的种类,每种都有其特点让它在电路的应用中不可代替。

在选择一个电容器时,可以参考这些特性:

  • 大小 – 通常指物理体积的大小和电容值的大小。电容器成为电路中最大的元件是很正常的。虽然它们可以非常小,但是更多的是比较大的电容器。
  • 最大电压 – 每个电容器的两端电压都有一个最大值。一些电容器可能是1.5V,其他可能是100V.超过最大电压可能会摧毁电容器。
  • 漏电 – 电容器不是完美的。每一个电容器都会有微弱的电荷流过电解质。这就是漏电。漏电现象是电容器的电能慢慢地跑光。
  • 自带电阻(ESR) – 通常指物理体积的大小和电容值的大小。电容器成为电路中最大的元件是很正常的。虽然它们可以非常小,但是更多的是比较大的电容器。
  • 公差 – 电容器的电容值不可能是精确的预想中的数字。每个电容器的电容值都会和名义上的值有差别,差别的多少取决于电容器的种类。实际的电容值与预想值之间会有1%到20%的偏差。

陶瓷电容

陶瓷电容是最常见的一种电容。它的名字来自于电解质的材料。

陶瓷电容通常在物理体积和电容值上都比较小。你很难找到一个大于10uF的陶瓷电容。一个表面安装型陶瓷电容通常封装成0402(0.4mm*0.2mm),0603(0.6mm*0.3mm)或0805.穿孔安装式陶瓷电容通常看起来像小小电灯泡,两端都有一条金属线引申出来。

Ceramic Capacitors

两个穿孔安装式电容器。一个22pF(左)一个0.1uF(右)。中间的是0603表面安装型0.1uF电容。

C和其它比较受欢迎的电容器相比,陶瓷电容式一个接近理想的电容(自带电阻和漏电都比较小),但是它们比较小的电容值可能是一个缺点。它们通常也是最不昂贵的一种选择。这些电容器同样适用于高频耦合和去耦。

铝电解电容和电解钽电容

电解式电容的好处在于它的体积通常比较小。如果你想找一个1uF到1mF之间的电容,最好去找电解电容。它们能适应比较大的电压,因为它们的最大电压值比较高。

电解铝电容是电容家族中最受欢迎的一员。它通常看起来像罐子,底部有两条导线。

Electrolytic caps

即可穿孔安装又可表面安装的电容。每一个都有阴极引脚。

很不幸运,电解电容通常是有极性的。它们有一个正极引脚——阳极,一个负极引脚——阴极。当在电容两端加上电压时,电容器阳极的电位一定要比阴极的电位高。电容器的阴极通常有一个“-”号标记符。阳极的引脚通常比阴极引脚长。如果将电容器反接在电路中(电位差相反),电容器就永久废掉了。一个爆炸后的电解电容看起来像经历了短路。

这些电容也因为漏电而臭名昭著——电流(nA级别)从一极流向另一极。这使电解电容在储存电能上不是那么理想。

超级电容

如果你想找一储存电能的电容器,超级电容是一个很好的选择。这些电容被独特地制造成具有法拉级别的电容值。

Supercapacitor

一个1F的超级电容器。超高的电容值,但是只能承受最大2.5V电压。这也是有极性的。

虽然超级电容能储存大量的电量,但是它不能承受太大的电压。一个10F的超级电容只能承受2.5V以内的电压。超过这个值就会摧毁它。超级电容通常串联在电路中,这样就可以适应一个比较大的电压(与之串联的元件承担了部分电压)。

超级电容的主要应用是充电和放电,就像它的竞争对手电池。虽然超级电容不能储存比同样大小电池多的电量,但是它放电速度更快,寿命更长。

其他内容

80%的电容器都是电解电容和陶瓷电容,超级电容只占2%。另一种比较流行的电容是薄膜电容,它的特点是自带电阻非常小,在有大电流时优点非常明显。

另外还有许多不太常见的电容器。可变电容器的容量有一个可调整的范围,这使它成为调谐电路中可变电阻的替选品。两根金属导线和PCB板之间可以形成电容器,因为它们中间被绝缘电解质隔离者。莱顿瓶(畜电器)——一个被导体填满包围的玻璃瓶——是电容器家族的老大。最后,磁通电容器(电感器和电容器的奇怪组合)是至关重要的。


串联和联电路中的电容器

就像电阻, 多个电容器可以在电路中串联或并联组成一个统一的电容器。然而,总电容的计算恰好和总电阻的计算想反。

并联电容

并联电路中电容器的总容量等于各电容容量之和。这和串联电阻的情况类似。

Capacitors in parallel add

例如,如果你有三个电容器,10uF,1uF和0.1uF,并联在电路中总容量就是11.1uF(10+1+0.1)。

串联电路中的电容器

就像将并联电路中的电阻加起来那样痛苦,串联电路中电容的相加也是那么难啃。N个串联电阻的总容量的倒数是各部分电阻容量的倒数之和。

Capacitors in series are the inverse of the sum of their inverses

如果电路中只有两个电容器,你可以用“积除以和”的方法去计算总容量:

Equation for 2 capacitors in series Ctot=C1*C2/(C1+C2)


应用举例

电容器应用范围很广泛。举几个例子:

退耦电容

你在大多数电路看到的电容都是用来退耦的。退耦电容用于高频消振,消除高频信号中的躁波。它们可以除去电源的电压波动,避免损坏脆弱的集成电路芯片。

退耦电容可以作为集成电路芯片的内置电源(就像电脑内部的不断续电源)。如果外置电源的电压突然下降,一个退耦电容可以提供补偿电压。它们通常被叫做旁路电容,可以在一定时间内充当电源。

退耦电容两端电压是5.5V或3.3V。用两个不同容量甚至是不同类型的电容器充当旁路电源并非罕见,因为一些电容器在滤除某个特定频率的躁波比较有优势。

Decoupling capacitor schematic

在这幅图中,三个退耦电容用于减少积分器供应电源电压的躁波。两个0.1uF的陶瓷电和一个10uF的钽电解电容被用于退耦。

这看起来像电源和地之间短路了,只有高频信号才能经过电容器通往地端。直流信号会直接传送到IC。另一个它们被叫做旁路电容的原因是高频信号绕过了芯片,直接从电容器通向地端。

当我们连接一个退耦电容时,它们通常尽量和芯片靠得近一些。离得越远,它们的效果越差。

ADXL345 breakout decoupling caps

图中是一个物理电路。小小的黑色集成芯片旁边有两个0.1uF的电容器和一个10uF的钽电解电容(高的,长方形的电容器)。

一个好的集成芯片,至少会有一个退耦电容。通常0.1uF是好的选择,1uF或10uF也可以。它们很便宜,可以保证芯片不会被突然过大的电压损坏。

电源滤波

二极管整流器 可以将交流电压转换成直流电压。但是一个单独的二极管没有办法将交流电转换成直流电,它需要电容器的帮助。将一个电容器并联到桥式整流器中,整流器的信号本来是这样:

Rectification pre-Cap

信号会被转换成这样:

Rectification post-cap

电容会抵抗电压的突然变化。当整流器的电压增加时,滤波电容会被充电。当整流器的电压有非常大的下降趋势时,电容器会慢慢放电,为电路提供能量。在整流器电压信号开始再次上升之前,电容器最好不要完全放电。这种电压的增减变化在一秒之内会发生许多次。

Power supply circuit

一个交流到直流的转换电路。滤波电容C1至关重要,因为它时电路的直流信号变得光滑。

如果你将交-直转换电路剖解,你一定可以至少找到一个大型的电容器。下图是9V的直流电压调整器的拆解图。看一看里面的每个电容器:

alt text

电容器的数量比你想象的要多。这里有四个看起来来像小罐子的电解电容,容量在47uF到1000uF之间。那个大的、长方形的黄色电容器是一个高电压的聚丙烯薄膜电容器,容量是0.1uF。蓝色圆盘状和绿色的小小那只都是陶瓷电容。

储电和供电

如果一个电容器储存了电能,那么很明显它的其中一个用途就是供电,就像电池那样。但问题是和电池相比,电容器的能量密度比较小,和相同大小的化学电池相比,它们储存的电量少一点(但也只是一点而已!)。

电容器的一个好处是它们寿命比电池的长,这使它们成为一种环境友好的选择。电容器还有一个本领,它的放电速度绝对比电池快,有时需要一些短促的但是爆发力强的能量时就需要它们了。照相机的闪光灯的电能就是来自电容器的(电容器的电能来自电池)。

电池还是电容?

电池 电容器
容量
能量密度
充、放电速度
寿命

 

信号滤波

滤波电容能将一定频段内的信号从总信号中去除。当只需要高频信号时,它可以将低频信号去除掉。它就像高频信号俱乐部的保镖。

滤波信号可以被用在各种信号接收设备中。收音机会利用电容器将不需要的频率去除。

另一个电容器的应用例子是扩音器里的分频电路,也就是将声音信号分成许多不同频段。一个串联的电容器会滤掉低频信号,剩下的高频信号就会到达这一对扩音器。在低通滤波电路里,高频信号会被并联电容器滤掉。

Crossover schematic

一个简单音箱分频电路。电容器阻拦了低频信号,电感器阻拦了高频信号。每一个扬声器都能接收到对应的信号。

降级

When working with capacitors, it’s important to design your circuits with capacitors that have a much higher tolerance than the potentially highest voltage spike in your system.

如果要使用电容器,电容器要有一个比电压最大值要大得多的耐受度。
这里有一个SparkFun的工程师Shawn的优秀视频,是关于当你降低电容器级别并使电压过大时,你的电容器会发生什么。你可以在这里了解更多本实验的内容。


资源和深入学习

现在是不是感觉自己像一个电容器专家呢。想持续学习电学基础知识?如果你已经准备好了,可以尝试阅读关于以下电子部件的文章:

你可能对以下文章感兴趣:

  • Battery Technologies(电池技术)
  • How to Power a Project(如何供电)
  • Electric Power(电能)

    cc

    原始文章采用CC BY-SA 4.0,您可以自由地:

    • 演绎 — 修改、转换或以本作品为基础进行创作
    • 在任何用途下,甚至商业目的。
    • 只要你遵守许可协议条款,许可人就无法收回你的这些权利。

    本文由翻译美国开源硬件厂商Sparkfun(火花快乐)的相关教程翻译,原始教程采用同样的CC BY-SA 4.0协议,为便于理解和方便读者学习使用,部分内容为适应国内使用场景稍有删改或整合,这些行为都是协议允许并鼓励的。

    原始文章及相关素材链接:

    https://www.sparkfun.com/search/results?term=DC+AC

如何使用面包板

简介

在学习如何搭建电路时,面包板是最基础的零件之一。在这篇教程,你将能学到一些关于面包板的知识:为什么什么它们叫面包板以及如何使用面包板。

A Breadboard

建议阅读

在学习面包板之前,你可能想要探索以下教程和概念:


历史

在上世纪60年代以前,如果你想搭建一个电路,你很有可能会用一种叫做绕线连接(wire-wrap)的技术。绕线连接是将金属导线环绕在导体柱的过程,被环绕的导体柱插在一块穿洞板上。就像你看到的下图,这种方法很快会变得复杂起来。虽然这种方法在今天仍然使用,但是已经有一种让电路测试更容易的方法————面包板。

wire-wrap circuit

绕线连接电路(图片来自维基百科用户Wilinaut)

名字的含义

当你在头脑里想象面包板这个词时,你的脑海里可能会浮现一大块木板,木板上有一块新鲜的烘焙面包。你的想象力不会偏离太远。

A literal breadboard

放在面包板上的面包

那么为什么这块用来建立电路的电子原件叫面包板呢?在很多年以前,电子产品又大又笨重,人们会收集他们老妈的面包板、少量的钉子和按钉,开始在板子上连接导线,为他们自己创建一个电路平台。

Circuit built on literal breadboard

一块“原汁原味”的面包板上的电路 (来自 mischka 的 literal breadboard tutorial)

从那以后,电子部件变小了很多,我们也想出更好的连接电路的方法,这让全世界妈妈们都很高兴,因为她们终于能拿回自己的面包板了。然而,我们无法摆脱这令人困惑的名字。技术上,这些依然是面包板,只不过它们是更加时尚的免焊面包板。


为什么我们使用面包板?

我们所说的电路面包板通常是指免焊面包板。这些都是制作临时电路和测试原型的最好元件,他们是绝对不需要焊接的。

测试原型,一种通过创建初始模型来测试想法的过程,而这个模型由其他形式开发或复制,这是面包板最广泛的用途。如果你不确定一个电路在给定参数的设置下会如何反应,建立一个测试原型去检测它是最好的。

对于那些电子电路的入门者,面包板是一个很好的开始。面包板的优美之处在于,它能同时容纳最简单和最复杂的电路。正如你会在文章的后面看到的那样,如果你的电路不能被当前的面包板所容纳,你能够拼接其他板子来适应所有大小和复杂度不同的电路。

另外一个普遍的用途是测试新模块,比如集成电路(ICs)。当你尝试掌握某个模块如何工作并且需要多次重新布线,你肯定不想每次都焊接电路接口。

正如所提及的,你不总是想建立一个永久电路。当尝试复制一个客户遇到的问题时,SparkFun的技术支持团队通常会用面包板去建立、测试以及分析电路。他们连接客户拥有的那部分电路,一旦他们建立起电路并发现问题,他们将每一部分拆开,放在一旁,为做一些故障排除做准备。

A circuit built on a solderless breadboard

一个建立在免焊面包板上的电路


解剖面包板

面包板主要特征

面包板主要特征(图片内容:接线柱,双列直插式封装支持,电源轨,终端带)

探索面包板如何工作的最好方法是将它解体,看看它里面是什么。使用一个小型面包板更容易看清楚它们是如何工作的的。

终端带

这里有一块面包板,它后面的黏贴纸被撕去了。你可以看到很多在底部的平行金属条。

SparkFun Mini Breadboard

一块SparkFun的迷你面包板正面(左)以及拆除了黏合板的背面(右)

金属条的顶部有一个小夹子。这些夹子能将一条导线或某个部件的引脚固定在塑料洞上,使它们放置在适当的位置上。

Clip

从面包板移除出来的导体金属条。

一旦插入,这个部件就和该行的其它地方电气相连。这是因为金属条是可导的,能够让电流通过金属条的任何地点。

你应该注意到这个金属条上只有五个夹子。对于大多数面包板来说这是典型的设置。因此,你最多能有五个部件连接在面包板的同一行上。每一行有十个洞,但是为什么你只能够连接最多五个部件呢?你一定同时注意到互相平行的行被一个在面包板中间的凹槽隔离了。这条沟壑将一行分了开来,使它们断开。待会我们会讨论这样设置的目的,但是现在,你只需要知道每一边的行并不与对方相连,让你只能在每一边上使用五个部件。

LED in Breadboard

一个插进面包板的发光二极管。请注意,二极管的两只引脚分别处于分隔带的两边。这阻止了二极管的短路连接。

电源轨

我们已经了解过面包板如何建立连接,接下来我们看一个更大、更典型的面包板。在平行的行的两侧,面包板通常有电源轨,它们处于面包板的两侧。

Front and back, medium breadboard with power rails exposed

一个中型面包板,它后面的黏合板被移除了,呈现处电源轨。

这些金属电源轨与垂直的金属条区别开来,但是它们是贯通的。在建立电路时,你应当在许多地方需要电源。电源轨让你在需要时随时可以提供电源。为了标识正极或负极,它们通常被标上红色的“+”和蓝色的“-”。

有一点非常重要:每一侧的电源轨是不相连的。因此,如果你想两侧使用同一个电源,你需要用一些跳线连接两侧。记住,标志只是一种参考。没有规则规定你只能将电源正极插进“+”轨将负极插入“-”轨,虽然这是让所有事情保持次序的良好方法。

Jumper wires connecting both sides of the power rails

两条用于连接两侧电源轨的跳线,总是正极轨和正极轨相连,负极轨和负极轨相连。

双列直插式封装(DIP)支持

先前我们提及了将面包板分成两侧的塑料带。这条塑料带有一个非常重要的目的。许多集成电路,通常指ICs或简单的芯片,被特定地制造成能够配合面包板。为了尽量减少它们在面包板上占据的空间,它们使用双列直插式封装形式(DIP)。

alt text

两个DIP集成电路,LM358(上),一个非常普遍的运算放大器,以及更加流行的ATmega328微控制器(下)

行和列

你应该注意到面包板上大多数的行和列都标有数字或字母。除了指导你建立电路,这些标志别无它用。电路很快就建立起来了,但是只要有任何一个引脚连接错误,就能使整个电路出错或不工作。如果你知道行号,你就能很轻易地将引脚接在正确的位置,这比起目测法优越太多了。

使用说明手册也很有用,比如包含在SparkFun创意包里的册子。许多书籍和向导都有帮助你建立电路的电路图解。请记住,你所建立的电路不一定要和书本上的一模一样。事实上,就连看起来相似也不需要。只要电路能够正确连接,你能按照你喜欢的方式建立电路。

接线柱

一些面包板的平台上连接着接线柱。这些接线柱允许你连接所有类型的电源到你的面包板上。在接下来的章节,我们会详细讲述这一内容。

其他特点

在建立电路时,你并没有被限制在一个面包板上。一些电路会需要更大的空间。大多数面包板的侧边会有凸起的方块和凹进去的槽,甚至有一些在板的顶部和底部。这些特点允许你连接更多的面包板载一起,以形成不限制大小的测试板面。

Four SparkFun mini breadboards connected togethe

四个SparkFun迷你面包板拼接在一起。

一些面包板的背面会有黏合板,让不同的板子能够连接在一起。如果您想将面包板连接到机箱或其他工程机箱的内部,这些功能将派上用场。

*一些更大的面包板通常会将面包板的电源轨的一半与另一半隔开。这对于你为电路提供不同的电压(比如3.3V或5V)是很方便的。 然而,如果你不知道电源轨是否被隔离,在构建电路时很容易出问题。用万用表来检测电源轨的连续性是一个不错的主意。

为面包板提供电源

当你需要为你的面包板提供电源时,有以下几种选择。

借用其他电源

如果你正在使用一个Arduino开发板,那么你可以轻易地从板子的母头得到电源。Arduino有多个电源和地引脚,你可以将它们和面包板的电源轨或其他行相连。

Sharing power with an Arduino

Arduino上的地引脚与迷你面包板上的某行相连。现在,与这一行连接的任何引脚等价于与地相连。

Arduino通常通过USB线与电脑连接或用一个外部电源得到电源。

接线柱

正如在前面所提到的,一些面包板具有接线柱,能够连接外部电源。

要使用接线柱的第一步是利用跳线将它们和面包板连接。虽然看起来接线柱和面包板连接了,但是其实并没有。正如我们所了解的,面包板是规范化生产的,所以接线柱也应该没什么不同。

接下来,我们要用导线将接线柱和面包板连接起来。为此,将接线柱拧开,直到你能完全看到柱子上的穿孔,将金属线放在孔中,拧紧接线柱。

Conneting wire to the binding posts

通常地,你只需要从接线柱连接一根电源线和地线。如果你需要使用内部电源,你可以选择第三个柱子。

现在,你的接线柱已经和面包板连接了,但是还没有电源。你可以用几种方法将电送到接线柱,从而给面包板上电。

工作台电源

许多电子实验室具备能够提供范围很广的电压的工作台电源。使用香蕉接头能将电从供应处送到接线柱。

A breadboard being powered through the binding posts from banana cables

香蕉线与接线柱连接,为面包板供电。

另外,你还可以使用鳄鱼夹,IC挂钩,或其他有香蕉接头的电线将你的面包板和几个不同的电源相连接。

A breadboard being powered through the binding posts with a barrel jack

两根导线焊接在一个接口上。如果你的面包板没有接线柱,你可以直接将接口的两根导线连到面包板上。

面包板电源

其他为你的面包板供电的方法是面包板电源。SparkFun提供一些模块,让你能够直接地为面包板提供电源。一些能够让你使用USB从电脑将电送到面包板。大多数模块都能自动调整电压以适应你的电路要求,这让你有一个比较宽的电压选择范围。

A SparkFun USB Breadboard Power Supply

一SparkFun的USB电源电源模块,能使面包板连接上3.3V到5V的电源。


构建第一个面包板电路

现在,我们已经知道了面包板的内部结构以及如何提供电源。接下来我们要干什么呢?我们将要建立一个简单的电路。

需要的物资

这里有一个本电路的部分物资清单。如果你有其他电路元件,你可以尝试自由地改动电路。记住,并不是只有唯一的一种方式建立给定的电路。大部分都有许多不同的方法去建立同一个电路。

此物料清单是假定你没有任何的工具和元件并且想要数量可观的物资。举个例子,你可能只需要一个发光二极管,但是我们列出了20个的数量。你可能不需要那么多数量,但是你可能会一直玩这个电路,当你需要的时候会特别方便。如果你不想要那么多数量的物资,你可以检查产品页底部一个叫“相关产品”的部分,然后你就能找到最少需要的数量。还有,面包板电源没有线头,如果你知道怎样焊接并有工具,你自己焊接线头吧。如果没有,就请在物料清单加上焊接好的接线头。

建立电路

Picture of Circuit

一个简单的电路,包括一个按钮,一个发光二极管,一个电阻。用两种方式建立。

你看到的红色的面包板电源,为面包板提供了5V的电源,而本身与9V的电源连接。

电路设计:

  • 一根导线将5V的电源轨与正极连接,发光二极管的阳脚与电源轨连接。
  • LED的阴极与330欧姆的电阻连接。
  • 电阻与一个按钮连接。
  • 按钮与地端相连,当按下按钮,电路为通路,有电流产生,LED发光。

电路示意图

在另一篇导文理我们介绍了如何阅读电路示意图。然而对于建立电路来说这是非常重要的,我们在这里也会稍微提及如何阅读电路示意图。

电路示意图是一种能够让全世界的人明白并建立电路的通用图解。每一种电路元件都有独一无二的电路符号。这些符号组成大量的电路图。你能徒手将它们画出来。如果你想深入地了解电子电路的建立,学习如何阅读电路图是非常重要的一步。

在这里,我们有一张关于上述电路的电路图。图中箭头上方指明这是5V的电源,然后线路连接到LED(一个三角形和一根线,并发射出箭头)。LED然后连接到了电阻,紧接着是开关,也就是按钮。最后按钮与地相连(底下平行的直线)。

Schematic

这看起来像一个有趣的画电路图的方法,但是即使是这样基础过程也是人们探索几十年的结果。电路图使不同国家、不同语言的人能建立任何一个人建立的电路。如前面说提到的,你可以有不同的方法建立一个电路,但是某些元件的连接是唯一确定的。从这个电路图中发散你的思维,你可以建立一个完全不一样的电路。

熟能生巧

最后一点要告诉你的知识是,你有无数的资源和方法建立一个电路而完全不适用面包板。一个非常普遍的方法就是使用SparkFun的 Fritzing。Fritzing是一个让你能在虚拟面包板上建立电路的开放平台。它能为你建立的电路提供所有的电路图。在这里我们能看到用Fritzing建立的同样的电路。

Fritzing Diagram

绿色的线表示处于不同行和列上的元件是相连的。


购买电路板

一个极好的开始是购买一块面包板作为工具包的一部分。 SparkFun的发明者工具包 包含所有能让你完成16种不同的路的材料/我们同时列举了一些少量的基础的不同大小的面包板,可能对你的项目有作用。

我们的推荐


资源和深入学习

希望你能较好地理解什么事面包板以及它如何工作。现在真正有趣的事情开始了。我们准备用面包板建立测试电路。这里有一些对你有帮助的教程,是关于一些电子元件和建立电路的知识的。

你可能感兴趣的文章:

如果你想提升你的电路能力,可以都这些文章:

一堂精彩绝伦的算法课

前情提要

有了三轴加速度计,又有开源的相关代码库,我们非常容易就能搜集加速度的数据。我使用Arduino控制板和OpenLog数据转录模块,收集了大量的加速度数据。不过问题也随之而来,你如何处理这样杂乱而庞大的数据来获得有用的信息?

Speed Bag Repeating Gif

这里有个非常实际的应用案例,多年前,我就搭建了一个基于拳击速度球沙袋的计数器,如上图所示。对于那些拳击初学者来说,速度球是一个液滴状的袋子,初练的拳击手通过快速打击它来训练他们的肩膀和发展手脑协调。 标准回合是三分钟,并且由于袋子弹跳的速度极快,几乎不可能通过人工来计数。我决定搭建一个计数器,然后抽空慢慢改进,仅仅把加速度计脸上带有显示器的Arduino控制板,然后就万事大吉了吗?不他们说得对,如何处理搜集到大量数据的算法才是大麻烦。

A log of triple axis accelerometer data

加速度计采集到的数据凌乱了我的天

为了看出这些返回数据中的端倪,我试图把这些数据转换成图形来显示。然而现实很残酷,真实世界中的有用信号总是被各种因素的噪声掩埋在其中。

不,等等,亮瞎我眼的是似乎这些数据还是有一定的周期性和特点的,元芳你怎么看?

Graph of data

不幸的是,即便采样频率高达500赫兹,这些数据仍然无法给出显而易见的信息,我要统计的击打次数。拿着这些数据,我用尽洪荒之力来构建一套能够统计出击打次数的系统。

/*
 BeatBag - A Speed Bag Counter打击沙袋-一个击打次数统计器
 Nathan Seidle(老板名字)
 SparkFun Electronics火花快乐电子
 2/23/2013(代码编写时间)

 License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
许可协议:本代码属于公共域,你想拿去干嘛就干嘛,不需要询问任何人或组织更不用付费,甚至连代码源出处都不用标明。但如果你用了这些代码并且某天邂逅了我,你要买瓶啤酒请我喝(啤酒协议)

 BeatBag is a speed bag counter that uses an accelerometer to counts the number hits. 打击沙袋是一个用加速计来统计沙袋被击打次数的装置。
 It's easily installed ontop of speed bag platform only needing an accelerometer attached to the top of platform. 它很容易安装在速度袋平台的顶部,只需要一个加速度计连接到平台的顶部。
 You don't have to alter the hitting surface or change out the swivel.
 你不需改变击球表面或改装它。

 I combine X/Y/Z into one vector and look only at the magnitude. 
我将XYZ三轴的矢量合成,并只通过观察最终数量大小获取信息
 I use a fourth order filter to see the impacts (accelerometer peaks) from the speed bag. It works pretty well.
我使用四阶滤波器来获取冲击信号(加速度峰值),效果还不错。
 It's very reproducible but I'm not entirely sure how accurate it is. I can detect both bag hits (forward/backward) then I divide by two to get the number displayed to the user.
此结果还是能较好的重现,不过我不是很确定它的准确性。它能检测到冲击时的前和后然后获得相关数据。

 I arrived at the peak detection algorithm using video and raw data recordings. After a fourth filtering I could glean the peaks. There is probably a much better way to do the math on the peak detection but it's not one of my strength.
我通过对比视频记录和峰值检测的算法,在四阶滤波后搜集到此峰值。很可能有更好的算法的相关数学处理步骤来进行峰值的检测,不过这似乎不是我的强项。

 Hardware setup:硬件连线指导:
 5V from wall supply goes into barrel jack on Redboard. Trace cut to diode. RedBoard barel jack is wired to power switch then to Vin diode. Display gets power from Vin and data from I2C pins Vcc/Gnd from RedBoard goes into Bread Board Power supply that supplies 3.3V to accelerometer. Future versions should get power from 3.3V rail on RedBoard. 

 MMA8452 Breakout ------------ Arduino
 3.3V --------------------- 3.3V
 SDA(yellow) -------^^(330)^^------- A4
 SCL(blue) -------^^(330)^^------- A5
 GND ---------------------- GND
 The MMA8452 is 3.3V so we recommend using 330 or 1k resistors between a 5V Arduino and the MMA8452 breakout.
 The MMA8452 has built in pull-up resistors for I2C so you do not need additional pull-ups.

 3/2/2013 - Got data from Hugo and myself, 3 rounds, on 2g setting. Very noisy but mostly worked

 12/19/15 - Segment burned out. Power down display after 10 minutes of non-use.
 Use I2C, see if we can avoid the 'multiply by 10' display problem.

 1/23/16 - Accel not reliable. Because the display is now also on the I2C the pull-up resistors on the accel where not enough. Swapped out to new accel. Added 100 ohm inline resistors to accel and 4.7k resistors from SDA/SCL to 5V.
 Reinforced connection from accel to RedBoard.

 */

#include <avr/wdt.h> //We need watch dog for this program

#include <Wire.h> // Used for I2C

#define DISPLAY_ADDRESS 0x71 //I2C address of OpenSegment display

int hitCounter = 0; //Keeps track of the number of hits

const int resetButton = 6; //Button that resets the display and counter
const int LED = 13; //Status LED on D3

long lastPrint; //Used for printing updates every second

boolean displayOn; //Used to track if display is turned off or not

//Used in the new algorithm
float lastMagnitude = 0;
float lastFirstPass = 0;
float lastSecondPass = 0;
float lastThirdPass = 0;
long lastHitTime = 0;
int secondsCounter = 0;

//This was found using a spreadsheet to view raw data and filter it
const float WEIGHT = 0.9;

//This was found using a spreadsheet to view raw data and filter it
const int MIN_MAGNITUDE_THRESHOLD = 1000; //350 is good

//This is the minimum number of ms between possible hits
//We use this to filter out peaks that are too close together
const int MIN_TIME_BETWEEN_HITS = 90; //100 works well

//This is the number of miliseconds before we turn off the display
long TIME_TO_DISPLAY_OFF = 60L * 1000L * 5L; //5 minutes of no use

int DEFAULT_BRIGHTNESS = 50; //50% brightness to avoid burning out segments after 3 years of use

unsigned long currentTime; //Used for millis checking

void setup()
{
  wdt_reset(); //Pet the dog
  wdt_disable(); //We don't want the watchdog during init

  pinMode(resetButton, INPUT_PULLUP);
  pinMode(LED, OUTPUT);

  //By default .begin() will set I2C SCL to Standard Speed mode of 100kHz
  Wire.setClock(400000); //Optional - set I2C SCL to High Speed Mode of 400kHz
  Wire.begin(); //Join the bus as a master

  Serial.begin(115200);
  Serial.println("Speed Bag Counter");

  initDisplay();

  clearDisplay();
  Wire.beginTransmission(DISPLAY_ADDRESS);
  Wire.print("Accl"); //Display an error until accel comes online
  Wire.endTransmission();

  while(!initMMA8452()) //Test and intialize the MMA8452
    ; //Do nothing

  clearDisplay();
  Wire.beginTransmission(DISPLAY_ADDRESS);
  Wire.print("0000");
  Wire.endTransmission();

  lastPrint = millis();
  lastHitTime = millis();

  wdt_enable(WDTO_250MS); //Unleash the beast
}

void loop()
{
  wdt_reset(); //Pet the dog

  currentTime = millis();
  if ((unsigned long)(currentTime - lastPrint) >= 1000)
  {
    if (digitalRead(LED) == LOW)
      digitalWrite(LED, HIGH);
    else
      digitalWrite(LED, LOW);

    lastPrint = millis();
  }

  //See if we should power down the display due to inactivity
  if (displayOn == true)
  {
    currentTime = millis();
    if ((unsigned long)(currentTime - lastHitTime) >= TIME_TO_DISPLAY_OFF)
    {
      Serial.println("Power save");

      hitCounter = 0; //Reset the count

      clearDisplay(); //Clear to save power
      displayOn = false;
    }
  }

  //Check the accelerometer
  float currentMagnitude = getAccelData();

  //Send this value through four (yes four) high pass filters
  float firstPass = currentMagnitude - (lastMagnitude * WEIGHT) - (currentMagnitude * (1 - WEIGHT));
  lastMagnitude = currentMagnitude; //Remember this for next time around

  float secondPass = firstPass - (lastFirstPass * WEIGHT) - (firstPass * (1 - WEIGHT));
  lastFirstPass = firstPass; //Remember this for next time around

  float thirdPass = secondPass - (lastSecondPass * WEIGHT) - (secondPass * (1 - WEIGHT));
  lastSecondPass = secondPass; //Remember this for next time around

  float fourthPass = thirdPass - (lastThirdPass * WEIGHT) - (thirdPass * (1 - WEIGHT));
  lastThirdPass = thirdPass; //Remember this for next time around
  //End high pass filtering

  fourthPass = abs(fourthPass); //Get the absolute value of this heavily filtered value

  //See if this magnitude is large enough to care
  if (fourthPass > MIN_MAGNITUDE_THRESHOLD)
  {
    //We have a potential hit!

    currentTime = millis();
    if ((unsigned long)(currentTime - lastHitTime) >= MIN_TIME_BETWEEN_HITS)
    {
      //We really do have a hit!
      hitCounter++;

      lastHitTime = millis();

      //Serial.print("Hit: ");
      //Serial.println(hitCounter);

      if (displayOn == false) displayOn = true;

      printHits(); //Updates the display
    }
  }


  //Check if we need to reset the counter and display
  if (digitalRead(resetButton) == LOW)
  {
    //This breaks the file up so we can see where we hit the reset button
    Serial.println();
    Serial.println();
    Serial.println("Reset!");
    Serial.println();
    Serial.println();

    hitCounter = 0;

    resetDisplay(); //Forces cursor to beginning of display
    printHits(); //Updates the display

    while (digitalRead(resetButton) == LOW) wdt_reset(); //Pet the dog while we wait for you to remove finger

    //Do nothing for 250ms after you press the button, a sort of debounce
    for (int x = 0 ; x < 25 ; x++)
    {
      wdt_reset(); //Pet the dog
      delay(10);
    }
  }
}

//This function makes sure the display is at 57600
void initDisplay()
{
  resetDisplay(); //Forces cursor to beginning of display

  printHits(); //Update display with current hit count

  displayOn = true;

  setBrightness(DEFAULT_BRIGHTNESS);
}

//Set brightness of display
void setBrightness(int brightness)
{
  Wire.beginTransmission(DISPLAY_ADDRESS);
  Wire.write(0x7A); // Brightness control command
  Wire.write(brightness); // Set brightness level: 0% to 100%
  Wire.endTransmission();
}

void resetDisplay()
{
  //Send the reset command to the display - this forces the cursor to return to the beginning of the display
  Wire.beginTransmission(DISPLAY_ADDRESS);
  Wire.write('v');
  Wire.endTransmission();

  if (displayOn == false)
  {
    setBrightness(DEFAULT_BRIGHTNESS); //Power up display
    displayOn = true;
    lastHitTime = millis();
  }
}

//Push the current hit counter to the display
void printHits()
{
  int tempCounter = hitCounter / 2; //Cut in half

  Wire.beginTransmission(DISPLAY_ADDRESS);
  Wire.write(0x79); //Move cursor
  Wire.write(4); //To right most position

  Wire.write(tempCounter / 1000); //Send the left most digit
  tempCounter %= 1000; //Now remove the left most digit from the number we want to display
  Wire.write(tempCounter / 100);
  tempCounter %= 100;
  Wire.write(tempCounter / 10);
  tempCounter %= 10;
  Wire.write(tempCounter); //Send the right most digit

  Wire.endTransmission(); //Stop I2C transmission
}

//Clear display to save power (a screen saver of sorts)
void clearDisplay()
{
  Wire.beginTransmission(DISPLAY_ADDRESS);
  Wire.write(0x79); //Move cursor
  Wire.write(4); //To right most position

  Wire.write(' ');
  Wire.write(' ');
  Wire.write(' ');
  Wire.write(' ');

  Wire.endTransmission(); //Stop I2C transmission
}

由于这是我非常不专业的尝试用自己想的滤波算法来抑制噪声,获得有效信息。到了这一步,我把相关流水数据的记录导入到LibreOffice(一款完全开源免费的办公软件,和微软的Offiice类似),然后通过里面的数学函数功能来尝试找个一个处理这些数据的算法,以获得真正合理有效的关于沙袋被击打次数的相关信息。从中,我得到了两个结论:

  1. 关于算法的专业造诣和技能,我真的知之甚少。
  2. 我的这些近似方法非常的不准确。平均误差竟有28%。我认为这是因为当拳击手进入比较固定的出击节奏时,有一些谐波的频率会破坏。

我非常确定这个问题有很大的改善空间。所以,我想出这么一个主意:我们来进行一场比赛,我们希望能得到这方面专业人士所提供的指导和帮助,我们可以籍由这次赛事来获得解决实际问题的思路和方法,汲取专业算法设计者的思路。你可以从这里获得相关的数据记录。这些文件的名字中已经给出了相关的击打次数,如果你不信,你可以从这里看到相关的视频的数据。

如果认为你能获得更加准确的沙袋击打次数:

  1. 写一个可以获得正确击打次数的算法并包含相关的数据输出。(数据从这里获取).
  2. 将此算法运用到某种微控制器上,8位或32位的都行,别上FPGA,PLC之类的,除非你疯了。
  3. 最重要的是:写下你解决这个问题的一系列详细步骤,你如何对数据进行滤波并最终解决问题,我们在这里等着向你学习。
  4. 将你的代码和文档发到我们相关的反馈途径或者公布到网上。
  5. 用你的算法来告诉我们未知数据1未知数据2到底有多少次击打。当比赛结束后,我们会公布这两个过程的视频来求证算法的可靠程度。

我们是开源硬件的忠实信徒。你的劳动成果必须以开源协议的方式发布,并且不能禁止此算法用于商业目的。我是没打算把这个东西做成产品的,不过如果某人想要运用此算法做一个击打计数器并出售它,用于盈利,你得乐见其成。

如何参与?

请发送你的相关链接到反馈或文章评论区。我们将会在本月底结束此竞赛(6月30日)。我会公布采用新算法在健身房直接测试新的解决方案。天外有天,人外有人,如果有不止一个非常成功的解决方案,我们将随机抽取一位作为比赛的胜利者,并公布所有测试通过成功者的结果和相关信息。

等一等,赢了这个比赛会有什么奖励?Wait, wait. So what do I win?

我们将邀请你和你的一位陪同者乘飞机来丹佛,下榻博尔德的酒店,带你参观火花快乐电子公司并一起去前沿拳击协会一同看看你代码的最终成果,一起在博尔德吃喝玩乐一把。如果你来自美国以外的地区,我们就只能提供你一人的往返机票,而非两人。

截止到2016年7月5日:感谢所有的参与者!即日起停止接受参赛方案,因为我们需要花费一段时间来测试每位参与者提交的解决方案。许多人的方案看起来都超赞的,我们会尽快发布更新消息并公布得胜者。


引言

今年(2016)早些时候,Nathan Seidle,Sparkfun(火花快乐)的创始人,提出了要众包一个算法问题。参加此众包的方案经过筛选后,最终有一位参与者的方案被选中。他就是此次众包竞赛的获胜者Barry Hannigan,我们希望他能将解决这个算法难题的过程整理成一篇教程来给大家带来更多的启发。这篇文章就是关于他是如何解决一个现实世界中的问题,即使这个问题并不是你目前工作中棘手的难题,但听他介绍如何一步一达成目标的过程,相信对于爱好开源硬件和热爱电子及软件技术的你也会感到醍醐灌顶。

相关资料Firmware Resources

点击下面托管在Github的程序,你可以得到这个问题的相关代码内容

BARRY’S SPEED BAG CHALLENGE GITHUB REPO

由于获得了Nate的高速拳击计数比赛的胜利,我有幸去博尔特的火花快乐电子公司总部和老板Nate面基。在我们的面基探讨过程中,我们认为专门来写一篇关于如何在短时间内解决复杂问题的教程很有必要。我会就专门解决这个问题为例,我希望能为你日后将此思路用于解决自己的问题,无论问题规模的巨细。

从何处开始Where to Start

对于一个完整的软件项目,从工程师的角度,都有四个过程:In full-fledged software projects, from an Engineer’s perspective, you have four major phases:

  • Requirements需求分析
  • Design架构设计
  • Implementation代码实施
  • Test结果测试

毋庸讳言,架构设计和代码实施似乎是所有热衷自己专业的软件工程师最感兴趣的工作。因为这些过程充满创造力和乐趣。自然低,就有一种只分析了问题的一个方面就开始进行架构设计和代码实施。然而,我一再强调上述过程中的第一步和最后一步对于项目的最终成功至关重要,无论问题的规模大或小。如果你对此质疑,你可以想象一下就我们这个沙袋计数问题可以快速设计架构,但由于我手头没有真实的装置去测试。但只需稍微简单的最终修改,就可以修复这些问题并最终获得正确的结果。反之亦然,一个漂亮的设计和优雅的实现但无法实现最终所需功能也是一个失败的方案。

我没有将原型设计列作专门的一个过程,因为根据具体的问题中,原型测试可能是一个过程的一部分或者多个过程中都包含。例如,如果一个问题并不是完全了解其实现过程,原型测试就可以帮助确定需求,至少可能一共一个概念的证明,或者验证一种技术是否有助于实现此方案。总而言之,原型测试在这些扮演的角色可能不止是一个过程。

回到这个案例中,即便如此小的项目,我也建议你花点时间把项目分成四个步骤来完成,否则你就很容易有疏漏。为了确定完整的项目需求,我们来罗列每个一个项目所需。网站上列出的需求可以罗列成五个部分。

这个案例中,我将Nate所做的工作视作为说明需求所做的原型尝试,用于指明不和构建有效的系统。通过Nate所叙述的系统搭建的过程,我们知道这是一个加速度计安装在速度球沙袋的基座上,这个系统的采样周期是2毫秒,我们也知道使用多项式平滑滤波方式可以布置信号的峰值,但却无法获得准确的击打次数统计。

 

对于这样一个较小的项目,在实现过程中,我们尝试不要太贵规范化的罗列目标(需求分析):

  • 该算法需要能够从原始记录的数据中获得正确的击打次数。
  • 该算法能够在8位或者32位的微控制器上实现
  • 撰写文档和教程帮助大家了解解决问题过程中的思路和方法
  • 将代码和文档在网站或者公共托管的地方发布
  • 测试你的算法用于数据记录的结果,并用于未知的数据记录并给出结果。
  • 加速度计放置在沙袋上方的基座,Z轴正向朝上方,负向朝下方。
  • 数据记录需要更加本质的处理算法,你需要根据来源的振幅校正已有数据-正如Nate所猜测的那样,共振可能是问题的源头。
  • 你有15天的时间完成此项目(哇哈!)

创建建解决方案

现在正式开始进入项目解决问题的阶段,因为现在需求已经明确了。时间紧迫,由于我没有硬件来测试并直观的看到算法实时处理数据的结果。我从在电脑上使用Java编程环境来验证测试。我先写程序让搜集到的数据以图表方式显示出来。我使用NetBeans这个Java开放环境多年了。其中,JFreeChart库用于绘制数据图表很赞,所以我先在项目中把此库引用进来。Netbeans用于构建图形化设计的开发非常棒。我只需要在现有的图形化接口上布局空白版面并且调用JFreeChart库在其上绘制图形。就像示波器视图一样很容易就能通过上述工具创建。

NetBeans IDE

由于这个算法的测试时间紧迫,我第一次测试就尽可能用使用面向对象的方法,借助Java语言中已有的特性尽可能便捷达成目的。然后我再使用更像是C语言的算法操作步骤。我先直接从记录的数据中分别绘制出XYZ的图形。当我观察现有的每天数据记录,我觉得需要先去掉偏置量(例如重力加速度引起的),然后求此三个量的平方和的根。我把相邻的数值求平均数使曲线稍显平滑,用阀值之间的最小时间作为基准来执行滤波算法。 总之,这么干反而使得图表上显示的情况更加糟糕。我决定放弃X和Y分量,一方面是由于我不清楚它的安装方向,另一方面它也不可能每次都精确放置在同一个位置。对我来说糟糕的是,即使是只考Z轴分量,图像看起来还都是完全淹没在噪声之中。我发现流水数据的峰值之间非常相近。仅仅是我设定的峰值间最小时间差对记录击打次数有些意义,然而其它的数据似乎并没有太多有价值的信息。甚至有些时候计数都不随着击打而增加,问题到底出在哪里?

下面就是执行了函数runF1后生成的波形图。蓝色的信号是Z轴滤波后的数据,红色是用于记录击打时产生的峰值。正如我之前所说的那样,如果记录每次击打不设置最少250毫米时间间隔,计数器就会疯狂的增加技术。注意到我引入了两个5毫秒的延时来处理峰值,情况就会有所改善。如果把时间间隔提升到10毫秒,情况就会更加改善。 我稍后会谈到更多关于对正信号的问题,不过就这幅图来看,你就知道这个步骤对于获得准确结果何等重要。

 

First filter with many peaks

蓝色信号是Z轴滤波后的图形,红色是其达到阀值时用于计数的击打

如果你仔细观察虚拟示波器的输出,你就会发现在25000毫秒到26000毫秒之间的1秒时间里,有9次显著的加速度事件发生。难怪Nate在这一秒记录了九次击打。那究竟在一秒的时间内,我们预期的击打次数能有多少?回到绘制的图形上,我需要增加些其它的近似方法或者约束。此时别忘了谦逊的美德,如果你趋之若鹜的骑上高马,那你也会被摔得更疼。

理解问题解答的有效域

典型的需求分析报告中,包含了问题解答的有效域。类似于一些一元二次方程出现两个数学解答时,往往符合合理事实的答案只有其中一个。譬如根据条件列出包含未知数的方程中,未知数是年龄,长度等只可能是正数的解答,而数学解答给出了一正一负的结果。那么负数的解答显然是不合事实情理的,应该被舍去。

通常在进行问题的需求分析时,就已经确定下了问题的可行域。根据具体问题的场景相关知识以及设计方案的过程中,我们就知道问题解答范围的合理性。我对于拳击和速度球沙袋没有什么太多的认知,所以做些Google搜索就很有必要。

我得到一些重要的信息就是当拳击手每次击打速度球沙袋进行训练时,将会导致速度球沙袋三次与基座之间的剧烈接触牵引:一次向前(击打方向),然后向后(击打方向反向),然后再一次向前(击打方向),然后拳击手给出下一次击打。这样一次练习的周期中实际有4次重要的数据信息,一次来源与击打时的震动,另外三次源于沙袋和基座之间的摆动。

现在,我们看着波形信息的意义就明确多了。每次击打沙袋并不在数据上只产生一次峰值。我的第二个问题是,对于一个正常的拳击手来说,他每秒可以击打沙袋多少次。我尝试用直观常识去思考,这肯定有个合理的范围,然后我查找了和拳击竞技相关资料的网站,以及结合相关视频,我最后自己总结了一下,拳击手训练时每秒的击打次数应该在2次到4次是合理范围。这样,问题确定下来了,我需要寻找在加速度计采集的信息中,发生频率在2至4赫兹之间的事情。是时候开始进行架构设计和代码实施了。

循序渐进,摸着石头过河,小步迭代验证方案

虽然每个人在设计架构和代码实施阶段的思路方式可能略有不同,但我还是强烈建议你采用迭代的策略来进行这两个阶段的步骤,尤其当你对一个亟待解决的问题面前没有明确清晰的解决方案,而是采用尝试方式进行问题处理时。我还建议当你准备对现有算法进行重大调整时,最好创建一个新的副本再开始修改。或者创建一个新的空函数,拷贝进原来的代码来开始修改,这样的源代码迭代控制方法能够保证保留你原有的迭代路径,如果出现问题或者之前的源代码有值得引用的地方都可以避免随时可以返回。我通常不会再写完10-20行代码后还继续写,我会先想办法验证它运行后打印一些东西,以确认我的逻辑和假设是正确的。在我的整个“码农”生涯中,如果写代码时没有可以验证运行的目标机器,我是会抱怨这样的工作方式。在2006年时,我曾听到过一位海军上将的话:

摸索一步,验证一步,收获颇丰。

– 美国海军上将迈耶斯

我非常认同他的说法,因为迭代验证能确保我的代码写的是按照我想要它运行的方向进发的。它要买确认你的假设要么揭示你正在朝错误方向迈进,无论哪一种,都能让你一直快速走在正确的道路上,而不会在做了一大堆工作之后才发现徒劳无功。这也是我选择在这次方案中使用Java作为原型开发平台的原因之一,因为我没有实际的硬件装置可用于测试,但我仍能快速的运行图示并测试代码。

下面你会考到6个runFx()的函数,函数以毫米为单位验证当前代码,并使我可以在Java绘图窗口中查看数据滚动和滤波后的外观。我将X,Y和Z加速度数据与X,Y和Z平均值一起传递。由于我在大多数算法中只使用Z数据,我忽略并发送其他值来绘制,所以当查看1到5的图形时会有点混乱,因为它们与图例不匹配。但是,实时绘图允许我查看数据并观察命中计数器增量。我实际上可以看到并感觉到击打的节奏感,以及加速度数据如何受到长时间恒定节奏下的共振的影响。除了使用Java System.out.println()函数的可视输出之外,我还可以将数据输出到NetBeans IDE中的窗口。

如果你看看我的GitHub上的Java子目录,有一个名为MainLoop.java的文件。 在该文件中,我有一些名为run1()到 run6()的函数。 这些是我的速度袋算法代码的六个主要迭代。

这里是六个迭代中的每一个的一些要点。

 

runF1

runF1() 仅使用Z轴,并且使用Z数据的均值去掉偏置,使用滑动窗口和滤波。 我创建了一个称为延迟的元素,这是一种延迟输入数据的方式,因此可以稍后与平均结果的输出对齐。 这允许基于周围值而不是先前的值从Z轴数据中减去滑动窗口平均值。 击打检测使用大于五个样本的平均值的放大滤波器数据的直接比较,在检测之间的最短时差为250毫秒。

runF2

runF2() used only Z axis, and employed weak bias removal via a sliding window but added dynamic beta amplification of the filtered Z data based on the average amplitude above the bias that was removed when the last punch was detected. Also, a dynamic minimum time between punches of 225ms to 270ms was calculated based on delta time since last punch was detected. I called the amount of bias removed noise floor. I added a button to stop and resume the simulation so I could examine the debug output and the waveforms. This allowed me to see the beta amplification being used as the simulation went along.

runF3

runF3() used X and Z axis data. My theory was that there might be a jolt of movement from the punching action that could be additive to the Z axis data to help pinpoint the actual punch. It was basically the same algorithm as RunF2 but added in the X axis. It actually worked pretty well, and I thought I might be onto something here by correlating X movement and Z. I tried various tweaks and gyrations as you can see in the code lots of commented out experiments. I started playing around with what I call a compressor, which took the sum of five samples to see if it would detect bunches of energy around when punches occur. I didn’t use it in the algorithm but printed out how many times it crossed a threshold to see if it had any potential as a filtering element. In the end, this algorithm started to implode on itself, and it was time to take what I learned and start a new algorithm.

runF4

In runF4(), I increased the bias removal average to 50 samples. It started to work in attenuation and sample compression along with a fixed point LSB to preserve some decimal precision to the integer attenuate data. Since one of the requirements was this should be able to run on 8-bit microcontrollers, I wanted to avoid using floating point and time consuming math functions in the final C/C++ code. I’ll speak more to this in the components section, but, for now, know that I’m starting to work this in. I’ve convinced myself that finding bursts of acceleration is the way to go. At this point, I am removing the bias from both Z and X axis then squaring. I then attenuate each, adding the results together but scaling X axis value by 10. I added a second stage of averaging 11 filtered values to start smoothing the bursts of acceleration. Next, when the smoothed value gets above a fixed threshold of 100, the unsmoothed combination of Z and X squared starts getting loaded into the compressor until 100 samples have been added. If the compressor output of the 100 samples is greater than 5000, it is recorded as a hit. A variable time between punches gate is employed, but it is much smaller since the compressor is using 100 samples to encapsulate the punch detection. This lowers the gate time to between 125 and 275 milliseconds. While showing some promise, it was still too sensitive. While one data set would be spot on another would be off by 10 or more punches. After many tweaks and experiments, this algorithm began to implode on itself, and it was once again time to take what I’ve learned and start anew. I should mention that at this tim I’m starting to think there might not be a satisfactory solution to this problem. The resonant vibrations that seem to be out of phase with the contacts of the bag just seems to wreak havoc on the acceleration seen when the boxer gets into a good rhythm. Could this all just be a waste of time?

runF5

runF5()’s algorithm started out with the notion that a more formal high pass filter needed to be introduced rather than an average subtracted from the signal. The basic premise of the high pass filter was to use 99% of the value of new samples added to 1% of the value of average. An important concept added towards the end of runF5’s evolution was to try to simplify the algorithm by removing the first stage of processing into its own file to isolate it from later stages. Divide and Conquer; it’s been around forever, and it really holds true time and time again. I tried many experiments as you can see from the many commented out lines in the algorithm and in the FrontEndProcessorOld.java file. In the end, it was time to carry forward the new Front End Processor concept and start anew with divide and conquer and a need for a more formal high pass filter.

runF6

With time running out, it’s time to pull together all that has been learned up to now, get the Java code ready to port to C/C++ and implement real filters as opposed to using running averages. In runF6(), I had been pulling together the theory that I need to filter out the bias on the front end with a high pass filter and then try to use a low pass filter on the remaining signal to find bursts of acceleration that occur at a 2 to 4 Hertz frequency. No way was I going to learn how to calculate my own filter tap values to implement the high and low pass filters in the small amount of time left before the deadline. Luckily, I discovered the t-filter web site. Talk about a triple play. Not only was I able to put in my parameters and get filter tap values, I was also able to leverage the C code it generated with a few tweaks in my Java code. Plus, it converted the tap values to fixed point for me! Fully employing the divide and conquer concept, this final version of the algorithm introduced isolated sub algorithms for both Front End Processor and Detection Processing. This allowed me to isolate the two functions from each other except for the output signal of one becoming the input to the other, which enabled me to focus easily on the task at hand rather than sift through a large group of variables where some might be shared between the two stages.

通过功能模块的划分,现在就非常能够明晰的在送数据给检测计数模块前进行抵消偏置量的工作。现在,检测部分的代码模块可以专注于过滤和实现一个功能,筛选选择每秒2到4次之间发生的击打事件。

需要注意的一点是,这个最终算法比一些先前的算法简洁。 即使它的软件,在过程中的某个时候,你应该仍然做一个称为Muntzing的技术。Muntzing是一种技术,回去看看什么可以删除而影响功能。 简洁优雅的代码标准是:每行代码都必不可少,否则就会导致错误。 你可以通过Google  Earl “Madman” Muntz来更好地理解和感受Muntzing的精神。

Final output of DET

Final output of DET

Above is the visual output from runF6. The Green line is 45 samples delayed of the output of the low pass filter, and the yellow line is an average of 99 values of the output of the low pass filter. The Detection Processor includes a detection algorithm that detects punches by tracking min and max crossings of the Green signal using the Yellow signal as a template for dynamic thresholding. Each minimum is a Red spike, and each maximum is a Blue spike, which is also a punch detection. The timescale is in milliseconds. Notice there are about three blue spikes per second inside the 2 to 4Hz range predicted. And the rest is history!

算法构成

这里简要介绍在各种算法中使用的个部分。

Delay

This is used to buffer a signal so you can time align it to some other operation. For example, if you average nine samples and you want to subtract the average from the original signal, you can use a delay of five samples of the original signal so you can use values that are itself plus the four samples before and four samples after.

Attenuate

Attenuation is a simple but useful operation that can scale a signal down before it is amplified in some fashion with filtering or some other operation that adds gain to the signal. Typically attenuation is measured in decibels (dB). You can attenuate power or amplitude depending on your application. If you cut the amplitude by half, you are reducing it by -6 dB. If you want to attenuate by other dB values, you can check the dB scale here. As it relates to the Speedbag algorithm, I’m basically trying to create clear gaps in the signal, for instance squelching or squishing smaller values closer to zero so that squaring values later can really push the peaks higher but not having as much effect on the values pushed down towards zero. I used this technique to help accentuate the bursts of acceleration versus background vibrations of the speed bag platform.

Sliding Window Average

Sliding Window Average is a technique of calculating a continuous average of the incoming signal over a given window of samples. The number of samples to be averaged is known as the window size. The way I like to implement a sliding window is to keep a running total of the samples and a ring buffer to keep track of the values. Once the ring buffer is full, the oldest value is removed and replaced with the next incoming value, and the value removed from the ring buffer is subtracted from the new value. That result is added to the running tally. Then simply divide the running total by the window size to get the current average whenever needed.

Rectify

This is a very simple concept which is to change the sign of the values to all positive or all negative so they are additive. In this case, I used rectification to change all values to positive. As with rectification, you can use a full wave or half wave method. You can easily do full wave by using the abs() math function that returns the value as positive. You can square values to turn them positive, but you are changing the amplitude. A simple rectify can turn them positive without any other effects. To perform half wave rectification, you can just set any value less than zero to zero.

Compression

In the DSP world Compression is typically defined as compressing the amplitudes to keep them in a close range. My compression technique here is to sum up the values in a window of samples. This is a form of down-sampling as you only get one sample out each time the window is filled, but no values are being thrown away. It’s a pure total of the window, or optionally an average of the window. This was employed in a few of the algorithms to try to identify bursts of acceleration from quieter times. I didn’t actually use it in the final algorithm.

FIR Filter

Finite Impulse Response (FIR) is a digital filter that is implemented via a number of taps, each with its assigned polynomial coefficient. The number of taps is known as the filter’s order. One strength of the FIR is that it does not use any feedback, so any rounding errors are not cumulative and will not grow larger over time. A finite impulse response simply means that if you input a stream of samples that consisted of a one followed by all zeros, the output of the filter would go to zero within at most the order +1 amount of 0 value samples being fed in. So, the response to that single sample of one lives for a finite amount of samples and is gone. This is essentially achieved by the fact there isn’t any feedback employed. I’ve seen DSP articles claim calculating filter tap size and coefficients is simple, but not to me. I ended up finding an online app called tFilter that saved me a lot of time and aggravation. You pick the type of filter (low, high, bandpass, bandstop, etc) and then setup your frequency ranges and sampling frequency of your input data. You can even pick your coefficients to be produced in fixed point to avoid using floating point math. If you’re not sure how to use fixed point or never heard of it, I’ll talk about that in the Embedded Optimization Techniques section.

基于嵌入式目标运行机进行优化

Magnitude Squared

Mag Square is a technique that can save computing power of calculating square roots. For example, if you want to calculate the vector for X and Z axis, normally you would do the following: val = sqr((X * X) + (Y * Y)). However, you can simply leave the value in (X * X) + (Y * Y), unless you really need the exact vector value, the Mag Square gives you a usable ratio compared to other vectors calculated on subsequent samples. The numbers will be much larger, and you may want to use attenuation to make them smaller to avoid overflow from additional computation downstream.

I used this technique in the final algorithm to help accentuate the bursts of acceleration from the background vibrations. I only used Z * Z in my calculation, but I then attenuated all the values by half or -6dB to bring them back down to reasonable levels for further processing. For example, after removing the bias if I had some samples around 2 and then some around 10, when I squared those values I now have 4 and 100, a 25 to 1 ratio. Now, if I attenuate by .5, I have 2 and 50, still a 25 to 1 ratio but now with smaller numbers to work with.

Fixed Point

Using fixed point numbers is another way to stretch performance, especially on microcontrollers. Fixed point is basically integer math, but it can keep precision via an implied fixed decimal point at a particular bit position in all integers. In the case of my FIR filter, I instructed tFilter to generate polynomial values in 16-bit fixed point values. My motivation for this was to ensure I don’t use more than 32-bit integers, which would especially hurt performance on an 8-bit microcontroller.

Rather than go into the FIR filter code to explain how fixed point works, let me first use a simple example. While the FIR filter algorithm does complex filtering with many polynomials, we could implement a simple filter that outputs the same input signal but -6dB down or half its amplitude. In floating point terms, this would be a simple one tap filter to multiply each incoming sample by 0.5. To do this in fixed point with 16 bit precision, we would need to convert 0.5 into its 16-bit fixed point representation. A value of 1.0 is represented by 1 * (216) or 65,536. Anything less than 65536 is a value less than 1. To create a fixed point integer of 0.5, we simply use the same formula 0.5 * (216), which equals 32,768. Now we can use that value to lower the amplitude by .5 of every sample input. For example, say we input into our simple filter a sample with the value of 10. The filter would calculate 10 * 32768 = 327,680, which is the fixed point representation. If we no longer care about preserving the precision after the calculations are performed, it can easily be turned back into a non-fixed point integer by simply right shifting by the number of bits of precision being used. Thus, 327680 >> 16 = 5. As you can see, our filter changed 10 into 5 which of course is the one half or -6dB we wanted out. I know 0.5 was pretty simple, but if you had wanted 1/8 the amplitude, the same process would be used, 65536 * .125 = 8192. If we input a sample of 16, then 16 * 8192 = 131072, now change it back to an integer 131072 >> 16 = 2. Just to demonstrate how you lose the precision when turning back to integer (the same as going float to integer) if we input 10 into the 1/8th filter it would yield the following, 10 * 8192 = 81920 and then turning it back to integer would be 81920 >> 16 = 1, notice it was 1.25 in fixed point representation.

Getting back to the FIR filters, I picked 16 bits of precision, so I could have a fair amount of precision but balanced with a reasonable amount of whole numbers. Normally, a signed 32-bit integer can have a range of – 2,147,483,648 to +2,147,483,647, however there now are only 16 bits of whole numbers allowed which is a range of -32,768 to +32,767. Since you are now limited in the range of numbers you can use, you need to be cognizant of the values being fed in. If you look at the FEPFilter_get function, you will see there is an accumulator variable accZ which sums the values from each of the taps. Usually if your tap history values are 32 bit, you make your accumulator 64-bit to be sure you can hold the sum of all tap values. However, you can use a 32 bit value if you ensure that your input values are all less than some maximum. One way to calculate your maximum input value is to sum up the absolute values of the coefficients and divide by the maximum integer portion of the fixed point scheme. In the case of the FEP FIR filter, the sum of coefficients was 131646, so if the numbers can be 15 bits of positive whole numbers + 16 bits of fractional numbers, I can use the formula (231)/131646 which gives the FEP maximum input value of + or – 16,312. In this case, another optimization can be realized which is not to have a microcontroller do 64-bit calculations.

Walking the Signal Processing Chain

Delays Due to Filtering

Before walking through the processing chain, we should discuss delays caused by filtering. Many types of filtering add delays to the signal being processed. If you do a lot of filtering work, you are probably well aware of this fact, but, if you are not all that experienced with filtering signals, it’s something of which you should be aware. What do I mean by delay? This simply means that if I put in a value X and I get out a value Y, how long it takes for the most impact of X to show up in Y is the delay. In the case of a FIR filter, it can be easily seen by the filter’s Impulse response plot, which, if you remember from my description of FIR filters, is a stream of 0’s with a single 1 inserted. T-Filter shows the impulse response, so you can see how X impacts Y’s output. Below is an image of the FEP’s high pass filter Impulse Response taken from the T-Filter website. Notice in the image that the maximum impact on X is exactly in the middle, and there is a point for each tap in the filter.

Impulse response from T-Filter

Below is a diagram of a few of the FEP’s high pass filter signals. The red signal is the input from the accelerometer or the newest sample going into the filter, the blue signal is the oldest sample in the filter’s ring buffer. There are 19 taps in the FIR filter so they represent a plot of the first and last samples in the filter window. The green signal is the value coming out of the high pass filter. So to relate to my X and Y analogy above, the red signal is X and the green signal is Y. The blue signal is delayed by 36 milliseconds in relation to the red input signal which is exactly 18 samples at 2 milliseconds, this is the window of data that the filter works on and is the Finite amount of time X affects Y.

Delayed Signal Example

Notice the output of the high pass filter (green signal) seems to track changes from the input at a delay of 18 milliseconds, which is 9 samples at 2 milliseconds each. So, the most impact from the input signal is seen in the middle of the filter window, which also coincides with the Impulse Response plot where the strongest effects of the 1 value input are seen at the center of the filter window.

It’s not only a FIR that adds delay. Usually, any filtering that is done on a window of samples will cause a delay, and, typically, it will be half the window length. Depending on your application, this delay may or may not have to be accounted for in your design. However, if you want to line this signal up with another unfiltered or less filtered signal, you are going to have to account for it and align it with the use of a delay component.

Front End Processor

I’ve talked at length about how to get to a final solution and all the components that made up the solution, so now let’s walk through the processing chain and see how the signal is transformed into one that reveals the punches. The FEP’s main goal is to remove bias and create an output signal that smears across the bursts of acceleration to create a wave that is higher in amplitude during increased acceleration and lower amplitude during times of less acceleration. There are four serial components to the FEP: a High Pass FIR, Attenuator, Rectifier and Smoothing via Sliding Window Average.

The first image is the input and output of the High Pass FIR. Since they are offset by the amount of bias, they don’t overlay very much. The red signal is the input from the accelerometer, and the blue is the output from the FIR. Notice the 1g of acceleration due to gravity is removed and slower changes in the signal are filtered out. If you look between 24,750 and 25,000 milliseconds, you can see the blue signal is more like a straight line with spikes and a slight ringing on it, while the original input has those spikes but meandering on some slow ripple.

FEP Highpass In Out

Next is the output of the attenuator. While this component works on the entire signal, it lowers the peak values of the signal, but its most important job is to squish the quieter parts of the signal closer to zero values. The image below shows the output of the attenuator, and the input was the output of the High Pass FIR. As expected, peaks are much lower but so is the quieter time. This makes it a little easier to see the acceleration bursts.

FEP Atten Out

Next is the rectifier component. Its job is to turn all the acceleration energy in the positive direction so that it can be used in averaging. For example, an acceleration causing a positive spike of 1000 followed by a negative spike of 990 would yield an average of 5, while a 1000 followed by a positive of 990 would yield an average of 995, a huge difference. Below is an image of the Rectifier output. The bursts of acceleration are slightly more visually apparent, but not easily discernable. In fact, this image shows exactly why this problem is such a tough one to solve; you can clearly see how resonant shaking of the base causes the pattern to change during punch energy being added. The left side is lower and more frequent peaks, the right side has higher but less frequent peaks.

FEP Rectifier Out

The 49 value sliding window is the final step in the FEP. While we have done subtle changes to the signal that haven’t exactly made the punches jump out in the images, this final stage makes it visually apparent that the signal is well on its way of yielding the hidden punch information. The fruits of the previous signal processing magically show up at this stage. Below is an image of the Sliding Window average. The blue signal is its input or the output of the Rectifier, and the red signal is the output of the sliding window. The red signal is also the final output of the FEP stage of processing. Since it is a window, it has a delay associated with it. Its approximately 22 samples or 44 milliseconds on average. It doesn’t always look that way because sometimes the input signal spikes are suddenly tall with smaller ringing afterwards. Other times there are some small spikes leading up to the tall spikes and that makes the sliding window average output appear inconsistent in its delay based on where the peak of the output shows up. Although these bumps are small, they are now representing where new acceleration energy is being introduced due to punches.

FEP Final Out

Detection Processor

Now it’s time to move on to the Detection Processor (DET). The FEP outputs a signal that is starting to show where the bursts of acceleration are occurring. The DET’s job will be to enhance this signal and employ an algorithm to detect where the punches are occurring.

The first stage of the DET is an attenuator. Eventually, I want to add exponential gain to the signal to really pull up the peaks, but, before doing that, it is important to once again squish down the lower values towards zero and lower the peaks to keep from generating values too large to process in the rest of the DET chain. Below is an image of the output from the attenuator stage, it looks just like the signal output from the FEP, however notice the signal level peaks were above 100 from the FEP, and now peaks are barely over 50. The vertical scale is zoomed in with the max amplitude set to 500 so you can see that there is a viable signal with punch information.

DET-Atten-Out

With the signal sufficiently attenuated, it’s time to create the magic. The Magnitude Square function is where it all comes together. The attenuated signal carries the tiny seeds from which I’ll grow towering Redwoods. Below is an image of the Mag Square output, the red signal is the attenuated input, and the blue signal is the mag square output. I’ve had to zoom out to a 3,000 max vertical, and, as you can see, the input signal almost looks flat, yet the mag square was able to pull out unmistakable peaks that will aid the detection algorithm to pick out punches. You might ask why not just use these giant peaks to detect punches. One of the reasons I’ve picked this area of the signal to analyze is to show you how the amount of acceleration can vary greatly as you can see the peak between 25,000 and 25,250 is much smaller than the surrounding peaks, which makes pure thresholding a tough chore.

DET Mag Square

Next, I decided to put a Low Pass filter to try to remove any fast changing parts of the signal since I’m looking for events that occur in the 2 to 4 Hz range. It was tough on T-Filter to create a tight low pass filter with a 0 to 5 Hz band pass as it was generating filters with over 100 taps, and I didn’t want to take that processing hit, not to mention I would then need a 64-bit accumulator to hold the sum. I relaxed the band pass with a 0 to 19 Hz range and the band stop at 100 to 250 Hz. Below is an image of the low pass filter output. The blue signal is the input, and the red signal is the delayed output. I used this image because it allows the input and output signal to be seen without interfering with each other. The delay is due to 6 sample delay of the low pass FIR, but I have also introduced a 49 sample delay to this signal so that it is aligned in the center of the 99 sample sliding window average that follows in the processing chain. So it is delayed by a total of 55 samples or 110 milliseconds. In this image, you can see the slight amplification of the slow peaks by their height and how it is smoothed as the faster changing elements are attenuated. Not a lot going on here but the signal is a little cleaner, Earl Muntz might suggest I cut the low pass filter out of the circuit, and it might very well work without it.

Low pass delayed DET

The final stage of the signal processing is a 99 sample sliding window average. I built into the sliding window average the ability to return the sample in the middle of the window each time a new value is added and that is how I produced the 49 sample delayed signal in the previous image. This is important because the detection algorithm is going to have 2 parallel signals passed into it, the output of the 99 sliding window average and the 49 sample delayed input into the sliding window average. This will perfectly align the un-averaged signal in the middle of the sliding window average. The averaged signal is used as a dynamic threshold for the detection algorithm to use in its detection processing. Here, once again, is the image of the final output from the DET.

DET Final Out

In the image, the green and yellow signals are inputs to the detection algorithm, and the blue and red are outputs. As you can see, the green signal, which is a 49 samples delayed, is aligned perfectly with the yellow 99 sliding window average peaks. The detection algorithm monitors the crossing of the yellow by the green signal. This is accomplished by both maximum and minimum start guard state that verifies the signal has moved enough in the minimum or maximum direction in relation to the yellow signal and then switches to a state that monitors the green signal for enough change in direction to declare a maximum or minimum. When the peak start occurs and it’s been at least 260ms since the last detected peak, the state switches to monitor for a new peak in the green signal and also makes the blue spike seen in the image. This is when a punch count is registered. Once a new peak has been detected, the state changes to look for the start of a new minimum. Now, if the green signal falls below the yellow by a delta of 50, the state changes to look for a new minimum of the green signal. Once the green signal minimum is declared, the state changes to start looking for the start of a new peak of the green signal, and a red spike is shown on the image when this occurs.

Again, I’ve picked this time in the recorded data because it shows how the algorithm can track the punches even during big swings in peak amplitude. What’s interesting here is if you look between the 24,750 and 25,000 time frame, you can see the red spike detected a minimum due to the little spike upward of the green signal, which means the state machine started to look for the next start of peak at that point. However, the green signal never crossed the yellow line, so the start of peak state rode the signal all the way down to the floor and waited until the cross of the yellow line just before the 25,250 mark to declare the next start of peak. Additionally, the peak at the 25,250 mark is much lower than the surrounding peaks, but it was still easily detected. Thus, the dynamic thresholding and the state machine logic allows the speed bag punch detector algorithm to “Roll with the Punches”, so to speak.

最后感言

总而言之,我们在本文中讨论了很多这次技术众包背后的细节。首先,充分分析问题并确定需求的重要性,因为它涉及到所需项目的努力方向以及最终顺利完成它所需的各领域知识。第二,对于这种性质的问题,创建验证环境来构建算法是势在必行的,并且在这种情况下,它是具有基于Java技术搭建的数据可视化处理的原型。第三,是在最终的目标机器和环境中实现,在一台PC上你有优秀的经过优化的编译器和强大的CPU及缓存,但对于微控制器,针对目标机器的优化是留给你的工作。使用您知道的每个优化技巧,以保证微控制器能尽可能快地处理数据。第四,迭代开发可以帮助你解决这样的问题:在尝试中摸着石头过河,边学边做边验证。

当我回顾这个众包项目,让我来探讨成功的终极奥秘,我想主要是两点。为这项工作创造正确的工具是无价的。能够直观看到算法作用后的信号结果的能力是无价的。不仅绘制输出信号,而且它实时绘制,使我完全理解生成的加速度信息背后的因素。就好像Nate在练习拳击,而我正在看着我的屏幕上的波形信息。然而,根本的因素是,我意识到这是一个每秒发生2到4次的事情。我坚定信念并不懈地追求如何将原始的输入信号转换成显示这些事件的东西。我并没有完全指望让Google找到答案。请谨记:知识不是来自书中,它只是被记录在书中。首先,总要有人抛下书本去发现一些新东西,然后它才成为知识。使用你已掌握或者可以获取的知识,但不要害怕使用你的想象力来尝试之前没有尝试过的未解问题。所以记住,比方说,当你来到铺砌的道路的尽头,你是转过头找一条别人已经铺好的路,还是说在岔路口,继续前进,发现属于自己的新路。我不能只是谷歌如何用加速度计记录拳击速度沙袋被击打次数,但现在你们就可以了。


cc

原始文章采用CC BY-SA 4.0,您可以自由地:

  • 演绎 — 修改、转换或以本作品为基础进行创作
  • 在任何用途下,甚至商业目的。
  • 只要你遵守许可协议条款,许可人就无法收回你的这些权利。

本文由翻译美国开源硬件厂商Sparkfun(火花快乐)的相关教程翻译,原始教程采用同样的CC BY-SA 4.0协议,为便于理解和方便读者学习使用,部分内容为适应国内使用场景稍有删改或整合,这些行为都是协议允许并鼓励的。

原始文章及相关素材链接:

https://www.sparkfun.com/news/2115?_ga=1.105187979.946766378.1445226389#requirements

https://learn.sparkfun.com/tutorials/lessons-in-algorithms

上拉电阻

介绍

  上拉电阻在使用微控制器(MCU)或任何数字逻辑器件时都非常常见。 本教程将说明在我们在什么情况下使用上拉电阻,然后我们将做一个简单的计算,来说明为什么上拉电阻是重要的。

什么是上拉电阻

  假设您有一个微控制器,其中一个引脚配置为输入。 如果没有东西任何连接到该引脚,并且您的程序读取该引脚的状态,那么它是高(拉到VCC)还是低(拉到地)呢? 这很难说。 我们将这种现象称为浮动。 为了防止这种未知状态,上拉或下拉电阻将确保引脚处于高或低状态,同时通过少量电流。

  为了简单起见,我们将着重讲上拉电阻,因为它比下拉电阻更常见。 它们使用相同的概念操作,但是上拉电阻连接到高电平上(这通常是3.3V或5V,通常被称为VCC),而下拉电阻连接到地。

  上拉电阻通常与按钮和开关一起使用。

  如图使用上拉电阻,当按钮未按下时,输入引脚将读取高电平状态。 换句话说,在VCC和输入引脚(不接地)之间流过少量电流,因此输入引脚读数接近VCC。 当按下按钮时,它将输入引脚直接连接到地。 电流流过电阻到地,因此输入引脚读取低电平状态。 记住,如果电阻不在那里,你的按钮将VCC直接连接到地,造成短路,那就糟糕了。

  那么我们应该如何选择电阻值呢?

  答案很简单,我们需要一个10kΩ的上拉电阻。

  阻值低电阻被称为强上拉电阻(流过的电流较多),阻值高的电阻被称为弱上拉电阻(流过的电流较少)。

  上拉电阻阻值的选择需要满足两个条件:

  1.当按下按钮时,输入引脚被拉低。 电阻R1的值控制从VCC流向地的电流。

  2.当未按下按钮时,输入引脚被拉高。 上拉电阻的值控制输入引脚上的电压。

  对于条件1而言,电阻的值不能太低。 电阻越低,按钮按下时消耗的功率就越多。 你通常需要一个大的电阻值(10kΩ)。但是太大也不合适,这会与条件2冲突,如果一个4MΩ的电阻作为上拉电阻,如此大的电阻会使得输入引脚的电压太低。

  为了满足条件2,我们一般使用比输入引脚的输入阻抗(R2)小一个数量级(1/10)的上拉电阻(R1)。微控制器上的输入引脚的阻抗一般是100k-1MΩ。所谓的输入阻抗,即图中的R2。因此,当按钮未被按下时,非常少量的电流从VCC流过R1并进入输入引脚。上拉电阻R1和输入引脚阻抗R2对电压进行分压,R2的电压需要足够高从而使输入引脚读取高电平状态。

  举个例子,如果使用1MΩ电阻作为上拉电阻R1,输入引脚的阻抗R2为1MΩ(形成分压器),输入引脚的电压将为VCC的一半左右,微控制器可能不会将引脚注册为处于高电平状态。在5V系统上,如果电压为2.5V,微控制器在输入引脚上读取的是什么?是高还是低?微控制器无法判断。 所以10k-100kΩ的上拉电阻可以避免大多数问题。

  由于上拉电阻是如此常见,所以许多微控制器,如Arduino平台上的ATmega328微控制器,具有可以使能和禁止的内部上拉电阻。 要在Arduino上启用内部上拉电阻,可以在setup()函数中输入以下代码行:

  pinMode(5, INPUT_PULLUP); // Enable internal pull-up resistor on pin 5

  另一个要指出的是,上拉电阻越大,引脚响应电压变化的速度越慢。 这是因为,馈送输入引脚的系统本质上是与上拉电阻耦合的电容,从而形成RC滤波器,而RC滤波器需要一些时间来充电和放电。 如果你有一个真正快速变化的信号(如USB),高值上拉电阻可以限制引脚,从而   限制改变状态的速度。 这就是为什么你会经常看到USB信号线上1k到4.7KΩ的电阻。

  所有这些因素都决定了上拉电阻的阻值。

计算上拉电阻阻值

  假设您想在上述电路中,使得按下按钮时,电流限制为约1mA,其中Vcc = 5V。 你应该选择阻值为多少的电阻?

  很显然应该使用欧姆定律计算上拉电阻:

  根据上面的示意图,欧姆定律现在应变形为:

  将方程再次变形并带入数值,求解电阻:

  记住在计算前将所有单位转换为伏特,安培和欧姆(例如1mA = 0.001安培)。 最后解答可知,应当选择5kΩ的上拉电阻电阻。

  现在你应该知道什么是上拉电阻以及它是如何工作的了吧。


cc

原始文章采用CC BY-SA 4.0,您可以自由地:

  • 演绎 — 修改、转换或以本作品为基础进行创作
  • 在任何用途下,甚至商业目的。
  • 只要你遵守许可协议条款,许可人就无法收回你的这些权利。

本文由翻译美国开源硬件厂商Sparkfun(火花快乐)的相关教程翻译,原始教程采用同样的CC BY-SA 4.0协议,为便于理解和方便读者学习使用,部分内容为适应国内使用场景稍有删改或整合,这些行为都是协议允许并鼓励的。

原始文章及相关素材链接:

https://learn.sparkfun.com/tutorials/pull-up-resistors

串口通信

介绍

嵌入式电子都是关于通过电路的互动(处理器或者其他集成电路)来制作一个共生系统。为了让那些单个电路交换信息,它们必须要有一个通讯协议。上百个通讯协议已经被定义为完成数据交换,而且一般每一个会被分为一或两类:并行或者串行。

并行vs串行

并行接口能同时进行多位传输。它们通常要求有八条十六或者更多分线的数据总线。数据以1和0的波形来传输。

1

一个八位的数据线受时钟信号的控制,以每个时钟脉冲发射一个字节的速度传输。这需要用到9条线

串行接口以每单位时间发射一个单字节的速度传输它们的数据。这类接口可以只用一条线进行操作,且通常不超过4条。

1.5

串行接口的例子,每个时钟脉冲传输一个位。仅仅用到两条线

把两种接口想象作车流:并行接口就如8+道的超级高速公路,然而串行接口就像两道的乡村道路。超过一定时间,高速公路就可能使更多人到达目的地,但乡村道路也能到达目的地而且花的建设费更少。

并行接口确实有它的优势。它快,直接而且容易实现。但是它要求更多的输入输出(I/O)线。如果你已经把你的任务从ArduinoUno移到了Mega,你就知道在单片机上的I/O线是多么珍贵而且少。所以我们选用串行接口,尽管牺牲引脚的潜在速度。

异步串行

这些年来,大量的串行协议被制作出来以满足嵌入式系统的特殊需求。USB(通用串行总线)和以太网是一对广为人知串行接口。其他普遍的串行接口包括SPI,I2C以及我们今天说的一些串行标准。所有的这些接口可以分成两类:同步或者异步。

同步串行接口总是数据线伴随着时钟信号,所以所有同步串行总线上的设备享用同一时钟信号。这使得传输更直接并能加快传输,但它要求至少有一条完整的线连接通信设备。同步串行接口的例子有SPI和I2C。

异步意味着数据的传输不需要外部提供时钟信号。这种传输方法能很好的降低线和I/O引脚的需求,但这也意味着我们需要花点精力来注意数据的输入输出。在这片指导里我们将会介绍最为常见的一些异步传输的串行协议。事实上,它是十分普通的,当众人在说‘串行’的时候就是再说这个协议了(你可能会通过这篇指导注意到一些)

无时钟信号的串行协议在嵌入式电子电路中是被广泛利用的。如果你想要加一个GPS模块,蓝牙,无线模块,串口液晶显示屏或者其他额外设备到你的项目里,你可能需要拿出一些串行符。

串行规则

异步串行协议有大量内建的规则——帮助确认无差错数据传输的机制。这些机制让我们脱离了额外的时钟信号,如:

  • 数据位

  • 同步位

  • 奇偶校验位

  • 波特率

尽管这些信令机制种类繁多,但你会发现这没有一个是串行传输数据的方式。协议高度集成。最重要的部分是用来确认串行总线上的设备是否被设置为使用同一套协议

波特率

波特率决定了一条串行线的传输速率。它的单位是每秒位数(bps)。如果你倒置了波特率,你可以知道它多久传输一位。值决定了发射器能维持串行线高电平/低电平的时间或者在什么时期接受设备的信号。

波特率可以使合理范围内的任意值。但要求两端的设备使用同一个波特率。9600bps是一个比较通用的波特率,尤其是对速度要求不严格的东西。其他的一些“标准”波特率包括1200,2400,4800,19200, 38400, 57600和115200

波特率越高,传输的速度就越快,但是会有一些速度的限制。你一般不会看到超过115200的速度——那是单片机的最高传输速率。如果太快,你会在接受结束时看到错误信息,因为时钟信号和采样周期会跟不上。

帧数

每一块(通常为一字节)数据。为我们的数据追加同部位和奇偶校验位从而产生了帧。

2

串行数据帧。一些帧的符号配置了位的长度。

让我们更详细的了解每一块帧。

数据块

每一个串行数据包真正有价值的它承载的数据。我们大概称它为块,因为它的长度并没有特别说明。每一块块的数据可以设置5到9位。当然,标准的数据长度是8位一字节,但是也有其他的长度规则。一个7位的数据块会比8位的更有效率,如果你只传输7位ASCII字符。

在商定了字符长度之后,两个串行设备还要商定数据的字节序。是以最高有效位到最低传输数据,或是反过来?如果没有其他说明,你可以假设是最低有效位先传。

同部位

同部位是每一块数据传输是比较特别的两三位。它们是起始位终止位(多位)。如它们的名字所示,这些位标记了一个包的起始和结束。起始位只有一位,但是终止位可以使一或者两位(虽然一般只有一位)。

起始位总是由空数据线开始从1到0表示,然而终止位会通过把线设为1从而转换为空状态。

奇偶校验位

奇偶校验是一种简单低层次的错误检查方式。它有两种结果:奇数或偶数。为了制作奇偶校验位,所有5-9位的数据字节要被加起来,而总数的均匀度将会决定是否设置位。举个例子,假设奇偶性设置为偶,而要加的数据位是0b01011101,有奇数个1,奇偶校验位就会设为1。反过来,如果奇偶性设为奇,奇偶校验位就会设为0。

奇偶性是可选的,并且利用不是很广。它有助于在嘈杂的媒介进行传输,但它也会降低一位你的数据传输并且要求你的发送器和接收器实施错误处理(通常,接收数据出错要求重新发送。)

9600 8N1(一个例子)

9600 8N1 – 9600波特,8位数据,没有奇偶校验,一个终止位——是最为常用的串行协议之一。所以,一包或者两个9600 8N1是怎样的呢?让我们看一个例子。

一个设备发送‘O’和‘K’的ASCII字符会用到两包数据。(大写的)O的ASCII值是79,转换为8位的二进制值是01001111,然而K的二进制值是01001011。剩下的全是同部位。

虽然没有特别声明,但它的数据传输是从最低有效位开始的。可以注意到两个字节如它从右到左读的顺序来传输的。

3

因为我们以9600 bps的速度传输,所以每一个高低电平的持续时间只有1/(9600 bps)或者104 µs每位。

每有一个字节被传输,实际上已经传输了10位:一位起始位,8位数据位以及一位终止位。所以,在9600 bps的状态下,我们事实上是传输9600位每秒或者说960字节每秒。

现在你已经知道如何构造串行数据包,我们就可以向硬件部分进军了。你可以看到1,0以及波特率是如何在信号电平上运作了。

写入和硬件

一个串行总线仅有两条线组成——一条输出另外一条接收。因此,串行设备需要有两个串行引脚:接收器RX和发射器TX。

4

注意设备上的RX和TX标签是很重要的。设备的RX端要连接到另一设备的TX端,反之亦然。如果你习惯性的像VCC接VCC,GND接GND,MOSI接MOSI会很奇怪的,但你如果思考一下就能想通了,发射器应该需要的接收器而不是另一个发射器。

串行接口上的设备会全双工或者半双工地进行数据发送和接收。全双工就是两端的设备可以同时发送和接收,而半双工是两个串行设备轮流发送接收。

一些串行总线可能只是单个连接发送和接收设备。比方说,我们支持串行的LCD只接收数据而没有任何数据反馈给控制器。这就是我们所知道的单纯的串口通信。你所需要的只是一条线从主设备的TX端连接到接收器的RX端。

硬件实现

我们已经了解了异步串行的概念了,也知道我们需要怎样的线。但究竟串行通信怎样在信号电平里实施呢?事实上有很多方法。这里各种串行信号的标准,一对比较大众的硬件实施串行方法:逻辑电平(TTL)和RS-232.

通常微处理器和其他低电平IC会用TTL(晶体管—晶体管逻辑)电平。TTL串行信号的大小在微处理器电压供应范围内——通常是0到3.3V或者5V。处于VCC电平(3.3V, 5V等)的信号表示空线或者值为1的位或者终止位。0V(GND)信号代表起始位或者值为0的位。

5

RS-232,可以在大部分古老的电脑和外围设备上找到,像TTL翻转了。RS-232信号通常在13V到-13V,尽管规范是允许+/-3V到+/-25V。在这些信号里,低电压(如-5V,-13V)表示空线,终止位或者值为1的位。高电平RS-232信号则表示起始位或者值为0的位。这与TTL串行方式正好相反。

6

这两种串行信号标准里,TTL更容易在嵌入式电路上实现。然而低电压电平更容易受到长线传输亏损的影响。RS-232或者更复杂的标准比如RS-485就更适合长距离串行传输了。

当你把两个串行设备连接在一起时,要确认它们的信号电压是否配对。你不能直接把一个TTL串行设备直接接到RS-232总线上,你必须先转换这些信号

接下来,我们将会探究微处理器把串行接口上的数据转换到并行总线上的工具,UART

完成制作串行包和控制物理硬件的线的最后一块拼图,UART。

通用异步收发器(UART)是一块负责实行串口通信的电路。实际上,UART就相当于串并行接口的媒介。在UART的末端是一个的8条数据线的总线(加了一些控制引脚),在另一边是两条串行线——RX和TX。

7

超简易UART接口。并行在末端,串行在另一边

UART也像独立的IC一样,但是它们常出现在微控制器里,你可以看看你微控制器的数据表是否有UART。有些没有,有些有一个,有些有许多。比如,ArduinoUno——基于“老友”Atmega2560——只有一个UART,然而ArduinoMega——基于Atmega2560——有高达四个UART。

因为R和T是缩写,UART要负责发送和接收串行数据。在发射端,UART需要制作附加同步位和奇偶校验位的数据包——并且把数据包从TX线按精确计时(按照设定的波特率)发送。在接收端,UART需要根据预期的波特率对RX线进行采样,挑出同步位,获得数据。

8

UART块的内部结构图(来自Exar ST16C550的数据表

越来越多先进的UART把它们接收的数据放进缓冲器,数据可以一直存放直到微控制器读取它们。

UART软件

如果微控制器没有UART(或者不够用),串行接口可以位脉冲——直接由处理器控制。这是Arduino库里像 SoftwareSerial做到的。位脉冲是密集型处理而不像 UART那样精确,但它在紧要关头有效 !

常见缺陷

关于串行通信,我想告诉你一些不同经验的工程师都常犯的一些错误:RX接TX,TX接RX

看上去十分简单,但它是一个我已经犯了不止几次的错了。你会想把它们的标签配对起来,所以一定要确认连接两个串行设备上的RX和TX线。

10

          FTDI Basic编译Pro Mini注意RX和TX!

错误配对波特率

波特率就像是串行通信的语言。如果两台设备不用同一个速度说话,数据就会错误输入,或者完全丢失,如果接受的东西在所有接收设备上看都是垃圾,那就确认一下波特率是否相同。

9

数据发射的波特率是9600 bps,但是接收的波特率是19200 bps。波特率错误配对=垃圾

总线争用

串行通信只允许两个设备通过一条串行总线通信,如果多于一台设备尝试在同一串行线上发送数据,就会发生总线争用。

举个例子,如果你接一个GPS模块到你的Arduino上,你可能只连了模块的TX到Arduino的RX上。但是Arduino得RX引脚已经连到了USB转串行的TX引脚上,一个你只要编译Arduino或者用串行监视器就会被用上的东西。这会导致GPS模块和FTDI同时用同一条线发送数据的潜在情况。

11

两个发射器发送信号给接收器会导致总线争用

两个设备想在同一线上同时发送数据是不行的。“最好”的结果是没有设备发送成功。最坏的结果是,两个发射器都坏掉(尽管这很少发生,尽量避免。)

单一发射装置可以连接多个接收器。这不是规范的做法,而且会让硬件工程师苦恼,但它能正常运作。比如,你连接一个串行LCD到Arduino上,最简单的办法就是把LCD模块的RX与Arduino的TX连接。Arduino的TX已经连接到USB编译器的RX了,但仍只有一个设备控制发射线

12

像这样分配TX线仍然会对硬件造成危险,因为你不能选择哪台设备接收信号。LCD会终止接收不属于它的数据,这会使数据进入一个未知状态。

总之,一个串行总线,两个设备。

 


cc

原始文章采用CC BY-SA 4.0,您可以自由地:

  • 演绎 — 修改、转换或以本作品为基础进行创作
  • 在任何用途下,甚至商业目的。

只要你遵守许可协议条款,许可人就无法收回你的这些权利。本文由美国开源硬件厂商Sparkfun(火花快乐)的相关教程翻译,原始教程采用同样的CC BY-SA 4.0协议,为便于理解和方便读者学习使用,部分内容为适应国内使用场景稍有删改或整合,这些行为都是协议允许并鼓励的。

原始文章及相关素材链接:

https://learn.sparkfun.com/tutorials/serial-communication