RelayController.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include "RelayController.h"
  2. #include <WiFi.h>
  3. #include <time.h>
  4. // 构造函数
  5. RelayController::RelayController(int pin22, int pin23, int pin4)
  6. : _relayPin22(pin22),
  7. _relayPin23(pin23),
  8. _relayPin4(pin4),
  9. _relay22State(HIGH_Z),
  10. _relay23State(HIGH_Z),
  11. _relay4State(HIGH_Z),
  12. _relay22TimeoutCheck(false),
  13. _relay22TempHold(false), // 初始化为未触发
  14. _relay4LastOnCycle(0),
  15. _powerOnTime(0),
  16. _simulatedUnixTime(0)
  17. {}
  18. // 初始化
  19. void RelayController::begin() {
  20. // 所有继电器初始化为高阻态
  21. pinMode(_relayPin22, INPUT);
  22. pinMode(_relayPin23, INPUT);
  23. pinMode(_relayPin4, INPUT);
  24. _powerOnTime = millis();
  25. _simulatedUnixTime = 0;
  26. Serial.println("继电器初始化完成,所有继电器默认高阻态");
  27. }
  28. // GPIO22控制方法
  29. void RelayController::setRelay22HighZ() {
  30. if (_relay22State != HIGH_Z) {
  31. pinMode(_relayPin22, INPUT);
  32. _relay22State = HIGH_Z;
  33. _relay22TimeoutCheck = false;
  34. _relay22TempHold = false; // 重置温度保持标记
  35. Serial.println("GPIO22继电器已设为高阻态");
  36. }
  37. }
  38. void RelayController::turnOnRelay22(float currentGpio6Temp) {
  39. if (_relay22State != ON) {
  40. pinMode(_relayPin22, OUTPUT);
  41. digitalWrite(_relayPin22, HIGH);
  42. _relay22State = ON;
  43. _relay22StartTime = millis();
  44. _gpio6TempAtRelay22On = currentGpio6Temp;
  45. _relay22TimeoutCheck = true;
  46. Serial.println("GPIO22继电器已打开(高电平)");
  47. }
  48. }
  49. // GPIO23控制方法
  50. void RelayController::setRelay23HighZ() {
  51. if (_relay23State != HIGH_Z) {
  52. pinMode(_relayPin23, INPUT);
  53. _relay23State = HIGH_Z;
  54. Serial.println("GPIO23继电器已设为高阻态");
  55. }
  56. }
  57. void RelayController::turnOnRelay23() {
  58. if (_relay23State != ON) {
  59. pinMode(_relayPin23, OUTPUT);
  60. digitalWrite(_relayPin23, HIGH);
  61. _relay23State = ON;
  62. Serial.println("GPIO23继电器已打开(高电平)");
  63. }
  64. }
  65. // GPIO4定时继电器控制方法
  66. void RelayController::setRelay4HighZ() {
  67. if (_relay4State != HIGH_Z) {
  68. pinMode(_relayPin4, INPUT);
  69. _relay4State = HIGH_Z;
  70. Serial.println("GPIO4定时继电器已设为高阻态");
  71. }
  72. }
  73. void RelayController::turnOnRelay4() {
  74. if (_relay4State != ON) {
  75. pinMode(_relayPin4, OUTPUT);
  76. digitalWrite(_relayPin4, HIGH);
  77. _relay4State = ON;
  78. _relay4OnTime = millis();
  79. Serial.println("GPIO4定时继电器已打开(高电平)");
  80. }
  81. }
  82. // 主控制逻辑(包含温度滞后控制)
  83. void RelayController::controlByTempConditions(float tempGpio2, float tempGpio3, float tempGpio6,
  84. float diffThreshold, float gpio6High, float gpio6Low,
  85. float highTempOn, float highTempOff) {
  86. float diff = tempGpio2 - tempGpio3;
  87. Serial.print("温度差 (GPIO2 - GPIO3): ");
  88. Serial.print(diff);
  89. Serial.print(" °C, GPIO6温度: ");
  90. Serial.print(tempGpio6);
  91. Serial.println(" °C");
  92. // 新增:高温控制逻辑(带滞后)
  93. // 当温度高于35℃时打开继电器并标记保持状态
  94. if (tempGpio6 > highTempOn) {
  95. turnOnRelay22(tempGpio6);
  96. _relay22TempHold = true; // 标记为需要滞后关闭
  97. }
  98. // 当温度低于25℃且已触发保持状态时,才关闭继电器
  99. else if (tempGpio6 < highTempOff && _relay22TempHold) {
  100. setRelay22HighZ();
  101. _relay22TempHold = false; // 重置保持状态
  102. }
  103. // 原有温度差控制逻辑(仅在未触发高温保持时生效)
  104. else if (!_relay22TempHold) {
  105. // 控制GPIO22:原有条件
  106. if (diff < -diffThreshold && tempGpio6 > gpio6High) {
  107. turnOnRelay22(tempGpio6);
  108. } else {
  109. setRelay22HighZ();
  110. }
  111. }
  112. // GPIO23控制逻辑(保持不变)
  113. if (diff > diffThreshold && tempGpio6 < gpio6Low) {
  114. turnOnRelay23();
  115. } else {
  116. setRelay23HighZ();
  117. }
  118. }
  119. // 定时任务处理(保持不变)
  120. void RelayController::handleTimedTasks(float currentGpio6Temp) {
  121. unsigned long currentTime = millis();
  122. // 1. GPIO22超时检测
  123. if (_relay22TimeoutCheck && _relay22State == ON) {
  124. if (currentTime - _relay22StartTime >= 15 * 60 * 1000) { // 15分钟
  125. float tempIncrease = currentGpio6Temp - _gpio6TempAtRelay22On;
  126. if (tempIncrease < 5.0) {
  127. setRelay22HighZ();
  128. Serial.println("警告:加热没有成功!15分钟内温度未上升5度");
  129. } else {
  130. _relay22TimeoutCheck = false;
  131. Serial.println("加热成功,温度上升达标");
  132. }
  133. }
  134. }
  135. // 2. 定时继电器GPIO4控制
  136. unsigned long currentCycle = get24hCycleCount();
  137. int currentHour = getCurrentHour();
  138. if (currentHour == _dailyOnHour && currentCycle != _relay4LastOnCycle) {
  139. turnOnRelay4();
  140. _relay4LastOnCycle = currentCycle;
  141. }
  142. if (_relay4State == ON && (currentTime - _relay4OnTime) >= _onDuration) {
  143. setRelay4HighZ();
  144. }
  145. }
  146. // 时间管理方法(保持不变)
  147. void RelayController::updateNtpTime() {
  148. if (WiFi.status() == WL_CONNECTED) {
  149. configTime(8 * 3600, 0, "pool.ntp.org", "time.nist.gov");
  150. time_t now;
  151. time(&now);
  152. if (now > 1609459200) {
  153. _simulatedUnixTime = now - ((millis() - _powerOnTime) / 1000);
  154. Serial.println("NTP时间同步成功,校准模拟时间");
  155. }
  156. }
  157. }
  158. unsigned long RelayController::getCurrentUnixTime() {
  159. return _simulatedUnixTime + ((millis() - _powerOnTime) / 1000);
  160. }
  161. int RelayController::getCurrentHour() {
  162. unsigned long secondsSincePowerOn = (millis() - _powerOnTime) / 1000;
  163. return (secondsSincePowerOn / 3600) % 24;
  164. }
  165. unsigned long RelayController::get24hCycleCount() {
  166. unsigned long secondsSincePowerOn = (millis() - _powerOnTime) / 1000;
  167. return secondsSincePowerOn / (24 * 3600);
  168. }
  169. unsigned long RelayController::getPowerOnTime() {
  170. return _powerOnTime;
  171. }
  172. // 获取状态字符串
  173. String RelayController::getRelay22State() {
  174. return (_relay22State == ON) ? "打开(高电平)" : "高阻态";
  175. }
  176. String RelayController::getRelay23State() {
  177. return (_relay23State == ON) ? "打开(高电平)" : "高阻态";
  178. }
  179. String RelayController::getRelay4State() {
  180. return (_relay4State == ON) ? "打开(高电平)" : "高阻态";
  181. }