èŠåºãã®æåã®éšåãèªãã§ããéãããªãã®å€ãã¯ããããèããŸãã-é·ãéèŠããã§ããArduinoã®å¥ã®ãµãŒã¢ã¹ã¿ããã ãããŠ...ããã¯æ¬åœã§ã-ã¯ããããã¯å¥ã®ãã€ã©ãŒãå¥ã®å®¶ã®ããã®å¥ã®ãµãŒã¢ã¹ã¿ããã§ãããçå®ã¯éšåçã«ãããããŸãã-ç§ã¯ããã€ã¹èªäœã«éäžããããªãèšäºã§ã¯-ãããã¯æ¬åœã«ãããããããŸãïŒèšäºïŒ ãã¡ããããµãŒã¢ã¹ã¿ããã«ã€ããŠèª¬æããŸããããã€ã¯ãã³ã³ãããŒã©ãŒèªäœããã€ã©ãŒã«æ¥ç¶ããæ¹æ³ã«ã€ããŠè©³ããã話ããããšæããŸãã ã ããã誰ãæ°ã«-ããŠãã ãã...
ãã¹ãŠã®å§ãŸã
ãŸã第äžã«ãç§ã¯ãŸã£ããããã°ã©ããŒã§ã¯ãªããå®éã®ãã€ã¯ãã³ã³ãããŒã©ãŒãšã¯äœã®é¢ä¿ããªãã£ããšèšãããã§ãã MK AVRïŒãããŠå®éã«ã¯MKïŒãåããŠç¥ã£ãã®ã¯é«æ ¡ã«æ»ã£ããšãã§ããã®äžæè°ãªããšãã©ã®ããã«æ©èœããããç¥ããããšæããŸããã ç§ã¯ããã€ãã®èšäºãèªã¿ãŸãããããã以æ¥ãDDRãšPORTãšãã2ã€ã®åèªã§èª¬æã§ããæç« ããèŠããŠããŸããã§ããã ãããã5幎ç®ã®å€§åŠããããŸããããããã°ã©ãã³ã°ãã€ã³ã³ãã§ãç§ãã¡å šå¡ãä»®æ³ç°å¢ã§MSC51ãšåºäŒããŸããã æ¢ã«äžæãã¿ã€ããŒããã®ä»ãã¹ãŠããããŸããã ããŠããã®ãããªè±å¯ãªç¥èã«ãããç§ã¯åé¡ã«çŽé¢ããŸããã ãã®èªäŒçããŒããçµäºããããã«èå³æ·±ãéšåã«é²ã¿ãŸãã
ã ãããå®éã«ã¯ããµãŒã¢ã¹ã¿ããã®äœæãéå§ãããã®-ã¬ã¹ãã€ã©ãŒã§èªåŸææ¿ãèšçœ®ããåŸãç§ã¯ãå€ãã®ããã«ãäžè¬çãªåé¡ã«ééããŸãã-家ã®æž©åºŠã¯å€ã®å€©æ°ã«éåžžã«äŸåããŠããŸãã-é-ã¢ããŒãã¯å¯ãã®ã§ãã¯ãŒã©ã³ãã®æž©åºŠãäžããå¿ èŠããããŸãããããªãŒããŠã©ãŒã ã¢ãã-éã«ã ã¿ã³ããªã³ãšã®ãã®ãããªãã³ã¹ã¯ããŸãç§ã«ã¯äŒŒåããŸããã§ããããªããªã ãã€ã©ãŒã®èª¿æŽã¯ããã¢ã®åŸãã«èšçœ®ããããã¢ãé»åã¬ã³ãžã§æ¯ããããŠããããã®äžã«ãŽãã®å±±ã眮ãããŠãããããè€éã§ããã ããŠãããªãã¯ç解ããŠããŸã-åµã®äžã®éãã¢ãã«ã®äžã®åµãªã©
ãã®åé¡ã¯éåžžã«ç°¡åã«è§£æ±ºãããŸãã-OTCã»ã³ãµãŒïŒå€æ°æž©åºŠè£æ£ïŒã¯ããã€ã©ãŒã«æ¥ç¶ããè¡è·¯ã®æž©åºŠã«å¿ããŠã¯ãŒã©ã³ãã®æž©åºŠãèªåçã«èª¿æŽã§ããããã«ããŸãã åé¡ã¯è§£æ±ºãããããã«èŠããŸãããããã€ã©ãŒã®ãµãŒãã¹ããã¥ã¢ã«ïŒFerolli Domiproject C24DïŒãèªããšããã«ç§ã®åžæãæã¡ç ãããŸãã-ãã®ã¢ãã«ã®å€éšæž©åºŠã»ã³ãµãŒã®æ¥ç¶ã¯æäŸãããŸããã ããã ãã§ããïŒ ããã ãã§ã ãããŠä»ããããããçµäºããããšã¯å¯èœã§ãããå€ã«ã¯ã³ã³ãããŒã«ããŒããé·éšã§çãå°œããŠããŸãããããã«ããæ¹æ³ã§ãµãŒãã¹ãã³ãšè©±ããŸãïŒããŒãã¯åŸã§ä¿®çãããŸããïŒOTCããã€ã©ãŒã«æ¥ç¶ã§ãããã©ãããå°ããŸãããïŒ åœŒã¯ãå€éšãµãŒã¢ã¹ã¿ããã䜿çšããŠæ¥ç¶ãããšçããŸããã ããã¯ç§ã®èšæ¶ã«é ããããŸããããå¯ã倩æ°ãå§ãŸãåã«ããããšãŸã£ããåãåé¡ã«æ¬åœã«éäžããŸããã§ããã
åããµãŒãã¹ããã¥ã¢ã«ã«ç®ãéããŸãããããã§ã«ãµãŒã¢ã¹ã¿ããã®æ¥ç¶æ¹æ³ã確èªããç®çã§ããOpenThermã³ã³ãããŒã©ãŒããåã端æ«ã«æ¥ç¶ãããŠããããšã«æ°ä»ããŸããã ããããç§ã¯æ°ã¥ãã-ããã«ããïŒ ãOpenTherm ArduinoããGoogleã§æ€çŽ¢ãããšãåã³æ°åã害ããŸããã ã¡ãã»ãŒãžã¢ãã¿ãŒã¯ãããŸããããããã§ã¯ãããŸãã-èãå¿ èŠã¯ãããŸãããäœããããŸãã-ãµãŒã¢ã¹ã¿ãããå¿ èŠã§ãã
ãããããèšäºhabrahabr.ru/post/214257ã«åºäŒããŸããã ããã®çµããã¯ç§ãæ··ä¹±ãããŸãã-ãªã·ãã¹ã³ãŒãã®ãªãèè ã¯ããã€ã©ãŒããã€ã¯ãã³ã³ãããŒã©ãŒã«æ¥ç¶ã§ããŸããã§ããã ãããŠãMKã«ç²Ÿéãã人ãåããªãã£ãå Žåãç§ã¯äœãããããšããã¹ãã§ããïŒïŒ Opentherm v2.2ãããã³ã«ã®è©³çŽ°ãªèª¬æãã€ã³ã¿ãŒãããã§èŠã€ãããŸãããããã¯ç§ã®ç±æãããã«å·ãããŸãã-ãããã³ã«ã®ç©çã¬ãã«ã¯ããæŽç·ŽãããŸãã-ãã€ã©ãŒããã®ããŒã¿ãçŸåšã®ã¬ãã«ïŒ5-7mA-äœã17-23mA-é«ïŒã§éä¿¡ãããé»æµã«ãŒããããã³ãµãŒã¢ã¹ã¿ãããããã€ã©ãŒãŸã§ã®é»å§ã¬ãã«ïŒ<7V-äœã¬ãã«ã15-18V-é«ïŒãããã«ã¯ãã¢ãªã³ã°åè·¯ãå¿ èŠã«ãªããŸããç§ã¯é»åæ©åšã«éåžžã«è¿ãã§ãã ããã«ãããŒã¿ã¯ãã³ãã§ã¹ã¿ãŒã³ãŒãã«ãã£ãŠéä¿¡ãããŸããã
ãã äžã€ã®çµè«ããããŸã-æ°ã«ããªãã§-ãã é»åã¬ã³ãžãšèŠç¯ãåãããŠãã ããã ããããç§ã¯æ§æ Œã«1ã€ã®ç¹åŸŽããããŸã-ããªããããªãã®é ã«äœããã®ã¢ã€ãã¢ã眮ããšãé ããæ©ãããããå®çŸããŸã-ã¯ããç§ã¯ãããå¿ããŸãïŒãã®ã¢ã€ãã¢ïŒããããã§ãã©ãã«ãè¡ããªãã§ãããXBMCã®ã¡ãã£ã¢ã»ã³ã¿ãŒãããã«å¯Ÿãããµãã©ã€ããDVBã«ãŒãããã®ä»å€ãã®å€ãã®ãã®ïŒã ããªãã¯å¯ãŠããŠããã³ãã§ã¹ã¿ãŒã®ã³ãŒããåãå ¥ããæ¹æ³ã«ã€ããŠã®èšç»ããã§ã«é ã®äžã§åŸªç°ããŠããŸãã
ããã§ãOT / +ãããã³ã«ã®ä»çµã¿ãç°¡åã«èª¬æããŸãïŒOTã®çš®é¡ã«ã€ããŠã¯ãäžèšã®èšäºã§èª¬æããŠããŸãïŒã ããã€ã¹éã®éä¿¡ã¯ãèŠæ±ãšå¿çã®åœ¢åŒã§è¡ãããŸãã ã€ãã·ãšãŒã¿ãŒã¯ãµãŒã¢ã¹ã¿ããã®ã¿ã§ãã 1ç§éã«å°ãªããšã1åèŠæ±ãéä¿¡ãã20ã800ããªç§ã®å¿çãåŸ ã¡ãŸãã ã¡ãã»ãŒãžèªäœã¯ã1ã€ã®éå§ããããš1ã€ã®åæ¢ããããæã€32ãããã§ãã
MSG-TYPE-ã¡ãã»ãŒãžã¿ã€ã-ãµãŒã¢ã¹ã¿ããã®å ŽåïŒ
0x0-READ-DATA-ããŒã¿ã®èªã¿åãã
0x1-WRITE-DATA-æžã蟌ã¿ã
ãã€ã©ãŒçšïŒ
0x4-READ-ACK-èªã¿åãã確èªããŸãïŒçããå ¥ã£ãŠããŸãïŒã
0x5-WRITE-ACK-èšé²ã確èªããŸãã
0x6-ããŒã¿ç¡å¹-ããŒã¿ãæ£ãããããŸããã
0x7-UNKNOWN-DATAID-ãã®ãããªDATA-IDã¯ãããŸããã
DATA-ID-ãã©ã¡ãŒã¿ãŒã®èå¥åã æåã®128åã¯äºçŽãããŠããããããã®ã»ãšãã©ã¯ãã§ã«ä»æ§ã§æå®ãããŠãããæ®ãã®128åã¯åãã³ããŒããã®è£éã§äœ¿çšããŠããŸãã
DATA-VALUE-ãã©ã¡ãŒã¿ãŒå€èªäœã ãã©ã¡ãŒã¿ãŒèªäœã«å¿ããŠãç°ãªã圢åŒã«ãªãå ŽåããããŸãã 2ã€ã®8ããããã©ã°å€ã笊å·ãªã16ãããæŽæ°ãåºå®å°æ°ç¹ä»ãåæ°ãªã© ãã©ã¡ãŒã¿ãŒããšã«ãå€ã®ã¿ã€ããå®çŸ©ãããŠããŸãã
åOTããã€ã¹ã«å¯ŸããŠããã©ã¡ãŒã¿ãŒã®ã»ãããå®çŸ©ãããŠããŸããããã¯å¿ ããµããŒãããå¿ èŠããããŸãã
ããŒã¿ID | 説æ | ãµãŒã¢ã¹ã¿ãã | ãã€ã©ãŒ |
0 | ããã€ã¹ã¹ããŒã¿ã¹ãã©ã° | DATA-VALUEãã£ãŒã«ãã®äžäœãã€ãã«å¿ èŠãªæ©èœãèšå®ããŠãèªã¿åãèŠæ±ãéä¿¡ããå¿ èŠããããŸã | DATA-VALUEãã£ãŒã«ãã®äžäœãã€ãã«ã¹ããŒã¿ã¹ããããèšå®ããŠããªã¯ãšã¹ãã«å¿çããå¿ èŠããããŸã |
1 | åžæã®ã¯ãŒã©ã³ã枩床ãèšå®ãã | åžæã®æž©åºŠå€ã§æžã蟌ã¿èŠæ±ãéä¿¡ããå¿ èŠããããŸã | å¿ èŠãªæž©åºŠã®èšå®ã®ç¢ºèªã§å¿çããå¿ èŠããããŸã |
3 | ãã€ã©ãŒæ§æ | ãã©ã¡ãŒã¿ãŒãèªã¿åãå¿ èŠããããŸã | èŠæ±ã«å¿çããå¿çã§éä¿¡ããããã¹ãŠã®æ©èœããµããŒãããå¿ èŠããããŸã |
14 | æ倧ç«çå€èª¿ | ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒ | å®è£ ããå¿ èŠããããŸã |
17 | çŸåšã®ç«çå€èª¿ã¬ãã« | ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒ | å®è£ ããå¿ èŠããããŸã |
25 | ã¯ãŒã©ã³ã枩床 | ãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒ | å®è£ ããå¿ èŠããããŸã |
ä»ã®ãã¹ãŠã®ãã©ã¡ãŒã¿ãŒã«å¯Ÿããçãã¯ããã€ã©ãŒã®è£œé å ã®èŠæ±ã«å¿ããŠããŸãã
ç¥ããªã人ã«ãšã£ãŠã®ç«çå€èª¿ãšã¯äœããå°ã説æããŸãã ææ°ã®ã¬ã¹ãã€ã©ãŒã¯ãã¹ãŠãçå ã®ç«çã¬ãã«ãå¶åŸ¡ããããšãã§ããŸã-ããã¯å€èª¿ãšåŒã°ããŸãã ããŒããŒã®åºåã倧ããã»ã©ãç±åªäœã®å ç±ãéããªããåºåã倧ãããããšãã€ã©ãŒã®åžžæãªã³/ãªãïŒã¯ããã¯ïŒãå°ãªããªããèšå®æž©åºŠã«éããããšãã§ããªããªããŸãã ãã€ã©ãŒãåæ¢ãããæå®ã¬ãã«ã®ã¯ãŒã©ã³ããç¶æããã®ã«ååãªåŒ·åºŠã§ççŒããæé©ãªåäœã¢ãŒããèæ ®ãããŸãã
ã芧ã®ãšããããã¹ãŠãéåžžã«ç°¡åã§ã-å®è£ ãèšè¿°ãããã€ã©ãŒã®å¶åŸ¡ãååŸããŸãã ããããæªéã¯ã圌ããèšãããã«ãããããªããšã«ãããŸãã ç©çã¬ãã«ãæãåºããŠãã ãã-ãã€ã©ãŒããã®ããŒã¿ã¯çŸåšã®ã¬ãã«ã§ãé»å§ã¬ãã«ã§ãã€ã©ãŒã«éä¿¡ãããŸã-ããã¯é»åå·¥åŠã«æ £ããŠããªã人ãæ··ä¹±ãããŸãã ãã€ã©ãŒãæèŒããŠããŸããïŒ ããã§ã¯ãé»å§ãå¶åŸ¡ããæ¹æ³ã¯ïŒ ãã€ã©ãŒããArduinoã«ã¯ã€ã€ãæ¥ç¶ããããšã¯ã§ããŸããã ç¥ã£ãŠãã人ã«ãšã£ãŠã¯ãçãã¯æããã§ã-ããã¯é»æµã«ãŒãã§ããããã¢ãªã³ã°åè·¯ã¯éåžžã«ç°¡åã§ãã ç§ã¯çãäžã®ã©ããã«ããã®ã§ãã€ã³ã¿ãŒãããã«ç»ã£ãŠãæ奜家ãOpenTherm Gatewayãäœã£ãotgw.tclcode.comãšãããµã€ããPICã§èŠã€ããŸããã ãã¢ãªã³ã°åè·¯ããããŸããã ããã¯æããŸã-PICãåããŸããããšããã§-è¯ãè©Šã¿ãæ inessããããããã-ç§ã¯ããã§ã¯ãªããç§ã®ãã®ã欲ããã§ãã
ããã ãã§ã-ãããåããéããŠãã ããã ãã®åŸã詳现ãšã»ããå šäœã®äŸ¡æ Œãå°ãå§ããŸãããããã³ãã§ã¹ã¿ãŒã®ã³ãŒããšãã圢ã§ãŸã é害ããããŸãã-ãããåãå ¥ããããã«ã©ã¡ãã®åŽã«è¿ã¥ãã¹ããã¯ããããŸããã§ããã ãããç§ã®ç©èªã®æ¬¡ã®éšåã®å§ãŸãã§ãã
ãã³ãã§ã¹ã¿ãŒã³ãŒã
Openthermãããã³ã«ã§ã¯ããã³ãã§ã¹ã¿ãŒã³ãŒãã䜿çšããŠããŒã¿ãç©ççã«è¡šããŸãããŸãã¯ãBi-Phase L.ä»æ§ã§åŒã°ããŠããŸãã
å®éã«ã¯ãããã«ãããŸãïŒ
å šäœã®ãã€ã³ãã¯ãããããä¿¡å·ã¬ãã«ã§ã¯ãªããæéäžã®ã¬ãã«éã®é·ç§»ã«ãã£ãŠãšã³ã³ãŒããããããšã§ãã
ããã«ããã®åãé·ç§»ã¯ãæéã®çãäžã«æ£ç¢ºã«ã¯çºçããŸããããã©ããã§çºçããŸãïŒ
ã芧ã®ãšãããæéèªäœã¯1ms -10ïŒ + 15ïŒ ã§ããã移è¡ã¯ãã®äžéã«ãããŸãã
ããã¯ç§ãé·ãéåæ¢ããå Žæã§ãã ã€ã³ã¿ãŒãããããäœããã³ããŒããããšãã欲æ±ã¯ãããŸããã§ããã åãããžã§ã¯ãã«ã¯ç¬èªã®ã€ãŸããããããããªãã¯åã«ã©ã€ãã©ãªã®èãã®ãªãã³ããŒã»ããŒã¹ããªã¹ãã§ããã ãã§ãªãããã®ãããžã§ã¯ããè¡ãéçºè ã ãšæããŠãããšå€æããŸããã ããã¯å®éããµãŒã¢ã¹ã¿ããã®å¿èéšã§ããOTãšé£æºããŠããããã³ããŒãããšããããšã¯ããã¶ã€ããŒããå¥ã®ããã¡ããçµã¿ç«ãŠãããšãæå³ããç¬èªã®äœããäœæããããšãæå³ããŸããã
ããã§ãå²ã蟌ã¿ãšã¿ã€ããŒãªã©ãMKã«ã€ããŠã®ç§ã®ããããªç¥èããã¹ãŠé©çšãããã£ãã®ã§ãã ã¯ããé 延ïŒïŒã§ãã¹ãŠãã¯ããã«ç°¡åã«ãªããŸããããŸããé 延ïŒïŒã䜿çšããŠåä¿¡ããã«ã¯éä¿¡ãé ãããŸãããåä¿¡/éä¿¡äžã«ä»ã®ã¢ã¯ã·ã§ã³ã䞊è¡ããŠå®è¡ããããšæããŸããããã¹ãŠããŸãšãã§ãç·åçåŸã®å·¥èžåã§ã¯ãããŸããã§ããã
ãŸãã«ãã®å€åãæããããšãã©ãã»ã©çŸãããããããåç·ãåŸéããåããããããå¥ã®è§åºŠããèŠããšããã«ãã¹ãŠãæ確ã«ãªããŸããã çµå±ãæéã®ååã®ã¬ãã«ã¯ãããã®æãŸããå€ã§ãïŒ
æåã®ã¹ãããããããŸã-æéã®ååïŒéå§åŸ250ÎŒsïŒã®ã¬ãã«ãååŸãã-ããããã¹ãŠãã³ãŒãã§ãã ããããããã§ã¯æ¬¡ã®å€±æãåŸ ã£ãŠããŸãã-æéã®å§ãŸãããã£ããããããšã¯åžžã«å¯èœãšããããã§ã¯ãããŸããïŒ01ãŸãã¯10ã®çµã¿åãããããå Žåãæéã®éã«é¡èãªãã®ã¯äœãèµ·ãããŸããã æããã«ãã¬ãã«ã¯å€æŽãããŸãã-ããã«èª¿ã¹ãå¿ èŠããããŸãã ãããŠãããã«2çªç®ã®å瀺ããããŸã-æéã®éäžã§åžžã«é·ç§»ããããŸã-ãããã¯0ãš1ã«ãšã³ã³ãŒããããŸãããããã£ãŠãããã«ã¢ã¿ããããããšãã§ãã次ã®ãããã®å€ã¯æéã®ååã«ãªããŸãïŒ ããã§ããã¹ãŠãå®å šã«æããã«ãªããŸããã
ãã§ã«ããã€ãã®ããããåãå ¥ããŠãããæåã®æéã®ã¡ããã©äžéã«äœçœ®ããŠããããšãæ³åããŠãã ããã
å ¥åä¿¡å·ã®å€åã§å²ã蟌ã¿ãæå¹ã«ããã ãã§ãã ãããèµ·ãããšããã«ãããã¯ãŸãã«ç§ãã¡ãæéã®çãäžã«ããããšãæå³ããŸãã ä¿¡å·ã®å€æŽæã«å²ã蟌ã¿ããªãã«ããã¿ã€ããŒããªã»ããããã¿ã€ããŒå²ã蟌ã¿ãããªã¬ãŒããããšãã«ã3/4åšæåŸïŒOTã®å Žåã¯750 µsïŒã«ã¿ã€ããŒå²ã蟌ã¿ãçºçãããå ¥åã¬ãã«ãèšé²ããã¿ã€ããŒå²ã蟌ã¿ãç¡å¹ã«ããŸããæ®ãã®ãã¹ãŠã®ãããã«ã€ããŠãããäžåºŠç¹°ãè¿ããŸãã
æåã®ã±ãŒã¹ã¯ç¹å¥ãªã±ãŒã¹ã«ãªããŸãããªããªãã 圌ã®ã¬ãã«ã3/4ã§ã¯ãªãã1/4ã®æéã«ãªãã®ãåŸ ã¡ãŸã
å²ã蟌ã¿ãã³ãã©ãŒã¯ããã«ã¹ã±ããããããã¡ãŒã ãŠã§ã¢ãçµã¿ç«ãŠãããŸãããããªã·ãã¹ã³ãŒããšä¿¡å·çºçåšãªãã§ã©ã®ããã«ãããã°ã§ããŸããïŒ ç¥èã倧åŠããæãåºãããŸãã-ããããŠã¹ã§ã¯ãäœãèµ·ãã£ãŠãããã段éçã«èŠãããšãã§ããŸãã
ç§ã¯èŠã€ããŠãã€ã³ã¹ããŒã«ããããã«ãã¹ãŠã®ç·Žç¿ã®é åããããŸãã-å²ã蟌ã¿ããªã³ã«ããåã«å²ã蟌ã¿ãã©ã°ã匷å¶çã«åé€ããå¿ èŠããããã¿ã€ããŒã¢ãŒããFastPWMããCTCã«å€æŽããåã«OCR2A / BãããŒããããšãããã®ãããªã¯ãŒã«ãªã¹ã©ãªãŒãçºçããŸãããããã°ã©ã ã§ãããããããéã§å€æããããã«ããŸã ãã£ãšæ¥œããã§ãïŒã ããŠãããã«æ±ºå®ãããã®ä»ã®ããããªããšã ãã®æ®µéã§ã¯éããªãããµãŒã¢ã¹ã¿ããã«ç¹å®ã®èŠä»¶ãèšããŠããªãã£ãããšãæãåºãããŠãã ããã
ãã³ãã§ã¹ã¿ãŒã³ãŒããåä¿¡ããã³ãŒããã©ã°ã¡ã³ãã次ã«ç€ºããŸãã
inline void OpenTherm::receive(){ cli(); first=1;//receiving first bit buf=0;//clear buffer rx=1; data_ready=0; length=0; parity=0; PCICR|=bit(rx_pcie); //enabling Pin Change Interrupt for RX port *rx_pcmsk|=rx_bitmask; //enabling Pin Change Interrupt for RX pin of rx Port TCCR2A=bit(WGM21);//mode CTC TCCR2B=0; OCR2A=TICKS_PER_MS*0.75;//interrupt at 0.75ms TCNT2=TICKS_PER_MS*0.5;//preload 0.5ms TIMSK2=bit(OCIE2A);//interrupt on OC0A TIFR2=bit(OCF2A); sei(); bool OpenTherm::extIntHandler(){ *rx_pcmsk&=~rx_bitmask; //Disable PCINT for RX pin if (first) { first=0; } else{ TCNT2=0; } if (length > MSG_LENGTH){ data_ready=1; TCCR2B=0;//disable Timer2 TIMSK2=0; return 1; } else TCCR2B=bit(CS22); //start timer clk/64 return 0; }; void OpenTherm::timer2CompAHandler(){ uint32_t tmp_buf; tmp_buf=buf; tmp_buf=tmp_buf<<1; if (rx) { if (*rx_port & rx_bitmask) { //Reading RX value tmp_buf=tmp_buf | 1; if (length > 1 ) parity^=1; //Don't calculate parity for start bit } *rx_pcmsk|=rx_bitmask; //Re-enabling PCINT for RX pin TCCR2B=0; //stop Timer2 } length++; buf=tmp_buf; }; }
転éã¯ãåŸã§ãå®å šã«è«ççãã€å®éçã«åããã³ãã©ãŒã«é©åããŸãã
ã¿ã€ããŒ2ã¯ãã¹ãŠåãCTCã¢ãŒãã§åäœããããªç§ããšã«ãŒãåãããŸããŒãåå²ã蟌ã¿ãã³ãã©ãŒïŒCTCã¢ãŒãã®OC2AïŒã§ã¯ã次ã®ãããã«åŸã£ãŠåºåãåãæ¿ããŸãã ããã«ãOC2Bå²ã蟌ã¿ãã¢ã¯ãã£ãã«ãªããŸããããã¯ãæ£ç¢ºã«ååšæïŒ0.5ããªç§ïŒããªã¬ãŒãããåºåç¶æ ãå転ããŸãã ããã転éã®ãã¹ãŠã®ç¥æµã§ãã
ããã§ã€ã³ã¿ãŒãã§ã€ã¹åè·¯ãçµã¿ç«ãŠãŠã3æéã§ãã®åäœã®åçãèŠã€ããŸãããããã¯éåžžã«åçŽã§ããããšãå€æããåè·¯ãå°ãå€æŽããŠãå ã®ããã«ããŒã¿ãå転ã§ã¯ãªãçŽæ¥éä¿¡ããŸããã
ããã«ãä¿¡å·çºçåšãHDLã«æžã蟌ãå¿ èŠããããŸããïŒæžã蟌ã¿æ¹æ³ãã€ã³ã¿ãŒãããããååŸããŠèªåã§å€æŽããæ¹æ³ïŒã ãã³ãã§ã¹ã¿ãŒã³ãŒãã§34ããããæåã§ãã€ã€ã«ããŸããããã¯4ãŸãã¯5ã§ã¯ãããŸããã
æåŸã«ãåä¿¡/éä¿¡ã確ç«ãããå¿ èŠãªæ©åšã決å®ããæãæ¥ãŸããã
è£ åå
ãã®ããããšãã¥ã¬ãŒã¿ã§åäœãããã³ãã§ã¹ã¿ãŒã³ãŒãã§OTã¡ãã»ãŒãžãéåä¿¡ããããã®ãã€ã©ãŒïŒFerolli Domiproject C24DïŒãšãã¡ãŒã ãŠã§ã¢ããããŸããã 次ã®ã¹ãããã«é²ã¿ãŸãããã
ãŸããArduinoã®ã»ãŒãã¹ãŠã®ããã€ã¹ã«å¿ èŠãªãã®ã¯äœã§ããïŒ Arduinoèªäœã§ããïŒ ééã£ãïŒ ãšã³ã³ãŒããŒã§ãããåžžã«ãã¿ã³ãä»ããŠããŸã ç§ã¯ãã€ããã®ã¿ã€ãã®å ¥åããã€ã¹ã«åžžã«æ¹ãããŠããã ãã§ãããã²è©ŠããŠã¿ãŠãã ããã
次ã«ããµãŒã¢ã¹ã¿ããã¯å éšãšå€éšã®æž©åºŠãååŸããå¿ èŠããããŸã-ãããã®ç®çã®ããã«ã2ã€ã®DS18B20ã»ã³ãµãŒãéåžžã«é©ããŠããŸãã1ã€ã¯ç±ãæ¥çå€ã§æºããããå€åŽã«çœ®ãããŸãã åœç¶ããã£ã¹ãã¬ã€ãå¿ èŠã§ãããã£ã¹ãã¬ã€ããªããã°ãã©ãžãªã³ã³ããŒãã³ããjarã«æ³šãã§ãSilpoããã±ãŒãžã«å ãã§é²ãããšãã§ããŸã-å¹æã¯åãã§ãã æšæºã®æåçæLCD 20 * 4ã䜿çšããããšã«ããŸãã-ããã§ååã§ããLCDçšã®I2CããŒããšã¯ã¹ãã³ããŒã ã³ã³ãããŒã©ãŒèªäœã¯ãArduino Nanoã§ååã§ãïŒä»åºŠã¯ããã°ã©ããŒãšäžç·ã«Pro Miniã䜿çšããŸããããã®çç±ã説æããŸãïŒã ããŠãã€ã³ã¿ãŒãã§ã€ã¹åè·¯ã®ããã€ãã®è©³çŽ°ã
ã¿ã€ãã«ã®åçãããããããã«ãäœããããããã£ãã 売ãæã¯ãã¹ãŠã«å¯ŸããŠéåžžã«é åçãªäŸ¡æ Œãæã£ãŠããã®ã§ããªã¹ããå°ãå€æŽããããšã«ããŸããã 2ã€ã®DS18B20ã®ä»£ããã«ã1ã€ãé²æ°Žã±ãŒã¹+ DHT22ã«å ¥ããã®ã§ãéšå±ã®æ¹¿åºŠãäžããããšãã§ããããã«ãªããŸããã LCD 20 * 4ã¯å©çšã§ãããNokia 5110ãããã£ã¹ãã¬ã€ãåããŸãããããã¿ã³ä»ãã®ãšã³ã³ãŒããŒããªãã£ãã®ã§ãéåžžã®+ 2ãã¿ã³ãåããŸããã
åé åŸããã¹ãŠãã¯ãã ä»ãããããã¹ãã±ãŒã¹ã§ãã¹ããããŸããã ãŸããLEDãç¹æ» ãããŸãïŒArduinoããŒããæåã«ãªã³ã«ãããšãã«ããããŸãããããã¯ç¥èã§ãïŒã ãã¹ãŠãæåŸ ã©ããã«æ©èœãããããæ¹åãéå§ã§ããŸãã
Atmega 328ã«ããŒããŠã§ã¢SPIãååšããã«ãããããããç§ã¯ãããæŸæ£ããããšã«ããŸããã 圌ã«ãã£ãŠèª²ãããå¶éã¯ç§ã«ã¯ããŸãåã°ããŸããã§ãã-MISOã¯èªåçã«å ¥åçšã«èšå®ãããSS-åºåã§ããå¿ èŠããããŸã-2ã€ã®åºåãåŒããããããœãããŠã§ã¢SPIãæ®ããŸãã ã©ã€ãã©ãªããCEãã£ã¹ãã¬ã€åºåã³ã³ãããŒã«ãåé€ããLCDã®GNDã«çŽæ¥æ¥ç¶ããŸãã ç§ã¯åŸã-ã®ãããªãã®ïŒ
Proteusã§ã€ã³ã¿ãŒãã§ã€ã¹åè·¯ãé åžãããã¬ããããŒãã§åæ§ã®ããšãç¹°ãè¿ããŸãã
ã¯ã€ã€ãŒã®ç«¯ã«ã¯ãæšæºã®ãã€ã©ãŒã¿ãŒããã«ãããã¯ããããŸããããã¯éåžžã«äŸ¿å©ã§ããããšãå€æããŸãããããŒã«ã䜿çšããã«ã«ããŒãå€ãããšãªãæ¥ç¶ããã³åæã§ããŸãã
ããŠãããã§ããªããã£ããã¡ãŒã ãŠã§ã¢ãäœæãããã€ã©ãŒãšã®éä¿¡ãè©Šãããšãã§ããŸãã ç§ã¯æžããŠãç¹æ» ããŠãæ¥ç¶ããŠããŸã...
ãã€ã©ãŒã¯æ£åžžã«æ©èœããèšäºãéããããšãã§ããŸãã
Trollface.jpg
åœç¶ãäœãæ©èœããŸããã
ã€ã³ã¿ãŒãã§ã€ã¹ã«ãŒãã§ãã¹ã¿ãŒãçªã-ããã¯åäœããŸãã-å ¥åã¯åžžã«20Vã§ãã ç§ã¯å解ããèŠãŠããããŠç¬ããŸãã ç§ã¯å人ã«æ¯æããã¯ãã ä»ãããŸããã ç§ã¯ããã«å¯Ÿè©±ãæãåºããŸããã
-ãããããã£ãšãã£ãšïŒ
-ããããã»ãŒå®äºããŸããã ä»ããã®é·ããã©ãã¯ãã¯ãã ä»ãããããã ãã§ãã äž»ãªããšã¯ã次ã«ããã2ã€ã®é£æ¥ããé£çµ¡å ãæ¥ç¶ããããšãå¿ããªãããšã§ãã
åããŠå¿ãããšæãïŒ
ãã®ãããã補åãã¯ä¿®æ£ãããæ¥ç¶ããã確èªãããŸãã ã¬ãã«ã¯æ£åžžã§ãã³ã³ãããŒã©ãŒãæ¥ç¶ã§ããŸãã æ¥ç¶-æ²é»ã ãã¹ãŠãå°çããŸããã ãªã·ãã¹ã³ãŒããªãã§ããããšã¯ãããŸããã ç§ã¯æåã®èšäºã®èè ãšããŠçµãããŸãã ãããããŸã å°ãã®åžæããããŸãã
åä¿¡ã«é¢ããéšåãã€ãŸããæéã®éäžã§ã¿ã€ããŒãã¬ãã«å€æŽã«ãªã»ããããããšãæãåºããŸãã çªç¶ãŒãã«ãªãã®ã¯ååã§ã¯ãªããçä¿¡ä¿¡å·ã®ã¿ã€ãã³ã°ã¯äžè¬ã«çœå®³ã§ãããšæããŸããã€ãŸããã¬ãã«ã®4åã®1ã®ã¬ãã«ãèªã¿åãç¬éã«ããããªãã«ãããŒããããªã³ã«ããããšãæå³ããŸãã ããã¯ãã®åå©ã§ãã-以åãMKãšè©±ãããã«ãã€ã³ã¿ãŒãããã§èŠã€ããããªãã£ãã©ã€ãã©ãªããŒãããæžããããã«ãªã·ãã¹ã³ãŒããªãã§2床ç®ã«åäœããããã«ããŸããã ç§ã®åã³ã¯ééããããŸããã
幞çŠæããå°ãé¢ããŠãæ°ãããã©ã¡ãŒã¿ãŒãèªã¿åãå¿ èŠããããã³ã«ã³ã³ãããŒã©ãŒããã©ãã·ã¥ããïŒãµã€ã¯ã«å ã®ãã¹ããã¡ãŒã ãŠã§ã¢ãåããã©ã¡ãŒã¿ãŒã1ç§ã«1åèªã¿åãïŒããšã¯ããããããŠãŒã¶ãŒãã¬ã³ããªãŒã§ã¯ãªããããç¶è¡ããå¿ èŠãããããšã«æ°ä»ããŸããã
ãã©ã¡ãŒã¿å€ãååŸããæ¹æ³ãåŠã³ãŸããããã®åœ¢åŒã§ã®ã¿ããµãŒã¢ã¹ã¿ããã§ã¯ãªãããªã¢ãŒããã£ã¹ãã¬ã€ã§ãã ãããå¿ èŠãªãã®ã«ãªãããã«ã¯ããã€ã©ãŒãå¶åŸ¡ããæ¹æ³ãåŠã¶å¿ èŠããããããã§ãç§ã¯é©ããåŸ ã£ãŠããŸããã
OpenThermã®ãããã°ãšæäœ
ãããã£ãŠãæåã®å€-ãã€ã©ãŒã®ã¹ããŒã¿ã¹-ãåä¿¡ãããŸãã ããã«ç§ãæ··ä¹±ãããã®ã¯ããã€ã©ãŒããã«ã®èšå®ã«é¢ä¿ãªãããã€ã¯ãã³ã³ãããŒã©ãŒãæ¥ç¶ãããšãã®æž©æ°Žæž©åºŠãããã«æ倧蚱容å€ã«ãªã£ãããšã§ãããã¡ãŒã«ãŒïŒFerolli Romeo WïŒã®æšæºOTãµãŒã¢ã¹ã¿ããã®ããã¥ã¢ã«ãåŸã§èªãã ãšãïŒæ¥ç¶ãããšããã³ãã«ã®ã¿ãæ©èœããŸã察å¿ããæ©èœãæå¹/ç¡å¹ã«ããä»ã«ã¯åœ±é¿ããŸããã DHW枩床ãã©ã¡ãŒã¿ãŒã®å€ã¯OTæ¥ç¶åãšåããŸãŸã§ãããšä»®å®ããããšã¯è«ççã§ããããHoneywellããã°ã©ããŒïŒããŒãã®è£œé å ãšãã€ã©ãŒã®èªååã®æ®ãã®éšåïŒã¯ãã®åé¡ã«ã€ããŠç¬èªã®æèŠãæã£ãŠããŸãã
ãã€ã©ãŒãå¶åŸ¡ããããã»ã¹ã¯ãæ£ããã¡ãã»ãŒãžã®ã·ãŒã±ã³ã¹ãèŠãããã«æã«ãµãŒã¢ã¹ã¿ãããæã£ãŠããªãã£ããšããäºå®ã«ãã£ãŠè€éã«ãªã£ããããç®é ãã«äŒŒãŠããŸããã ä»æ§ã§ã¯ãæããã«ã絊湯ã®æž©åºŠã«é¢äžããŠããDHWã»ãããã€ã³ããã©ã¡ãŒã¿ãŒãèŠã€ãããŸããïŒä»¥äžãæ¬åŒ§å ã«åŒã³åºããããã©ã¡ãŒã¿ãŒã®DATA-IDããã®å Žåã¯56ã瀺ããŸãïŒã æ®åœ±äžãç¹æ» äž-ãã¿ã³ãã¯ãªãã¯ãããšãåžæã®æž©åºŠãéä¿¡ãããŸããã 確èªããŠãã ããã æ°Žæž©ã¯ããã«æ£åžžã«ãªããŸãããCHSetpointïŒ1ïŒ-å ç±åè·¯ã®æž©åºŠ-ãã¹ãŠãéå§ããã調æŽãéå§ããŸãã ããã§ç§ã¯3æ¥éãé·ãéç«ã¡åŸçããŠããŸãã ã©ã®ããã«è©ŠããŠããå¿ èŠãªæž©åºŠãäœã§ãã£ãŠãããã€ã©ãŒã¯ãããçŽ30床ã«ä¿ã¡ãŸããã 補é æ¥è ã¯ä»ã®äººã®ãµãŒã¢ã¹ã¿ããã®æ¥ç¶ããèªåèªèº«ãä¿è·ãããšããèãããã§ã«æã£ãŠããŸãã-å¯äžã®æãããªæ±ºå®ã¯ããã€ã©ãŒããã¡ã³ããŒIDãååŸãïŒ3ïŒåãçããããããšã§ããïŒ2ïŒã ãããŠãããå©ãã«ã¯ãªãããå人ã«ç¶æ³ãç°¡åã«æŠèª¬ãã圌ã¯ä»®å®ãæã£ãŠããŸããïŒ
-ãããã³ããŒããã¹ã¿ãŒïŒãµãŒã¢ã¹ã¿ããïŒããã€ã¹ãšã¹ã¬ãŒãïŒãã€ã©ãŒïŒããã€ã¹ã«ç°ãªãã¡ã³ããŒIDã䜿çšããŠããå Žåã¯ã©ãã§ããããã ãã€ã©ãŒã®èªååãå¥ã®ãã€ã©ãŒã«ãã£ãŠå¶åŸ¡ãããŠããããšã«æ°ä»ãããšãã«ããã€ã©ãŒã®èªååãã©ã®ããã«é©ãããæ°ããŸãã
ãããããã¹ãŠãã¯ããã«åçŽã§ããããšãå€æããŸããã ãã©ã¡ãŒã¿Max CH SetpointïŒ57ïŒ-å ç±åè·¯ã®æé«æž©åºŠã«ãããŸããã DHWåç·ã§ã®ã€ãã³ãã®åŸãæ倧å€ããããšä»®å®ããããšã¯è«ççã§ãããããããã30床ã®å€ãããã«èšå®ãããŸããã ãã®åŸãç©äºã¯èãã楜ãããªããŸããã
ãããããµãŒã¢ã¹ã¿ããèªäœã®ç©èªã®å§ãŸãã§ãã
ãµãŒã¢ã¹ã¿ãã
æããã«ããã€ã©ãŒã®ãã©ã¡ãŒã¿ãŒã倧éã«æäŸããããããå€æŽã§ããå¿ èŠããããŸããããããªããšãå¥ã®ãµãŒã¢ã¹ã¿ãããäœæããŠãæå³ããããŸããã ãã§ã«è¿°ã¹ãããã«ãåãªã¯ãšã¹ãã¯ããã1ç§ã«1åéä¿¡ããå¿ èŠããããŸããæãè«ççãªã®ã¯ããµã€ã¯ã«ããšã«1ã€ã®ç¶æ ããå¥ã®ç¶æ ã«ç§»è¡ããæéç¶æ ãã·ã³ãèšè¿°ããããšã§ããã æçµçã«ããªãŒãããã³ã®ãã©ã³ãã¯æ¬¡ã®ããã«ãªããŸãã3
1.ãã€ã©ãŒã®çŸåšã®ç¶æ ã枩床ãããã³å€èª¿ã¬ãã«ã調æ»ãããäœæ¥ãã©ã³ãã ã€ãŸãã次ã®ããã«è¡šãããšãã§ããŸãã
2.æ å ±ããã³ãã€ã©ãŒåå²ïŒè¿œå ã®æž©åºŠã»ã³ãµãŒãæµéã»ã³ãµãŒãªã©ã [æ å ±]ã¡ãã¥ãŒãçµäºãããšãæåã®ãã©ã³ãã«æ»ããŸãã
3.çµ±èšã®ãã©ã³ãïŒããŒããŒã®çšŒåæéããã¡ã³/ãã³ãã®å§ååæ°ãªã©ã çµäºæã段èœ2ãšåãã
ãã©ã¡ãŒã¿ãŒãªãã®updateïŒïŒé¢æ°ã®åŒã³åºãã¯ããã®ãã¹ãŠã®äœæ¥ãæ åœããŸãã 1ç§éã«çŽ1ååŒã³åºãã ãã§ååã§ãã 圌女ã¯åã®ãªã¯ãšã¹ãã®çµæãåãåããããã«åºã¥ããŠæ°ãããªã¯ãšã¹ããéä¿¡ããŸãã ãã©ã³ããåãæ¿ããã«ã¯ãç®çã®ãã©ã³ãã®æåã®ãã©ã¡ãŒã¿ãŒã«çãããã©ã¡ãŒã¿ãŒã§é¢æ°ãåŒã³åºãå¿ èŠããããŸãã ããšãã°ãæŽæ°ïŒ0ïŒã¯ã¡ã€ã³ãã©ã³ãïŒ0-ãã€ã©ãŒã¹ããŒã¿ã¹ã®èŠæ±ïŒãæŽæ°ïŒ18ïŒ-ãã©ã¡ãŒã¿ãŒ18ïŒå ç±åè·¯ã®å§åã®èŠæ±ïŒã§å§ãŸã2çªç®ã®ãã©ã³ãããã©ã³ã3-ãã©ã¡ãŒã¿ãŒ116ïŒããŒããŒã®éå§æ°ïŒã«é²ã¿ãŸãã
ä»ã®åŒæ°å€ããããŸãã
1-å ç±åè·¯ã®æ°ãã枩床ãèšé²ããŸãã
56-DHWåè·¯ã®æ°ãã枩床ãªã©ãèšé²ããŸãã
å¯èœãªãã¹ãŠã®åŒæ°ã¯ãæŽæ°é¢æ°ã®æåŸã«è¡šç€ºãããŸãã
ããã§ããã¹ãŠã®å¿ èŠãªãã©ã¡ãŒã¿ãååŸãããŸããããè»èã«ããšããããŸãã-èŠããŠãããŠãç§ã¯ããŒãã«ã®åŸã«æžãã-ãã€ã©ãŒã¡ãŒã«ãŒã®ãªã¯ãšã¹ãã§ä»ã®ãã¹ãŠã®ãã©ã¡ãŒã¿ïŒ ã ãã-ãããã®ååã¯ç§ã®ãã€ã©ãŒã§ãŒãã§ãããååã¯ãŸã£ããç¥ãããŠããªãã å°ãªããšã誰ãã«åœ¹ç«ã€ãããããªããã圌ã¯ç¡é§ã«ããæžããŠããªãã
æãæ¥åžžçã§éå±ãªè·æ¥ã¯ãæããã«ã¡ãã¥ãŒãæžãããšã§ããã çŽæã©ããããµãŒã¢ã¹ã¿ããèªäœã«ã€ããŠã¯è©³ãã説æããŸããããã¹ãŠã¯æçµãã¡ãŒã ãŠã§ã¢ã§èŠãããšãã§ããŸã
ãã®èšäºã®å·çäžã«æåŸã«è¿œå ããã®ã¯ããããããã®æåããå«ãéå±ãªç»é¢ã§ã¯ãªããã°ã©ãã£ãã¯ãã£ã¹ãã¬ã€ïŒã¢ãã«ã«äŒŒããã®-ãããªWïŒã®ããã«èŠããŸããã ããŠãæèš-ã¢ããŒãã«ã¯ãããã®å€ãã¯ãªããRTC DS323xã ããæ¬ èœããŠããŸã-é»æºãåããšãæéãåèšå®ããå¿ èŠããããŸãã ãããè¡ãã«ã¯ãããã€ãã®æåãæåã§æç»ãããã©ã³ãã«è¿œå ããå¿ èŠããããŸããã çµæã¯ããããŒã®äžã®åçã§ç¢ºèªã§ããŸãã
ã¹ã±ãã
#include <OpenTherm.h> #include <LCD5110_Basic.h> #include <OneWire.h> #include <dht.h> #include <dallastemp.h> #include <avr/eeprom.h> //#include <Power.h> #define DHT22_PIN 14 #define LCD_IDLE 0 #define LCD_MAIN 1 #define LCD_MENU 2 #define LCD_CONFIG_1 11 #define LCD_CONFIG_2 12 #define LCD_CONFIG_3 13 #define LCD_INFO_1 21 #define LCD_INFO_2 22 #define LCD_STATISTICS_1 31 #define LCD_STATISTICS_2 32 #define LCD_ITEM_MODE 1 #define LCD_ITEM_CH_EN 2 #define LCD_ITEM_DHW_EN 3 #define LCD_ITEM_CH_MAX 4 #define LCD_ITEM_CH 5 #define LCD_ITEM_DHW 6 #define LCD_ITEM_ROOM 7 #define LCD_ITEM_BRIGH 8 #define LCD_ITEM_ACTIVE 9 #define LCD_ITEM_MAX_MODULATION 10 #define LCD_ITEM_DAYS 11 #define LCD_ITEM_HOURS 12 #define LCD_ITEM_MINUTES 13 #define LCD_ITEM_KP 14 #define LCD_ITEM_KI 15 dht internal_s; OneWire ow(A1); Dallastemp external_s(&ow); OpenTherm ot(8,7); LCD5110 lcd(13,11,10,12,0); //Power sleep; extern uint8_t SmallFont[]; extern uint8_t MediumNumbers[]; extern uint8_t BigNumbers[]; //Encoder handling volatile uint32_t ts_enc=0; volatile int8_t encoder=0; //Clock handling uint32_t clock_ts=0,clock_delta=0; uint8_t hour=0,minute=0,second=0,day=0; //Menu Handling uint8_t menu,item; int8_t pos=0; const char* day_names[7]={"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}; const char* mode_names[2]={"Manual","Auto"}; //Misc uint8_t display_enabled,cfg_enabled,button1=0,button2=0,item_tmp=0,update_period=0; float iSum; struct thermostat_config{ uint8_t address[8]; ot_init_settings ot_settings; float indoor_target_temp; uint8_t active_time; uint8_t brightness; uint8_t mode; uint8_t Kp; uint8_t Ki; uint8_t reserved[8]; }; //thermostat_config settings={{0x28,0xFF,0x53,0x76,0x60,0x14,0x02,0xFC},{1,1,70,30.0,40},22.0,30,130,1}; thermostat_config settings; /* ISR(INT0_vect){ ot.extIntHandler(); } */ ISR(PCINT0_vect){ ot.extIntHandler(); } ISR(PCINT1_vect){ ot.extIntHandler(); } ISR(PCINT2_vect){ ot.extIntHandler(); } ISR(TIMER2_COMPA_vect){ ot.timer2CompAHandler(); } ISR(TIMER2_COMPB_vect){ ot.timer2CompBHandler(); } ISR(WDT_vect) { // sleep.watchdogEvent(); } ISR(INT1_vect){ display_enabled=settings.active_time; OCR1A=settings.brightness; if((millis()-ts_enc >20) && cfg_enabled) { ts_enc=millis(); if ((PIND&bit(4))) { encoder++; } else { encoder--; } } } void fade_display(){ for(uint8_t i=settings.brightness;i>10;i-=10){ OCR1A=i; delay(20); } OCR1A=0; } void enc_setup(){ cli(); DDRD&=~(bit(3)|bit(4)); //set A and B to input EIMSK|=bit(INT1); EICRA|=bit(ISC11); EICRA&=~bit(ISC10); EIFR|=bit(INTF1); sei(); } void button_setup(){ DDRC&=~(bit(2)|bit(3)); } void read_config(){ eeprom_read_block(&settings, 0, sizeof(thermostat_config)); } void write_config(){ eeprom_write_block(&settings, 0, sizeof(thermostat_config)); } void lcd_idle(){ char mod_lev[2]={'\0','\0'}; lcd.setFont(BigNumbers); lcd.print(":",24,0); lcd.print(";",0,24);//";" - thermometer icon lcd.print("0",0,0); lcd.print("0",34,0); lcd.print("<=>",42,24);//"<=>" - House icon lcd.printNumI(hour,(hour>9)?0:14,0); lcd.printNumI(minute,(minute>9)?34:48,0); lcd.setFont(SmallFont); lcd.print(day_names[day],62,16); lcd.printNumF(internal_s.temperature,1,60,40); switch(ot.status&0x7){ case OT_STATUS_CH: lcd.print(">",78,32); break; case OT_STATUS_DHW: lcd.print("=",78,32); break; case OT_STATUS_FAULT: lcd.print("?@",72,32); break; }; if (ot.status&0x8){ if (ot.modulation < 34) *mod_lev='^'; else if (ot.modulation < 67) *mod_lev='_'; else *mod_lev='`'; lcd.print(mod_lev,72,32); } lcd.setFont(MediumNumbers); lcd.printNumF(external_s.getTemp(settings.address),0,6,32); lcd.printNumI(internal_s.temperature,48,32); } void lcd_main(){ lcd.print("Room: /",LEFT,0); lcd.printNumF(internal_s.temperature,1,30,0); if (settings.mode) lcd.printNumF(settings.indoor_target_temp,1,60,0); else lcd.print(" ",54,0); lcd.print("Hum: \%",LEFT,8); lcd.printNumF(internal_s.humidity,1,24,8); lcd.print("Outdoor:",LEFT,16); lcd.printNumF(external_s.getTemp(settings.address),1,48,16); lcd.print("Heat: /",LEFT,24); lcd.printNumF(ot.CH,1,30,24); lcd.printNumF(settings.ot_settings.CH_temp,1,60,24); lcd.print("DHW: /",LEFT,32); lcd.printNumF(ot.DHW,1,24,32); lcd.printNumF(ot.target_DHW,1,54,32); switch(ot.status&0x7){ case OT_STATUS_CH: lcd.print("CH ",LEFT,40); break; case OT_STATUS_DHW: lcd.print("DHW ",LEFT,40); break; case OT_STATUS_FAULT: lcd.print("FAULT:",LEFT,40); switch(ot.fault&0x3D){ case OT_FAULT_SERVICE: lcd.print("FAULT:SERV REQ",LEFT,40); break; case OT_FAULT_LOW_WATER: lcd.print("FAULT:NO WATER",LEFT,40); break; case OT_FAULT_GAS: lcd.print("FAULT:NO FLAME",LEFT,40); break; case OT_FAULT_AIR_PRESSURE: lcd.print("FAULT:AIR PRES",LEFT,40); break; case OT_FAULT_WATER_OV_TEMP: lcd.print("FAULT:WATER OT",LEFT,40); break; } break; default: lcd.print(" ",LEFT,40); break; }; if (ot.status&0x8) { lcd.print("Flame: %",24,40); lcd.printNumI(ot.modulation,60,40); } } void lcd_menu(){ lcd.print(" 1)Config",LEFT,0); lcd.print(" 2)Info",LEFT,8); lcd.print(" 3)Stats",LEFT,16); } void lcd_config_1(){ lcd.print(" Mode:",LEFT,0); lcd.print(mode_names[(item==LCD_ITEM_MODE)?item_tmp:settings.mode],RIGHT,0); lcd.print(" CH enabled:",LEFT,8); lcd.printNumI((item==LCD_ITEM_CH_EN)?item_tmp:ot.CH_enabled,RIGHT,8); lcd.print(" DHW enabled:",LEFT,16); lcd.printNumI((item==LCD_ITEM_DHW_EN)?item_tmp:ot.DHW_enabled,RIGHT,16); lcd.print(" CH max t:",LEFT,24); lcd.printNumI((item==LCD_ITEM_CH_MAX)?item_tmp:ot.CH_max,RIGHT,24); lcd.print(" CH temp:",LEFT,32); lcd.printNumI((item==LCD_ITEM_CH)?item_tmp:ot.target_CH,RIGHT,32); lcd.print(" DHW temp:",LEFT,40); lcd.printNumI((item==LCD_ITEM_DHW)?item_tmp:ot.target_DHW,RIGHT,40); } void lcd_config_2(){ lcd.print(" Room temp:",LEFT,0); lcd.printNumF((item==LCD_ITEM_ROOM)?(float)item_tmp/10+10:settings.indoor_target_temp,1,RIGHT,0); lcd.print(" Brightness:",LEFT,8); lcd.printNumI((item==LCD_ITEM_BRIGH)?item_tmp:settings.brightness,RIGHT,8); lcd.print(" Light time:",LEFT,16); lcd.printNumI((item==LCD_ITEM_ACTIVE)?item_tmp:settings.active_time,RIGHT,16); lcd.print(" Max modul:",LEFT,24); lcd.printNumI((item==LCD_ITEM_MAX_MODULATION)?item_tmp:settings.ot_settings.max_modulation,RIGHT,24); lcd.print(" Days:",LEFT,32); lcd.print(day_names[(item==LCD_ITEM_DAYS)?item_tmp:day],RIGHT,32); lcd.print(" Hours:",LEFT,40); lcd.printNumI((item==LCD_ITEM_HOURS)?item_tmp:hour,RIGHT,40); } void lcd_config_3(){ lcd.print(" Minutes",LEFT,0); lcd.printNumI((item==LCD_ITEM_MINUTES)?item_tmp:minute,RIGHT,0); lcd.print(" Kp",LEFT,8); lcd.printNumI((item==LCD_ITEM_KP)?item_tmp:settings.Kp,RIGHT,8); lcd.print(" Ki",LEFT,16); lcd.printNumI((item==LCD_ITEM_KI)?item_tmp:settings.Ki,RIGHT,16); } void lcd_info_1(){ lcd.print(" CH press:",LEFT,0); lcd.printNumF(ot.CH_water_pressure,1,RIGHT,0); lcd.print(" DHW flow:",LEFT,8); lcd.printNumF(ot.DHW_flow,1,RIGHT,8); lcd.print(" Ret.temp:",LEFT,16); lcd.printNumF(ot.CH_return_temp,1,RIGHT,16); lcd.print(" Max cap.:",LEFT,24); lcd.printNumI(ot.max_capacity,RIGHT,24); lcd.print(" Min mod.:",LEFT,32); lcd.printNumI(ot.min_modulation,RIGHT,32); lcd.print(" DHW min lim:",LEFT,40); lcd.printNumI(ot.DHW_min_lim,RIGHT,40); } void lcd_info_2(){ lcd.print(" DHW lim:",LEFT,0); lcd.printNumI(ot.DHW_max_lim,RIGHT,0); lcd.print(" CH lim:",LEFT,8); lcd.printNumI(ot.CH_min_lim,RIGHT,8); lcd.print(" CH lim:",LEFT,16); lcd.printNumI(ot.CH_max_lim,RIGHT,16); lcd.print(" Int.Sum.:",LEFT,24); lcd.printNumF(iSum,1,RIGHT,24); } void lcd_stats_1(){ lcd.print(" Burn.st:",LEFT,0); lcd.printNumI(ot.burner_starts,RIGHT,0); lcd.print(" CH pump:",LEFT,8); lcd.printNumI(ot.CH_pump_starts,RIGHT,8); lcd.print(" DHW p/v:",LEFT,16); lcd.printNumI(ot.DHW_pump_starts,RIGHT,16); lcd.print(" DHW bur:",LEFT,24); lcd.printNumI(ot.DHW_burner_starts,RIGHT,24); lcd.print(" B.hours:",LEFT,32); lcd.printNumI(ot.burner_op_hours,RIGHT,32); lcd.print(" CHpump H",LEFT,40); lcd.printNumI(ot.CH_pump_op_hours,RIGHT,40); } void lcd_stats_2(){ lcd.print(" DHWp/v H",LEFT,0); lcd.printNumI(ot.DHW_pump_op_hours,RIGHT,0); lcd.print(" DHWburn H",LEFT,8); lcd.printNumI(ot.DHW_burner_op_hours,RIGHT,8); } void update_clock(){ uint32_t tmp=millis()-clock_ts; clock_delta+=(tmp>0)?tmp:0; clock_ts=millis(); while (clock_delta >= 1000){ second++; clock_delta-=1000; if (second > 59){ second=0; minute++; if (minute > 59){ minute=0; hour++; if (hour > 23){ hour=0; day++; if (day>6) day=0; } } } } } void update_display(){ lcd.clrScr(); lcd.setFont(SmallFont); if (menu != LCD_MAIN && menu != LCD_IDLE) { if (pos>5){ pos=0; switch(menu){ case LCD_INFO_1: menu=LCD_INFO_2; break; case LCD_STATISTICS_1: menu=LCD_STATISTICS_2; break; case LCD_CONFIG_1: menu=LCD_CONFIG_2; break; case LCD_CONFIG_2: menu=LCD_CONFIG_3; break; default: pos=5; } } if (pos<0){ pos=5; switch(menu){ case LCD_INFO_2: menu=LCD_INFO_1; break; case LCD_STATISTICS_2: menu=LCD_STATISTICS_1; break; case LCD_CONFIG_2: menu=LCD_CONFIG_1; break; case LCD_CONFIG_3: menu=LCD_CONFIG_2; break; default: pos=0; } } }; switch(menu){ case LCD_IDLE: lcd_idle(); break; case LCD_MAIN: lcd_main(); break; case LCD_MENU: lcd_menu(); break; case LCD_CONFIG_1: lcd_config_1(); break; case LCD_CONFIG_2: lcd_config_2(); break; case LCD_CONFIG_3: lcd_config_3(); break; case LCD_INFO_1: lcd_info_1(); break; case LCD_INFO_2: lcd_info_2(); break; case LCD_STATISTICS_1: lcd_stats_1(); break; case LCD_STATISTICS_2: lcd_stats_2(); break; }; if (menu != LCD_IDLE && menu != LCD_MAIN) if(! item) lcd.print("\\",LEFT,pos*8); else lcd.print("*",LEFT,pos*8); } void setup(){ lcd.InitLCD(); lcd.setFont(SmallFont); lcd.clrScr(); enc_setup(); button_setup(); read_config(); //sleep.measure_wdt(1); // external_s.setRes(settings.address,TEMP_11_BIT); // external_s.startConv(settings.address); analogWrite(9,settings.brightness); display_enabled=settings.active_time; lcd.print("OT init.",CENTER,16); ot.begin(&settings.ot_settings); //sleep.measure_wdt(0); lcd.clrScr(); lcd.print("Slave OT ver.:",CENTER,0); lcd.printNumF(ot.slave_ver,1,CENTER,8); lcd.print("Slave Memb. ID:",CENTER,16); lcd.printNumI(ot.member_id,CENTER,24); lcd.print("Slave CFG:",CENTER,32); lcd.printNumI(ot.sl_cfg,CENTER,40); } void loop(){ //DEBUG //uint8_t type=0,id=0; //uint16_t data=0; float ext_temp,int_temp,t_error; if (!update_period) { internal_s.read22(DHT22_PIN); external_s.startConv(settings.address); } if(display_enabled){ OCR1A=settings.brightness; if(! --display_enabled) { fade_display(); cfg_enabled=0; menu=LCD_IDLE; item=0; delay(1000); ot.update(0); //main thread update_display(); } } if (cfg_enabled) delay (100); else delay(1000); //sleep 1s here // else sleep.sleep(); if (cfg_enabled || !update_period) { update_display(); } if ( (PINC&bit(2)) && button1) button1=0; //if button released reset state if ( (PINC&bit(3)) && button2) button2=0; //Esc if (! (PINC&bit(2)) && ! button1) { button1=1; display_enabled=settings.active_time; OCR1A=settings.brightness; cfg_enabled=1; switch(menu){ case LCD_IDLE: menu=LCD_MAIN; break; case LCD_MAIN: if ((ot.status&0x7) == OT_STATUS_FAULT) { delay(1000); ot.communicate(1,4,256); } break; case LCD_MENU: menu=LCD_MAIN; break; case LCD_CONFIG_1: case LCD_CONFIG_2: case LCD_CONFIG_3: if(! item) menu=LCD_MENU; else item=0; break; default: menu=LCD_MENU; break; }; pos=0; } //Enter if (! (PINC&bit(3)) && ! button2) { button2=1; display_enabled=settings.active_time; OCR1A=settings.brightness; cfg_enabled=1; if (! item){ //standart menu navigation switch(menu){ case LCD_IDLE: case LCD_MAIN: menu=LCD_MENU; break; case LCD_MENU: switch(pos){ case 0: menu=LCD_CONFIG_1; break; case 1: menu=LCD_INFO_1; delay(1000); ot.update(18); //start to get info break; case 2: menu=LCD_STATISTICS_1; delay(1000); ot.update(116); //start to get stats break; } break; case LCD_CONFIG_1: if (!item) item=pos+1; case LCD_CONFIG_2: if (!item) item=pos+7; case LCD_CONFIG_3: if (!item) item=pos+13; switch(item){ case LCD_ITEM_MODE: item_tmp=settings.mode; break; case LCD_ITEM_CH_EN: item_tmp=ot.CH_enabled; break; case LCD_ITEM_DHW_EN: item_tmp=ot.DHW_enabled; break; case LCD_ITEM_CH_MAX: item_tmp=ot.CH_max; break; case LCD_ITEM_CH: item_tmp=settings.ot_settings.CH_temp; break; case LCD_ITEM_DHW: item_tmp=ot.target_DHW; break; case LCD_ITEM_ROOM: item_tmp=(uint8_t)(settings.indoor_target_temp*10 - 100); break; case LCD_ITEM_BRIGH: item_tmp=settings.brightness; break; case LCD_ITEM_ACTIVE: item_tmp=settings.active_time; break; case LCD_ITEM_MAX_MODULATION: item_tmp=settings.ot_settings.max_modulation; break; case LCD_ITEM_DAYS: item_tmp=day; break; case LCD_ITEM_HOURS: item_tmp=hour; break; case LCD_ITEM_MINUTES: item_tmp=minute; break; case LCD_ITEM_KP: item_tmp=settings.Kp; break; case LCD_ITEM_KI: item_tmp=settings.Ki; break; } break; case LCD_INFO_1: break; case LCD_INFO_2: break; }; if (!item) pos=0; } else { //item save switch(item){ case LCD_ITEM_MODE: settings.mode=item_tmp; break; case LCD_ITEM_CH_EN: ot.CH_enabled=item_tmp; settings.ot_settings.CH_enabled=item_tmp; break; case LCD_ITEM_DHW_EN: ot.DHW_enabled=item_tmp; settings.ot_settings.DHW_enabled=item_tmp; break; case LCD_ITEM_CH_MAX: ot.CH_max=item_tmp; settings.ot_settings.CH_max_temp=item_tmp; delay(1000); ot.update(57); break; case LCD_ITEM_CH: settings.ot_settings.CH_temp=item_tmp; ot.target_CH=item_tmp; delay(1000); ot.update(1); break; case LCD_ITEM_DHW: ot.target_DHW=item_tmp; settings.ot_settings.DHW_temp=item_tmp; delay(1000); ot.update(56); break; case LCD_ITEM_ROOM: settings.indoor_target_temp=(float)item_tmp/10+10.0; break; case LCD_ITEM_BRIGH: settings.brightness=item_tmp; break; case LCD_ITEM_ACTIVE: settings.active_time=item_tmp; break; case LCD_ITEM_MAX_MODULATION: ot.max_modulation=item_tmp; settings.ot_settings.max_modulation=item_tmp; delay(1000); ot.update(14); break; case LCD_ITEM_DAYS: day=item_tmp; break; case LCD_ITEM_HOURS: hour=item_tmp; break; case LCD_ITEM_MINUTES: minute=item_tmp; break; case LCD_ITEM_KP: settings.Kp=item_tmp; break; case LCD_ITEM_KI: settings.Ki=item_tmp; break; } write_config(); item_tmp=0; item=0; } } /* ot.complete(&type,&id,&data); lcd.setFont(SmallFont); lcd.print(" / /",LEFT,40); lcd.printNumI(type,0,40); lcd.printNumI(id,12,40); lcd.printNumI(data,36,40); //debug */ if (encoder !=0 ) { if (menu != LCD_MAIN) if(!item) pos=constrain(pos+encoder,-1,6); else switch (item){ case LCD_ITEM_MODE: item_tmp=constrain(item_tmp+encoder,0,1); break; case LCD_ITEM_CH_EN: item_tmp=constrain(item_tmp+encoder,0,1); break; case LCD_ITEM_DHW_EN: item_tmp=constrain(item_tmp+encoder,0,1); break; case LCD_ITEM_CH_MAX: item_tmp=constrain(item_tmp+encoder,ot.CH_min_lim,ot.CH_max_lim); break; case LCD_ITEM_CH: item_tmp=constrain(item_tmp+encoder,ot.CH_min_lim,ot.CH_max_lim); break; case LCD_ITEM_DHW: item_tmp=constrain(item_tmp+encoder,ot.DHW_min_lim,ot.DHW_max_lim); break; case LCD_ITEM_ROOM: item_tmp=constrain(item_tmp+encoder,50,180); break; case LCD_ITEM_BRIGH: item_tmp=constrain(item_tmp+encoder*10,0,255); break; case LCD_ITEM_ACTIVE: item_tmp=constrain(item_tmp+encoder,10,100); break; case LCD_ITEM_MAX_MODULATION: item_tmp=constrain(item_tmp+encoder,10,100); break; case LCD_ITEM_DAYS: item_tmp=constrain(item_tmp+encoder,0,6); break; case LCD_ITEM_HOURS: item_tmp=constrain(item_tmp+encoder,0,23); break; case LCD_ITEM_MINUTES: item_tmp=constrain(item_tmp+encoder,0,59); break; case LCD_ITEM_KP: case LCD_ITEM_KI: item_tmp=constrain(item_tmp+encoder,0,255); break; item_tmp=constrain(item_tmp+encoder,0,255); break; } else if (settings.mode) settings.indoor_target_temp=constrain(settings.indoor_target_temp+encoder*0.1,15.0,28.0); else settings.ot_settings.CH_temp+=encoder*0.1; encoder=0; }; if (menu == LCD_IDLE && ! cfg_enabled && !update_period--) { update_period=60; update_clock(); int_temp=internal_s.temperature; ext_temp=external_s.getTemp(settings.address); t_error=settings.indoor_target_temp-int_temp; iSum=constrain(iSum+t_error,-ot.CH_max_lim,ot.CH_max_lim); if (settings.mode) settings.ot_settings.CH_temp=1*(20.0 + (settings.indoor_target_temp-ext_temp)) + settings.Kp*t_error + settings.Ki*iSum/256; if (settings.ot_settings.CH_temp < ot.CH_min_lim) ot.CH_enabled=0; else ot.CH_enabled = 1; settings.ot_settings.CH_temp=constrain(settings.ot_settings.CH_temp,ot.CH_min_lim,ot.CH_max_lim); if ((!settings.mode && ot.target_CH != settings.ot_settings.CH_temp ) || (settings.mode && abs(ot.target_CH - settings.ot_settings.CH_temp) > 0.5)){ ot.target_CH=settings.ot_settings.CH_temp; // delay(1000); ot.update(1); return; } } ot.update(); }
é·ãéãç§ã¯ãPIã¬ã®ã¥ã¬ãŒã¿ãŒã«ãªãããšãå€æãããŸã§ãå·åŽå€ã®å¿ èŠãªæž©åºŠãèšç®ããåŒãå€ããŠããŸãããèšå®ã§ã¯ãä¿æ°ã®å€æŽãšç©åæåã®è¡šç€ºãè¿œå ããŸããã PIã³ã³ãããŒã©ãŒèªäœã®åã«ãå¿ èŠãªæž©åºŠãèšç®ããããã«ãæåã®èšäºããåŒãåããŸããããç©åæåããªããšã枩床ã¯å¿ èŠãªãã®ã«å¯Ÿå¿ããªãã£ããã倧ããªæ¯äŸä¿æ°ã§å¿ èŠãªãã®ã«å¯Ÿå¿ãããååŸã«ãžã£ã³ãããŸãããããããHabrãèªããšãå®è£ ãããPIDã³ã³ãããŒã©ãŒã®èª¬æãžã®ãªã³ã¯ãããã«ããããŸããã
äžè¬ã«ã2ã€ã®åäœã¢ãŒããäœæããŸãã
ã1ïŒCHã»ãããã€ã³ãã®çŽæ¥å¶åŸ¡-çµæã¯ãã€ã©ãŒã®ãªã¢ãŒãããã³ãããã«ã«ãããŸããïŒããã«ãå€éš/å éšã®æž©åºŠãšæ¹¿åºŠã衚瀺ãããŸãïŒã
2ïŒå®éã«OTCãåãããµãŒã¢ã¹ã¿ããã
ãããããOTCã»ã³ãµãŒããªãã«ããŠæ²ç·ã®åŸãã調æŽããããšãè¿œå ããŸãïŒä¿æ°ïŒïŒsettings.indoor_target_temp-ext_tempïŒã§ïŒïŒãããã®ç¹ã¯ãŸã ããããŸããã
OTCã»ã³ãµãŒã®é 眮ã«ã€ããŠå°ã説æããŸããç§ã¯çªãå£ã«ç©ŽãéããããããŸããã§ãããããã®åé¡ãèãããšã誀ã£ãŠMIDIã³ãã¯ã¿ãŒã®å€ãã«ãŒãã«ç®ãåããŸãããèãçŽããã«ãã»ã³ãµãŒã¯ã€ã€ãŒãã¯ãã ä»ããããããã¡ã«ãæ¥çå€ã§æ¥ç¶ãå¯å°ããŸããïŒè·¯äžã«ããããïŒãçŽå°æ¥å ã«ãã£ãŠå ç±ãããªãããã«ãã»ã³ãµãŒèªäœããšã¢ã³ã³ã®å€éšãŠãããã®åŸãã®æ¥é°ã«èšçœ®ããŸããã
OTCã€ã³ã¹ããŒã«
çãšã
ã³ãŒããããå°ã泚ææ·±ãèŠãŠãã人ã¯ãããããæªç¥ã®Powerã©ã€ãã©ãªã«æ°ã¥ããã§ããããå®éãããã€ã¹å šäœã®ãšãã«ã®ãŒæ¶è²»ãåæžããããšãæåŸ ããŠããŸããããã€ã³ãã¯ãã¡ã€ã³ã«ãŒãã®é 延ïŒ1000ïŒã§ã¯ãªããMKã1ç§éã¹ãªãŒãç¶æ ã«ããããšã§ããåé¡ã¯ãTimer2ãå®è¡ããŠOpenThermã¡ãã»ãŒãžãéåä¿¡ããããã®ç¹å®ã®ã¹ãªãŒãã¢ãŒããå¿ èŠãªããšã§ããèŠããŠããããã«ããããã¯éåæã«çºçããŸããããããæ®å¿µãªãããProteusã¯Sleepã§ã¯ããŸãæ©èœããããã®éšåããããã°ã§ããŸããã§ãããã¹ãªãŒãã¯æ©èœããŠãããããªç§ïŒïŒã®èªã¿åãå€ã¯ä¿®æ£ãããŠããŸãïŒãã®ããããŠã©ããããã°ã¿ã€ããŒã®ç²ŸåºŠã®æž¬å®ãå®è£ ããŸããïŒããOTã¯æ©èœããªããªããŸãããã®ç®çã®ããã«ãPro Miniãè³Œå ¥ããŸããïŒãã®åŸãã¹ã¿ãã©ã€ã¶ãŒãšLEDãåãå€ããŸããïŒ-ããå°ããªããŒã+ 3.3Vã®åäœãå¯èœã§ããããã«ãããOTã€ã³ã¿ãŒãã§ãŒã¹ããçŽæ¥é»æºãäŸçµŠã§ããŸãã Powerã©ã€ãã©ãªã³ãŒããæã¡èŸŒã¿ãèå³ããã人ã®ããã«ïŒ
Power.h
#include <avr/wdt.h> #include <avr/sleep.h> #include <Arduino.h> class Power{ private: uint16_t wdt_delay; volatile uint32_t ts,delta; volatile uint8_t wdt_count; uint8_t calibration; public: void watchdogEvent(); void prepare_wdt(); void measure_wdt(uint8_t); void sleep(); };
Power.cpp
#include "Power.h" void Power::watchdogEvent(){ if (calibration) { delta+=millis()-ts; ts=millis(); }else wdt_disable(); wdt_count++; } void Power::prepare_wdt(){ wdt_reset(); WDTCSR|=1<<WDCE|1<<WDE; WDTCSR=1<<WDIE|1<<WDP2|1<<WDP1; } void Power::measure_wdt(uint8_t start){ cli(); if (start){ prepare_wdt(); ts=millis(); calibration=1; }else{ calibration=0; wdt_delay=delta/wdt_count; } sei(); } void Power::sleep(){ extern volatile unsigned long timer0_millis; prepare_wdt(); set_sleep_mode (SLEEP_MODE_PWR_DOWN); sleep_enable(); wdt_count=0; do sleep_cpu(); while(!wdt_count); timer0_millis+=wdt_delay; sleep_disable(); }
, â , , :
â . , :
â , . , 3D-, , , . , :
â , ?
â ?
â , , , â .
:
åç
6x8: 0x98, 0x3c, 0x66, 0x99, 0x7e, 0x30, // 0x3c, 0x18, 0x1a, 0x1e, 0xba, 0xb0, // ( ) 0x04, 0xfd, 0x84, 0xfd, 0x84, 0xfd, // ( ) 0x00, 0xe0, 0x90, 0x8c, 0x82, 0xdd, // ( ) 0xdd, 0x82, 0x8c, 0x90, 0xe0, 0x00, // 0x00, 0x60, 0xf0, 0x7a, 0x20, 0x00, // 0x00, 0x70, 0xd8, 0x6d, 0x18, 0x00, // 0x0c, 0x72, 0xdb, 0x6c, 0x1b, 0x06, // 24x14: 0x00, 0xf8, 0x04, 0xfa, 0x85, 0x3a, 0x44, 0x44, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0xff, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x3f, 0x3f, 0x3f, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80, 0x80, 0xc0, 0xc0, 0x40, 0x40, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x08, 0x01, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08, 0x08, 0x10, 0x10, 0x1a, 0x3b, 0x21, 0x20, 0x40, 0x40, 0x40, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
, , , update(), , communicate() â complete() â
åç §è³æ
github.com/gavrilov-i/OpenTherm
habrahabr.ru/post/214257
otgw.tclcode.com
www.domoticaforum.eu/uploaded/Ard%20M/Opentherm%20Protocol%20v2-2.pdf
PS , , â â , . , .. , OpenTherm, .
PPS , . , â +5, TX ( ), RX ( ) â 1,5, GND.
:
â , . RX ( . ) TX ( R3) +5. 20. R3 â 7 ( 5). , . .