application.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. #include <SmingCore.h>
  2. #include <Libraries/DHTesp/DHTesp.h>
  3. ///////////////////////////////////////////////////////////////////
  4. // Set your SSID & Pass for initial configuration
  5. #include "configuration.h" // application configuration
  6. ///////////////////////////////////////////////////////////////////
  7. #include "webserver.h"
  8. #include "tm1650.h"
  9. #include "SparkFun_Alphanumeric_Display.h"
  10. #include "AHTxx.h"
  11. HT16K33 display;
  12. /** DHT22 */
  13. #define DHT22_PIN 2
  14. DHTesp dht;
  15. TempAndHumidity th;
  16. Timer readTemperatureProcTimer;
  17. void onTimer_readDHT22();
  18. Timer procTimer, procRTimer;
  19. Timer displayTimer, tmpTimer;
  20. Timer showHighTimer, showLowTimer;
  21. Timer dotTimer;
  22. // Sensors values
  23. ahtxx_t sensorData;
  24. String StrCF;
  25. // Time values
  26. time_t Time, NTPLastUpdate;
  27. DateTime dt;
  28. float SensorT, SensorH, SensorHI, SensorCR;
  29. void GetData(void);
  30. void connectOk(const String& SSID, MacAddress bssid, uint8_t channel);
  31. void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason);
  32. void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway);
  33. void showWatch(void);
  34. void showTime(void);
  35. void dotOff(void);
  36. void showTemperature(void);
  37. void showHumidity(void);
  38. void showError(void);
  39. void shiftStringLeft(void);
  40. // NTP Client
  41. void onNtpReceive(NtpClient& client, time_t timestamp);
  42. NtpClient ntpClient("ntp.time.in.ua", 1500, onNtpReceive); // every 15 min
  43. void init(void) {
  44. spiffs_mount(); // Mount file system, in order to work with files
  45. Serial.begin(SERIAL_BAUD_RATE); // 115200 by default
  46. Serial.systemDebugOutput(false); // Debug output to serial
  47. Serial.println("Wall Segment Clock");
  48. ActiveConfig = loadConfig();
  49. // set timezone hourly difference to UTC
  50. SystemClock.setTimeZone(ActiveConfig.AddTZ);
  51. WifiStation.config(ActiveConfig.NetworkSSID, ActiveConfig.NetworkPassword);
  52. WifiStation.enable(true);
  53. WifiAccessPoint.enable(false);
  54. WifiEvents.onStationConnect(connectOk);
  55. WifiEvents.onStationDisconnect(connectFail);
  56. WifiEvents.onStationGotIP(gotIP);
  57. // initialize I2C
  58. Wire.pins(4, 5);
  59. Wire.begin();
  60. // BIG digits
  61. TM1650_Init();
  62. // Low 14-Seg LED output
  63. if (display.begin(DEFAULT_ADDRESS) == false) {
  64. Serial.println("HT16K33 device did not acknowledge!");
  65. } else {
  66. if (display.initialize() != false) {
  67. Serial.println("HT16K33 displays acknowledged. Init OK");
  68. } else {
  69. Serial.println("HT16K33 displays acknowledged. Init FAIL");
  70. }
  71. }
  72. display.print("1234");
  73. tmpTimer.initializeMs(500, shiftStringLeft).start();
  74. // refresh big led
  75. displayTimer.initializeMs(1000, showWatch).start();
  76. /* AHTxx Sensor */
  77. // AHTxx_Init();
  78. // procTimer.initializeMs(2000, GetData).start();
  79. /* DHT22 */
  80. dht.setup(DHT22_PIN, DHTesp::DHT22);
  81. readTemperatureProcTimer.initializeMs(30000, onTimer_readDHT22).start(); // every so often.
  82. }
  83. void showWatch(void) {
  84. static time_t oldTime;
  85. Time = SystemClock.now();
  86. dt.setTime(Time);
  87. /*
  88. * Now, in dt we have:
  89. * int8_t Hour;
  90. * int8_t Minute;
  91. * int8_t Second;
  92. * int16_t Milliseconds;
  93. * int8_t Day;
  94. * int8_t DayofWeek; -- Sunday is day 0
  95. * int8_t Month; // Jan is month 0
  96. * int16_t Year; // Full Year numer
  97. */
  98. if (oldTime != Time) {
  99. // New Second
  100. oldTime = Time;
  101. showTime();
  102. if (dt.Second == 0x00) {
  103. Serial.printf("Time: %02d:%02d:00\r\n", dt.Hour, dt.Minute);
  104. }
  105. }
  106. }
  107. /*
  108. * Выводим текущее время [HH MM] на верхние индикаторы
  109. */
  110. void showTime(void) {
  111. static uint8_t oldHour = 0xFF, oldMinute = 0xFF;
  112. if (oldMinute != dt.Minute) {
  113. oldMinute = dt.Minute;
  114. // ...
  115. if (oldHour != dt.Hour) {
  116. oldHour = dt.Hour;
  117. // ...
  118. } // new hour
  119. } // new minute
  120. TM1650_Out(dt.Hour/10, dt.Hour%10, dt.Minute/10, dt.Minute%10);
  121. TM1650_DotSet(Dig_2);
  122. TM1650_DotSet(Dig_3);
  123. dotTimer.initializeMs(500, dotOff);
  124. dotTimer.startOnce();
  125. }
  126. void dotOff(void)
  127. {
  128. TM1650_DotRes(Dig_2);
  129. TM1650_DotRes(Dig_3);
  130. }
  131. /*
  132. * Show temperature, small indicators
  133. */
  134. void showTemperature(void)
  135. {
  136. SensorT = th.temperature;
  137. uint8_t a, b;
  138. a = (uint8_t)th.temperature / 10;
  139. b = (uint8_t)th.temperature % 10;
  140. TM1650_Out(a, b, 0, 0);
  141. TM1650_Out3(Sym_o);
  142. TM1650_Out4(Sym_C);
  143. }
  144. /*
  145. * Show humidity, small indicators
  146. */
  147. void showHumidity(void) {
  148. SensorH = th.humidity;
  149. uint8_t a, b;
  150. a = (uint8_t)th.humidity / 10;
  151. b = (uint8_t)th.humidity % 10;
  152. TM1650_Out(a, b, 0, 0);
  153. TM1650_Out3(Sym_Off);
  154. TM1650_Out4(Sym_H);
  155. }
  156. /*
  157. * Show error, small indicators
  158. */
  159. void showError(void) {
  160. TM1650_DotRes(Dig_2);
  161. TM1650_Out1(Sym_E);
  162. TM1650_Out2(Sym_r);
  163. TM1650_Out3(Sym_r);
  164. TM1650_Out4(Sym_Off);
  165. }
  166. /*
  167. * Выводим дату на верхние индикаторы [DD MM]
  168. */
  169. void showDate(void) {
  170. // ...
  171. }
  172. /**
  173. * @brief Get data from Temperature/Humidity Sensor.
  174. */
  175. void GetData(void) {
  176. static bool st = false;
  177. AHTxx_GetData(&sensorData);
  178. if (sensorData.Error != St_OK) {
  179. Serial.println("Sensor: Data error!");
  180. return;
  181. }
  182. th.temperature = (float)sensorData.Temperature / 10.0;
  183. th.humidity = (float)sensorData.Humidity / 10.0;
  184. if (st) {
  185. st = !st;
  186. showTemperature();
  187. } else {
  188. st = !st;
  189. showHumidity();
  190. }
  191. Serial.printf("Humidity: %d.%d %%; Temperature: %d.%d *C\r\n", sensorData.Humidity/10, sensorData.Humidity%10, sensorData.Temperature/10, sensorData.Temperature%10);
  192. }
  193. void connectOk(const String& SSID, MacAddress bssid, uint8_t channel)
  194. {
  195. debugf("connected");
  196. WifiAccessPoint.enable(false);
  197. }
  198. void gotIP(IpAddress ip, IpAddress netmask, IpAddress gateway)
  199. {
  200. Serial.print("Got IP address: ");
  201. Serial.println(ip);
  202. // Restart main screen output
  203. procTimer.restart();
  204. displayTimer.restart();
  205. // start NTP Client there?
  206. startWebServer();
  207. }
  208. void connectFail(const String& ssid, MacAddress bssid, WifiDisconnectReason reason)
  209. {
  210. debugf("connection FAILED: %s", WifiEvents.getDisconnectReasonDesc(reason).c_str());
  211. WifiAccessPoint.config("ClockConfig", "", AUTH_OPEN);
  212. WifiAccessPoint.enable(true);
  213. // Stop main screen output
  214. procTimer.stop();
  215. displayTimer.stop();
  216. Serial.println("WiFi ClockConfig");
  217. Serial.println(WifiAccessPoint.getIP());
  218. startWebServer();
  219. WifiStation.disconnect();
  220. WifiStation.connect();
  221. }
  222. /**
  223. * @brief NTP Client
  224. */
  225. void onNtpReceive(NtpClient& client, time_t timestamp)
  226. {
  227. SystemClock.setTime(timestamp, eTZ_UTC);
  228. NTPLastUpdate = SystemClock.now();
  229. Serial.println("*** Time synchronized OK! ***"); // DEBUG
  230. }
  231. void onTimer_readDHT22()
  232. {
  233. //* try different reading methods (Adafruit compatible) vs improved */
  234. static bool toggle = false;
  235. toggle = !toggle;
  236. float humidity = 0;
  237. float temperature = 0;
  238. Serial << _F("TickCount=") << RTC.getRtcNanoseconds() / 1000000 << endl;
  239. if(toggle) {
  240. Serial.println(_F("Read using Adafruit API methods"));
  241. humidity = dht.getHumidity();
  242. temperature = dht.getTemperature();
  243. th.humidity = humidity;
  244. th.temperature = temperature;
  245. // check if returns are valid, if they are NaN (not a number) then something went wrong!
  246. if(dht.getStatus() == DHTesp::ERROR_NONE) {
  247. Serial << _F("\tHumidity: ") << humidity << _F("% Temperature: ") << temperature << " °C" << endl;
  248. } else {
  249. Serial << _F("Failed to read from DHT: ") << dht.getStatus() << endl;
  250. }
  251. } else {
  252. //* improved reading method
  253. Serial.println(_F("\r\n"
  254. "Read using new API methods"));
  255. th = dht.getTempAndHumidity();
  256. humidity = th.humidity;
  257. temperature = th.temperature;
  258. if(dht.getStatus() == DHTesp::ERROR_NONE) {
  259. Serial << _F("\tHumidity: ") << th.humidity << _F("% Temperature: ") << th.temperature << " °C" << endl;
  260. } else {
  261. Serial << _F("Failed to read from DHT: ") << dht.getStatus() << endl;
  262. }
  263. }
  264. // Other goodies:
  265. //
  266. // Heatindex is the perceived temperature taking humidity into account
  267. // More: https://en.wikipedia.org/wiki/Heat_index
  268. //
  269. Serial << _F("Heatindex: ") << dht.computeHeatIndex(temperature, humidity) << " °C" << endl;
  270. //
  271. // Dewpoint is the temperature where condensation starts.
  272. // Water vapors will start condensing on an object having this temperature or below.
  273. // More: https://en.wikipedia.org/wiki/Dew_point
  274. //
  275. Serial << _F("Dewpoint: ") << dht.computeDewPoint(temperature, humidity) << " °C" << endl;
  276. //
  277. // Determine thermal comfort according to http://epb.apogee.net/res/refcomf.asp
  278. //
  279. ComfortState cf;
  280. Serial << _F("Comfort is at ") << dht.getComfortRatio(cf, temperature, humidity) << " %, (";
  281. switch(cf) {
  282. case Comfort_OK:
  283. Serial.print(_F("OK"));
  284. break;
  285. case Comfort_TooHot:
  286. Serial.print(_F("Too Hot"));
  287. break;
  288. case Comfort_TooCold:
  289. Serial.print(_F("Too Cold"));
  290. break;
  291. case Comfort_TooDry:
  292. Serial.print(_F("Too Dry"));
  293. break;
  294. case Comfort_TooHumid:
  295. Serial.print(_F("Too Humid"));
  296. break;
  297. case Comfort_HotAndHumid:
  298. Serial.print(_F("Hot And Humid"));
  299. break;
  300. case Comfort_HotAndDry:
  301. Serial.print(_F("Hot And Dry"));
  302. break;
  303. case Comfort_ColdAndHumid:
  304. Serial.print(_F("Cold And Humid"));
  305. break;
  306. case Comfort_ColdAndDry:
  307. Serial.print(_F("Cold And Dry"));
  308. break;
  309. default:
  310. Serial.print(_F("Unknown:"));
  311. Serial.print(cf);
  312. break;
  313. }
  314. Serial.println(')');
  315. }
  316. void shiftStringLeft(void) {
  317. display.shiftLeft();
  318. }