作坊

如何构建智能灯:3个步骤(带图片)

Video 154 Norsk uttale: Æ - Ø - Å

Video 154 Norsk uttale: Æ - Ø - Å

目录:

Anonim

这个Instructable是关于建立自己的智能灯!这个Instructable将非常深入,我们将重温您在设计和构建自己的美丽智能灯方面所需的一切!这个Instructable确实让你对Fusion 360有了一些了解,而且你在电子方面的经验有点先进,但这将非常彻底,包括上传到3D打印机并打印你的灯所需的所有STL文件因为所有原理图和代码都包含在内!这些应该可以帮助您构建自己的智能灯!

物联网:一个“更聪明”的灯

物联网是当今科技界的流行语。你到处听到它,但没有人能真正指出它的定义。它真正意味着不同的人不同的东西。科技世界中最大的参与者,谷歌和世界各地的Facebook,似乎无法就定义达成一致。但尽管如此,似乎每个公司现在都有一个与物联网相关的内部组织或部门,因为统计数据如' 到2020年将有40亿台连接设备 '和' 未来5年,公司将在连接设备解决方案上花费6万亿美元 迫使公司重新评估他们是否有能力错失潜在的增长机会。但这不应该阻止任何人进入物联网。事实上,物联网是令人难以置信的。我们以前从未有机会实际使用大量数据。我们可以告诉许多以前无法准确知道的有趣的事情,例如当您的汽车需要维修时,由于您周围的当地天气模式,您的家庭花园中哪些类型的植物将蓬勃发展,土壤类型和饱和度。 IoT将猜测工作从您设备的维护中解脱出来;简而言之,它可以让生活变得更轻松。我们一直有数据;到目前为止,我们还不知道该怎么做。物联网处于初期阶段;它以惊人的速度增长,随着行业开始解决物联网日益增长的一些痛苦,我们将开始看到真正连接的设备。我们可以看到未来的图像,你的烤面包机与你的冰箱说话,他们都与你的电视交谈。在解决网络协议问题之前,这些愿景无法实现;也就是说,某些公司,如菲利普斯拥有非常传统的设备到设备通信方法的版权,例如I²C(如果您不知道这些是什么,请不要担心,它不会影响您完成灯泡的能力:))由于其中使用的语言的性质,许多芯片制造商通过创建该特定协议的变体来绕过此版权。这种情况也发生在所有其他主要问题上,例如SPI,UART,ANT等。这已经在设备之间的握手上产生了大量的排列,这使得公司的连接设备无法与另一个设备通话。无论如何,物联网仍然处于起步阶段,并且有很大的发展潜力,并且在日常生活中变得有用!

所以,如果你还在读书,真棒!这意味着你要么对物联网充满热情,要么你真的很喜欢这种灯或两者兼而有之!无论哪种方式,我都会打破智能灯。这是一个物联网设备,这意味着它连接到互联网,数据用于有趣的目的(我将在下面详细说明)。此智能灯通过WiFi芯片和微控制器连接到互联网。此外,电容式触摸板用于触摸按键界面。您可以选择使用环境光线传感器来读取灯泡当前所处的照明类型(代码包括对此的支持),您可以使用该数据来决定何时打开灯泡。灯可以配置为连接到任何WPA或WPA2个人网络(不幸的是没有企业支持)或WEP,并且数据可以发送到您配置的任何个人家庭服务器。我们将灯配置并连接到远程服务器,从中将数据拉入游戏引擎。这款灯具有更多功能,而不仅仅是一些互联网连接灯。

智能灯的目的是完全访问您的灯(或设备),并始终提供有关您的系统的有趣信息。我们使用游戏引擎在虚拟环境中构建了我们的灯的虚拟模型。我们使用网络将两个灯连接在一起并使它们相互影响。在虚拟模型中,您可以打开和关闭灯泡并调整亮度,物理灯泡将立即远程反映这些变化。在另一个方向,您可以打开和关闭灯泡以及更改亮度,您的模型将准确地反映这一点。此外,当您的灯泡未连接到网络时,灯泡将进入传统模式并恢复到正常工作灯泡状态。在游戏引擎中构建此信息的虚拟模型是完全可选的;您可以轻松构建任何前端Web客户端或Android或iOS应用程序,以充当发送数据的位置或具有游戏引擎模型将为您提供的远程控制。

为什么我要一台支持WiFi的Lamp?

这个项目的真正价值不在于实体灯;虽然它设计精美,灯泡很漂亮,但能够监控和控制连接设备的网络具有所有的价值。以工厂为例。在工厂中,通常存在许多执行类似任务的机器。连接工业机械网络可以帮助管理人员远程操作他们的工厂,同时收集数据并监控他们的机器状态。您收集的数据实际上非常重要,可以帮助您得出可能不太明显的结论。例如,对于汽车,您可以使用物联网传感器来监控发动机温度,汽车施加的力,每分钟转数和里程数。这些组合可以用来确定您汽车的整体健康状况。汽车不需要知道何时更换油或轮胎,而是已经知道并通知您通过手机通知。此外,从包含汽车的数据集中添加一层数据及其相对于里程数的平均服务时间可以帮助使该预测更加准确。另一个例子是,使用3D打印机加工工业零件的工厂将从了解何时完成夜间工作中受益匪浅。一旦发生这种情况,经理将通过应用程序在他们的手机上收到通知,这将允许经理关闭所有不活动的打印机,节省公用事业费用。方便您了解您的机器会发生什么,能够更智能和远程操作,以及在整个过程中节省资金,这也是物联网在当今科技世界中如此重要的原因。换句话说,智能灯是省钱的???

供应:

第1步:灯的设计和大会

设计

在设计任何东西时,首先要确定约束和目标。在我们的例子中,界面必须足够直观,任何人都可以走路和使用。在一天结束时,我们仍然在建造一盏灯,增加技术不能减损。由于用户从数字灯输入,按钮必须保持“无状态”。无国籍,我的意思是我们不得不避开具有物理状态的切换开关和输入。如果使用标准开关,则开关的状态可能与灯的状态不对齐并且将导致用户混淆。

有机形式也受到决定3D打印灯体的影响。通过3D打印,我们能够减少加工车身所花费的时间,并引入通过手工制造无法实现的复杂性。缺点是需要多天的清理和表面处理。 3D打印经常产生的粗糙表面在涂漆之前进行打磨和填充,以使灯具具有最终的生产质量。

印花

所有需要打印此灯的STL文件都可以在GrabCAD上找到。

重要的是要理解,虽然所有具有足够大信封的3D打印机都可以打印这些部件,但可用的公差和材料可能不同。灯的主体印在Stratasys Fortus 450mc上。按钮和漫射器印在Stratasys Objet Connex500上。

在打印灯体时,方向非常重要,因为与木材一样,3D打印也有颗粒。你需要确保灯的侧面印有灯,以便在颈部提供最大的强度。参考附带的照片以获得印刷品的直观表示。

精加工

接下来的步骤将概述我将3D打印表面细化到不再“打印”的程度,并应用于除漫射器之外的所有部件。

虽然3D打印机仍然在制造商和消费者社区中进行各种概念炒作,但重要的是要了解它们主要是一种工具。它可以让您比以往更快地接近物理模型。虽然你获得了速度(超过大多数其他方法)并降低了成本(与注塑成型相比),但可以进行相当多的清理。

步骤1:去除/溶解所有支撑材料。
步骤2:用中等横列(120粒度)砂纸轻轻打磨印花
步骤3:用与塑料兼容的环氧树脂胶粘合灯的顶部和底部(而不是盖子)(我建议使用5到10分钟的环氧树脂。在胶水上打磨,直到其余的印刷品光滑。
步骤4:涂上一层薄薄的Bondo,以填充印刷层所产生的脊。
步骤5:干燥后,将邦多沙子放回原处,直至看到印刷品。虽然120粒度仍然很好,但你可以用80粒度开始。始终戴口罩并在通风良好的地方工作。不要在打印中打磨,我们试图在不修改原始几何体的情况下填充脊。
步骤6:根据需要重复步骤4和5,直至触摸完全平滑,然后用220粒度砂磨。
步骤7:用不起毛的无绒抹布彻底清洁印花。

画身体

最终的印刷品分为3层:可打底的底漆,珐琅漆(任何颜色)和哑光透明珐琅。通过分离底漆和涂漆步骤(而不是使用二合一类型的涂料),它可以让您在放下油漆之前捕获一些最后的表面缺陷。我发现哑光珐琅不会像光面一样容易划伤。随意试试!

步骤1:剥离内部表面(基座和LED放置在引擎盖中的位置)
第2步:放置/悬挂灯泡,这样您就可以在不触碰的情况下转动灯泡。我建议制作一个夹具,使其可以通过内部标签倒置。底盖将获得相同的油漆
步骤3:施加2层中等底漆。让它干燥一小时或更长时间然后检查。
步骤4:用220粒度砂纸轻轻打磨所有涂底漆的表面。专注于有表面缺陷的区域,但不要太多;我们不是想把一个坑打入其中。
步骤5:重新悬挂并涂上一层轻薄的底漆。如果您有任何粗糙的区域需要填充,在这些区域涂抹稍重的涂层可能会有所帮助。让它干燥一小时或更长时间。
步骤6:对于最终的打磨,可以使用320粒度的砂纸。专注于保持锋利的锋利边缘和均匀打磨。
第7步:现在我们想要涂上一层薄薄的涂层珐琅质。至少给整整一天干。
步骤8:用400目砂纸轻轻擦拭,然后用湿的,无光泽的抹布擦拭干净。
步骤9:重新涂上薄薄的中间层,涂上透明的哑光珐琅质。让它干燥至少一天。

现在你完成了灯的主体和底盖。接下来,我们将对按钮进行类似的处理。它们的模型具有非常小的公差,因此找到与220砂砾砂纸的完美配合,然后减少一点点以考虑油漆的厚度。

画按钮

绘制按钮的步骤与上面相同,减去电源按钮上的底漆步骤,因为光需要从LED通过。注意不要在按钮上积累太多厚度,因为它们不能装回灯中。

安装按钮

按钮上有小标签,可帮助您找到正确的深度。使用与灯颈相同的环氧胶,将每个按钮粘贴到位。务必将胶带从底座周围的外部区域上取下,以限制用胶水弄乱美观油漆工作的可能性。

安装环境光传感器

此灯中使用的环境光传感器是Adafruit TSL2561光传感器。它需要在安装LED之前进入。需要从传感器板的底部尽可能平坦地安装带状电缆。然后将它放在灯的颈部,额外松弛。根据您的打印机/焊接工作,适合可能有点紧张。如果您需要更多空间,那么锋利的#11 Exacto刀将成为关键。

安装LED灯条

LED灯条需要切成3个四段(并在照片中看到)。 LED上有内置粘合剂,足以将它们固定到位。将它们安装在相同的方向,以便更容易将它们焊接在一起。所有颜色和12V +应平行焊接。安装好条带后,将颈部向下送入,并将四个彩色编码的引线焊接到中心条带上。热胶将增加焊点的强度。将12V +线连接到电源,并将R,G或B线中的一根接地。确认所有三个亮起后,继续执行下一步。

安装扩散器

我们准备完成发动机罩组件并安装扩散器。小心地擦掉LED阵列周围的区域,这样就不会有油漆上的胶水。使用LED腔体水平将灯泡背面固定。使用小棒作为涂抹器,小心地将胶水添加到LED腔两侧的凸起表面上。一旦胶水均匀地涂在两侧,小心放置扩散器,同时监测胶水是否渗出。如果有,请在有机会设置之前快速将其擦除。

第2步:电子摇滚!

电子:现代巫术

如今技术可能看起来像我们技术的能力一样神奇;但是,我向你们保证,任何人都可以学习或做电子学。我们打破了一切,让你们能够复制这个灯,并希望学到一两件事,以及我们解释一些电子设备背后的基本原理。

零件清单:

以下是完成此灯的网络和电子设备所需的所有内容!

  • 3D打印机
  • 来自Adafruit的WINC1500分线板
  • 3通道N通道MOFSETS
  • Adafruit TSL2561光传感器
  • Adafruit MPR121电容式触摸板
  • 用于背光电源按钮的LED(您只需要几个LED)
  • 绞线芯线
  • 剪线钳
  • 剥线钳
  • 实芯电线(用于电容式触摸按键)
  • 灯带
  • 双向定时开关(12V至5V)
  • Teensy 3.2或Arduino Mega(需要扩展内存)
  • 3倍的sparkfun原型板(或类似尺寸的东西 - 虽然不大!)
  • 12V直流电源和2.1毫米桶式插座(链接包括两个!)
  • 3x 68欧姆电阻(每个背光LED一个)
  • 热缩管1/8''
  • 面包板(如果你想先建立一个非永久版本的原型)
  • 热枪
  • 烙铁(链接包括与焊料相关的所有内容 - 包括焊料)
  • 焊料
  • 水(用于清洁焊盘)

第1步:将WIFI突破连接到Teensy

获得此灯泡的连接功能是该设备的“酷”因素的50%和物联网部分的100%,因此非常重要。上图显示了如何将每个引脚连接到Teensy上的正确引脚。

此链接是Adafruit的教程,并逐步向您展示如何将每个引脚连接到微控制器。他们使用了一种具有不同引脚输出的Arduino。但是,我在上面包含了两个版本的鹰图示,可以帮助任何人正确地将WiFi板连接到Teensy以及此灯中包含的任何其他板。在更高级的“高级原理图”中,原理图分解了每个分线板和子电路的功能,并满足所有适当的尺寸,以防任何高级制造商希望将电路板整合到单个电路板中。 在“基本原理图”中,WiFi板被抽象为一个黑色的盒子,引脚伸出。这些引脚都标有网络标签,与Teensy上应该连接的引脚相匹配,具有精确的命名! 该示意图不应用作合并电路板设计的基础;它没有正确的尺寸,也没有适当的电路。

如果您想测试每个部分并验证您的连接,可以使用面包板;这个instructable假定您目前正在制作原型板。我们独立完成了测试和几次面包板迭代,因此您可以轻松地直接焊接连接。

这种指导性的确假设您知道如何焊接。如果您还在学习,请查看此链接!

您需要先将标头针焊接到Teensy上。 如果您不确定如何操作,请查看此链接!

一旦你将你的标题针焊接到你的青少年,把Teensy放到SparkFun板上并按照这个特定的方向对齐teensy:你需要在青少年一侧有两个垂直的柱子,上面有石英晶体(它是一个闪亮的金属矩形,通常刻有数字)。在这里了解更多!对面应该只适合三个垂直列。由于外围设备,这种方向是必需的。电容式触摸板,WIFI板和Lux传感器都通过SPI通信引脚进行通信。由于灯座的尺寸限制,我们只能使用零件清单中指定的原型板的尺寸。因此,只有两个方向可以适合LED驱动电路的所有连接(来自栅极的PWM引脚),其一侧有2或3个垂直列,而另一侧有列数你没有从另一边选择(即2对1和3对另一方或反之亦然)。

一旦你有正确的方向,你可以使连接永久化并将Teensy焊接到SparkFun原型板上。您可以使用剪线钳夹住电路板底部伸出的电路板底部。

焊接完Teensy之后,Solder插头引脚连接到WIFI板。这些应该包含在WIFI板的包装中。在将插头焊接到WIFI板之后,您需要将WIFI板焊接到单独的原型板上。

为了节省您的时间,请继续指定您将用于哪些电路板。第1板应该只有你的青少年,没有别的。第二板只有wifi板。第3板将配备您的LED驱动电路,双向开关稳压器,以及从直流墙电源到LED /电路其余部分的电源连接器

将WiFi板倒置到原型板上 (参见连接的三块板的图片以供参考)并剪下标题。这样做是因为该方向允许三块板整齐地折叠到灯的底座中。

这里的最后一步是使用上面的原理图来路由连接。切割并剥去一段比连接长度略长的绞合芯线,使其稍微松弛。然后在两端焊接连接。

一般提示: 颜色编码您的电线并在整个电路中保持一致!使您的电源线全部为红色绞线芯线,黑色应接地。这有助于您进行调试过程,并有助于保持整洁有序。

LED驱动电路和电平转换器

这个部分有多个部分,所以我们将它分成更小的部分,然后引导你完成这里的所有内容。让我们从电源电路开始吧!

在电源电路中,我们有一个连接器部件,允许您连接直流电源(墙砖)的正负引线(红色和黑色线)。我们想将这块焊接到电路板的顶部,在第一排和第二排的最后一个点对角线。这也可以在照片的上方看到。在这之后,让我们将注意力转向MOSFET驱动器电路。

首先,让我们为那些不知道MOSFET是什么的MOSFET提供一些背景知识。 MOSFET代表 中号等人 Ø喜得 小号emiconductor Field Ëffect Ťransistor。第一部分仅涉及晶体管的材料类型(高度简化,因为对所选材料的类型及其产生的晶体管特性有影响)。这个陈述的后半部分有点复杂;场效应是指通过在通道之间移动的电荷通过感应电流下拉晶体管的栅极(如果您不理解,请不要担心,但这里有更多信息!)。晶体管基本上只是开关;您可以通过向栅极施加电压来控制电流,以使电路的某些部分获得电力。晶体管非常复杂;简而言之,所有晶体管都有栅极,漏极和源极。漏极和源极可视为电路的输入和输出。 MOSFET有许多不同的类型,但我们将解释您作为制造商遇到的主要问题。 NMOS和PMOS代表正负通道MOSFET。这种区别非常重要,因为它可以确定您可以向栅极施加何种电压,以允许电流从源极流向漏极或从漏极流向源极。 NMOS栅极在其栅极和源极之间需要正电位电压。 PMOS在其栅极和源极之间需要负电位。您可以在这里了解有关MOSFET的所有信息!

在我们焊接电源插孔后,我们想要放下我们的MOSFET。将它们放在同一块板上,每块板之间应有一个孔。它们都应垂直排列,每个MOSFET面向相同的方向。如上图所示,当书写面朝上时,方向正确。在图片中,MOSFET已经向下折叠,所以如果你遇到麻烦就可以想象它们不是,你应该能够正确定位。一旦方向正确,焊接在引脚上。

在具有MOSFET的示意图中,二极管(具有水平线的三角形)代表LED灯条。 LED灯条有四个金属焊盘(电源,红色,绿色,蓝色),您可以从烙铁上加热并将更多的绞合芯线(当然是彩色编码)连接到焊盘上。一旦连接牢固,您将提供12伏电压。这意味着您需要将直流电源的电源线连接到焊接到电路板上的连接器。您可以通过将代表电源的Led条带的电线焊接到电路板上与连接器电源引脚相同的行中的空孔来轻松完成此操作。这将为LED供电。如果此时已正确连接电源,您应该会看到LED指示灯亮起。现在是时候从LED灯条连接其余的引线了。这些应该是红色,绿色和蓝色控制引线。您需要做的是将每根导线连接到连接MOSFET中间引脚的行。您应该有三条线连接到MOSFET的三个不同的栅极。然后,您将需要三条线(红色,绿色和蓝色)连接从Teensy上的漏极到数字引脚。漏极是MOSFET上最左侧的引脚,您只需将每根导线焊接到该行上的一个自由孔即可。

连接LED灯条后,我们将连接双向开关稳压器。我们的LED工作电压为12伏,以便开启。然而,其余的电路和电路板只能工作在最大5伏逻辑电压,这意味着如果我们不想破坏我们的电子设备,我们将需要降低电路的其余部分的电压。我们通过开关稳压器做到这一点!开关调节器是从一些较高电压下降到较低电压的电压(在这种情况下为12伏至5伏)。现在您可能会问为什么不使用电阻降低电压或使用电阻分压电路?这样做有很多问题;我们强烈建议AGAINST这样做。为什么?电阻会根据需要降低电压,但会产生大量热量!事实上,如果您熟悉它们,可以使用电阻器或线性稳压器轻松熔化电路。但是,我不能只使用散热片并将热量从电路中漏出来吗?是的,你可以,但我们在能源效率问题上出现了!这将是非常低效的!如果你回忆一些高中物理学,那么功率是电流倍数电压或电流平方倍数电阻的乘积。功率以瓦特为单位测量,您需要一个相当大的电阻器才能将12伏特降至5伏特。这将导致功耗非常大。这会使你的灯非常低效。我们通过使用双向开关稳压器来避免这个问题!该稳压器可轻松实现85%的效率,降低12伏至5伏。这有助于降低温度并延长灯泡的使用寿命!

要连接开关稳压器,请参见此数据表!一个很好的技能是阅读数据表!每个信誉良好的部件都有一个数据表,向您展示如何使用该设备及其特性和操作范围。对于此调节器,在第8页,共12页,左下角有针脚表和标签。引脚1是最左边的引脚,它是电源输入。您应该将电线从与电源连接器相同的一排上的孔焊接到与引脚1相同的一排上的孔。引脚2是地线。因此,从电源连接器接地引脚排上的空孔,将电线焊接到与引脚2相同的一排空孔。引脚3是输出。这将作为电路其余部分的电源线。我们为每块电路板创建了一排专用电源轨,以便于调试。每块电路板上的电源导轨如上图所示。来自连接器输出(仅用于接地)的接地和电源的单个连接以及用于电源的开关稳压器的输出。每个电路板在行间的大间隙之间需要较小的跳跃(行不是直接连接在整个电路板上),在原型板之间,您还需要焊接连接。看上面的图片来获取要点!

电容式触控分线板

这是电子设备的最后一部分,适用于那些不想将电子设备扩展到环境光传感器的人。对于此部分,您不需要任何插头引脚或将电路板连接到Sparkfun原型板。该板最终将粘在灯的内侧,尽可能靠近按钮,以使每个按钮的有源电容式触摸引线尽可能短。这是为了防止干扰,并且允许接收干净的电容式触摸读数。电路板本身有几个引脚,您可以在上面的“简单”版本的鹰图中找到它们。它可以准确地告诉您连接到青少年的引脚,就像在这个指令的WIFI模块部分一样。将这些连接焊接在一起,这应该提供到板的SPI通信链路以及电源。

下一步是连接按钮的引线。如前所述,您希望这些电线尽可能短,以使您的电容式触摸按钮尽可能灵敏。为此,您需要使用导线创建各种接触垫,如上所示。取一些实心的芯线并将电线螺旋成一角形的圆形扁平线圈。线圈的另一端应该是导线的直线部分,并焊接到引脚中。每个按钮自然需要3根按钮接触线,这些接线将焊接到引脚0,1,2中。在引脚11中,您将焊接另一根用于电源LED的电线。这是GPIO引脚(通用输入/输出引脚),还具有PWM(脉冲宽度调制)功能。我们将使用此引脚来控制成为电源按钮背光的LED的逻辑。编程和代码部分将解释如何完成。

环境光传感器

本节专门介绍环境光传感器,它是一个分线板,可从周围环境中获取光线,并具有板载滤波功能,可提供有关房间亮度以及红外和可见光读数的用户数据。这个突破非常简单,并没有包含在老鹰的原理图中,但Adafruit有一个非常好的教程链接在这里!此链接将逐步指导您如何将环境光传感器连接到青少年。连接上面有一张图片;我已经提供了一个链接,可以为您提供Teensy的引脚分布,并且可以帮助您将电线连接在一起。您需要将分线板上的电源连接到电路板上的任何位置。我建议将此连接连接到最方便的电源导轨上。上面的图片包括我们的电源连接位置。接下来,您需要将SDA和SCL引脚连接到Teensy。青少年上的那些针脚标记在鹰图中,您需要做的就是使连接永久化。将电路上的SDA引脚上的电线焊接到光传感器上的SDA引脚上,类似地,将电线从teensy(引脚13)上的SCL引脚连接到teensy上的SCL引脚。在此之后,需要进行的最后一次连接是GND。将接地板从接地板连接到任何可用的接地导轨。再次尝试选择一个可以让您更容易焊接和组装电子元件的地方。有关我们的版本,请参见上图。所有地线和电源线分别为黑色和红色。

第3步:编程Chops:MQTT网络

软件:使愚蠢的对象变得聪明

您现在已经完成了该项目的软件方面!如果你已经做到这一点,恭喜你!你基本上有一个智能灯,因为我们已经包含了这个教程中的所有代码,你已经准备好上传代码并拥有一个智能灯!如果您有兴趣了解代码的更多信息,代码部分中的注释将详细说明并解释所有内容!

对于那些只想上传代码感兴趣的人,无需进一步阅读。这部分教程将讨论如何将代码上传到青少年。对于背景,teensy是一个微控制器,需要一个手动/自动引导加载程序(程序),将处理器切换到编程模式。对于之前使用过Arduino的用户,在为Arduino项目编写程序时,右上角的复选标记将验证草图是否有错误,一旦代码编译完成,您可以单击箭头上传代码。 Arduino的IDE会自动将Arduino切换到编程模式,并将新代码闪存到您的主板上。使用Teensy,此功能已被抽象出Teensy引导程序。每个Teensy用户都需要下载引导加载程序,如果还没有,请下载位于此处的Arduino IDE。完成安装后,请下载我们上面包含的代码。它将在您的Arduino IDE中打开。包含了许多库,需要编译代码。下面是指向下载.zip文件并将其安装到库中所需的库的链接。如果您不知道如何将库安装到Arduino草图中,这里有一个指向如何执行此操作的指导链接。

图书馆:

  • Adafruit MQTT库
  • MPR121电容式触控板
  • WINC1500 wifi板
  • Adafruit Lux传感器
  • Wire.h(没有库,因为它已预先安装)
  • String.h(没有库,因为它已预先安装)
  • SPI.h(没有库,因为它已预先安装)
  • Adafruit_Sensor.h
  • ArduinoJSON

一旦安装了所有这些库,您的代码就会编译完毕。按下arduino IDE上的验证码按钮(复选标记)后,打开Teensy的引导加载程序窗口。您应该看到一个小窗口,其中包含Teensy的虚拟版本。单击自动按钮并确保其凹陷(就好像您实际按下了一个按钮…请参阅teensy bootloader链接以查看我们的意思)。然后,按下Teensy本身的物理按钮,该按钮位于USB对面板的末端。检查arduino IDE中您的草图,然后单击工具。确保电路板显示Teensy 3.1 / 3.2,USB类型设置为Serial,CPU速度设置为96 MHz优化超频,端口设置为“usb后跟一些长串数字和字母”。完成后,按下arduino上的上传按钮(侧向箭头)。 Teensy板上应该有一个LED,上传代码时应该闪烁。完成上传后,您只需将电子设备放入灯泡底座即可完成所有操作!

如果您对代码的作用感兴趣,请查看以下代码中包含的注释!

#include #include #include #include #include #包括 #包括 #include #include
#包括 #包括
#包括 #define WINC_CS 10 #define WINC_IRQ 7 #define WINC_RST 4 #define AIO_SERVER“mqtt2.seecontrol.com”#define AIO_SERVERPORT 1883 #define AIO_USERNAME“IoTLamp”#define AIO_KEY“b184b39888dc43fea40fd55e5da0a360”#define halt(s){Serial.println(F (s));而(1); } #define LEDPIN 3 #define LED_RED 23 #define LED_GREEN 5 #define LED_BLUE 6 #define touch_pin0 0 #define touch_pin1 1 #define touch_pin2 2 char ssid =“”; //你的网络SSID(名字)字符传递 =“”; //您的网络密码(用于WPA,或用作WEP的密钥)int keyIndex = 0; //您的网络密钥索引号(仅适用于WEP)int status = WL_IDLE_STATUS; // wifi status const char MQTT_SERVER PROGMEM = AIO_SERVER; const char MQTT_CLIENTID PROGMEM = __TIME__ AIO_USERNAME; const char MQTT_USERNAME PROGMEM = AIO_USERNAME; const char MQTT_PASSWORD PROGMEM = AIO_KEY; const char IOTLAMP_FEED PROGMEM =“/ IoTLampDemo”; //发布和订阅通道名称const char RETURN_FEED PROGMEM =“/ IoTLampDemo”; uint32_t x = 0; // uint8_t POWER_STATE = 0; uint8_t pinNum; uint8_t led_brightness = 100; uint8_t redVal = 0; uint8_t greenVal = 0; uint8_t blueVal = 0; uint16_t lux; bool Network_Mode = false; bool cap_touch_activated = false; const int irqpin = 2; // activity-indicator volatile boolean flagIrq的引脚号; struct JSON {const char * targetVal; const char * codeVal; int lamponVal; int brightnessVal; }; / *所有声明* / Adafruit_WINC1500 WiFi(WINC_CS,WINC_IRQ,WINC_RST); Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); //光传感器Adafruit_WINC1500客户端; // wifi芯片Adafruit_MQTT_Client mqtt(&client,MQTT_SERVER,AIO_SERVERPORT,MQTT_CLIENTID,MQTT_USERNAME,MQTT_PASSWORD); // mqtt声明Adafruit_MQTT_Publish IOTLAMP = Adafruit_MQTT_Publish(&mqtt,IOTLAMP_FEED); Adafruit_MQTT_Subscribe VIRTUAL_LAMP = Adafruit_MQTT_Subscribe(&mqtt,RETURN_FEED); / * *此功能是设置。在设置中,我们已经初始化了* LED的所有引脚以及我们连接到按钮的中断。我们已经调用了*设置wifi板,电容式触摸板以及订阅*正确主题路径的功能。 * * / void setup(){pinMode(irqpin,INPUT); Serial.begin(9600); //设置中断Serial.println(“启动程序”); attachInterrupt(irqpin,isrIrqPin,CHANGE); //附加irq引脚中断和RISING / HIGH / CHANGE / LOW / FALLING MPR121.setInterruptPin(irqpin); pinMode(LED_RED,OUTPUT); pinMode(LED_BLUE,OUTPUT); pinMode(LED_GREEN,OUTPUT); digitalWrite(LED_RED,LOW); digitalWrite(LED_GREEN,LOW); digitalWrite(LED_BLUE,LOW); capacitiveTouch_Setup(); wifi_module_config(); //配置wifi mqtt.subscribe(&VIRTUAL_LAMP); } / * *这个函数是循环。它会无限地重复此函数中发生的任何事情,除非检测到*中断,在这种情况下执行另一个函数而其他所有函数都停止。 *此函数检查是否触发了中断,如果是,则运行resetButton函数。 *如果我们处于网络模式(意味着我们有wifi连接),则运行网络*功能。如果两者都不是真的,就像普通灯一样。 * * / void loop(){if(flagIrq == true){ResetBUTTONFlag(); //如果发生了BUTTON中断,请重置标志。 } else {if(Network_Mode){networking();在触发中断时调用此函数,然后调用电容式按钮函数*并将标志布尔值设置为true。* / void isrIrqPin(){capacitiveTouch_buttons(); flagIrq = true; } / * *这个函数只处理状态:它只在中断被触发时被调用*并且标志布尔值变为false并且电容触摸布尔值被设置为真。 * / void ResetBUTTONFlag(){// reset BUTTON 1 flag + show led activity-indicator flagIrq = false; cap_touch_activated = true; } //取消注释此函数以扩展勒克斯传感器读数,并在需要的地方调用它。 // void luxSensor_Readout(void){// sensor_t sensor; // tsl.getSensor(&sensor); // Serial.println(“------------------------------------”); // Serial.print(“Max Value:”); Serial.print(sensor.max_value); Serial.println(“lux”); // Serial.print(“最小值:”); Serial.print(sensor.min_value); Serial.println(“lux”); // Serial.print(“Resolution:”); Serial.print(sensor.resolution); Serial.println(“lux”); // Serial.println(“------------------------------------”); // Serial.println(“”); //延迟(500); //} / * *此功能设置电路板。首先提供调试语句,以了解*电容式触摸板是否配置正确。然后它会初始化电路板上的数字引脚*本身的按钮和电源按钮。它设置灵敏度并开始校准*数据。然后打开POWER LED启动。 * * / void capacitiveTouch_Setup(){if(!MPR121.begin(0x5A)){Serial.println(“error setting up MPR121”); switch(MPR121.getError()){case NO_ERROR:Serial.println(“no error”);打破; case ADDRESS_UNKNOWN:Serial.println(“错误的地址”);打破; case READBACK_FAIL:Serial.println(“readback failure”);打破; case OVERCURRENT_FLAG:Serial.println(“REXT引脚上的过流”);打破; case OUT_OF_RANGE:Serial.println(“电极超出范围”);打破; case NOT_INITED:Serial.println(“not initialised”);打破;默认值:Serial.println(“未知错误”);打破; } while(1); } Serial.println(“找到MPR121!”); MPR121.setTouchThreshold(2); //触摸MPR121.setReleaseThreshold(1)的默认值为40; //触摸的默认值为20;必须始终小于触摸阈值MPR121.setNumDigPins(1); // LED输出MPR121.pinMode(11,OUTPUT); MPR121.updateTouchData(); //初始数据更新MPR121.digitalWrite(11,HIGH); } / * *这是wifi配置功能。这将检查是否已为* WIFI模块提供电源,然后根据是否已提供电源*将网络布尔值设置为true或false。然后,如果是这样,打印出您已连接。 * * / void wifi_module_config(){Serial.println(F(“用于WINC1500的Adafruit MQTT演示”)); Serial.print(F(“ nInit the WiFi module …”)); //初始化客户端if(WiFi.status()== WL_NO_SHIELD){//检查是否存在突破Serial.println(“WINC1500 not present”); //不要继续:Network_Mode = false;而(真); } Serial.println(“ATWINC OK!”); Network_Mode = true; } / * *此函数为RGB值创建映射。它可以缩放灯泡输出的最大白色*。然后在为每种颜色Red green和Blue创建映射后,*我们调用辅助函数来设置LED颜色的实际色调* * / void map_white(int new_brightness){redVal = map(new_brightness,0,255, 0,255); //映射红色值greenVal = map(new_brightness,0,255,0,255); //映射绿色值blueVal = map(new_brightness,0,255,0,240); //映射蓝色值set_leds(redVal,greenVal,blueVal); } / * *此功能实际设置LED颜色值并使LED亮起。 * * / void set_leds(uint8_t redVal,uint8_t greenVal,uint8_t blueVal){analogWrite(LED_RED,redVal); //将当前值写入LED引脚analogWrite(LED_GREEN,greenVal); analogWrite(LED_BLUE,blueVal); } / * *此功能配置光传感器。它首先检查传感器是否连接到电源。一旦它,它设置增益。如果传感器周围的光线很低,它会根据*放大它最初获得的值,它会放大到高增益。然后,它设置*积分时间,即测量所需的时间。函数*的其余部分在串行监视器中打印出您选择的信息。 * / void configureSensor(void){Serial.println(“Starting Adafruit TSL2591 Test!”); if(tsl.begin()){Serial.println(“Found a TSL2591 sensor”); } else {Serial.println(“找不到传感器……检查你的接线?”);而(1); } //你可以动态改变增益,以适应更亮/更暗的光线情况//tsl.setGain(TSL2591_GAIN_LOW); // 1x增益(强光)tsl.setGain(TSL2591_GAIN_MED); // 25x增益// tsl.setGain(TSL2591_GAIN_HIGH); // 428x增益//改变积分时间可以让你有更长的时间感知光线//更长的时间线更慢,但是在非常低的光线下也很好! //tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); //最短积分时间(强光)// tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS); tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS); // tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS); // tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS); // tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); //最长积分时间(昏暗的光线)

/ *显示增益和积分时间以供参考* / Serial.println(“-------------------------------- ----“); Serial.print(“Gain:”); tsl2591Gain_t gain = tsl.getGain(); switch(gain){case TSL2591_GAIN_LOW:Serial.println(“1x(Low)”);打破; case TSL2591_GAIN_MED:Serial.println(“25x(Medium)”);打破; case TSL2591_GAIN_HIGH:Serial.println(“428x(High)”);打破; case TSL2591_GAIN_MAX:Serial.println(“9876x(Max)”);打破; } Serial.print(“Timing:”); Serial.print((tsl.getTiming()+ 1)* 100,DEC); Serial.println(“ms”); Serial.println( “------------------------------------”); Serial.println( “”); } / * *触摸按钮后会启动此功能。在那之后,它会更新电容板存储的数据*。然后运行可用的引脚(我们只从0-2 *开始,因为我们只有3个引脚连接到按钮)。然后它将返回已被触摸的引脚号。 * * / uint8_t capacitiveTouch_pinTouched(){MPR121.updateTouchData(); for(pinNum = 0; pinNum <= 2; pinNum ++){if(MPR121.isNewTouch(pinNum)){return pinNum; } pinNum = 4; return pinNum; } * * *电容触摸按钮实际上包含了触摸按钮时处理的所有逻辑。到目前为止,假设已经触摸了一个按钮,现在它将弄清楚*如何处理已触摸的特定按钮。它控制*电源状态和电源LED以及亮度控制的所有逻辑。 * * / void capacitiveTouch_buttons(){uint8_t touchingPin = capacitiveTouch_pinTouched(); switch(touchingPin){case 0:{if(POWER_STATE == 1){if(led_brightness> 230){led_brightness = 255; map_white(led_brightness); } else {led_brightness = led_brightness + 25; map_white(led_brightness); }} else {MPR121.digitalWrite(11,LOW); map_white(led_brightness); POWER_STATE = 1;打破情况1:{if(POWER_STATE == 1){MPR121.digitalWrite(11,HIGH); POWER_STATE = 0; map_white(0); } else {MPR121.digitalWrite(11,LOW); POWER_STATE = 1; map_white(led_brightness);打破案例2:{if(POWER_STATE == 1){if(led_brightness <= 30){led_brightness = 25; map_white(led_brightness); } else {led_brightness = led_brightness - 25; map_white(led_brightness); }} else {MPR121.digitalWrite(11,LOW); map_white(led_brightness); POWER_STATE = 1;打破默认值:{} break;此函数是光传感器的高级读取功能。光传感器将*为您提供32位代表红外和可见光谱。它抓取可见光谱的16位*并返回可见光谱的计算勒克斯值。 * * / uint16_t advancedRead(void){uint32_t lum = tsl.getFullLuminosity(); //读取32位,前16位IR,后16位全谱uint16_t ir,full; ir = lum >> 16; full = lum&0xFFFF; lux = tsl.calculateLux(full,ir);返回lux; } / * *此函数处理以JSON格式化的数据包的传输。如果您的频道名称正确,它会检查*,如果是,那么它会将数据包发布到该频道* / void mqtt_transmit(char buf ){//现在我们可以发布内容! Serial.print(F(“ n发送JSON”)); Serial.print( “…”); if(!IOTLAMP.publish(buf)){Serial.println(F(“Failed”)); } else {Serial.println(F(“OK!”)); Serial.println(BUF);这个函数设置MQTT并设置它。有声明处理超时和*建立wifi连接后,程序尝试连接到MQTT。一旦它连接,它会闪烁绿色并关闭,让您知道您已连接。如果您没有连接,它将在搜索wifi进程期间保持红色。 * * / void MQTT_connect(){int8_t ret; uint8_t timeout = 10; //等待10秒进行连接:bool timedOut = false; while(WiFi.status()!= WL_CONNECTED && timedOut == false){//尝试连接到Wifi网络:digitalWrite(LED_RED,HIGH); Serial.print(“试图连接到SSID:”); Serial.println(SSID); status = WiFi.begin(ssid,pass); //连接到WPA / WPA2网络。如果使用open或WEP网络,请更改此行:timeout--;延迟(10); if(timeout == 0){timedOut = true; digitalWrite(LED_RED,LOW); } Network_Mode = false; } while(timedOut){Network_Mode = false; Serial.println(“输入传统模式”); } if(mqtt.connected()){//如果已连接则停止。 Network_Mode = true;返回; } Serial.print(“连接到MQTT ……”); while((ret = mqtt.connect())!= 0){// connect将为连接的Serial.println返回0(mqtt.connectErrorString(ret)); Serial.println(“在5秒内重试MQTT连接……”); mqtt.disconnect(); Network_Mode = false;延迟(500); //等待5秒} Network_Mode = true; Serial.println(“MQTT Connected!”); digitalWrite(LED_RED,LOW); digitalWrite(LED_GREEN,HIGH);延迟(1000); digitalWrite(LED_GREEN,LOW); } / * *这是格式化JSON的函数。现在,它在某种程度上是硬编码的*,但是,你可以很容易地将它改为基于*传入的参数。* * / String json_Packet(){String pubString =“{”target “: “灯”,“代码”:“灯”,“;字符串值=“”values “:{”; String onOff =“”lampon “:”; //整数保持整数而不是在它们周围加上JSON格式的引号String lampState = onOff + POWER_STATE +“,”; String brightnessState =“”lampintensity “:”; String lamp_brightness = brightnessState + led_brightness +“,”; String lamp_luminosity =“”luminosity “:”; String initial_string = pubString + values + lampState + lamp_brightness + lamp_luminosity; return initial_string; } / * *此函数是来自订阅频道的数据的逻辑。 *根据*订阅频道发送的值,它会改变LED电源背光的开启和关闭。它还根据该数据改变实际的LED亮度* * / void subscribe_StateChange(JSON&json){POWER_STATE = json.lamponVal; led_brightness = json.brightnessVal; if(POWER_STATE == 1){MPR121.digitalWrite(11,LOW); map_white(led_brightness); } else {MPR121.digitalWrite(11,HIGH); map_white(0);这个函数是处理所有网络的更高级别的函数。它调用*函数来设置MQTT连接。一旦建立,初始化订阅的实例*,您将从中获取数据。然后创建一个我们之前创建的struct的实例,它将存储我们从订阅包解析的字段。我们创建一个*缓冲区来存储所有订阅数据。然后检查按钮是否被触摸*这将导致我们读取光数据,打包数据,然后发送数据包。 *如果我们没有改变灯的状态(触摸任何按钮),那么看看我们是否有任何*数据包要读取。如果我们这样做,解析它并填充我们之前创建的JSON结构中的字段。 * * / void networking(){MQTT_connect(); Adafruit_MQTT_Subscribe *订阅; JSON json; String basic_string = json_Packet(); StaticJsonBuffer <5000> jsonBuffer; while(cap_touch_activated){lux = advancedRead(); //获取lux值并将其设置为等于lux String finalString = basic_string + lux +“}}”; char buf finalString.length()+ 1; finalString.toCharArray(buf,finalString.length()+ 1); mqtt_transmit(BUF); cap_touch_activated = false; } while((subscription = mqtt.readSubscription(5000))){if(subscription ==&VIRTUAL_LAMP){JsonObject&root = jsonBuffer.parseObject((char *)VIRTUAL_LAMP.lastread); if(!root.success()){Serial.println(“parseObject()failed”);返回; } json.targetVal = root “target”; json.codeVal = root “code”; json.lamponVal = root “values” “lampon”; json.brightnessVal = root “values” “lampintensity”; subscribe_StateChange(JSON); }}}

网络:WIFI,MQTT和MQTT.fx

这是一个专门解释MQTT和网络的部分!让我们开始吧!

在我们进入MQTT之前,您需要为此分立设备设置WIFI网络凭据。由于安全性,此灯无法连接到WPA2企业网络。这些库不是为处理用户名字段而设计的。只是一个网络SSID和密码,目前尚未提供企业网络支持。目前支持WPA,WPA2个人和WEP网络。您需要更改将要使用的网络凭据的SSID和密码。见下面的行:

char ssid =“”; //你的网络SSID(名字)
char pass =“”; //您的网络密码(用于WPA,或用作WEP的密钥)int keyIndex = 0; //您的网络密钥索引号(仅适用于WEP)

除非使用WEP网络,否则无需更改KeyIndex值。

所以MQTT … MQTT是一台机器到机器连接协议。所有这些意味着什么?对于初学者来说,MQTT是设备相互通信的一种方式,而无需使用大量功率。它具有非常小的数据包,因此也可以实现更快的传输。 MQTT曾被称为MQ遥测传输。在任何情况下,MQTT都依赖于发布和订阅模型来发送和接收数据。

MQTT使用发布和订阅在设备之间来回发送数据,为此,他们需要一个数据代理。这意味着,您需要一个中间位置来发送设置“主题”的数据或专用于发布和订阅数据的渠道。该代理处理发送和接收数据的逻辑。当然,您仍然需要编写一些函数来指定您希望从此代理中获取数据的位置或发送数据,但您可以监视从此代理接收和发送的数据。出版与传播相同;您以您希望的格式打包数据,然后指定要发布到的通道名称。完成后,您可以使用从adafruit下载的库实际将数据发送到此频道,在设置代理后,您可以看到正在接收的数据。

在实际接收数据到设备方面,订阅比发布要困难一些。通过发布,您只需传输即可。根据您的使用情况,您不一定关心在另一端收到或解析您的数据。但是,通过订阅,它在客户端(设备制造商)确保从订阅通道主题正确读取数据,没有丢失数据包,解析数据,并相应地对该数据做出反应。通过订阅,您必须不断地监听是否获得数据并阻止其他所有事件发生,因为设备的状态将在此后不久收到数据包。订阅与发布的工作方式类似;您建立一个通道,并通过Adafruit MQTT库中的函数调用(subscription * .readSubscription(int timeout))从中读取数据。您可以不断地循环遍历数据包并在获取数据包时进行解析,并立即更改有关物理灯状态的信息。如果您正在做一些特别需要知道每个数据包都已收到并且质量如何的事情,那么每个数据包发送的服务质量都有一个额外的字段。这用于通知您传输的质量。如果您收到了所有数据包,那么您将收到2个数据包。这意味着您已成功发送数据包并收回ping数据包。如果你拿到了一个,那么数据包就会被发送,但是你无法肯定你已经收到了所有数据包。 QoS为0表示您已发送它,并且没有关于是否已收到或是否收到所有数据包的其他信息。

我们使用的代理是MQTT.fx,你可以在这里下载。 MQTT.fx是一个处理所有数据管理的客户端代理。要使用它,您需要进行设置。在尝试连接到MQTT.fx之前,您需要做的第一件事是单击设备的齿轮。单击它之后,您需要为要发送数据的服务器以及端口号提供URL(代理地址)。为自己提供一个简化的配置文件名称,我们使用该配置文件名称,并将其作为我们的发布渠道名称和订阅名称,并在配置文件名称前加上“/”。输入所有信息后,生成随机密钥并记录该密钥。您将使用您生成的新密钥替换代码中AIO_KEY的值。您也可以转到“常规”选项卡并提供用户名和密码,但我们没有,并且没有特别必要。之后,您已准备好点击“应用”按钮,然后单击“确定”按钮,然后点击“连接”按钮,您应该配置为正常工作的服务器。然后,您可以在下拉选项卡中键入发布和订阅频道名称,只要在频道名称前面包含反斜杠,就可以在那里看到您的数据。这个很重要;它是MQTT中的硬编码格式,如果您指定的频道名称前没有反斜杠,则不会显示您的数据。在此之后,你们都准备好了!