作为一个自豪的小型光伏系统的所有者,令我感到痛苦的是,我几乎没有回报地出口大部分发电量,而在太阳下山时以更高的价格进口。
白天用多余的太阳能为电热水储水箱“充电”,而不是将其输出到电网,这在某种程度上可以弥补不平衡、节省资金和保护地球。
该项目旨在满足以下要求:
为了确定发送到加热元件的功率量,系统需要知道“房子”是输入还是输出功率。在我的例子中,此信息是通过对基于 NodeMCU 的 4 象限功率计的 HTTP 请求获得的,这不是该项目的一部分。
HTTP 的替代方案:在 ESP32 上实施太阳能分流器(这样您就有多个模拟输入)并使用 analogueRead() 读取以下项目的输出以获得功率导入/导出读数。您可能需要添加一个运算放大器电路或类似的东西来将可用电压范围转换为更适合 ADC 的电压范围。
主要组件是一个温度传感器,我把它推到水箱周围的绝缘层下,一个固态继电器驱动加热元件,一个基于 NodeMCU/ESP8266 的控制器提供智能。
必须以平衡产生的多余太阳能的方式来控制加热功率。
最明显的方法是使用“相位延迟”开关三端双向可控硅开关元件,但这会产生大量 RFI。或者,可以使用继电器或双向晶闸管定期打开/关闭电源:没有 RFI,但电表将记录交替的输出和输入,而不仅仅是零消耗。
快乐的中位数:一个“突发式”开关固态接触器(过零),它在 36 周期突发周期(50Hz 网格)的可变部分关闭。实际上,这仍然是开/关原则,但速度足够快,电表记录平均消耗而不是单独的导入/导出事件。
选择“36”个周期是因为加热元件为 3600W,因此每个“开启”周期都会增加一个易于记忆的 100W 功率。
驾驶SSR :
TRIAC 的输入由软件定时器 (ssr_control_fun) 在每个电源周期 (= 20 ms) 上的回调确定,每个周期编号为 [0..35]。
循环是“开”还是“关”由 3 个变量控制:
// Cycles per period to divert excess power.
static int16_t nDivertCycles;
// Max cycles per period to prevent the thermostat from triggering early.
static int16_t nLimitCycles;
// Max power boost is required to reach by .
static bool bBoost;
static void ssr_control_fun( void * )
// Runs on a 20msec timer, i.e. once every mains cycle.
// counts cycles, turns off power after the specified # of cycles,
// resets at the end of the PWM period.
{
static int16_t iCurrentCycle; // Current cycle counter.
// Turn on SSR until we have reached nDivertCycles, or when we need to boost.
digitalWrite
( ssrControlPin,
( bBoost // Always on when boosting.
|| (haveImport && (iCurrentCycle < nDivertCycles))// or when diversion is on
)
&& (iCurrentCycle < nLimitCycles) // either way, never exceed temp based power limit.
);
// Give each cycle a number 0..PwmCycles-1
iCurrentCycle = (iCurrentCycle+1) % PwmCycles;
}
我们需要在每天下午 3 点之前达到 :我们估计从当前温度到 应用全功率需要多长时间。=67>如果晚于下一个下午 3 点,则激活“提升”。估计时间基于一组 10 度温度间隔,其中包含应用满载时估计度数/小时的增加。
// Target temperature to aim for by TargetTOD
#define TargetTemp 67
// Time-of-day after which only solar power should be used (secs)
// (start of peak tariff)
#define TargetTOD (15 * SECS_PER_HOUR)
// Estimated average temperature rise for every hour under 100% power (C/hr)
// The rate varies depending on temp in 10 degree increments, starting at 0.
static const uint8_t heating_rates[] =
{ 15, 15, 13, 11, 9, 7, 6, 6, 6 };
// start-temp 0 10 20 30 40 50 60 70 80
static float heatingTime( const float from, const float to ) {....}
// estimated time in hours to reach starting at
static void updateBoost(const uint32_t utc, const float curTemp) {....}
// Check if it is still possible to reach by at less
// than full power. If not, start a 15 min timer to turn on full power.
// The timer is prevent unnecessary boosts (which cost money) due to temporary
// temperature reductions when the hot tap is opened and cold water flows in.
转移的功率量通过 nDivertCycles 控制,应用 36 个功率中的循环数。该值通过一个简单的反馈回路确定:系统每 10 秒检查一次当前功率输出/输入水平并调整活动周期数以获得 0 到 100W 之间的输出。
static void updateDivertCycles( const int16_t exp )
// Updates nDivertCycles to match spare power.
(可选)为了最大化存储容量,我们需要防止内置在水箱中的机械恒温器断开电路。这发生在大约 69℃。不幸的是,在全功率下,水箱内的温度分布使得我靠在水箱壁上的传感器不能很好地指示内置恒温器的温度。所以我们需要降低功率,以便在不触发恒温器的情况下进一步加热水箱。
这是通过线性减少最大值来完成的。在 67 和 69℃ 之间从 100% 到 12.5% 的活性循环数。
static void updateLimitCycles( const float curTemp )
// Limit the duty-cycle when water temperature exceeds TargetTemp
该系统旨在每天在同一当地时间完成对水的加热。因此,它需要访问时间服务器以获取 UTC,并将 UTC 转换为本地时间,同时考虑夏令时的变化。
获得 UTC 是相当标准的。本地时间的转换由“timeZone”库模块提供(根据 Jack Christensen 的设计稍作修改)。timeZone 模块为澳大利亚维多利亚州提供转换例程和单一时区规范。您需要修改/添加您所在地区的 TZ 规范。
// Victoria, Oz timezone
static TimeChangeRule aeST = {"AEST", First, Sun, Apr, 3, 600}; // UTC + 10 hours
static TimeChangeRule aeDT = {"AEDT", First, Sun, Oct, 2, 660}; // UTC + 11 hours
Timezone ae(aeDT, aeST);
solar_diverter_report.ino:
#include // settimeofday_cb()
#include
const uint32_t utc = utcTime();
const uint32_t localTime = ae.toLocal( utc );
该系统包括许多 http/svg 网页,提供多个时间尺度上的温度/功率历史记录。提供了代码,但没有记录......
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !