亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

带 MKR1000 的多模式环境传感器平台

组件和用品

Arduino MKR1000
× 1
MOD-1016 闪电传感器
× 1
DFRobot MQ-9 气体传感器
× 1
Adafruit 湿度和温度传感器
× 1
Adafruit 压力/高度/温度传感器
× 1
SparkFun ML8511 紫外线传感器
× 1
chronodot RTC
× 1
SparkFun Photon Weather Shield
× 1
Adafruit neopixels
× 1
面包板(通用)
× 1
跳线(通用)
× 1

关于这个项目

我喜欢看天气,我想尝试捕捉并绘制它。家庭气象站让我看到“现在”的详细信息,有时还会显示过去一小时或一天的信息。我想做更多,并使用 Arduino 来完成这项工作。每个人都从温度和湿度开始,有时是气压,但我想要更多!风速和雨量测量都需要硬件输入。一旦我掌握了 i2c 的使用,我发现了像 AS3935 闪电探测器这样的东西!然后悲伤开始了......我没有足够的硬件中断来完成你的基本 Arduino 的工作。 Sparkfun 甚至有一个用于 Photon 的天气传感器板,但它仍然有限。我必须做出选择,并且没有一些传感器。 :-(

然后我看到了 MKR1000 ,我发现了最好的功能,它有 8 个硬件中断!现在我可以拥有一切!

选择您的传感器

传感器分为三种基本类型;

  • 模拟 :光(包括红外线和紫外线)、风向、气体、称重传感器...
  • I2C :温度、湿度、气压、加速度计、陀螺仪...
  • 中断 :自卸车、风速、闪电、计时器...(串行、PWM、时钟、伺服等功能使用定时中断)

MKR1000 为所有这些提供了充足的 I/O!

请注意 I2C 和中断上的 I/O 所需的电压!例如,MKR1000、Photon 和许多 Arduino 版本使用 3.3v I/O 而不是 5v。如果您的 CPU 和您想要的传感器使用不同的电压,您还需要在这些设备之间使用电平转换器。

我一直在使用的所有传感器都很常见,可以从 Adafruit、SparkFun、Element-14 和其他公司获得,通常成本在 5-10 美元(美国)之间。气体传感器通常花费 10-20 美元。对于闪电探测器(AS3935 芯片),我选择了 Embedded Adventures MOD-1016,它也需要 26 美元(美国)来安装板上的天线。我还买了 Sparkfun Photon Weather Shield,因为我有一个 Photon,我可能会买他们的“天气计”(风速和风向仪)。也许我会添加一个土壤湿度传感器,一旦我弄清楚我将安装 MKR1000 的位置。有些传感器不喜欢长引线。

将您的传感器分配给引脚

一旦你知道你想要哪些传感器,你就会知道你需要哪种类型的输入,下一步就是决定哪些传感器将连接到哪些引脚上。我从纸上开始,但我也会将此列表作为块注释添加到我的代码中,作为提醒。

以下是我为我的传感器平台所做的 MKR1000 引脚分配。

  • A0 (我正在保存 A0 以防我以后需要 DAC...)
  • A1 ML8511 紫外线传感器
  • A2 可见光传感器
  • A3 TMP36 本地温度传感器
  • A4 MQ-9 气体传感器
  • A5 湿度传感器
  • A6 风速传感器?
  • 0 (HW INT) 按钮
  • 1 (HW INT) 作为闪电探测器
  • 2 (HW INT) 风速风速计(每转中断)
  • 3 (HW INT) 雨车……
  • 4
  • 5
  • 6 (与板载 LED 共享)
  • 7 NeoPixel 输出...

开始...

对于你们中间的初学者,我建议从您要使用的每个传感器开始,一次一个,然后从加载示例代码开始,并安装所需的库。请记住更改传感器引脚,以匹配您选择的引脚分配,并将演示代码的副本保存在您的项目文件夹中。

当您可以运行测试代码并从串行监视器读取结果时,您就可以尝试添加另一个代码了。当您完成对每个传感器的测试后,它们现在都已接线并准备好开始构建更大的草图!

我最初对传感器的修补包括使用基于 i2c 的实时时钟 (RTC),因此我可以登录到 SD 存储卡。尽管 MKR1000 有自己的 RTC 和电池,但我无法仅使用电池来获得时钟来计时,所以我也会保留 ChronoDot v2.1 i2c RTC。

查看下图中的面包板,您可以看到正在使用的各种跳线。橙色用于为每个传感器提供 3.3v 电源,因此我只能在准备好使用它们时将它们插入。 (通过拔下橙色跳线可以轻松禁用传感器。)

关于库的说明

我发现您可以安装的一些库不能与 MKR1000 和/或 Arduino.cc IDE 版本 1.6.7 完美配合,您可能需要进行一些调整,具体取决于传感器的年龄是。这方面的一个例子是较旧的 AVR libc 中较旧的 ATOMIC_* 宏 库(它们被丢弃在 Arduino IDE 1.6.5 中),并且在 Arduino.cc 的论坛帖子中有一个关于问题和建议解决方案的好帖子。对中级 Arduino 黑客进行一些建议的更改,但对新黑客来说可能会令人生畏。并且,对于稍旧的库,原作者可能不在身边更新库并消除依赖。

不幸的是,在购买传感器并对其进行测试之前,您通常无法知道需要调整哪些库。在这一点上,我建议您在开始更改代码之前仔细查看当您尝试上传草图时以橙色显示的错误消息,以查看问题是出在您的代码中,还是出在库中。如果它在库中,请在网络上搜索“arduino”和错误消息。如果找不到解决方案,请尝试给作者发电子邮件,让他们知道错误,也许他们会更新库。

我买了个人芯片,试图省钱。我已经决定,在我准备好并能够制作自己的电路板(可能使用 EagleCAD 和 OSHPark)之前,从 Adafruit 和 SparkFun 购买传感器模块会更容易,因为它们非常适合修补库。

一点关于 WiFi 和加密

我还考虑了让我的天气传感器向网站报告的 wifi。我们甚至在 MKR1000 上安装了加密引擎,以帮助确保我们的数据在 Internet 上传输的安全!但是,这比我在第一个项目中能够做的要多。这是我要做的事情,因为将数据安全作为设计的一部分对于物联网很重要,但我没有时间添加我的 MKR1000 竞赛条目。注意我的这个项目的“版本 2”。这是 SAMD 模块的框图,该模块是您开发板的核心。

我可以为您提供一个开始使用板载 WiFi 的提示:确保您使用的是最新版本的 WiFi101 库! 如果不这样做,您的草图将无法识别 wifi 模块,并且您的 wifi 草图只会在对 wifi 模块的调用进行错误检查时报告。)我要感谢 Charif Mahmoudi 在他关于 Hackster 的伟大的“MKR1000 入门”教程中指出了这一点!在我做黑客的时候,你可以在这里找到 WiFi101 Githuib。

模拟传感器的提示

大多数“模拟输出”传感器模块会产生简单的模拟电压输出,使用 analogRead 可以轻松读取 传感器引脚。但是,那么您需要知道这意味着什么。通常,您需要使用 map 命令,或者您可能需要进行一些数学运算。电阻元件通常需要一些额外的电路。您可能需要添加一个电位计来“微调”电压。

在其他情况下,您需要使用方程式将输出电压转换为人类可以理解的值。 TMP36 温度传感器就是一个有据可查的例子。这部分被设计为以摄氏度为单位读出,所以你需要测量电压,并做一些数学运算来得到 C,如果你想要华氏度,你需要将 C 转换为 F。阅读组件的数据表将解释该部分的工作原理,但随着您的经验积累,您会发现跟随他人的脚步会更容易。

然而,其他传感器需要一个放大器,以便使微小的电压摆幅足够大,以便您的 ADC 获得从高到低的良好范围。这些类型的传感器(称重传感器、湿度、加速度计)是我发现最好花一些钱购买已经有放大器的模块和帮助了解输出范围的库的地方。

使用 I2C 设备的提示

I2C 有时被称为“双线接口”,因为您需要一个时钟信号以及一个数据信号。 (您只需要一根数据线,因为“​​主”和“从”将轮流在其上发送数据。)当然,您的 I2C 传感器还需要接地和电源线,并且地线需要连接回您的 CPU。

每个 I2C 设备在总线上都有一个十六进制地址。最好避免使用具有相同地址的多个设备。 (如果你想拥有多个,你需要用额外的电路管理它们,以便“启用”你想要与之通信的那个,然后在完成后禁用它,然后再启用另一个通信。)文档应该告诉您设备可以是哪个地址。 (注意如果您在 I2C 总线上有两个地址相同的设备,并且都有一个“启用”或“关闭”引脚,您将能够在另一个处于唤醒状态时禁用其中一个。但是,您不能只是关闭 vdd 引脚的电源,因为传感器可以从 SDA 和 SCL 引脚获取一些电源,并且会导致该地址的读数错误。 I2C 的错误检查不足以检测/纠正这种情况。 )

I2C 规范告诉我们,我们应该在时钟和数据引线上,在电线上最远的传感器上都有一个“强”的上拉电阻。因此,一些传感器模块已经在板载电阻,您可能只需要添加几个跳线,因此请务必阅读模块的文档。

除了“总线终端电阻”之外,我很久以前还从一位黑客那里找到了一个提示,即在数据 (SDA) 和时钟 (SCL) 引线上添加一个串联电阻。这大大提高了从几个传感器读取数据的可靠性。对于 MKR1000,使用 3.3v 信号,我使用 220 欧姆电阻。在 5 伏 CPU 上,您可能想尝试 330 欧姆。请参阅下面的示意图以了解放置的差异。

您将如何处理这些数据?

现在,我只是将它发送到串行监视器。可以加个液晶显示器。我打算添加一个 SD 卡,但现在我内置了 wifi,我想将数据上传到云端……想象一下有几个这样的传感器平台,知道它们的纬度和经度,并且能够通过比较给定雷击的每个站点的功率读数,对雷击进行三角测量!

旁边 :2017-11-29; 我一直无法让硬件中断在 MKR1000 上工作。我正在为一个 9 年级的班级(13-14 岁)做笔记和传感器实验,也许你会发现这些草图很有趣。该类是围绕 Adalogger M0 板构建的,并将数据保存到 SD 卡中,并且 WiFi 模块仍有大量引脚。 http://arduinoclass.pbworks.com

在我研究传感器的同时,我还在宜家发现了 SODERSVIK 灯具(见下图)。想象一下,用 20 个 Neopixels 替换这盏灯内的白色 LED,并添加一个红外遥控接收器。吹来的风仿佛云朵飘过,颜色可以指示温度。遥控器还可以选择暂时显示一些其他信息,例如过去 12 小时内的温度变化。

你想监控和显示什么?

代码

  • 整个监控草图
  • 进行平均模拟读数
  • I2C 总线扫描仪
  • ML8511 演示代码
整个监控草图Arduino
此草图中有许多传感器报告,并且库协同工作良好。然而,AVR-libc 中的经典中断锁定方法已在最新版本的 Arduino IDE 中删除,这已禁用 NeoPixel 和闪电传感器的库。我希望这会在今年某个时候得到解决,但这意味着我已经将它们排除在最终草图之外。
/* RTC-Weather-Sensors_v6_MKR1000 by Zonker Harris Spring 2016 * 万岁!一个小板,有2个以上的硬件中断! * 加上 WiFi、* 和* 加密(物联网应用程序非常必要!) * * 新手黑客注意:我在代码中添加了许多注释,如您所见。 * 点击上传时,*评论被忽略*,不吃内存! * 我建议您在进行更改 * 和添加内容时也添加大量评论,以帮助您记住几个月前您为什么这样做。 * 他们还会帮助那些追随你的人学习一两件事。 * * 现在,库 *DO* 会占用您的程序内存... */#include #include #include #include // 包括新像素作为占位符,但库中断向量需要更新。// 包括 Adafruit_NeoPixel 库 https://github.com/adafruit/Adafruit_NeoPixel//#include  //const int numLeds =1; // 字符串中有多少个新像素?用于设置 NeoPixel 库 // 参数 1 =条带中的像素数 // 参数 2 =引脚编号(大多数有效) // 参数 3 =像素类型标志,根据需要相加: // NEO_RGB 像素为 RGB 接线比特流 // NEO_GRB 像素为 GRB 比特流连接 // NEO_KHZ400 400 KHz 比特流(例如 FLORA 像素)// NEO_KHZ800 800 KHz 比特流(例如高密度 LED 灯条)//Adafruit_NeoPixel strip =Adafruit_NeoPixel(numLeds);KH0000000 /* BMP085_U 驱动程序使用 Adafruit 统一传感器库(Adafruit_Sensor),它为传感器数据和一些辅助函数提供了一个通用的“类型”。 (BMP180 与此库兼容,并提供相同的输出,但该库会将 BMP180 识别为 BMP085。)要使用此驱动程序,您还需要下载 Adafruit_Sensor 库并将其包含在您的库文件夹中。您还应该为此传感器分配一个唯一 ID 以与 Adafruit 传感器 API 一起使用,以便您可以在任何数据日志等中识别此特定传感器。要分配唯一 ID,只需在下面的构造函数中提供适当的值(12345 是本例中默认使用)。 */Adafruit_BMP085_Unified bmp =Adafruit_BMP085_Unified(10180);/* 此草图也设计用于 Adafruit 的 HTU21D-F 传感器 ----> https://www.adafruit.com/products/1899 */Adafruit_HTU21DF htu =Adafruit_HTU ();/* Macetech Chronodot v2.1 电池供电实时时钟 (RTC)... http://docs.macetech.com/doku.php/chronodot(因为我的 MKR1000 上的电池似乎没有保持板载 RTC 处于活动状态)Adafruit 实时时钟 (RTC) 库信息 https://learn.adafruit.com/adafruit-data-logger-shield/using-the-real-time-clock Analog Devices TMP36 模拟校准的温度传感器。这需要一些数学 https://learn.adafruit.com/tmp36-temperature-sensor http://www.analog.com/media/en/technical-documentation/data-sheets/TMP35_36_37.pdf ML8511 紫外线传感器...该传感器最有效地检测 280-390nm 的光。这被归类为 UVB(燃烧射线)光谱的一部分和大部分 UVA(晒黑射线)光谱。 MOD-1016(AS3935 闪电传感器)i2c 地址 0x03 - AS3935 闪电传感器 Adafruit 有一个风速计,可提供直流电压输出 (0.4-2.0v) https://www.adafruit.com/products/1733 http://www. instructables.com/id/Breezefinder-Citizen-Science-Windpower-Tool/step2/Build-the-housing/ 土壤水分检测器(YL-69 传感器或类似传感器)需要模拟输入... http://www.instructables.com /id/Arduino-LCD-Soil-Moisture-Sensor/step3/Connect-moisture-sensor/ 我的 MKR1000 连接(所有传感器必须是 3.3v 信号!) ============*/int UVOUT =A1; // MV8511 UV sensorint lightOut =A2 的输出; // TEMT6000 可见光传感器的输出int tmp36out =A3; // TMP36 本地温度传感器的输出int mq9out =A4; // DFrobot MQ-9 CO/可燃 Gs 传感器的输出/* A5 湿度传感器 A6 风速传感器? 0 (HW INT) 按钮 1 (HW INT) AS 闪电探测器 2 (HW INT) 风速风速计? (每转中断) 3 (HW INT) Rain Tipper… 4 5 */int sounderPin =6; // 压电发声器输出(与板载 LED 共享)//(您可以使用跳线禁用发声器,但板载 LED 会闪烁) int neopixelPin =7; // NeoPixel 输出,用于使用基于移位寄存器的 LED 进行可视化/*11 i2c SDA 12 i2c SCL */ // Chronodot i2c RTC 的声明变量...int addrRTC =(0x68); // RTC i2c addressint seconds; //从RTC (00h)int seconds1 中组合BCD; //0-9int seconds10; //0-5int 分钟; //从RTC (01h)in​​t minutes1 中组合BCD; //0-9int 分钟10; //0-6int 小时; //从RTC (02h)int hours1 组合BCD; //0-9 int hours10; //0-2int 天; //1-7 (03h) int date; //01-31 (04h)int 月; //01-12 (05h)int 年; //0-99; (06h)int a1secs; // (07h) get Alarm 1 secondsint a1mins; // (08h) get Alarm 1 minutesint a1hrs; // (09h) get Alarm 1 hoursint a1daydate; // (0Ah) 获取闹钟 1 天和日期 bitsint a2mins; // (0Bh) get Alarm 2 minutesint a2hrs; // (0Ch) get Alarm 2 hoursint a2daydate; // (0Dh) 获取闹钟 2 天和日期 bitsint rtcstatus; // (0Eh) 获取 RTC 状态 bitsintaginginfo; // (0Fh) 获取老化偏移信息// 10h 是什么?int temprtc; //从RTC (11h)in​​t tempfrtc 组合BCD; //来自RTC的组合BCD(12h)/******************************************* ************************************/// Arduino 设置函数(启动时自动调用)/** ****************************************************** **********************/void setup(void) { Serial.begin(9600);延迟(1000); Serial.println("i2c Sensor Deck");// 记得设置你的输入和输出引脚! pinMode(UVOUT,输入); // ML8511 紫外线传感器 pinMode(lightOut, INPUT); // TEMT6000 可见光传感器 pinMode(tmp36out, INPUT); // 模拟设备 TMP36 温度传感器 pinMode(sounderPin, OUTPUT); // HIGH 会导致发声器发出噪音 pinMode(neopixelPin, OUTPUT); // 使用 220 欧姆电阻串联到条带 /* 初始化 BMP085/BMP180 传感器 */ if(!bmp.begin()) { /* 检测 BMP085/180 时出现问题...检查您的连接 */ Serial.print("哎呀,没有检测到 BMP085/180 ...检查你的接线或 I2C 地址!");同时(1); } /* 显示此传感器的一些基本信息,BMP180 报告为 BMP085 */ displaySensorDetails();/* 初始化 HTU21D 传感器 */ if (!htu.begin()) { Serial.println("Couldn't find the HTU21 -DF 传感器!");而 (1); }// 初始化 Chronodot RTC 时钟//(更改值,取消注释,然后上传设置时间,然后再次注释掉) /* seconds =0;分钟 =41;小时 =20;天 =7;日期 =3;月 =1;年 =16; initChrono();*/}void loop(void) { beep(50, 2); // 在发声器上宣布循环的开始 // 将新像素设置为青色... //int red =0; int 绿色 =45; int 蓝色 =30; //strip.setPixelColor(0, (red, green, blue)); //strip.show();/********************************************* *****************************/* 拉取 Chronot info i2c 地址 0x68 - DS1307 RTC *//* Board info:http ://docs.macetech.com/doku.php/chronodot *//* DS3231 数据表:http://datasheets.maxim-ic.com/en/ds/DS3231.pdf *//******* ****************************************************** *************/ int temprtc; /* 获取一个新的时间戳 */ Wire.beginTransmission(0x68); // 0x68 是 DS3231 设备地址 Wire.write((byte)0); // 从寄存器 0 开始 Wire.endTransmission(); Wire.requestFrom(0x68, 13); // 请求 19 个字节(是字节数 DEC 还是 HEX?)//(秒、分、小时、日、日期、月、小时、// a1secs、a1mins、a1hrs // a1secs、a1mins、a1hrs // Aging偏移量,临时整数,临时分数)while(Wire.available()) { seconds =Wire.read(); // (00h) 获取秒分钟 =Wire.read(); // (01h) 获取分钟 hours =Wire.read(); // (02h) get hours day =Wire.read(); // (03h) 获取星期几 date =Wire.read(); // (04h) 获取月份的日期 month =Wire.read(); // (05h) 获取月份和世纪位年份 =Wire.read(); // (06h) 获取年份 int a1secs =Wire.read(); // (07h) get Alarm 1 seconds int a1mins =Wire.read(); // (08h) 获取闹钟 1 分钟 int a1hrs =Wire.read(); // (09h) get Alarm 1 hours int a1daydate =Wire.read(); // (0Ah) 获取闹钟 1 天和日期位 int a2mins =Wire.read(); // (0Bh) 获取警报 2 分钟 int a2hrs =Wire.read(); // (0Ch) get Alarm 2 hours int a2daydate =Wire.read(); // (0Dh) 获取闹钟 2 天和日期位 int rtcstatus =Wire.read(); // (0Eh) 获取 RTC 状态位 intaginginfo =Wire.read(); // (0Fh) 获取老化偏移信息 temprtc =Wire.read(); // (11h) 获取 temp 的整数部分,并对 tempfrtc =Wire.read(); // (12h) 获取临时值的小数部分 // 读取我们的位,并使用前导零填充对数据进行标准化 // 注意:Chronodot 不知道夏令时,您的代码应该吗? seconds10 =((seconds &0b11110000)>>4); seconds1 =((seconds &0b00001111)); // 将 BCD 转换为十进制 mins10 =((minutes &0b11110000)>>4);分钟 1 =(分钟 &0b00001111); // 将 BCD 转换为十进制 hours10 =(((hours &0b00100000)>>5)*2 + ((hours &0b00010000)>>4)*1);小时 1 =(小时 &0b00001111); // 将 BCD 转换为十进制(假设为 24 小时模式) years =(years + 2000); temprtc =((temprtc &0b01111111) + (((tempfrtc &0b11000000)>>6)*0.25)); } get_date(); // 这是一个你可以添加夏令时决定来改变时间的地方... Serial.print("ChronoDot - "); Serial.print(hours10); Serial.print(hours1); Serial.print(":"); Serial.print(minutes10); Serial.print(minutes1); Serial.print(":"); Serial.print(seconds10); Serial.print(seconds1); Serial.print(" 20"); Serial.print(年); Serial.print(" "); Serial.print(月); Serial.print(" "); Serial.print(日期); Serial.print(" \t"); Serial.print(temprtc); Serial.println("C");延迟(100); // 所以这将完成打印,以防下一个传感器停止 /************************************ ************************************/* 获取 BMP180 数据 i2c 地址 0x77 - BMP180 Baro Pres 和温度 *//* 数据:http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf *//******************* ****************************************************** */ sensors_event_t event; bmp.getEvent(&event); /* First we get the current temperature from the BMP085/BMP180 */ float BMPtemperature; bmp.getTemperature(&BMPtemperature); float BMPtempF =(BMPtemperature * 1.8 + 32); Serial.print("Temp:"); Serial.print(BMPtemperature); Serial.print(" C ("); Serial.print(BMPtempF); Serial.print(" F) \t"); /* Display the results (barometric pressure is measure in hPa) */ if (event.pressure) { /* Display atmospheric pressue in hPa */ Serial.print("BMP180 - Pres:"); Serial.print(event.pressure); Serial.print(" hPa\t"); /* Calculating altitude with reasonable accuracy requires pressure * * sea level pressure for your position at the moment the data is * * converted, as well as the ambient temperature in degress * * celcius. If you don't have these values, a 'generic' value of * * 1013.25 hPa can be used (defined as SENSORS_PRESSURE_SEALEVELHPA * * in sensors.h), but this isn't ideal and will give variable * * results from one day to the next. * * * * You can usually find the current SLP value by looking at weather * * websites or from environmental information centers near any major * * airport. * * * * convert inches-mercury http://www.csgnetwork.com/pressinmbcvt.html * * * For example, for Paris, France you can check the current mean * * pressure and sea level at:http://bit.ly/16Au8ol */ /* Then convert the atmospheric pressure, and SLP to altitude */ /* Update this next line with the current SLP for better results */ float seaLevelPressure =SENSORS_PRESSURE_SEALEVELHPA; Serial.print("Alt:"); Serial.print(bmp.pressureToAltitude(seaLevelPressure, event.pressure)); Serial.println(" m");延迟(100); // so this will finish printing, in case the next sensor is stalled } else { Serial.println("Sensor error"); } /**********************************************************************/* Get HTU21-DF data i2c address 0x40 - Humidity and Temp Sensor */* Then convert the atmospheric pressure, and SLP to altitude */* Update this next line with the current SLP for better results */* https://learn.adafruit.com/adafruit-htu21d-f-temperature-humidity-sensor/overview/**********************************************************************/ float HTUtemperature =htu.readTemperature(); float HTUtempF =(HTUtemperature * 1.8 + 32); Serial.print("HTU21-DF - Temp:"); Serial.print(HTUtemperature); Serial.print(" C ("); Serial.print(HTUtempF); Serial.print(" F)\tHum:"); Serial.print(htu.readHumidity()); Serial.println("%");延迟(100); // so this will finish printing, in case the next sensor is stalled/**********************************************************************/* Analog Devices venerable TMP36 precision temperature sensor/* this requires a bit of math after reading the output.../* https://learn.adafruit.com/tmp36-temperature-sensor/using-a-temp-sensor/**********************************************************************/ //getting the voltage reading from the temperature sensor int reading =averageAnalogRead(tmp36out); // 0.0032258064516129 are the DAC unit for 3.3v float tmp36voltage =0.0032258064516129 * reading; // print out the voltage Serial.print("TMP36 - temp:"); float tmp36temperatureC =(tmp36voltage - 0.5) * 100; //converting from 10 mv per degree with 500 mV offset to degrees ((voltage - 500mV) times 100) Serial.print(tmp36temperatureC); Serial.print(" C \t"); // now convert to Fahrenheit float tmp36temperatureF =(tmp36temperatureC * 9.0 / 5.0) + 32.0; Serial.print(tmp36temperatureF); Serial.print(" F, out:"); Serial.print(tmp36voltage); Serial.println("v");延迟(100); // so this will finish printing, in case the next sensor is stalled/********************************************************************** * Vishay TEMT6000 Visible Light sensor - analog reading * https://www.sparkfun.com/products/8688/**********************************************************************/ int vLevel =averageAnalogRead(lightOut); // 0.0032258064516129 is (3.3v (the DAC ref voltage) \ 1023 * uvLevel) float newVOutVolts =0.0032258064516129 * vLevel; Serial.print("TEMT6000 out:"); Serial.println(vLevel);延迟(100); // so this will finish printing, in case the next sensor is stalled /********************************************************************** * ML8511 UV Sensor - analog reading * https://learn.sparkfun.com/tutorials/ml8511-uv-sensor-hookup-guide */**********************************************************************/ int uvLevel =averageAnalogRead(UVOUT); // 0.0032258064516129 is (3.3v (the DAC ref voltage) \ 1023 * uvLevel) float newOutVolts =0.0032258064516129 * uvLevel; //Convert the voltage to a UV intensity level float uvIntensity =mapfloat(newOutVolts, 0.99, 2.8, 0.0, 15.0); Serial.print("ML8511 UV out:"); Serial.print(uvLevel); Serial.print(" / UV Intensity (mW/cm^2):"); Serial.println(uvIntensity);延迟(100); // so this will finish printing, in case the next sensor is stalled/********************************************************************** * DFrobot MQ-9 CO/Combustable Gas sensor - analog reading * http://www.dfrobot.com/wiki/index.php/Analog_Gas_Sensor(MQ9)_(SKU:SEN0134) * https://www.pololu.com/category/83/gas-sensors There are many available * But, deciphering what the output levels mean is an exercise for the buyer. :-(/**********************************************************************/ int MQ9volts =analogRead(mq9out); // Read Gas value from the MQ-9 sensor Serial.print("MQ-9 Gas:"); Serial.println(MQ9volts,DEC); delay(100); // so this will finish printing, in case the next sensor is stalled Serial.println(""); delay(3500); // looking to time the loop at about 5 seconds... // End of the main loop...}/**************************************************************************//* The code below are supporting subroutines */**************************************************************************//* Chronodot-related subroutines * * initChrono, set_date, get_date, set_time, get_time, get_temp, * * setHour, SetMinutes, decToBcd, bcdToDec *//**************************************************************************/void initChrono(){ set_time(); set_date();}void set_date(){ Wire.beginTransmission(104); Wire.write(4); Wire.write(decToBcd(day)); Wire.write(decToBcd(date)); Wire.write(decToBcd(mont h)); Wire.write(decToBcd(years)); Wire.endTransmission();}void get_date(){ Wire.beginTransmission(104); Wire.write(3);//set register to 3 (day) Wire.endTransmission(); Wire.requestFrom(104, 4); //get 4 bytes(day,date,month,year); day =bcdToDec(Wire.read()); date =bcdToDec(Wire.read()); month =bcdToDec(Wire.read()); years =bcdToDec(Wire.read());}void set_time(){ Wire.beginTransmission(104); Wire.write((byte)0); Wire.write(decToBcd(seconds)); Wire.write(decToBcd(minutes)); Wire.write(decToBcd(hours)); Wire.endTransmission();}void get_time(){ Wire.beginTransmission(104); Wire.write((byte)0);//set register to 0 Wire.endTransmission(); Wire.requestFrom(104, 3);//get 3 bytes (seconds,minutes,hours); seconds =bcdToDec(Wire.read() &0x7f); minutes =bcdToDec(Wire.read()); hours =bcdToDec(Wire.read() &0x3f);}void get_temp(){ Wire.beginTransmission(104); Wire.write((byte)0); //set register to 0 Wire.endTransmission(); Wire.requestFrom(104, 3);//get 3 bytes (seconds,minutes,hours); seconds =bcdToDec(Wire.read() &0x7f); minutes =bcdToDec(Wire.read()); hours =bcdToDec(Wire.read() &0x3f);}void setHour(){ hours++; if (hours> 23) { hours =0; seconds =0; minutes =0; } set_time();}void setMinutes(){ minutes++; if (minutes> 59) { minutes =0; } seconds =0; set_time();}byte decToBcd(byte val){ return ( (val / 10 * 16) + (val % 10) );}byte bcdToDec(byte val){ return ( (val / 16 * 10) + (val % 16) );}/**************************************************************************//* Displays some basic information on this sensor from the unified sensor API sensor_t type (see Adafruit_Sensor for more information) *//**************************************************************************/void displaySensorDetails(void){ sensor_t sensor;// bmp.getSensor(&sensor); Serial.println("------------------------------------"); Serial.print ("Sensor:"); Serial.println(sensor.name); Serial.print ("Driver Ver:"); Serial.println(sensor.version); Serial.print ("Unique ID:"); Serial.println(sensor.sensor_id); Serial.print ("Max Value:"); Serial.print(sensor.max_value); Serial.println(" hPa"); Serial.print ("Min Value:"); Serial.print(sensor.min_value); Serial.println(" hPa"); Serial.print ("Resolution:"); Serial.print(sensor.resolution); Serial.println(" hPa"); Serial.println("------------------------------------"); Serial.println(""); delay(500);}/**************************************************************************//* Takes an average of readings on a given pin, Returns the average */* used for the TMP36 and ML8511 UV Sensor readings./**************************************************************************/int averageAnalogRead(int pinToRead){ byte numberOfReadings =8; unsigned int runningValue =0; for(int x =0; x  
Taking an Average Analog ReadingArduino
This was a clever hack I found in the SparkFun library for the ML8511 UV Sensor, but I'm calling it out specifically, since you can use it for any analog read! If you ever meet Nathan Seidl, please buy him a beer (it's a Beerware license.)
//Takes an average of readings on a given pin//Returns the averageint averageAnalogRead(int pinToRead){ byte numberOfReadings =8; unsigned int runningValue =0; for(int x =0; x  
I2C bus scannerArduino
If you don't know the base address for your i2c devices, use this to scan the range of valid addresses. It knows about the sensors that I've been working with. You can add sections for your other sensors.
// --------------------------------------// i2c_scanner//// Found at http://playground.arduino.cc/Main/I2cScanner?action=sourceblock&num=1// 26 OCT 2015//// Version 1// This program (or code that looks like it)// can be found in many places.// For example on the Arduino.cc forum.// The original author is not know.// Version 2, Juni 2012, Using Arduino 1.0.1// Adapted to be as simple as possible by Arduino.cc user Krodal// Version 3, Feb 26 2013// V3 by louarnold// Version 4, March 3, 2013, Using Arduino 1.0.3// by Arduino.cc user Krodal.// Changes by louarnold removed.// Scanning addresses changed from 0...127 to 1...119,// according to the i2c scanner by Nick Gammon// http://www.gammon.com.au/forum/?id=10896// Version 5, March 28, 2013// As version 4, but address scans now to 127.// A sensor seems to use address 120.//// This sketch tests the standard 7-bit addresses// Devices with higher bit address might not be seen properly.//// Zonk er Harris added device descriptions, comments. OCT 10 2015// #include void setup(){ Wire.begin(); Serial.begin(9600); Serial.println("\nI2C Scanner");}void loop(){ byte error, address; int nDevices; Serial.println("Scanning..."); nDevices =0; for(address =1; address <127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error =Wire.endTransmission(); if (error ==0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); // Serial.print(address); If needed, print the address in decimal // // Now, detail sensors that we know about or expect... if (address ==3) { // DEC 3 =0x03 HEX =AS3935 Lightning Sensor Serial.print(" - AS3935 Lightning Sensor"); } if (address ==64) { // DEC 64 =0x40 HEX =HTU21D Humidity and Temp Sensor Serial.print(" - HTU21D Humidity and Temp Sensor"); } if (address ==104) { // DEC 104 =0x68 HEX =DS1307 (Chrono-Dot?) RTC Serial.print(" - DS1307 RTC (Chrono-Dot?)"); } if (address ==119) { // DEC 119 =0x77 HEX =BMP180 Barometric Pressure and Tem Sensor Serial.print(" - BMP180 Barometric Pressure and Tem Sensor"); } Serial.println(" "); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); if (address ==3) { // DEC 3 =0x03 HEX =AS3935 Lightning Sensor Serial.print(" - AS3935 Lightning Sensor"); } if (address ==64) { // DEC 64 =0x40 HEX =HTU21D Humidity and Temp Sensor Serial.print(" - HTU21D Humidity and Temp Sensor"); } if (address ==104) { // DEC 104 =0x68 HEX =DS1307 (Chrono-Dot?) RTC Serial.print(" - DS1307 RTC (Chrono-Dot?)"); } if (address ==119) { // DEC 119 =0x77 HEX =BMP180 Barometric Pressure and Tem Sensor Serial.print(" - BMP180 Barometric Pressure and Tem Sensor"); } } } if (nDevices ==0) Serial.println("No I2C devices found\n"); else Serial.println("done\n");延迟(5000); // wait 5 seconds for next scan}/* The output looks like this... * * Scanning... * I2C device found at address 0x03 - AS3935 Lightning Sensor * I2C device found at address 0x40 - HTU21D Humidity and Temp Sensor * I2C device found at address 0x68 - DS1307 RTC (Chrono-Dot?) * I2C device found at address 0x77 - BMP180 Barometric Pressure and Tem Sensor * done * */
ML8511 Demo CodeArduino
Modified for use with a 3.3v-native CPU (for DAC reference units).
/* * From https://learn.sparkfun.com/tutorials/ml8511-uv-sensor-hookup-guide 19 MAR 2016 * (Adapted for MKR1000 by Zonker Harris, MAR 2016) ML8511 UV Sensor Read Example By:Nathan Seidle SparkFun Electronics Date:January 15th, 2014 License:This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). The ML8511 UV Sensor outputs an analog signal in relation to the amount of UV light it detects. Connect the following ML8511 breakout board to Arduino:3.3V =3.3V OUT =A1 GND =GND EN =3.3V * The Sparkfun demo presumes 5v VCC, but the MKR1000 is 3.3v native. * Because of this, the second reference voltage value will always be "1023". * As a result of testing, I cut that part out... -Z- Test your sensor by shining daylight or a UV LED:https://www.sparkfun.com/products/8662 This sensor detects 280-390nm light most effectively. This is categorized as part of the UVB (burning rays) spectrum and most of the UVA (tanning rays) spectrum. There's lots of good UV radiation reading out there:http://www.ccohs.ca/oshanswers/phys_agents/ultravioletradiation.html https://www.iuva.org/uv-faqs *///Hardware pin definitionsint UVOUT =A1; //Output from the sensorvoid setup(){ Serial.begin(9600); pinMode(UVOUT, INPUT); Serial.println("ML8511 example");}void loop(){ int uvLevel =averageAnalogRead(UVOUT); float newOutVolts =0.0032258064516129 * uvLevel; // This is 3.3v \ 1023 * uvLevel float uvIntensity =mapfloat(newOutVolts, 0.99, 2.8, 0.0, 15.0); //Convert the voltage to a UV intensity level Serial.print("ML8511 out:"); Serial.print(uvLevel); Serial.print(" / UV Intensity (mW/cm^2):"); Serial.print(uvIntensity); Serial.println(); delay(100);}//Takes an average of readings on a given pin//Returns the averageint averageAnalogRead(int pinToRead){ byte numberOfReadings =8; unsigned int runningValue =0; for(int x =0; x  

示意图

I'm too new to Fritzing, and couldn't find many parts in the library, so I made this mock-up instead.

制造工艺

  1. 传感器融合带来多重好处
  2. 传感器数据与 Raspberry Pi 微处理器的集成
  3. 带 RPi 的线跟踪传感器
  4. 带有 RPi 的环境传感器 API
  5. 带有 Raspberry Pi 和湿度传感器的 Aeroponics
  6. 带有 PIR 运动传感器的 Raspberry Pi GPIO:最佳教程
  7. 将 A111 脉冲雷达传感器与 Raspberry Pi 结合使用
  8. 将 HC-SR501 PIR 运动传感器与 Raspberry Pi 连接
  9. Python/MicroPython Sensor Logger with Google Sheets
  10. Raspberry Pi 2 上的 Windows 10 IoT Core – Adafruit 传感器数据
  11. 具有睡眠模式的树莓派关机电路
  12. Portenta 和热电偶传感器(带 MAX6675)