该项目是我的项目“具有最小值和最大值的极低功率温度和湿度监视器”的演变。我想扩展它以存储 24 小时的历史记录并将其显示在图表中。如下所述,我必须删除使处理器进入睡眠状态的代码,因此我还添加了一个电池电量指示器,以便知道何时需要充电。
我在扩展项目时遇到了几个问题:
int tempHistory[96];
,这很好用,但是一旦我添加了第二个数组来消除湿度历史int humidHistory[96]
,程序就不再运行。它编译并上传,但甚至没有运行 setup()。尽管看起来有大量的备用程序和变量空间,但我能得出的唯一结论是它的内存不足。因此,我更改了曲目,现在将历史记录存储在 EPROM 中。millis()
在睡眠期间不会前进。这是一个问题,因为我想每 15 分钟(每天 96 分钟)存储一次读数,并且无法跟踪睡眠时的经过时间。因此,我删除了激活睡眠模式的代码。由于取消睡眠模式会缩短电池寿命,因此我添加了电池监控功能,以便知道电池电量何时变低。该代码使用以下库:
#include // This is the DHT sensor library by Adafruit
// required for the OLED display
#include // Synchronous serial data protocol library
#include // IC2 communications library
#include // Adafruit Graphics Core Library
#include // SSD1306 library for Monochrome 128x64 and 128x32 OLEDs
#include // Library to support writing to and reading from EPROM
这些来自 Adafruit 图形核心库的字体:
#include
#include
代码中主要感兴趣的领域:
检查是否需要激活屏幕保护模式或移动位图。loop()
// Check if the time since last display of data started is greater than
// the time set to keeo the display showing
if ((millis() - timeDisplay) > keepDisplayFor) {
// If so in screen save mode
// Set flag to indicate data not being displayed
displaying = false;
// Check if we need to move the bitmap
if ((millis() - lastMoved) > moveEvery) {
// Update time last moved
lastMoved = millis();
// Dislpay battery bitmap in random position
DrawScreenSave(random(10, 110), random(10, 45));
}
}
我们首先检查系统显示数据的时间是否超过了设置的时间以保持显示。timeDisplay
是millis()
按下按钮以激活显示或更改屏幕所经过的时间。
if ((millis() - timeDisplay) > keepDisplayFor)...
如果这个时间已经过去,那么我们确保标志设置为指示我们不显示数据,并检查自上次移动位图以来经过的时间是否超过moveEvery
,如果超过,那么我们调用例程来显示电池位图每次随机放置一个位置,以免烧坏。
然后系统检查自上次读取一组读数后是否已过 2 秒,如果已过,则刷新读数并更新最小值和最大值。
if ((millis() - lastReadingUpdate) > 2000ul) ...
如果系统正在显示,则使用 switch 语句调用例程以呈现当前选定的数据屏幕,然后调用例程以检查是否已按下按钮。
最后,如果自历史数据中的最后一条记录更新以来已经过去了 15 分钟,则系统调用例程将当前读数存储在历史中。
我们使用模拟输入引脚来读取电压。由于我们使用 3.7v 伏电池运行,我们需要调整引脚使用的参考电压,否则它会将电压与自身进行比较。该语句analogReference(INTERNAL)
将引脚设置为将输入电压与稳定的 1.1v 进行比较。因此,我们需要将输入引脚上的电压降低到 1.1v 以下才能正常工作。这是通过使用 2 个电阻器(1m 和 330k 欧姆)对电压进行分压来完成的。这将电压除以大约 4,因此当电池充满电时,即 4.2v,引脚输入的电压为 4.2/4 = 1.05v。
// Read the monitor pin and calculate the voltage
float BatteryVoltage(){
float reading = analogRead(MONITOR_PIN);
// Calculate voltage - reference voltage is 1.1v
return 1.1 * (reading/1023) * voltageDivider;
}
该函数BatterVoltage()
读取模拟引脚,其范围从 0 表示 0 伏到 1,023 表示 1.1 伏,并使用该读数计算来自电池的实际电压。
函数调用 this 然后根据DrawScreenSave()
以下内容选择要显示的适当位图:
如上所述,我最初将历史记录存储在数组中,但似乎这会导致内存问题。因此,我将数据存储在 EPROM 中的 96 个位置,分别是温度和历史,在一个循环列表中。EEPROM 库在此处提供了管理数据的功能。
历史记录以整数形式存储,在 Arduino 上每个占 2 个字节。数据地址的指针histPointer
从0到95再回到0。tempStart
并humidStart
存储每个列表的起始位置,每个位置就是起始位置+位置*2。
图形例程首先获取历史中的最小值和最大值,计算比例,然后使用从最旧值 ( histPointer
+1) 到存储在的最新值的线绘制来绘制图形histPointer
。
如果您想添加一个开/关开关,请将其插入从充电器模块 OUT+ 到 Arduino 板的电线中。这将允许您在设备关闭的情况下为电池充电。
所使用的 TP4056 充电器包括一个 1.1K 欧姆的调节电阻,以 1, 000mAh 的速率提供充电。对于使用的 1, 000mAh 电池来说,这实在是太高了,应该以最大 500mAh 充电。这很繁琐,但是您可以卸下板上安装的电阻器(R3),或者我发现用刀刮过它更容易将其破坏,因为这会使柱子焊接到,并焊接在外部电阻器上以减少电流。下表显示了电阻值和产生的电流。(用仪表检查您是否仍在读取连接上的正确电阻,因为很容易将它们短路,这可能会造成损坏。)
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !