电子说
概述
这是一个方便的Arduino防护板:我们有很多人在寻找专用且设计良好的数据记录防护板。我们努力设计出价格低廉但功能全面的设计。此防护罩可轻松为您的Arduino添加具有千兆字节存储空间的“硬盘”!
此流行防护罩的最新版本具有流行原始防护罩的所有功能,并且与“ R3”兼容,因此您几乎可以将其与任何Arduino或兼容产品一起使用。您可以在不到15分钟的时间内启动并运行它-将数据保存到任何FAT16或FAT32格式的SD卡上的文件中,以供任何绘图,电子表格或分析程序读取。本教程还将向您展示如何使用两个免费软件程序来绘制数据。随附的RTC(实时时钟)可用于以当前时间为所有数据添加时间戳,以便您确切地了解何时发生了什么!
数据记录器是可靠,全面且通用的设计。它易于扩展或修改,并得到在线文档和库的很好支持
功能:
SD卡接口可用于FAT16或FAT32格式的卡。内置的3.3v电平转换器电路使您可以超快地读取或写入数据,并防止损坏SD卡
即使在拔下Arduino的情况下,实时时钟(RTC)仍可以保持时间。纽扣电池备份可以持续多年
包含的库以及用于SD和RTC的示例代码,这意味着您可以快速上手
用于焊接连接器,电路或传感器的原型区域。
li》
两个可配置指示灯LED
板载3.3v稳压器既是可靠的参考电压,又可可靠地运行需要大量功率才能运行的SD卡
使用“ R3布局”的I2C和ICSP/SPI端口,因此与各种Arduino和Arduino兼容产品兼容
在此新版本中,您可以将其与:
兼容Arduino UNO或ATmega328-4个模拟通道,分辨率为10位,如果不使用RTC,则为6个
Arduino Leonardo或ATmega32u4兼容-12个模拟通道,分辨率为10位分辨率
兼容Arduino Mega或ATmega2560-16个模拟输入(10位)
兼容Arduino零或ATSAMD21-6个模拟输入(12位)
兼容Arduino Due-12个模拟输入(12位)
当然,您可以记录任何您喜欢的东西,包括具有Arduino库,串行数据,位时序等等的数字传感器!
安装接头连接器
Adafruit Data Logger防护板经过测试,已组装好所有组件和SD插槽,但是您仍然需要安装接头连接器,以便可以将其插入Arduino
,因为有两个选项,所以我们不会预先组装接头!您可以使用普通的0.1英寸公头(包括在屏蔽中)或Arduino Shield Stacking头。这两个选项还需要焊接一个2x3母头。
带公头的组装
大多数人都会对他与公头的屏蔽罩组装感到满意。使用它们的好处是不要在项目的高度上添加任何东西,它们会建立良好的牢固连接。但是,您将无法在顶部堆叠另一个盾牌。权衡取舍!
翻转并焊接另一侧以及2x3接头
将标头切成一定长度:
将标头条与在标头边缘上的孔对齐屏蔽并切下标题栏的4个部分以适合。
放置插头:
将插头部分(长针向下)插入Arduino/Metro的母头中。另外,将2x3母头插入USB另一侧的相应插针中。
放置防护罩:
将防护罩与排针对齐,然后按下。
然后焊接!
焊接每个引脚以确保良好的电接触。有关焊接的技巧,请参阅《 Adafruit优秀焊接指南》。
使用堆栈头进行组装:堆栈头为您的数据记录仪提供了更大的灵活性。您可以将其与其他防护罩(例如RGB/LCD显示器防护罩)结合使用,以使紧凑型测井仪具有用户界面。您还可以将其与一个或多个Proto-Shield堆叠在一起,以增加更多的原型空间来与传感器接口。
堆叠接头安装在板的顶部而不是底部,因此该过程与安装简单的公头。
定位头:
从屏蔽层顶部插入页眉,然后将屏蔽层翻转并将其放置在平坦的表面上。调整标题以使其垂直。
请确保从屏蔽层的顶部插入插头,以便可以将其与底部。
将板子放在Metro上并焊接2x3接头
然后焊接!
将每个引脚焊接成固体电气连接。
提示:从每个插头部分焊接一个引脚。如果其中任何一个弯曲,只需重新加热一个焊点并用手将其拉直即可。一旦所有接头都直了,继续焊接其余的引脚。
翻转并焊接另一面
放置2x3母头Arduino/Metro上的标题
防护罩概述
数据记录器防护罩有几件事使其成为跟踪数据的绝佳方法。这是盾牌的大致图:
我们的最新版本为5V,3.3V和地面添加了电源轨:
div》 SD卡
大的SD卡夹可容纳最大32G和最小32MB的SD/MMC存储(任何格式的FAT16或FAT32)。如果您有MicroSD卡,则可以使用低成本的适配器SD卡比MicroSD更难丢失,并且有足够的空间容纳标准尺寸的存储卡。
只需按一下即可插入,或拉出即可从该插槽中取出卡
SD活动LED 连接到时钟引脚,当数据经过SPI时它将闪烁,这可以帮助您确定何时可以移除或插入SD卡或电源。
电平转换器将所有信号从3.3V或5V DOW移动n至3.3V,因此您可以安全地将此屏蔽罩与 any Arduino一起使用,而不会损坏卡。便宜的屏蔽层使用电阻器进行电平转换,但这在高速或在所有电压电平下均无法正常工作!
实时时钟
这是计时设备。它包括一个8针芯片,一个矩形的32KHz晶体和一个电池座
电池座必须包含一个电池,以便RTC能够跟踪从Arduino断开电源时的时间!使用任何与CR1220兼容的纽扣电池
CR1220 12mm直径-3V锂币电池 strong》
产品ID:380
这些是最高质量的产品。容量的电池,与iCufflinks,iNecklace,Datalogging和GPS Shields,GPS HAT等产品随附的电池相同。每笔订购一个电池。..
$ 0.95
入库
添加到购物车
3.3V电源
板载3.3V LDO(低压降)稳压器可保持屏蔽的3V零件运行平稳。一些旧的Arduinos没有完整的3.3V稳压器,写入SD卡可能会导致Arduino重新启动。为了保持兼容性,我们只需将其保留在那里。右侧还有一个绿色的PWR(电源)良好LED指示灯
用户LED
我们有两个用户可配置的LED。将任何Arduino引脚上的电线连接到标记有 L1 或 L2 的焊盘,并拉高以打开 LED1 或 LED2
LED右侧的重置按钮将重置整个Arduino,方便您在要重新启动电路板时使用
原型开发区域
大的中间部分充满了0.1“网格原型孔,因此您可以自定义您的
顶部和底部两行原型孔是电源导轨。
突破垫
上面在分支板区域附近还显示了一些额外的分支。
在SD卡持有者的右侧:
CD -这是SD卡上的卡检测垫。将其接地后,将插入SD卡。它是漏极开路,使用上拉电阻(物理电阻或在软件中启用)
WP-这是SD卡上的写保护板,您可以使用它来通过检查此引脚来检测卡上的写保护选项卡。它是漏极开路,使用上拉电阻(物理电阻器或在软件中启用)
SQ -这是RTC的可选方波输出。您必须发送命令将其打开,但这是选择获取精确方波的一种方法。我们主要将其用于测试。输出是开漏输出,因此具有上拉电阻(物理电阻或在软件中启用)
3V -这是稳压器输出的3V。它是高质量的3.3V参考电压,您可能希望为传感器供电。高达50mA可用
数字10号附近
CS -这是芯片选择 SD卡的引脚。如果由于冲突而需要将迹线切割到引脚10,可以将该焊盘焊接到任何数字引脚上,并重新上载软件
在数字3和#4附近 p》
L2 和 L1 -这些是可选的用户LED。连接到任何数字引脚,将其拉高以打开相应的LED。这些LED已经串联了470欧姆电阻。
接线和配置
从Datalogger屏蔽的B版本开始,我们不再使用数字引脚10、11、12、13用于SPI和A4,A5用于I2C。现在,我们使用2x3 ICSP标头,这意味着您不需要特殊的自定义I2C或SPI库即可与Mega,Leonardo或Zero(或其他任何将来的类型)的Arduino一起使用!
我具有哪个版本?
这是较旧的Datalogger屏蔽。特别要注意的是,原型区域完全充满了0.1“间隔的孔
这是“与R3兼容”的数据记录器。它具有较小的原型区域,并且在右侧有一个2x3 SPI头点
较旧的屏蔽插脚
在较旧的屏蔽上,插脚固定为固定 :
数字#13- SPI时钟
数字#12- SPI MISO
数字#11- SPI MOSI
数字#10- SD卡芯片选择(可以切割痕迹以重新分配)
SDA 已连接至 A4
SCL 已连接至 A5
RTC(DS13 07)I2C逻辑电平固定为5V
修订版B屏蔽引脚排列
ICSP SCK- SPI时钟
ICSP MISO- SPI MISO
ICSP MOSI- SPI MOSI
数字#10- SD卡芯片选择(可以切割痕迹以重新分配)
SDA 不 连接到 A4
SCL not 连接到 A5
RTC(PCF8523)逻辑电平可以是3V或5V
在UNO上,请注意,数字#13与ICSP SCK相同,#12是ICSP MISO,#11是ICSP MOSI,SDA连接到A4,SCL连接到A5。但是,这仅适用于UNO!其他Arduino具有不同的连接。由于屏蔽不再假设它位于UNO上,因此它是最兼容的屏蔽。
在Rev B屏蔽的底部,您可以看到,如果您有一个较旧的Arduino,没有ICSP 2x3接头连接器,也没有SDA/SCL引脚,则可以使焊接跳线短路。
如果您将屏蔽与3.3V逻辑Arduino配合使用,则可能需要更改 Vio 跳线。这就是I2C的10K上拉电阻。老实说,上拉非常弱,所以如果您忘记了,这没什么大不了的。但是,如果可以的话,请在中心焊盘和5V之间切一条小线,然后焊接另一侧,以便将Vio连接到3V
较旧的数据记录器Shield Leonardo&Mega Library
仅当您有没有SPI端口连接的较旧的Datalogger屏蔽。
仅当您使用带有旧版Datalogger防护罩的Leonardo或Mega时才需要!
如果您的屏蔽罩如上所示,并且在右侧具有2x3引脚头,请跳过此页面!
如果您的屏蔽罩没有2x3引脚头部分,并且您使用的是Mega或Leonardo(例如,不兼容UNO),那么您可以继续阅读!/p》
如果您使用的Leonardo或Mega带有较旧的数据记录屏蔽,则必须替换现有的SD卡库以添加“任何引脚上的SD卡”支持。 如果您拥有Uno/Duemilanove/Diecimila,则不需要这样做。如果您使用的是B版防护罩,那么也不需要这样做!
首先,找到“核心库”文件夹-如果您使用的是Windows或Linux,它将位于包含 Arduino 可执行文件,查找 libraries 文件夹。在内部,您会看到一个 SD 文件夹(其中将是 SD.cpp SD.h 等)
在库文件夹中,新建一个名为 SDbackup 的文件夹。然后将 SD 文件夹拖到 SDbackup 中,这将“隐藏”旧的 SD 库而不删除它。 请注意,SDBackup必须位于库文件夹的外部之外,以便有效地“隐藏” SD库。
现在,我们将获取新的SD库,请访问https://github。 com/adafruit/SD ,然后单击 ZIP 下载按钮,或单击下面的按钮
下载SD库压缩文件
解压缩并重命名未压缩的文件夹 SD 。检查 SD 文件夹中是否包含 SD.cpp 和 SD.h
放置 SD 库文件夹,即写生簿库文件夹。如果您是第一个库,则可能需要创建库子文件夹。有关如何安装库的更多详细信息,请查看我们的超详细教程,网址为http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use
使用Mega和Leonardo的SD库因为Mega和Leonardo如果没有相同的硬件SPI引脚分配,则需要指定将用于与卡进行SPI通信的引脚。对于数据记录器屏蔽,它们将是引脚10、11、12和13。在草图中找到调用SD.begin()的位置(如下所示):
下载:文件
复制代码
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
并对其进行更改,以添加这些引脚号,如下所示:
下载:文件
复制代码
// see if the card is present and can be initialized:
if (!SD.begin(10, 11, 12, 13)) {
// see if the card is present and can be initialized:
if (!SD.begin(10, 11, 12, 13)) {
cardinfo cardinfo草图使用较低级别的库直接与卡对话,因此调用card.init()而不是SD.begin()。
下载:file
复制代码
// we‘ll use the initialization code from the utility libraries
// since we’re just testing if the card is working!
while (!card.init(SPI_HALF_SPEED, chipSelect)) {
// we‘ll use the initialization code from the utility libraries
// since we’re just testing if the card is working!
while (!card.init(SPI_HALF_SPEED, chipSelect)) {
在调用card.init()时,必须更改调用以指定SPI引脚,如下所示:
下载:文件
复制代码
// we‘ll use the initialization code from the utility libraries
// since we’re just testing if the card is working!
while (!card.init(SPI_HALF_SPEED, 10, 11, 12, 13)) {
// we‘ll use the initialization code from the utility libraries
// since we’re just testing if the card is working!
while (!card.init(SPI_HALF_SPEED, 10, 11, 12, 13)) {
使用实时时钟
是实时时钟吗?
记录数据时,通常非常有用的是带有时间戳记!这样一来,您可以每隔一分钟(通过检查时钟)或记录一天中的什么时间记录数据。
Arduino确实有一个称为 millis()的内置计时器。 ,并且该芯片还内置了计时器,可以跟踪更长的时间段,例如分钟或几天。那么,为什么要有单独的RTC芯片呢?好吧,最大的原因是 millis()只跟踪时间,因为Arduino上次通电是- ,这意味着何时通电打开后,毫秒计时器将设置为0。Arduino不知道它的“星期二”或“ 3月8日”,只能告诉我“自上次打开以来已经过了14,000毫秒”。
好的,如果您想在Arduino上设置时间怎么办?您必须编程日期和时间,从那时起您就可以算上它了。但是,如果失去电源,则必须重新设置时间。就像非常便宜的闹钟一样:每次断电时,它们都会闪烁 12:00
尽管某些项目可以使用这种基本的计时功能,但数据记录器需要具有一致的计时功能,当Arduino电池耗尽或重新编程时,计时不会重置。因此,我们包括一个单独的RTC! RTC芯片是一种专门的芯片,可以跟踪时间。它可以计算leap年,并且知道一个月中有多少天,但是它不考虑夏时制(因为它在不同的地方有所不同)
此图显示了具有实时功能的计算机主板时钟称为DS1387。
我们要使用的RTC是 PCF8523 或 DS1307 》。
如果您拥有Adafruit Datalogger Shield B版,则将使用PCF8523 -该RTC较DS1307更新且更好。看一下屏蔽罩,看看是否在芯片上方写有 PCF8523 。
如果您使用的是较旧的Datalogger保护罩,则将使用DS1307 -没有文本,因此您只需记住,如果不是 说是PCF8523,那就是DS1307
备用电池
只要有一个纽扣电池可以运行,即使在
使用任何CR1220 3V锂金属纽扣电池:
CR1220直径12毫米-3V锂纽扣电池
产品ID:380
这些是最高质量的产品,容量的电池,与iCufflinks,iNecklace,Datalogging和GPS Shields,GPS HAT等产品随附的电池相同。每笔订购一个电池。..
$ 0.95
入库
添加到购物车
您必须安装纽扣电池才能使RTC正常工作,如果没有纽扣电池,它将表现得很奇怪,并可能在您尝试使用Arduino时将其挂起,因此始终确保已安装电池,即使电池没电了。
RTC
RTC是一种i2c设备,这意味着它使用2条线进行通信。这两条线用于设置时间并进行检索。在Arduino UNO上,这些引脚还连接到模拟4 和 5 引脚。这有点烦人,因为我们当然希望最多有6个模拟输入来读取数据,而现在我们已经丢失了2个。
对于RTC库,我们将使用JeeLab卓越的分叉器可以在GitHub上找到RTC库 。您可以通过访问github存储库并手动下载来实现此目的,或者只需单击此按钮即可下载zip
下载RTC库
重命名未压缩的文件夹 RTClib ,并检查 RTClib 文件夹是否包含 RTClib 。 cpp 和 RTClib 。h
将 RTClib 库文件夹放在 arduinosketchfolder/libraries/文件夹。
如果您是第一个库,则可能需要创建库子文件夹。重新启动IDE。
我们还提供了有关Arduino库安装的出色教程,网址为:
http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use
完成后,重新启动IDE
第一次RTC测试
我们将演示的第一件事是一个测试草图,它将每秒从RTC读取一次时间。我们还将显示如果您卸下电池并更换电池会发生什么,因为这会导致RTC停止。因此,要开始使用,请在未给Arduino供电或未将其插入USB的情况下从电池座中取出电池。等待3秒钟,然后更换电池。这将重置RTC芯片。现在,为您的RTC加载匹配的草图
对于Adafruit Datalogger盾牌版本B,打开示例-》 RTClib-》 pcf8523
较旧的Adafruit数据记录器,请使用示例-》 RTClib-》 ds1307
在数据记录器防护罩打开的情况下将其上传到Arduino!
如果遇到问题,请确保运行正确的示例! PCF8523和DS1307 RTC芯片不相同,因此它们有单独的示例!
现在打开串行控制台,并确保将波特率正确设置为 57600波特,您应该会看到以下内容:
每当RTC芯片失去所有电源(包括备用电池)时,它将重置为较早的日期,并将时间报告为0:0:0或类似时间。 DS1307甚至不会数秒(已停止)。无论何时设置时间,这都会启动时钟的滴答声。
因此,基本上,这里的结果是,您永远不要卸下电池您已设定时间。您不需要,电池座也非常贴合,因此除非面板被压碎,否则电池不会“掉落”
设置时间
在加载了相同草图的情况下,取消注释以 RTC开头的行。/strong》,例如:
下载:文件
复制代码
if (! rtc.initialized()) {
Serial.println(“RTC is NOT running!”);
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); if (! rtc.initialized()) {
Serial.println(“RTC is NOT running!”);
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
这行很可爱,它的作用是根据您使用的计算机获取日期和时间(编译时正确)代码)并将其用于RTC编程。如果您的计算机时间设置不正确,则应首先解决该问题。然后,您必须按上传按钮进行编译,然后立即上传。如果您先编译然后再上传,则该时间将关闭时钟。
然后打开“串行”监视器窗口以显示时间已设置
从现在开始,您不会必须再次设置时间:电池将使用5年或以上
读取时间
现在,RTC快活了,我们想查询一下时间。让我们再次看一下草图,看看如何完成
下载:文件
复制代码
void loop () {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print(‘/’);
Serial.print(now.month(), DEC);
Serial.print(‘/’);
Serial.print(now.day(), DEC);
Serial.print(“ (”);
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(“) ”);
Serial.print(now.hour(), DEC);
Serial.print(‘:’);
Serial.print(now.minute(), DEC);
Serial.print(‘:’);
Serial.print(now.second(), DEC);
Serial.println(); void loop () {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print(‘/’);
Serial.print(now.month(), DEC);
Serial.print(‘/’);
Serial.print(now.day(), DEC);
Serial.print(“ (”);
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(“) ”);
Serial.print(now.hour(), DEC);
Serial.print(‘:’);
Serial.print(now.minute(), DEC);
Serial.print(‘:’);
Serial.print(now.second(), DEC);
Serial.println();
使用RTClib获取时间的方法几乎只有一种,即调用 now(),此函数返回一个DateTime对象,该对象描述了调用 now()时的年,月,日,时,分和秒。
有一些RTC库可以代替您调用 RTC.year()和 RTC.hour()之类的东西来获取当前的年份和小时。但是,存在一个问题,如果您碰巧在下一分钟滚动之前在 3:14:59 询问分钟,然后在分钟滚动之后询问第二分钟(所以在 3:15:00 ),您会看到时间为 3:14:00 ,该时间需要一分钟。如果您以其他方式进行操作,则可能会得到 3:15:59 -在另一方向上间隔一分钟。
因为这不是特别不可能发生的情况-特别是如果您经常查询时间-我们会一次从RTC中获取时间的“快照”,然后将其拆分为 day()或 second() (如上所示)。付出了更多的努力,但是我们认为避免错误是值得的!
我们还可以通过调用 unixtime 来从DateTime对象中获取“时间戳”,该计数会计数自1970年1月1日午夜以来的秒数(不计算leap秒)
下载:文件
复制代码
Serial.print(“ since 2000 = ”);
Serial.print(now.unixtime());
Serial.print(“s = ”);
Serial.print(now.unixtime() / 86400L);
Serial.println(“d”); Serial.print(“ since 2000 = ”);
Serial.print(now.unixtime());
Serial.print(“s = ”);
Serial.print(now.unixtime() / 86400L);
Serial.println(“d”);
由于一天中有60 * 60 * 24 = 86400秒,因此我们可以轻松计算天数从那以后。当您想要跟踪自上次查询以来已经过去了多少时间,使一些数学变得容易得多时(例如检查是否过了5分钟,只需查看 unixtime()),这可能会很有用。增加了300,您不必担心小时的变化)
使用SD卡
数据记录器防护板的另一半是SD卡。 SD卡是我们存储长期数据的方式。尽管Arduino芯片具有永久的EEPROM存储,但只有几百个字节-与2 gig SD卡相比很小。 SD卡非常便宜且易于获得,它是长期存储的明显选择,因此我们将其用作屏蔽。
SD卡不附带屏蔽套件,但我们可以在其中随身携带SD卡。保证工作的商店。几乎所有SD卡都可以使用,但要注意一些廉价的卡是“假货”,并且会引起头痛。
4GB空白SD/MicroSD存储卡
产品ID:102
使用此4GB micro-SD卡可以轻松添加大型存储。它带有SD适配器,因此您可以将其与我们的任何屏蔽罩或适配器一起使用!预格式化为FAT,因此无法使用。..
缺货
缺货
您还需要一种从SD卡进行读写的方法。有时您可以使用相机和MP3播放器-插入相机后,您就可以将其视为磁盘。或者您可能需要SD卡读卡器。 屏蔽 不 能够将SD卡显示为“硬盘”,例如某些MP3播放器或游戏,而Arduino没有该硬件,因此您将需要一个外部读取器!
USB MicroSD卡读取器/写入器-microSD/microSDHC/microSDXC
产品ID:939
这是最可爱的小型microSD卡读/写器-但不要被它的可爱性所迷惑!它速度快,可支持多达64 GB的SDXC卡!只需将卡滑入。..
$ 5.95
进货
添加到购物车
格式化在Windows/Mac操作系统下
如果您购买了SD卡,则可能已经使用FAT文件系统对其进行了预格式化。但是,您可能对工厂格式化卡的方式有疑问,或者如果它是旧卡,则需要重新格式化。我们使用的Arduino SD库支持 FAT16 和 FAT32 文件系统。如果您的SD卡非常小,例如说8-32 MB,您可能会发现它的格式为 FAT12 ,该格式不受支持。您必须重新格式化这些卡。无论哪种方式,即使使用新的总是格式化存储卡的好主意!请注意,格式化会删除卡,因此请先保存您想要的任何内容
我们强烈建议您使用的是官方SD卡格式化程序实用程序-由SD协会编写,它解决了格式错误带来的许多问题!
https上提供了官方SD格式化程序://www.sdcard.org/downloads/formatter_4/
下载并在您的计算机上运行,该页面上还有一个手册链接供使用
下载适用于Windows的官方SD Formatter软件
获取卡信息
Arduino SD卡库有一个内置示例,可以帮助您测试屏蔽和连接
如果您使用的是较旧的没有SPI头连接的数据记录屏蔽 ,并且您使用的是 Leonardo,Mega 或UNO以外的任何其他产品,则需要安装规格SD库的正式版本
在 SD 库中打开文件 CardInfo 示例草图:
该草图不会向卡中写入任何数据,只会告诉您它是否能够识别它,以及一些有关它的信息。尝试确定是否支持SD卡时,这可能非常有用。在试用新卡之前,请先试用此草图!
转到草图的开头,并确保 chipSelect 行正确,这是因为数据记录器屏蔽了我们的‘重新使用数字引脚10,因此将其更改为10!
如果您具有Datalogger Shield的pre-reB版本,并且您正在使用Mega或Leonardo,请在此处进行检查以调整引脚设置
好的,现在将SD卡插入Arduino并上传草图
打开串行监视器,并在出现提示时在文本框中键入一个字符(并点击发送)。您可能会得到类似以下的内容:
它主要是乱码,但查看卷类型为FAT16 部分以及卡的大小(大约2 GB,这应该是有用的)很有用是)等。
如果您的卡片质量较差(好品牌的盗版版本似乎更多),您可能会看到:
卡大部分响应,但是数据都很差。请注意,产品ID 为“不适用” ,并且没有制造商ID 或 OEM ID 。该卡返回了一些SD错误。它基本上是一个坏场景,我只保留这张卡作为坏卡的例子!如果您收到类似这样的消息(有响应但它已损坏),则应该扔掉卡
最后,尝试取出SD卡并再次运行草图,您将得到以下内容,
它甚至无法初始化SD卡。如果出现焊接错误或卡确实损坏
,也可能发生这种情况。如果您遇到SD卡问题,建议您使用上述SD格式化器首先确保卡清洁并可以使用!
光和温度记录器
简介
已经介绍了RTC和SD卡,并验证了它们是否可以正常工作,我们可以继续进行日志记录!
我们将使用一个非常好的详细演示来展示这些最出色的数据的功能。测井屏蔽:我们将记录温度和相对光照水平,以确定:
随着压缩机的开启和关闭,冰箱中的温度变化多少?
保持门打开是否会导致温度大幅下降?冷却需要多长时间?
真的里面的灯在关门时会熄灭吗?
构建它!
您的项目会需要:
Arduino(当然!)最好是Atmega328类型的-我们始终建议使用正式的“经典” Arduino,例如Uno。
Adafruit数据记录器防护罩-组装的
SD卡,已格式化为FAT,并使用示例草图进行了测试
CdS光电管和匹配的10K下拉电阻
温度传感器,具有模拟输出,例如TMP36
电池组,例如6-AA’brick‘和2.1mm DC插孔。
或,您可以将9V夹子用于一个电源,但一个9V供电的记录仪将仅持续几个小时,因此我们建议使用6xAA的
一些22 AWG导线,烙铁,焊料等。
您可以在Adafruit商店中以折扣价获得该列表中的大部分商品!
i》
rs
我们将使用两个基本传感器来记录数据,一个CdS光电管来跟踪光(这将告诉我们门何时打开),以及一个半导体温度传感器来记录冰箱的周围温度。
我们的站点上针对这些传感器有两个很棒的教程,如果您以前从未使用过它们或需要一些刷新,请立即阅读!
Photocell教程
TMP36教程
我们将如下图所示对传感器进行接线。
请注意,我们连接了 ARef,温度传感器的电源引脚和 3.3V 不是5.0V 的光传感器-我们这样做是因为5V线路噪声很大,而3.3V稳压器是更好地过滤。在实际的电路板上,我们使用了数据记录器稳压器提供的3.3V线,请参见下图-理论上与Arduino相同,但我们更信任我们。
接线板上的原型区域是带有焊垫的简单孔阵列。下面的步骤说明了我们如何构建此电路,并说明了一些基本的电路原型技术。为了清楚起见,我们将使用与上面电路图中所示相同的色线:
传感器的位置传感器可以放置在原型区域的任何位置,但是我们选择这种布置以简化组件之间的连接。
准备一些跳线测量一根电线(红色)的长度足以从3v插孔延伸到温度传感器上方的1/2英寸处。从一端剥去大约3/4英寸,从另一端剥去大约1/4英寸。
测量另一端(黄色)从AREF引脚到达两个传感器之间的孔的长度足够长。一端剥去1/2英寸,另一端剥去1/4英寸。
安装跳线如图所示放置跳线,长条形的末端靠近传感器。
由于在原型制作区域的孔之间没有信号迹线,因此我们将使用长的剥去的末端来连接电路板上组件的支脚。
建立连接
将第一个跳线(红色)焊接到3v孔中。
弯曲电线的剥皮末端,使其紧靠光传感器,温度传感器和AREF跳线的末端。
将传感器支脚和AREF支脚折叠在3v跳线上并焊接以形成连接。
为传感器添加更多跳线
从模拟引脚0到光传感器和电阻器附近的孔。 (白色)
从GND到电阻另一端旁边的孔(黑色)
从模拟引脚1到电阻旁边的孔。温度传感器的中心引脚(绿色)
以及LED指示灯
从L1到数字引脚2(黄色)
从L2到数字引脚3(黄色)
焊接并修剪所有内容连接使用相同的方法将组件支腿折叠在跳线上-进行所有连接,如接线图所示。
确保所有连接均已焊接。还要将电线和组件脚焊接到穿过孔的板上。
准备电池组
将连接器上的黑色塑料套圈放在电池组电线上。
将红色电线从电池组焊接到中心销
将黑色电线焊接到外部枪管。
压接以牢固地保持电线
拧紧黑色塑料套圈
现在,您的Light Temp Logger已连接好并可以进行测试了!/div》
使用它!
Sensor test
我们现在将使用此草图来测试传感器,这是本教程中两个示例的混搭
下载:文件
复制代码
#include
#include
/* Sensor test sketch
for more information see http://www.ladyada.net/make/logshield/lighttemp.html
*/
#define aref_voltage 3.3 // we tie 3.3V to ARef and measure it with a multimeter!
int photocellPin = 0; // the cell and 10K pulldown are connected to a0
int photocellReading; // the analog reading from the analog resistor divider
//TMP36 Pin Variables
int tempPin = 1; //the analog pin the TMP36’s Vout (sense) pin is connected to
//the resolution is 10 mV / degree centigrade with a
//500 mV offset to allow for negative temperatures
int tempReading; // the analog reading from the sensor
void setup(void) {
// We‘ll send debugging information via the Serial monitor
Serial.begin(9600);
// If you want to set the aref to something other than 5v
analogReference(EXTERNAL);
}
void loop(void) {
photocellReading = analogRead(photocellPin);
Serial.print(“Light reading = ”);
Serial.print(photocellReading); // the raw analog reading
// We’ll have a few threshholds, qualitatively determined
if (photocellReading 《 10) {
Serial.println(“ - Dark”);
} else if (photocellReading 《 200) {
Serial.println(“ - Dim”);
} else if (photocellReading 《 500) {
Serial.println(“ - Light”);
} else if (photocellReading 《 800) {
Serial.println(“ - Bright”);
} else {
Serial.println(“ - Very bright”);
}
tempReading = analogRead(tempPin);
Serial.print(“Temp reading = ”);
Serial.print(tempReading); // the raw analog reading
// converting that reading to voltage, which is based off the reference voltage
float voltage = tempReading * aref_voltage / 1024;
// print out the voltage
Serial.print(“ - ”);
Serial.print(voltage); Serial.println(“ volts”);
// now print out the temperature
float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
//to degrees ((volatge - 500mV) times 100)
Serial.print(temperatureC); Serial.println(“ degrees C”);
// now convert to Fahrenheight
float temperatureF = (temperatureC * 9 / 5) + 32;
Serial.print(temperatureF); Serial.println(“ degrees F”);
delay(1000);
} #include
#include
/* Sensor test sketch
for more information see http://www.ladyada.net/make/logshield/lighttemp.html
*/
#define aref_voltage 3.3 // we tie 3.3V to ARef and measure it with a multimeter!
int photocellPin = 0; // the cell and 10K pulldown are connected to a0
int photocellReading; // the analog reading from the analog resistor divider
//TMP36 Pin Variables
int tempPin = 1; //the analog pin the TMP36‘s Vout (sense) pin is connected to
//the resolution is 10 mV / degree centigrade with a
//500 mV offset to allow for negative temperatures
int tempReading; // the analog reading from the sensor
void setup(void) {
// We’ll send debugging information via the Serial monitor
Serial.begin(9600);
// If you want to set the aref to something other than 5v
analogReference(EXTERNAL);
}
void loop(void) {
photocellReading = analogRead(photocellPin);
Serial.print(“Light reading = ”);
Serial.print(photocellReading); // the raw analog reading
// We‘ll have a few threshholds, qualitatively determined
if (photocellReading 《 10) {
Serial.println(“ - Dark”);
} else if (photocellReading 《 200) {
Serial.println(“ - Dim”);
} else if (photocellReading 《 500) {
Serial.println(“ - Light”);
} else if (photocellReading 《 800) {
Serial.println(“ - Bright”);
} else {
Serial.println(“ - Very bright”);
}
tempReading = analogRead(tempPin);
Serial.print(“Temp reading = ”);
Serial.print(tempReading); // the raw analog reading
// converting that reading to voltage, which is based off the reference voltage
float voltage = tempReading * aref_voltage / 1024;
// print out the voltage
Serial.print(“ - ”);
Serial.print(voltage); Serial.println(“ volts”);
// now print out the temperature
float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
//to degrees ((volatge - 500mV) times 100)
Serial.print(temperatureC); Serial.println(“ degrees C”);
// now convert to Fahrenheight
float temperatureF = (temperatureC * 9 / 5) + 32;
Serial.print(temperatureF); Serial.println(“ degrees F”);
delay(1000);
}
确定上传此草图,然后再次检查串行监视器
在我的工作室中,我的温度约为24摄氏度,“光度”约为400-请记住,尽管温度传感器以C或F给出“绝对”读数,但光传感器为
一旦您确认传感器已正确连接并运行其时间来记录日志,就无法精确地给出读数!
测井草图
从Git下载光和温度测井草图毂。插入SD卡。
在该部分的草图顶部查找,并取消注释任何相关的行。如果您不确定自己拥有哪一个,请查看RTC页面以获取详细信息。
下载:文件
复制代码
/************** if you have a DS1307 uncomment this line **************/
//RTC_DS1307 RTC; // define the Real Time Clock object
/************** if you have a PCF8523 uncomment this line **************/
//RTC_PCF8523 RTC; // define the Real Time Clock object
/**********************************************************************/ /************** if you have a DS1307 uncomment this line **************/
//RTC_DS1307 RTC; // define the Real Time Clock object
/************** if you have a PCF8523 uncomment this line **************/
//RTC_PCF8523 RTC; // define the Real Time Clock object
/**********************************************************************/
将草图上传到Arduino。现在,我们将在仍“绑定”到计算机上的情况下对其进行测试
在Arduno仍保持连接,闪烁并通电的情况下,将您的手放在光电管上几秒钟,然后将闪光灯照在它上面。您还应该用手指挤压温度传感器以对其加热
使用电子表格绘制
当您准备检查数据时,请拔下Arduino并将SD卡放入计算机的读卡器中。您将至少看到一个文件,或者可能是几个文件,每次记录器最终运行时都一个文件
我们将打开最新的一个。如果要使用图形演示中使用的相同日志文件,请单击此处下载。
查看数据的最快方法是使用OpenOffice或Excel之类的文件,您可以在其中打开.csv文件并将其直接导入电子表格
然后您可以通过选择数据列来执行一些绘图操作
点击图表 按钮并使用线条(我们认为它们最适合此类图表)
设置第一列作为标签
这将生成此图
您可以清楚地看到我如何遮蔽传感器,然后在其上照手电筒。
您可以使图形显示两者都具有不同的轴(因为温度变化是一组不同的单位。选择临时线(红色),右键单击并选择格式化数据系列。在选项标签中,将数据系列与次要Y轴对齐。
或者您也可以仅使用 temp 数据
现在可以清楚地看到如何通过将其握在手指之间来对其进行加热
使用Gnuplot
Gnuplot是一个免费的(但不是开源的?)超强大的绘图程序。使用起来也很痛苦!但是,如果您买不起Mathematica或Matlab等专业的数学/绘图软件包,则Gnuplot可以做很多!
我们不足以提供有关gnuplot的完整教程,这里有一些我们发现方便的链接。 Google一定会帮助您找到更多的教程和链接。也是最好的老师。
http://www.cs.hmc.edu/~vrable/gnuplot/using-gnuplot.html
http://www.duke.edu/~hpgavin/gnuplot.html
http://www.ibm.com/developerworks/library/l-gnuplot/
我们发现按顺序执行以下命令将生成此数据的漂亮图形,请确保将LOGTEST.CSV与 wgnuplot.exe 放在同一目录中(或者,如果您知道如何引用目录,则可以可以放在其他位置)
下载:文件
复制代码
set xlabel “Time” # set the lower X-axis label to ’time‘
set xtics rotate by -270 # have the time-marks on their side
set ylabel “Light level (qualitative)” # set the left Y-axis label
set ytics nomirror # tics only on left side
set y2label “Temperature in Fahrenheit” # set the right Y-axis label
set y2tics border # put tics no right side
set key box top left # legend box
set key box linestyle 0
set xdata time # the x-axis is time
set format x “%H:%M:%S” # display as time
set timefmt “%s” # but read in as ’unix timestamp‘
plot “LOGTEST.CSV” using 2:4 with lines title “Light levels”
replot “LOGTEST.CSV” using 2:5 axes x1y2 with lines title “Temperature (F)”
set xlabel “Time” # set the lower X-axis label to ’time‘
set xtics rotate by -270 # have the time-marks on their side
set ylabel “Light level (qualitative)” # set the left Y-axis label
set ytics nomirror # tics only on left side
set y2label “Temperature in Fahrenheit” # set the right Y-axis label
set y2tics border # put tics no right side
set key box top left # legend box
set key box linestyle 0
set xdata time # the x-axis is time
set format x “%H:%M:%S” # display as time
set timefmt “%s” # but read in as ’unix timestamp‘
plot “LOGTEST.CSV” using 2:4 with lines title “Light levels”
replot “LOGTEST.CSV” using 2:5 axes x1y2 with lines title “Temperature (F)”
这是这样的:
请注意超酷的双面y轴刻度!您也可以轻松放大内容。
其他绘图仪
我们的朋友约翰还建议将Live-Graph作为免费的绘图程序-我们还没有尝试过,但是如果您需要进行大量绘图,它值得一看!/p》
便携式日志记录
当然,有一个数据记录器链接到台式计算机并不是那么方便。我们可以通过增加电池组来制造便携式记录仪。获得大量电量的最便宜方法是使用6节AA电池。我在这里用可充电电池和6xAA电池座制作了一个。它每秒运行Arduino日志一次,持续18.5小时。如果您使用碱,则可以轻松获得24小时或更长时间。
冰箱日志记录
准备好我的便携式记录仪之后,该做一些冰箱Loggin了!两者都放在冰箱的中间架子中央。
我将其放置在晚上10点左右,然后第二天中午将其移除。如果您没有冰箱,则可以从此zip文件中获取数据并使用它。
以下是记录的数据:
您可以在中间看到并结束温度和光照水平很高,因为记录仪在冰箱外面。绿线是温度,因此您可以看到温度缓慢升高,然后每半小时左右启动压缩机。红线表示门何时打开。今晚比平常更残酷!
在大约12:40 AM放大图,我们可以看到门打开时温度是如何上升的,即使在几秒钟内温度也可以很快上升4度!
结论!
好的,这是一个详细的项目,但是它是测试数据记录的一个好项目的能力,尤其是因为它更难以修复现场的错误。通常,我们建议尝试其他传感器,并在可能的情况下在家进行测试。记录比所需更多的数据,并使用软件程序过滤不需要的内容也是一个好主意。例如,我们不使用VCC日志,但是如果您的传感器行为异常,它可能会为您提供电池寿命是否在影响它的线索。
代码演练
简介
这是“光和温度记录”草图的演练。它冗长而详尽,因此我们将其放在此处以供您细读。我们强烈建议您仔细阅读它,该代码具有非常多的用途,并且我们的文字描述应清楚说明其中为什么存在所有内容!
在此处下载完整文件:
包含并定义
下载:文件
复制代码
#include “SD.h”
#include
#include “RTClib.h” #include “SD.h”
#include
#include “RTClib.h”
确定这是文件的顶部,其中我们包括三个将要使用的库:用于与卡对话的 SD 库,可帮助Arduino的 Wire 库使用i2c和 RTClib 与实时时钟聊天
下载:文件
复制代码
// A simple data logger for the Arduino analog pins
#define LOG_INTERVAL 1000 // mills between entries
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
// the digital pins that connect to the LEDs
#define redLEDpin 3
#define greenLEDpin 4
// The analog pins that connect to the sensors
#define photocellPin 0 // analog 0
#define tempPin 1 // analog 1 // A simple data logger for the Arduino analog pins
#define LOG_INTERVAL 1000 // mills between entries
#define ECHO_TO_SERIAL 1 // echo data to serial port
#define WAIT_TO_START 0 // Wait for serial input in setup()
// the digital pins that connect to the LEDs
#define redLEDpin 3
#define greenLEDpin 4
// The analog pins that connect to the sensors
#define photocellPin 0 // analog 0
#define tempPin 1 // analog 1
接下来都是“定义” -常量和可调整项。
LOG_INTERVAL是传感器读数之间的毫秒数。 1000是1秒,这不是一个不好的起点。
ECHO_TO_SERIA L确定是否将写入卡的内容也发送到串行监视器。这会使记录器更加缓慢,您可能需要串行监视器来查看其他内容。另一方面,它的使用很有用。我们将其设置为 1 以保持打开状态。将其设置为 0 将其关闭
WAIT_TO_START意味着您必须向Arduino的串行端口发送一个字符才能启动记录。如果您启用了此功能,则基本上无法使其脱离计算机,因此我们暂时将其保持关闭状态(设置为 0 )。如果要打开它,请将其设置为 1
其他定义更容易理解,因为它们只是引脚定义
redLEDpin是您连接到记录仪护罩上红色LED的一切
greenLEDpin是您连接到记录仪护罩上绿色LED的一切
photocellPin是CdS单元连接到的模拟输入
tempPin是TMP36连接到的模拟输入
对象和错误()
下载:文件
复制代码
RTC_DS1307 RTC; // define the Real Time Clock object
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str)
{
Serial.print(“error: ”);
Serial.println(str);
// red LED indicates error
digitalWrite(redLEDpin, HIGH);
while(1);
} RTC_DS1307 RTC; // define the Real Time Clock object
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str)
{
Serial.print(“error: ”);
Serial.println(str);
// red LED indicates error
digitalWrite(redLEDpin, HIGH);
while(1);
}
接下来,我们已经有了RTC的所有对象以及SD卡芯片选择引脚。对于我们所有的屏蔽,我们将 pin 10 用于SD卡芯片选择线
接下来是error()功能,这对我们来说只是一个快捷方式,我们在以下情况下使用它发生了一件非常糟糕的事情,例如我们无法写入SD卡或将其打开。它将错误输出到串行监视器,打开红色错误LED,然后永远处于while(1);循环,也称为 halt
设置
下载:文件
复制代码
void setup(void)
{
Serial.begin(9600);
Serial.println();
#if WAIT_TO_START
Serial.println(“Type any character to start”);
while (!Serial.available());
#endif //WAIT_TO_START
void setup(void)
{
Serial.begin(9600);
Serial.println();
#if WAIT_TO_START
Serial.println(“Type any character to start”);
while (!Serial.available());
#endif //WAIT_TO_START
K现在我们进入代码。我们首先以9600波特初始化串口。如果我们将WAIT_TO_START设置为除 0 之外的任何值,则Arduino将等待直到用户键入内容为止。否则,它将进入下一部分
下载:文件
复制代码
// initialize the SD card
Serial.print(“Initializing SD card.。.”);
// make sure that the default chip select pin is set to
// output, even if you don’t use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println(“Card failed, or not present”);
// don‘t do anything more:
return;
}
Serial.println(“card initialized.”);
// create a new file
char filename[] = “LOGGER00.CSV”;
for (uint8_t i = 0; i 《 100; i++) {
filename[6] = i/10 + ’0‘;
filename[7] = i%10 + ’0‘;
if (! SD.exists(filename)) {
// only open a new file if it doesn’t exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error(“couldnt create file”);
}
Serial.print(“Logging to: ”);
Serial.println(filename); // initialize the SD card
Serial.print(“Initializing SD card.。.”);
// make sure that the default chip select pin is set to
// output, even if you don‘t use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println(“Card failed, or not present”);
// don’t do anything more:
return;
}
Serial.println(“card initialized.”);
// create a new file
char filename[] = “LOGGER00.CSV”;
for (uint8_t i = 0; i 《 100; i++) {
filename[6] = i/10 + ‘0’;
filename[7] = i%10 + ‘0’;
if (! SD.exists(filename)) {
// only open a new file if it doesn‘t exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error(“couldnt create file”);
}
Serial.print(“Logging to: ”);
Serial.println(filename);
现在代码开始与SD卡通信,它将尝试初始化SD卡并找到FAT16/FAT32分区。
接下来它将尝试创建日志文件。我们在这里做了一些棘手的事情,我们基本上希望将文件命名为 LOGGERnn 。 csv ,其中 nn 是一个数字。通过开始尝试创建 LOGGER00.CSV 并在文件已经存在时每次递增,直到我们到达 LOGGER99.csv ,我们基本上每次创建一个新文件Arduino启动
要创建文件,我们使用一些Unix风格的命令标志,您可以在logfile.open() 过程中看到这些标志。 FILE_WRITE 表示创建文件并向其中写入数据。
假设我们成功创建了文件,则将名称打印到串行端口。
下载:文件
复制代码
Wire.begin();
if (!RTC.begin()) {
logfile.println(“RTC failed”);
#if ECHO_TO_SERIAL
Serial.println(“RTC failed”);
#endif //ECHO_TO_SERIAL
}
logfile.println(“millis,time,light,temp”);
#if ECHO_TO_SERIAL
Serial.println(“millis,time,light,temp”);
#if ECHO_TO_SERIAL// attempt to write out the header to the file
if (logfile.writeError || !logfile.sync()) {
error(“write header”);
}
pinMode(redLEDpin, OUTPUT);
pinMode(greenLEDpin, OUTPUT);
// If you want to set the aref to something other than 5v
//analogReference(EXTERNAL);
} Wire.begin();
if (!RTC.begin()) {
logfile.println(“RTC failed”);
#if ECHO_TO_SERIAL
Serial.println(“RTC failed”);
#endif //ECHO_TO_SERIAL
}
logfile.println(“millis,time,light,temp”);
#if ECHO_TO_SERIAL
Serial.println(“millis,time,light,temp”);
#if ECHO_TO_SERIAL// attempt to write out the header to the file
if (logfile.writeError || !logfile.sync()) {
error(“write header”);
}
pinMode(redLEDpin, OUTPUT);
pinMode(greenLEDpin, OUTPUT);
// If you want to set the aref to something other than 5v
//analogReference(EXTERNAL);
}
好的,我们在这里结束了。现在,我们通过初始化Wire库开始RTC,并戳RTC以查看其是否还存在。
然后我们打印标题。标头是文件的第一行,可帮助您的电子表格或数学程序确定接下来要执行的操作。数据采用CSV(逗号分隔值)格式,因此标头也是如此:“ millis,time,light,temp”第一项 millis 是自Arduino启动以来的毫秒数,时间是RTC的时间和日期, light 是CdS单元中的数据, temp 是读取的温度。
您将请注意,在每次调用 logfile.print()之后,我们都有#if ECHO_TO_SERIAL和匹配的 Serial.print()调用,接着是#if ECHO_TO_SERIAL,这就是调试我们前面提到的输出。 logfile.print()调用是将数据写入SD卡上的文件的功能,其作用与 Serial 版本非常相似。如果将 ECHO_TO_SERIAL 设置为顶部的 0 ,则看不到打印到串行终端的书面数据。
最后,我们将两个LED引脚作为输出,因此我们可以使用它们与用户进行通信。有一条注释行用于设置模拟参考电压。此代码假定您将使用“默认”参考,该参考是芯片的VCC电压-在传统的Arduino上这是5.0V。有时可以通过降低参考来获得更高的精度。但是,我们暂时将其保持简单!稍后,您可能要尝试一下。
主循环
现在进入循环,循环基本上重复执行以下操作:
等待直到下一次出现读(每秒说一次-取决于我们定义的内容)
询问当前时间和日期,以免RTC
将时间和日期记录到SD卡上
读取光电池和温度传感器
将这些读数记录到SD卡上
如果时间到,将数据同步到SD卡
时间戳
让我们看一下第一部分:
下载:文件
复制代码
void loop(void)
{
DateTime now;
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
digitalWrite(greenLEDpin, HIGH);
// log milliseconds since starting
uint32_t m = millis();
logfile.print(m); // milliseconds since start
logfile.print(“, ”);
#if ECHO_TO_SERIAL
Serial.print(m); // milliseconds since start
Serial.print(“, ”);
#endif
// fetch the time
now = RTC.now();
// log time
logfile.print(now.get()); // seconds since 2000
logfile.print(“, ”);
logfile.print(now.year(), DEC);
logfile.print(“/”);
logfile.print(now.month(), DEC);
logfile.print(“/”);
logfile.print(now.day(), DEC);
logfile.print(“ ”);
logfile.print(now.hour(), DEC);
logfile.print(“:”);
logfile.print(now.minute(), DEC);
logfile.print(“:”);
logfile.print(now.second(), DEC);
#if ECHO_TO_SERIAL
Serial.print(now.get()); // seconds since 2000
Serial.print(“, ”);
Serial.print(now.year(), DEC);
Serial.print(“/”);
Serial.print(now.month(), DEC);
Serial.print(“/”);
Serial.print(now.day(), DEC);
Serial.print(“ ”);
Serial.print(now.hour(), DEC);
Serial.print(“:”);
Serial.print(now.minute(), DEC);
Serial.print(“:”);
Serial.print(now.second(), DEC);
#endif //ECHO_TO_SERIAL
void loop(void)
{
DateTime now;
// delay for the amount of time we want between readings
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
digitalWrite(greenLEDpin, HIGH);
// log milliseconds since starting
uint32_t m = millis();
logfile.print(m); // milliseconds since start
logfile.print(“, ”);
#if ECHO_TO_SERIAL
Serial.print(m); // milliseconds since start
Serial.print(“, ”);
#endif
// fetch the time
now = RTC.now();
// log time
logfile.print(now.get()); // seconds since 2000
logfile.print(“, ”);
logfile.print(now.year(), DEC);
logfile.print(“/”);
logfile.print(now.month(), DEC);
logfile.print(“/”);
logfile.print(now.day(), DEC);
logfile.print(“ ”);
logfile.print(now.hour(), DEC);
logfile.print(“:”);
logfile.print(now.minute(), DEC);
logfile.print(“:”);
logfile.print(now.second(), DEC);
#if ECHO_TO_SERIAL
Serial.print(now.get()); // seconds since 2000
Serial.print(“, ”);
Serial.print(now.year(), DEC);
Serial.print(“/”);
Serial.print(now.month(), DEC);
Serial.print(“/”);
Serial.print(now.day(), DEC);
Serial.print(“ ”);
Serial.print(now.hour(), DEC);
Serial.print(“:”);
Serial.print(now.minute(), DEC);
Serial.print(“:”);
Serial.print(now.second(), DEC);
#endif //ECHO_TO_SERIAL
第一个重要的事情是 delay()调用,这就是使Arduino等待直到需要再次读取的原因。如果您还记得我们 #defined ,则两次读数之间的延迟为1000毫秒(1秒)。由于两次读取之间有更多延迟,因此我们可以使用更少的电量,而无法尽快填充存储卡。这基本上是一个折衷,您希望多久读取一次数据,但是对于基本的长期日志记录,每秒获取数据将导致大量数据!
然后我们打开绿色LED,这对于告诉我们,是的,我们现在正在读取/写入数据。
接下来,我们调用 millis ()以获取“自arduino开启以来的时间”并将其记录到卡上。拥有它很方便-尤其是如果您最终不使用RTC时。
然后熟悉的 RTC.now()调用以获取时间快照。有了这些信息后,我们便可以使用电子表格可以轻松识别的时间戳记(自2000年以来的秒数)以及 YY/MM/DD HH:MM:SS 时间格式。我们两者都有,因为时间戳的好处是它会单调增加,而打印日期的好处是它的可读性
记录传感器数据
下一个是传感器记录代码
下载:文件
复制代码
int photocellReading = analogRead(photocellPin);
delay(10);
int tempReading = analogRead(tempPin);
// converting that reading to voltage, for 3.3v arduino use 3.3
float voltage = (tempReading * 5.0) / 1024.0;
float temperatureC = (voltage - 0.5) * 100.0 ;
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
logfile.print(“, ”);
logfile.print(photocellReading);
logfile.print(“, ”);
logfile.println(temperatureF);
#if ECHO_TO_SERIAL
Serial.print(“, ”);
Serial.print(photocellReading);
Serial.print(“, ”);
Serial.println(temperatureF);
#endif //ECHO_TO_SERIAL
digitalWrite(greenLEDpin, LOW);
} int photocellReading = analogRead(photocellPin);
delay(10);
int tempReading = analogRead(tempPin);
// converting that reading to voltage, for 3.3v arduino use 3.3
float voltage = (tempReading * 5.0) / 1024.0;
float temperatureC = (voltage - 0.5) * 100.0 ;
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
logfile.print(“, ”);
logfile.print(photocellReading);
logfile.print(“, ”);
logfile.println(temperatureF);
#if ECHO_TO_SERIAL
Serial.print(“, ”);
Serial.print(photocellReading);
Serial.print(“, ”);
Serial.println(temperatureF);
#endif //ECHO_TO_SERIAL
digitalWrite(greenLEDpin, LOW);
}
此代码非常简单,处理代码已从我们之前的教程中删除。然后我们只需将其打印()到卡上,并用逗号将两者分开即可
我们通过关闭绿色LED指示灯完成
下载
文件 GitHub上的
EagleCAD PCB文件
Adafruit Fritzing库中的Fritzing对象
修订版C原理图和构造打印
版本B原理图
点击放大
原始版本原理图
点击放大
责任编辑:wv
全部0条评论
快来发表一下你的评论吧 !