ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಒಂದಾನೊಂದು ಕಾಲದಲ್ಲಿ, ಮನೆ ಯಾಂತ್ರೀಕೃತಗೊಂಡ ವ್ಯವಸ್ಥೆಗಳು ಅಥವಾ "ಸ್ಮಾರ್ಟ್ ಹೋಮ್" ಎಂದು ಕರೆಯಲ್ಪಡುವಂತೆ, ಭಯಾನಕ ದುಬಾರಿ ಮತ್ತು ಶ್ರೀಮಂತರು ಮಾತ್ರ ಅವುಗಳನ್ನು ನಿಭಾಯಿಸಬಲ್ಲರು. ಇಂದು ಮಾರುಕಟ್ಟೆಯಲ್ಲಿ ನೀವು ಬೆಳಕು, ಸಾಕೆಟ್‌ಗಳು, ವಾತಾಯನ, ನೀರು ಸರಬರಾಜು ಮತ್ತು ಇತರ ಗ್ರಾಹಕರನ್ನು ನಿಯಂತ್ರಿಸಲು ಸಂವೇದಕಗಳು, ಬಟನ್‌ಗಳು / ಸ್ವಿಚ್‌ಗಳು ಮತ್ತು ಆಕ್ಯೂವೇಟರ್‌ಗಳೊಂದಿಗೆ ಸಾಕಷ್ಟು ಅಗ್ಗದ ಕಿಟ್‌ಗಳನ್ನು ಕಾಣಬಹುದು. ಮತ್ತು ಅತ್ಯಂತ ವಕ್ರವಾದ DIY ವ್ಯಕ್ತಿಯೂ ಸಹ ಸೌಂದರ್ಯದಲ್ಲಿ ತೊಡಗಿಸಿಕೊಳ್ಳಬಹುದು ಮತ್ತು ಅಗ್ಗದ ಬೆಲೆಯಲ್ಲಿ ಸ್ಮಾರ್ಟ್ ಮನೆಗಾಗಿ ಸಾಧನಗಳನ್ನು ಜೋಡಿಸಬಹುದು.

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ವಿಶಿಷ್ಟವಾಗಿ, ಪ್ರಸ್ತಾವಿತ ಸಾಧನಗಳು ಸಂವೇದಕಗಳು ಅಥವಾ ಪ್ರಚೋದಕಗಳಾಗಿವೆ. "ಚಲನೆಯ ಸಂವೇದಕವನ್ನು ಪ್ರಚೋದಿಸಿದಾಗ, ದೀಪಗಳನ್ನು ಆನ್ ಮಾಡಿ" ಅಥವಾ "ನಿರ್ಗಮನದ ಬಳಿಯ ಸ್ವಿಚ್ ಇಡೀ ಅಪಾರ್ಟ್ಮೆಂಟ್ನಲ್ಲಿ ದೀಪಗಳನ್ನು ಆಫ್ ಮಾಡುತ್ತದೆ" ನಂತಹ ಸನ್ನಿವೇಶಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಅವರು ಸುಲಭಗೊಳಿಸುತ್ತಾರೆ. ಆದರೆ ಹೇಗಾದರೂ ವಿಷಯಗಳು ಟೆಲಿಮೆಟ್ರಿಯೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲಿಲ್ಲ. ಅತ್ಯುತ್ತಮವಾಗಿ, ಇದು ತಾಪಮಾನ ಮತ್ತು ತೇವಾಂಶದ ಗ್ರಾಫ್, ಅಥವಾ ನಿರ್ದಿಷ್ಟ ಔಟ್ಲೆಟ್ನಲ್ಲಿ ತತ್ಕ್ಷಣದ ಶಕ್ತಿ.

ನಾನು ಇತ್ತೀಚೆಗೆ ಪಲ್ಸ್ ಔಟ್ಪುಟ್ನೊಂದಿಗೆ ನೀರಿನ ಮೀಟರ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಿದೆ. ಮೀಟರ್ ಮೂಲಕ ಹಾದುಹೋಗುವ ಪ್ರತಿ ಲೀಟರ್‌ಗೆ, ರೀಡ್ ಸ್ವಿಚ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಸಂಪರ್ಕವನ್ನು ಮುಚ್ಚುತ್ತದೆ. ತಂತಿಗಳಿಗೆ ಅಂಟಿಕೊಳ್ಳುವುದು ಮತ್ತು ಅದರ ಲಾಭ ಪಡೆಯಲು ಪ್ರಯತ್ನಿಸುವುದು ಮಾತ್ರ ಉಳಿದಿದೆ. ಉದಾಹರಣೆಗೆ, ವಾರದ ಗಂಟೆ ಮತ್ತು ದಿನದ ಮೂಲಕ ನೀರಿನ ಬಳಕೆಯನ್ನು ವಿಶ್ಲೇಷಿಸಿ. ಸರಿ, ಅಪಾರ್ಟ್ಮೆಂಟ್ನಲ್ಲಿ ಹಲವಾರು ವಾಟರ್ ರೈಸರ್ಗಳು ಇದ್ದರೆ, ಬ್ಯಾಟರಿಯೊಂದಿಗೆ ತಲುಪಲು ಕಷ್ಟವಾದ ಗೂಡುಗಳಿಗೆ ಏರುವುದಕ್ಕಿಂತ ಪ್ರಸ್ತುತ ಎಲ್ಲಾ ಸೂಚಕಗಳನ್ನು ಒಂದೇ ಪರದೆಯಲ್ಲಿ ನೋಡುವುದು ಹೆಚ್ಚು ಅನುಕೂಲಕರವಾಗಿದೆ.

ಕಟ್ ಕೆಳಗೆ ESP8266 ಆಧಾರಿತ ಸಾಧನದ ನನ್ನ ಆವೃತ್ತಿಯಾಗಿದೆ, ಇದು ನೀರಿನ ಮೀಟರ್‌ಗಳಿಂದ ದ್ವಿದಳ ಧಾನ್ಯಗಳನ್ನು ಎಣಿಸುತ್ತದೆ ಮತ್ತು MQTT ಮೂಲಕ ಸ್ಮಾರ್ಟ್ ಹೋಮ್ ಸರ್ವರ್‌ಗೆ ರೀಡಿಂಗ್‌ಗಳನ್ನು ಕಳುಹಿಸುತ್ತದೆ. ನಾವು uasyncio ಲೈಬ್ರರಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಮೈಕ್ರೋಪೈಥಾನ್‌ನಲ್ಲಿ ಪ್ರೋಗ್ರಾಮ್ ಮಾಡುತ್ತೇವೆ. ಫರ್ಮ್ವೇರ್ ಅನ್ನು ರಚಿಸುವಾಗ, ನಾನು ಹಲವಾರು ಆಸಕ್ತಿದಾಯಕ ತೊಂದರೆಗಳನ್ನು ಎದುರಿಸಿದ್ದೇನೆ, ಅದನ್ನು ನಾನು ಈ ಲೇಖನದಲ್ಲಿ ಚರ್ಚಿಸುತ್ತೇನೆ. ಹೋಗು!

ಯೋಜನೆ

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಸಂಪೂರ್ಣ ಸರ್ಕ್ಯೂಟ್‌ನ ಹೃದಯವು ESP8266 ಮೈಕ್ರೊಕಂಟ್ರೋಲರ್‌ನಲ್ಲಿ ಮಾಡ್ಯೂಲ್ ಆಗಿದೆ. ESP-12 ಅನ್ನು ಮೂಲತಃ ಯೋಜಿಸಲಾಗಿತ್ತು, ಆದರೆ ನನ್ನದು ದೋಷಯುಕ್ತವಾಗಿದೆ. ಲಭ್ಯವಿರುವ ESP-07 ಮಾಡ್ಯೂಲ್‌ನೊಂದಿಗೆ ನಾವು ತೃಪ್ತರಾಗಿರಬೇಕು. ಅದೃಷ್ಟವಶಾತ್, ಪಿನ್‌ಗಳು ಮತ್ತು ಕ್ರಿಯಾತ್ಮಕತೆಯ ವಿಷಯದಲ್ಲಿ ಅವು ಒಂದೇ ಆಗಿರುತ್ತವೆ, ಆಂಟೆನಾದಲ್ಲಿ ಮಾತ್ರ ವ್ಯತ್ಯಾಸವಿದೆ - ESP-12 ಅಂತರ್ನಿರ್ಮಿತ ಒಂದನ್ನು ಹೊಂದಿದೆ, ಆದರೆ ESP-07 ಬಾಹ್ಯವನ್ನು ಹೊಂದಿದೆ. ಆದಾಗ್ಯೂ, ವೈಫೈ ಆಂಟೆನಾ ಇಲ್ಲದಿದ್ದರೂ ಸಹ, ನನ್ನ ಬಾತ್ರೂಮ್ನಲ್ಲಿ ಸಿಗ್ನಲ್ ಅನ್ನು ಸಾಮಾನ್ಯವಾಗಿ ಸ್ವೀಕರಿಸಲಾಗುತ್ತದೆ.

ಪ್ರಮಾಣಿತ ಮಾಡ್ಯೂಲ್ ವೈರಿಂಗ್:

  • ಪುಲ್-ಅಪ್ ಮತ್ತು ಕೆಪಾಸಿಟರ್‌ನೊಂದಿಗೆ ಮರುಹೊಂದಿಸುವ ಬಟನ್ (ಎರಡೂ ಈಗಾಗಲೇ ಮಾಡ್ಯೂಲ್‌ನಲ್ಲಿದೆ)
  • ಸಕ್ರಿಯಗೊಳಿಸುವ ಸಂಕೇತವನ್ನು (CH_PD) ಪವರ್‌ಗೆ ಎಳೆಯಲಾಗುತ್ತದೆ
  • GPIO15 ಅನ್ನು ನೆಲಕ್ಕೆ ಎಳೆಯಲಾಗುತ್ತದೆ. ಇದು ಪ್ರಾರಂಭದಲ್ಲಿ ಮಾತ್ರ ಅಗತ್ಯವಿದೆ, ಆದರೆ ಈ ಕಾಲಿಗೆ ಲಗತ್ತಿಸಲು ನನಗೆ ಇನ್ನೂ ಏನೂ ಇಲ್ಲ; ನನಗೆ ಇನ್ನು ಮುಂದೆ ಇದು ಅಗತ್ಯವಿಲ್ಲ

ಮಾಡ್ಯೂಲ್ ಅನ್ನು ಫರ್ಮ್‌ವೇರ್ ಮೋಡ್‌ಗೆ ಹಾಕಲು, ನೀವು GPIO2 ಅನ್ನು ನೆಲಕ್ಕೆ ಶಾರ್ಟ್-ಸರ್ಕ್ಯೂಟ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ, ಮತ್ತು ಅದನ್ನು ಹೆಚ್ಚು ಅನುಕೂಲಕರವಾಗಿಸಲು, ನಾನು ಬೂಟ್ ಬಟನ್ ಅನ್ನು ಒದಗಿಸಿದೆ. ಸಾಮಾನ್ಯ ಸ್ಥಿತಿಯಲ್ಲಿ, ಈ ಪಿನ್ ಅನ್ನು ಶಕ್ತಿಗೆ ಎಳೆಯಲಾಗುತ್ತದೆ.

GPIO2 ಸಾಲಿನ ಸ್ಥಿತಿಯನ್ನು ಕಾರ್ಯಾಚರಣೆಯ ಪ್ರಾರಂಭದಲ್ಲಿ ಮಾತ್ರ ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ - ವಿದ್ಯುತ್ ಅನ್ನು ಅನ್ವಯಿಸಿದಾಗ ಅಥವಾ ಮರುಹೊಂದಿಸಿದ ತಕ್ಷಣ. ಆದ್ದರಿಂದ ಮಾಡ್ಯೂಲ್ ಎಂದಿನಂತೆ ಬೂಟ್ ಆಗುತ್ತದೆ ಅಥವಾ ಫರ್ಮ್‌ವೇರ್ ಮೋಡ್‌ಗೆ ಹೋಗುತ್ತದೆ. ಒಮ್ಮೆ ಲೋಡ್ ಮಾಡಿದ ನಂತರ, ಈ ಪಿನ್ ಅನ್ನು ಸಾಮಾನ್ಯ GPIO ಆಗಿ ಬಳಸಬಹುದು. ಸರಿ, ಅಲ್ಲಿ ಈಗಾಗಲೇ ಬಟನ್ ಇರುವುದರಿಂದ, ನೀವು ಅದಕ್ಕೆ ಕೆಲವು ಉಪಯುಕ್ತ ಕಾರ್ಯವನ್ನು ಲಗತ್ತಿಸಬಹುದು.

ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಮತ್ತು ಡೀಬಗ್ ಮಾಡಲು ನಾನು UART ಅನ್ನು ಬಳಸುತ್ತೇನೆ, ಇದು ಬಾಚಣಿಗೆಗೆ ಔಟ್ಪುಟ್ ಆಗಿದೆ. ಅಗತ್ಯವಿದ್ದಾಗ, ನಾನು USB-UART ಅಡಾಪ್ಟರ್ ಅನ್ನು ಅಲ್ಲಿಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇನೆ. ಮಾಡ್ಯೂಲ್ 3.3V ನಿಂದ ಚಾಲಿತವಾಗಿದೆ ಎಂಬುದನ್ನು ನೀವು ನೆನಪಿಟ್ಟುಕೊಳ್ಳಬೇಕು. ಈ ವೋಲ್ಟೇಜ್ಗೆ ಅಡಾಪ್ಟರ್ ಅನ್ನು ಬದಲಾಯಿಸಲು ಮತ್ತು 5V ಅನ್ನು ಪೂರೈಸಲು ನೀವು ಮರೆತರೆ, ಮಾಡ್ಯೂಲ್ ಹೆಚ್ಚಾಗಿ ಸುಟ್ಟುಹೋಗುತ್ತದೆ.

ಬಾತ್ರೂಮ್ನಲ್ಲಿ ವಿದ್ಯುಚ್ಛಕ್ತಿಯೊಂದಿಗೆ ನನಗೆ ಯಾವುದೇ ಸಮಸ್ಯೆಗಳಿಲ್ಲ - ಔಟ್ಲೆಟ್ ಮೀಟರ್ನಿಂದ ಸುಮಾರು ಒಂದು ಮೀಟರ್ ಇದೆ, ಆದ್ದರಿಂದ ನಾನು 220V ಯಿಂದ ಶಕ್ತಿಯನ್ನು ಪಡೆಯುತ್ತೇನೆ. ಶಕ್ತಿಯ ಮೂಲವಾಗಿ ನಾನು ಚಿಕ್ಕದನ್ನು ಹೊಂದಿದ್ದೇನೆ ಬ್ಲಾಕ್ HLK-PM03 ಟೆನ್‌ಸ್ಟಾರ್ ರೋಬೋಟ್‌ನಿಂದ. ವೈಯಕ್ತಿಕವಾಗಿ, ನಾನು ಅನಲಾಗ್ ಮತ್ತು ಪವರ್ ಎಲೆಕ್ಟ್ರಾನಿಕ್ಸ್ನೊಂದಿಗೆ ಕಠಿಣ ಸಮಯವನ್ನು ಹೊಂದಿದ್ದೇನೆ, ಆದರೆ ಇಲ್ಲಿ ಸಣ್ಣ ಪ್ರಕರಣದಲ್ಲಿ ಸಿದ್ಧ ವಿದ್ಯುತ್ ಸರಬರಾಜು ಇದೆ.

ಆಪರೇಟಿಂಗ್ ಮೋಡ್‌ಗಳನ್ನು ಸಂಕೇತಿಸಲು, ನಾನು GPIO2 ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವ LED ಅನ್ನು ಒದಗಿಸಿದೆ. ಆದಾಗ್ಯೂ, ನಾನು ಅದನ್ನು ಮಾರಾಟ ಮಾಡಲಿಲ್ಲ, ಏಕೆಂದರೆ ... ESP-07 ಮಾಡ್ಯೂಲ್ ಈಗಾಗಲೇ LED ಹೊಂದಿದೆ, ಮತ್ತು ಇದು GPIO2 ಗೆ ಸಂಪರ್ಕ ಹೊಂದಿದೆ. ಆದರೆ ನಾನು ಈ ಎಲ್‌ಇಡಿಯನ್ನು ಕೇಸ್‌ಗೆ ಔಟ್‌ಪುಟ್ ಮಾಡಲು ಬಯಸಿದರೆ ಅದು ಬೋರ್ಡ್‌ನಲ್ಲಿರಲಿ.

ಅತ್ಯಂತ ಆಸಕ್ತಿದಾಯಕ ಭಾಗಕ್ಕೆ ಹೋಗೋಣ. ನೀರಿನ ಮೀಟರ್‌ಗಳಿಗೆ ಯಾವುದೇ ತರ್ಕವಿಲ್ಲ; ಪ್ರಸ್ತುತ ವಾಚನಗೋಷ್ಠಿಗಳಿಗಾಗಿ ನೀವು ಅವರನ್ನು ಕೇಳಲಾಗುವುದಿಲ್ಲ. ನಮಗೆ ಲಭ್ಯವಿರುವ ಏಕೈಕ ವಿಷಯವೆಂದರೆ ಪ್ರಚೋದನೆಗಳು - ಪ್ರತಿ ಲೀಟರ್‌ಗೆ ರೀಡ್ ಸ್ವಿಚ್‌ನ ಸಂಪರ್ಕಗಳನ್ನು ಮುಚ್ಚುವುದು. ನನ್ನ ರೀಡ್ ಸ್ವಿಚ್ ಔಟ್‌ಪುಟ್‌ಗಳು GPIO12/GPIO13 ಗೆ ಸಂಪರ್ಕಗೊಂಡಿವೆ. ನಾನು ಮಾಡ್ಯೂಲ್ ಒಳಗೆ ಪುಲ್-ಅಪ್ ರೆಸಿಸ್ಟರ್ ಅನ್ನು ಪ್ರೋಗ್ರಾಮಿಕ್ ಆಗಿ ಸಕ್ರಿಯಗೊಳಿಸುತ್ತೇನೆ.

ಆರಂಭದಲ್ಲಿ, ನಾನು ಪ್ರತಿರೋಧಕಗಳು R8 ಮತ್ತು R9 ಅನ್ನು ಒದಗಿಸಲು ಮರೆತಿದ್ದೇನೆ ಮತ್ತು ಬೋರ್ಡ್ನ ನನ್ನ ಆವೃತ್ತಿಯು ಅವುಗಳನ್ನು ಹೊಂದಿಲ್ಲ. ಆದರೆ ಎಲ್ಲರಿಗೂ ನೋಡಲು ನಾನು ಈಗಾಗಲೇ ರೇಖಾಚಿತ್ರವನ್ನು ಪೋಸ್ಟ್ ಮಾಡುತ್ತಿರುವುದರಿಂದ, ಈ ಮೇಲ್ವಿಚಾರಣೆಯನ್ನು ಸರಿಪಡಿಸುವುದು ಯೋಗ್ಯವಾಗಿದೆ. ಫರ್ಮ್‌ವೇರ್ ಗ್ಲಿಚ್‌ಗಳು ಮತ್ತು ಪಿನ್ ಅನ್ನು ಒಂದಕ್ಕೆ ಹೊಂದಿಸಿದರೆ ಪೋರ್ಟ್ ಅನ್ನು ಸುಡದಂತೆ ರೆಸಿಸ್ಟರ್‌ಗಳು ಅಗತ್ಯವಿದೆ, ಮತ್ತು ರೀಡ್ ಸ್ವಿಚ್ ಈ ರೇಖೆಯನ್ನು ನೆಲಕ್ಕೆ ಚಿಕ್ಕದಾಗಿರುತ್ತದೆ (ರೆಸಿಸ್ಟರ್‌ನೊಂದಿಗೆ ಗರಿಷ್ಠ 3.3V/1000Ohm = 3.3mA ಹರಿಯುತ್ತದೆ).

ಕರೆಂಟ್ ಹೋದರೆ ಏನು ಮಾಡಬೇಕು ಎಂದು ಯೋಚಿಸುವ ಸಮಯ ಬಂದಿದೆ. ಪ್ರಾರಂಭದಲ್ಲಿ ಸರ್ವರ್‌ನಿಂದ ಆರಂಭಿಕ ಕೌಂಟರ್ ಮೌಲ್ಯಗಳನ್ನು ವಿನಂತಿಸುವುದು ಮೊದಲ ಆಯ್ಕೆಯಾಗಿದೆ. ಆದರೆ ಇದಕ್ಕೆ ವಿನಿಮಯ ಪ್ರೋಟೋಕಾಲ್‌ನ ಗಮನಾರ್ಹ ತೊಡಕುಗಳು ಬೇಕಾಗುತ್ತವೆ. ಇದಲ್ಲದೆ, ಈ ಸಂದರ್ಭದಲ್ಲಿ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆಯು ಸರ್ವರ್ನ ಸ್ಥಿತಿಯನ್ನು ಅವಲಂಬಿಸಿರುತ್ತದೆ. ವಿದ್ಯುತ್ ಅನ್ನು ಆಫ್ ಮಾಡಿದ ನಂತರ (ಅಥವಾ ನಂತರ ಪ್ರಾರಂಭಿಸಿದಾಗ) ಸರ್ವರ್ ಪ್ರಾರಂಭವಾಗದಿದ್ದರೆ, ನೀರಿನ ಮೀಟರ್ ಆರಂಭಿಕ ಮೌಲ್ಯಗಳನ್ನು ವಿನಂತಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ ಮತ್ತು ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುವುದಿಲ್ಲ.

ಆದ್ದರಿಂದ, I2C ಮೂಲಕ ಸಂಪರ್ಕಿಸಲಾದ ಮೆಮೊರಿ ಚಿಪ್‌ನಲ್ಲಿ ಕೌಂಟರ್ ಮೌಲ್ಯಗಳನ್ನು ಉಳಿಸಲು ನಾನು ನಿರ್ಧರಿಸಿದೆ. ಫ್ಲ್ಯಾಶ್ ಮೆಮೊರಿಯ ಗಾತ್ರಕ್ಕೆ ನಾನು ಯಾವುದೇ ವಿಶೇಷ ಅವಶ್ಯಕತೆಗಳನ್ನು ಹೊಂದಿಲ್ಲ - ನೀವು ಕೇವಲ 2 ಸಂಖ್ಯೆಗಳನ್ನು ಮಾತ್ರ ಉಳಿಸಬೇಕಾಗಿದೆ (ಬಿಸಿ ಮತ್ತು ತಣ್ಣನೆಯ ನೀರಿನ ಮೀಟರ್ಗಳ ಪ್ರಕಾರ ಲೀಟರ್ಗಳ ಸಂಖ್ಯೆ). ಚಿಕ್ಕ ಮಾಡ್ಯೂಲ್ ಸಹ ಮಾಡುತ್ತದೆ. ಆದರೆ ನೀವು ರೆಕಾರ್ಡಿಂಗ್ ಚಕ್ರಗಳ ಸಂಖ್ಯೆಗೆ ಗಮನ ಕೊಡಬೇಕು. ಹೆಚ್ಚಿನ ಮಾಡ್ಯೂಲ್‌ಗಳಿಗೆ ಇದು 100 ಸಾವಿರ ಸೈಕಲ್‌ಗಳು, ಕೆಲವು ಮಿಲಿಯನ್‌ಗೆ.

ಒಂದು ಮಿಲಿಯನ್ ಬಹಳಷ್ಟು ಎಂದು ತೋರುತ್ತದೆ. ಆದರೆ ನನ್ನ ಅಪಾರ್ಟ್ಮೆಂಟ್ನಲ್ಲಿ ವಾಸಿಸುವ 4 ವರ್ಷಗಳಲ್ಲಿ, ನಾನು 500 ಕ್ಯೂಬಿಕ್ ಮೀಟರ್ಗಿಂತ ಸ್ವಲ್ಪ ಹೆಚ್ಚು ನೀರನ್ನು ಸೇವಿಸಿದೆ, ಅದು 500 ಸಾವಿರ ಲೀಟರ್! ಮತ್ತು ಫ್ಲಾಶ್ನಲ್ಲಿ 500 ಸಾವಿರ ದಾಖಲೆಗಳು. ಮತ್ತು ಅದು ಕೇವಲ ತಣ್ಣೀರು. ನೀವು ಸಹಜವಾಗಿ, ಪ್ರತಿ ಎರಡು ವರ್ಷಗಳಿಗೊಮ್ಮೆ ಚಿಪ್ ಅನ್ನು ಮರುಮಾರಾಟ ಮಾಡಬಹುದು, ಆದರೆ FRAM ಚಿಪ್‌ಗಳಿವೆ ಎಂದು ಅದು ತಿರುಗುತ್ತದೆ. ಪ್ರೋಗ್ರಾಮಿಂಗ್ ದೃಷ್ಟಿಕೋನದಿಂದ, ಇದು ಒಂದೇ I2C EEPROM ಆಗಿದೆ, ಕೇವಲ ಹೆಚ್ಚಿನ ಸಂಖ್ಯೆಯ ಪುನಃ ಬರೆಯುವ ಚಕ್ರಗಳೊಂದಿಗೆ (ನೂರಾರು ಮಿಲಿಯನ್). ಅಂತಹ ಮೈಕ್ರೋ ಸರ್ಕ್ಯೂಟ್‌ಗಳೊಂದಿಗೆ ನಾನು ಇನ್ನೂ ಅಂಗಡಿಗೆ ಹೋಗಲು ಸಾಧ್ಯವಿಲ್ಲ, ಆದ್ದರಿಂದ ಸದ್ಯಕ್ಕೆ ಸಾಮಾನ್ಯ 24LC512 ನಿಲ್ಲುತ್ತದೆ.

ಮುದ್ರಿತ ಸರ್ಕ್ಯೂಟ್ ಬೋರ್ಡ್

ಆರಂಭದಲ್ಲಿ, ನಾನು ಮನೆಯಲ್ಲಿ ಬೋರ್ಡ್ ಮಾಡಲು ಯೋಜಿಸಿದೆ. ಆದ್ದರಿಂದ, ಬೋರ್ಡ್ ಅನ್ನು ಏಕಪಕ್ಷೀಯವಾಗಿ ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿದೆ. ಆದರೆ ಲೇಸರ್ ಕಬ್ಬಿಣ ಮತ್ತು ಬೆಸುಗೆ ಮುಖವಾಡದೊಂದಿಗೆ ಒಂದು ಗಂಟೆ ಕಳೆದ ನಂತರ (ಹೇಗಾದರೂ ಅದು ಇಲ್ಲದೆ ಬರುವುದಿಲ್ಲ), ನಾನು ಇನ್ನೂ ಚೀನಿಯರಿಂದ ಬೋರ್ಡ್‌ಗಳನ್ನು ಆದೇಶಿಸಲು ನಿರ್ಧರಿಸಿದೆ.

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಬೋರ್ಡ್ ಅನ್ನು ಆರ್ಡರ್ ಮಾಡುವ ಮೊದಲು, ಫ್ಲ್ಯಾಷ್ ಮೆಮೊರಿ ಚಿಪ್ ಜೊತೆಗೆ, I2C ಬಸ್‌ಗೆ ಡಿಸ್ಪ್ಲೇಯಂತಹ ಉಪಯುಕ್ತವಾದ ಯಾವುದನ್ನಾದರೂ ನಾನು ಸಂಪರ್ಕಿಸಬಹುದು ಎಂದು ನಾನು ಅರಿತುಕೊಂಡೆ. ಇದಕ್ಕೆ ನಿಖರವಾಗಿ ಏನು ಔಟ್‌ಪುಟ್ ಮಾಡುವುದು ಇನ್ನೂ ಒಂದು ಪ್ರಶ್ನೆಯಾಗಿದೆ, ಆದರೆ ಅದನ್ನು ಬೋರ್ಡ್‌ನಲ್ಲಿ ರೂಟ್ ಮಾಡಬೇಕಾಗಿದೆ. ಸರಿ, ನಾನು ಕಾರ್ಖಾನೆಯಿಂದ ಬೋರ್ಡ್‌ಗಳನ್ನು ಆದೇಶಿಸಲು ಹೋಗುತ್ತಿದ್ದರಿಂದ, ಏಕ-ಬದಿಯ ಬೋರ್ಡ್‌ಗೆ ನನ್ನನ್ನು ಸೀಮಿತಗೊಳಿಸುವುದರಲ್ಲಿ ಯಾವುದೇ ಅರ್ಥವಿಲ್ಲ, ಆದ್ದರಿಂದ I2C ಸಾಲುಗಳು ಬೋರ್ಡ್‌ನ ಹಿಂಭಾಗದಲ್ಲಿ ಮಾತ್ರ ಇರುತ್ತವೆ.

ಒನ್-ವೇ ವೈರಿಂಗ್‌ನಲ್ಲಿಯೂ ಒಂದು ದೊಡ್ಡ ಸಮಸ್ಯೆ ಇತ್ತು. ಏಕೆಂದರೆ ಬೋರ್ಡ್ ಅನ್ನು ಏಕಪಕ್ಷೀಯವಾಗಿ ಚಿತ್ರಿಸಲಾಗಿದೆ, ಆದ್ದರಿಂದ ಟ್ರ್ಯಾಕ್‌ಗಳು ಮತ್ತು SMD ಘಟಕಗಳನ್ನು ಒಂದು ಬದಿಯಲ್ಲಿ ಇರಿಸಲು ಯೋಜಿಸಲಾಗಿದೆ, ಮತ್ತು ಔಟ್‌ಪುಟ್ ಘಟಕಗಳು, ಕನೆಕ್ಟರ್‌ಗಳು ಮತ್ತು ವಿದ್ಯುತ್ ಸರಬರಾಜು ಇನ್ನೊಂದೆಡೆ. ಒಂದು ತಿಂಗಳ ನಂತರ ನಾನು ಬೋರ್ಡ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಿದಾಗ, ನಾನು ಮೂಲ ಯೋಜನೆಯನ್ನು ಮರೆತಿದ್ದೇನೆ ಮತ್ತು ಮುಂಭಾಗದ ಭಾಗದಲ್ಲಿ ಎಲ್ಲಾ ಘಟಕಗಳನ್ನು ಬೆಸುಗೆ ಹಾಕಿದೆ. ಮತ್ತು ವಿದ್ಯುತ್ ಸರಬರಾಜನ್ನು ಬೆಸುಗೆ ಹಾಕಲು ಬಂದಾಗ ಮಾತ್ರ ಪ್ಲಸ್ ಮತ್ತು ಮೈನಸ್ ಅನ್ನು ಹಿಮ್ಮುಖವಾಗಿ ತಂತಿ ಮಾಡಲಾಗಿದೆ ಎಂದು ತಿಳಿದುಬಂದಿದೆ. ನಾನು ಜಿಗಿತಗಾರರೊಂದಿಗೆ ಕೃಷಿ ಮಾಡಬೇಕಾಗಿತ್ತು. ಮೇಲಿನ ಚಿತ್ರದಲ್ಲಿ, ನಾನು ಈಗಾಗಲೇ ವೈರಿಂಗ್ ಅನ್ನು ಬದಲಾಯಿಸಿದ್ದೇನೆ, ಆದರೆ ಬೂಟ್ ಬಟನ್‌ನ ಪಿನ್‌ಗಳ ಮೂಲಕ ನೆಲವನ್ನು ಬೋರ್ಡ್‌ನ ಒಂದು ಭಾಗದಿಂದ ಇನ್ನೊಂದಕ್ಕೆ ವರ್ಗಾಯಿಸಲಾಗುತ್ತದೆ (ಆದರೂ ಎರಡನೇ ಪದರದಲ್ಲಿ ಟ್ರ್ಯಾಕ್ ಅನ್ನು ಸೆಳೆಯಲು ಸಾಧ್ಯವಿದೆ).

ಇದು ಈ ರೀತಿ ಹೊರಹೊಮ್ಮಿತು

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ವಸತಿ

ಮುಂದಿನ ಹಂತವು ದೇಹವಾಗಿದೆ. ನೀವು 3D ಪ್ರಿಂಟರ್ ಹೊಂದಿದ್ದರೆ, ಇದು ಸಮಸ್ಯೆಯಲ್ಲ. ನಾನು ಹೆಚ್ಚು ತಲೆಕೆಡಿಸಿಕೊಳ್ಳಲಿಲ್ಲ - ನಾನು ಸರಿಯಾದ ಗಾತ್ರದ ಪೆಟ್ಟಿಗೆಯನ್ನು ಸೆಳೆಯುತ್ತೇನೆ ಮತ್ತು ಸರಿಯಾದ ಸ್ಥಳಗಳಲ್ಲಿ ಕಟೌಟ್‌ಗಳನ್ನು ಮಾಡಿದ್ದೇನೆ. ಸಣ್ಣ ಸ್ವಯಂ-ಟ್ಯಾಪಿಂಗ್ ತಿರುಪುಮೊಳೆಗಳೊಂದಿಗೆ ಕವರ್ ದೇಹಕ್ಕೆ ಲಗತ್ತಿಸಲಾಗಿದೆ.

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಬೂಟ್ ಬಟನ್ ಅನ್ನು ಸಾಮಾನ್ಯ ಉದ್ದೇಶದ ಬಟನ್ ಆಗಿ ಬಳಸಬಹುದು ಎಂದು ನಾನು ಈಗಾಗಲೇ ಉಲ್ಲೇಖಿಸಿದ್ದೇನೆ - ಆದ್ದರಿಂದ ನಾವು ಅದನ್ನು ಮುಂಭಾಗದ ಫಲಕದಲ್ಲಿ ಪ್ರದರ್ಶಿಸುತ್ತೇವೆ. ಇದನ್ನು ಮಾಡಲು, ಬಟನ್ ವಾಸಿಸುವ ವಿಶೇಷ "ಬಾವಿ" ಅನ್ನು ನಾನು ಚಿತ್ರಿಸಿದೆ.

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಪ್ರಕರಣದ ಒಳಗೆ ಬೋರ್ಡ್ ಅನ್ನು ಸ್ಥಾಪಿಸಿದ ಮತ್ತು ಒಂದೇ M3 ಸ್ಕ್ರೂನೊಂದಿಗೆ ಭದ್ರಪಡಿಸಿದ ಸ್ಟಡ್‌ಗಳಿವೆ (ಬೋರ್ಡ್‌ನಲ್ಲಿ ಹೆಚ್ಚಿನ ಸ್ಥಳವಿರಲಿಲ್ಲ)

ನಾನು ಪ್ರಕರಣದ ಮೊದಲ ಮಾದರಿ ಆವೃತ್ತಿಯನ್ನು ಮುದ್ರಿಸಿದಾಗ ನಾನು ಈಗಾಗಲೇ ಪ್ರದರ್ಶನವನ್ನು ಆಯ್ಕೆ ಮಾಡಿದ್ದೇನೆ. ಪ್ರಮಾಣಿತ ಎರಡು-ಸಾಲಿನ ರೀಡರ್ ಈ ಪ್ರಕರಣಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗಲಿಲ್ಲ, ಆದರೆ ಕೆಳಭಾಗದಲ್ಲಿ OLED ಡಿಸ್ಪ್ಲೇ SSD1306 128×32 ಇತ್ತು. ಇದು ಸ್ವಲ್ಪ ಚಿಕ್ಕದಾಗಿದೆ, ಆದರೆ ನಾನು ಅದನ್ನು ಪ್ರತಿದಿನ ನೋಡಬೇಕಾಗಿಲ್ಲ - ಇದು ನನಗೆ ತುಂಬಾ ಹೆಚ್ಚು.

ಈ ರೀತಿಯಲ್ಲಿ ಮತ್ತು ಅದರಿಂದ ತಂತಿಗಳನ್ನು ಹೇಗೆ ತಿರುಗಿಸಲಾಗುತ್ತದೆ ಎಂಬುದನ್ನು ಕಂಡುಹಿಡಿಯುವುದು, ನಾನು ಪ್ರಕರಣದ ಮಧ್ಯದಲ್ಲಿ ಪ್ರದರ್ಶನವನ್ನು ಅಂಟಿಸಲು ನಿರ್ಧರಿಸಿದೆ. ದಕ್ಷತಾಶಾಸ್ತ್ರವು ಸಹಜವಾಗಿ ಕೆಳಗಿದೆ - ಬಟನ್ ಮೇಲ್ಭಾಗದಲ್ಲಿದೆ, ಪ್ರದರ್ಶನವು ಕೆಳಭಾಗದಲ್ಲಿದೆ. ಆದರೆ ನಾನು ಈಗಾಗಲೇ ಡಿಸ್ಪ್ಲೇ ಅನ್ನು ಲಗತ್ತಿಸುವ ಕಲ್ಪನೆಯು ತಡವಾಗಿ ಬಂದಿತು ಮತ್ತು ಬಟನ್ ಅನ್ನು ಸರಿಸಲು ಬೋರ್ಡ್ ಅನ್ನು ರಿವೈರ್ ಮಾಡಲು ನಾನು ತುಂಬಾ ಸೋಮಾರಿಯಾಗಿದ್ದೆ ಎಂದು ನಾನು ಈಗಾಗಲೇ ಹೇಳಿದೆ.

ಸಾಧನವನ್ನು ಜೋಡಿಸಲಾಗಿದೆ. ಡಿಸ್ಪ್ಲೇ ಮಾಡ್ಯೂಲ್ ಬಿಸಿ ಅಂಟು ಜೊತೆ snot ಗೆ ಅಂಟಿಕೊಂಡಿರುತ್ತದೆ

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಅಂತಿಮ ಫಲಿತಾಂಶವನ್ನು KDPV ನಲ್ಲಿ ನೋಡಬಹುದು

ಫರ್ಮ್ವೇರ್

ಸಾಫ್ಟ್ವೇರ್ ಭಾಗಕ್ಕೆ ಹೋಗೋಣ. ಈ ರೀತಿಯ ಸಣ್ಣ ಕರಕುಶಲತೆಗಳಿಗಾಗಿ, ನಾನು ಪೈಥಾನ್ ಅನ್ನು ಬಳಸಲು ಇಷ್ಟಪಡುತ್ತೇನೆ (ಮೈಕ್ರೋಪೈಥಾನ್) - ಕೋಡ್ ತುಂಬಾ ಕಾಂಪ್ಯಾಕ್ಟ್ ಮತ್ತು ಅರ್ಥವಾಗುವಂತಹದ್ದಾಗಿದೆ. ಅದೃಷ್ಟವಶಾತ್, ಮೈಕ್ರೋಸೆಕೆಂಡ್‌ಗಳನ್ನು ಹಿಂಡುವ ಸಲುವಾಗಿ ರಿಜಿಸ್ಟರ್ ಮಟ್ಟಕ್ಕೆ ಇಳಿಯುವ ಅಗತ್ಯವಿಲ್ಲ - ಪೈಥಾನ್‌ನಿಂದ ಎಲ್ಲವನ್ನೂ ಮಾಡಬಹುದು.

ಎಲ್ಲವೂ ಸರಳವಾಗಿದೆ ಎಂದು ತೋರುತ್ತದೆ, ಆದರೆ ತುಂಬಾ ಸರಳವಲ್ಲ - ಸಾಧನವು ಹಲವಾರು ಸ್ವತಂತ್ರ ಕಾರ್ಯಗಳನ್ನು ಹೊಂದಿದೆ:

  • ಬಳಕೆದಾರರು ಗುಂಡಿಯನ್ನು ಚುಚ್ಚುತ್ತಾರೆ ಮತ್ತು ಪ್ರದರ್ಶನವನ್ನು ನೋಡುತ್ತಾರೆ
  • ಫ್ಲ್ಯಾಶ್ ಮೆಮೊರಿಯಲ್ಲಿ ಲೀಟರ್‌ಗಳು ಮೌಲ್ಯಗಳನ್ನು ಟಿಕ್ ಮಾಡಿ ಮತ್ತು ನವೀಕರಿಸಿ
  • ಮಾಡ್ಯೂಲ್ ವೈಫೈ ಸಿಗ್ನಲ್ ಅನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುತ್ತದೆ ಮತ್ತು ಅಗತ್ಯವಿದ್ದರೆ ಮರುಸಂಪರ್ಕಿಸುತ್ತದೆ
  • ಸರಿ, ಮಿಟುಕಿಸುವ ಬೆಳಕಿನ ಬಲ್ಬ್ ಇಲ್ಲದೆ ಅದು ಅಸಾಧ್ಯ

ಯಾವುದೋ ಕಾರಣಕ್ಕಾಗಿ ಮತ್ತೊಂದು ಕಾರ್ಯವು ಅಂಟಿಕೊಂಡರೆ ಒಂದು ಕಾರ್ಯವು ಕಾರ್ಯನಿರ್ವಹಿಸಲಿಲ್ಲ ಎಂದು ನೀವು ಊಹಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಾನು ಈಗಾಗಲೇ ಇತರ ಪ್ರಾಜೆಕ್ಟ್‌ಗಳಲ್ಲಿ ಪಾಪಾಸುಕಳ್ಳಿಯನ್ನು ತುಂಬಿದ್ದೇನೆ ಮತ್ತು ಈಗ ನಾನು ಇನ್ನೂ "ಇನ್ನೊಂದು ಲೀಟರ್ ಅನ್ನು ಕಳೆದುಕೊಂಡಿದ್ದೇನೆ ಏಕೆಂದರೆ ಆ ಕ್ಷಣದಲ್ಲಿ ಡಿಸ್‌ಪ್ಲೇ ಅಪ್‌ಡೇಟ್ ಆಗುತ್ತಿದೆ" ಅಥವಾ "ಮಾಡ್ಯೂಲ್ ಅನ್ನು ಸಂಪರ್ಕಿಸುವಾಗ ಬಳಕೆದಾರರು ಏನನ್ನೂ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ ವೈಫೈ." ಸಹಜವಾಗಿ, ಕೆಲವು ವಿಷಯಗಳನ್ನು ಅಡಚಣೆಗಳ ಮೂಲಕ ಮಾಡಬಹುದು, ಆದರೆ ನೀವು ಅವಧಿ, ಕರೆಗಳ ಗೂಡುಕಟ್ಟುವಿಕೆ ಅಥವಾ ವೇರಿಯಬಲ್‌ಗಳಿಗೆ ಪರಮಾಣು ಅಲ್ಲದ ಬದಲಾವಣೆಗಳ ಮೇಲೆ ಮಿತಿಗಳನ್ನು ಎದುರಿಸಬಹುದು. ಸರಿ, ಎಲ್ಲವನ್ನೂ ಮಾಡುವ ಕೋಡ್ ತ್ವರಿತವಾಗಿ ಮುಶ್ ಆಗಿ ಬದಲಾಗುತ್ತದೆ.

В ಹೆಚ್ಚು ಗಂಭೀರ ಯೋಜನೆ ನಾನು ಕ್ಲಾಸಿಕ್ ಪೂರ್ವಭಾವಿ ಬಹುಕಾರ್ಯಕ ಮತ್ತು FreeRTOS ಅನ್ನು ಬಳಸಿದ್ದೇನೆ, ಆದರೆ ಈ ಸಂದರ್ಭದಲ್ಲಿ ಮಾದರಿಯು ಹೆಚ್ಚು ಸೂಕ್ತವಾಗಿದೆ. ಕೊರೂಟಿನ್ಗಳು ಮತ್ತು ಯುಸಿಂಕ್ ಲೈಬ್ರರಿಗಳು . ಇದಲ್ಲದೆ, ಕೊರೂಟಿನ್ಗಳ ಪೈಥಾನ್ ಅನುಷ್ಠಾನವು ಸರಳವಾಗಿ ಅದ್ಭುತವಾಗಿದೆ - ಪ್ರೋಗ್ರಾಮರ್ಗಾಗಿ ಎಲ್ಲವನ್ನೂ ಸರಳವಾಗಿ ಮತ್ತು ಅನುಕೂಲಕರವಾಗಿ ಮಾಡಲಾಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ವಂತ ತರ್ಕವನ್ನು ಬರೆಯಿರಿ, ಸ್ಟ್ರೀಮ್‌ಗಳ ನಡುವೆ ನೀವು ಯಾವ ಸ್ಥಳಗಳಲ್ಲಿ ಬದಲಾಯಿಸಬಹುದು ಎಂಬುದನ್ನು ನನಗೆ ತಿಳಿಸಿ.

ಐಚ್ಛಿಕ ವಿಷಯವಾಗಿ ಪೂರ್ವಭಾವಿ ಮತ್ತು ಸ್ಪರ್ಧಾತ್ಮಕ ಬಹುಕಾರ್ಯಕಗಳ ನಡುವಿನ ವ್ಯತ್ಯಾಸಗಳನ್ನು ಅಧ್ಯಯನ ಮಾಡಲು ನಾನು ಸಲಹೆ ನೀಡುತ್ತೇನೆ. ಈಗ ಅಂತಿಮವಾಗಿ ಕೋಡ್‌ಗೆ ಹೋಗೋಣ.

#####################################
# Counter class - implements a single water counter on specified pin
#####################################
class Counter():
    debounce_ms = const(25)
    
    def __init__(self, pin_num, value_storage):
        self._value_storage = value_storage
        
        self._value = self._value_storage.read()
        self._value_changed = False

        self._pin = Pin(pin_num, Pin.IN, Pin.PULL_UP)

        loop = asyncio.get_event_loop()
        loop.create_task(self._switchcheck())  # Thread runs forever

ಪ್ರತಿ ಕೌಂಟರ್ ಅನ್ನು ಕೌಂಟರ್ ವರ್ಗದ ನಿದರ್ಶನದಿಂದ ನಿರ್ವಹಿಸಲಾಗುತ್ತದೆ. ಮೊದಲನೆಯದಾಗಿ, ಆರಂಭಿಕ ಕೌಂಟರ್ ಮೌಲ್ಯವನ್ನು EEPROM (value_storage) ನಿಂದ ಕಳೆಯಲಾಗುತ್ತದೆ - ವಿದ್ಯುತ್ ವೈಫಲ್ಯದ ನಂತರ ಮರುಪಡೆಯುವಿಕೆ ಕಾರ್ಯಗತಗೊಳಿಸುವುದು ಹೀಗೆ.

ವಿದ್ಯುತ್ ಸರಬರಾಜಿಗೆ ಅಂತರ್ನಿರ್ಮಿತ ಪುಲ್-ಅಪ್‌ನೊಂದಿಗೆ ಪಿನ್ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ: ರೀಡ್ ಸ್ವಿಚ್ ಮುಚ್ಚಿದ್ದರೆ, ಲೈನ್ ಶೂನ್ಯವಾಗಿರುತ್ತದೆ, ಲೈನ್ ತೆರೆದಿದ್ದರೆ, ಅದನ್ನು ವಿದ್ಯುತ್ ಸರಬರಾಜಿಗೆ ಎಳೆಯಲಾಗುತ್ತದೆ ಮತ್ತು ನಿಯಂತ್ರಕವು ಒಂದನ್ನು ಓದುತ್ತದೆ.

ಇಲ್ಲಿ ಪ್ರತ್ಯೇಕ ಕಾರ್ಯವನ್ನು ಸಹ ಪ್ರಾರಂಭಿಸಲಾಗಿದೆ, ಇದು ಪಿನ್ ಅನ್ನು ಪೋಲ್ ಮಾಡುತ್ತದೆ. ಪ್ರತಿ ಕೌಂಟರ್ ತನ್ನದೇ ಆದ ಕೆಲಸವನ್ನು ನಡೆಸುತ್ತದೆ. ಅವಳ ಕೋಡ್ ಇಲ್ಲಿದೆ

    """ Poll pin and advance value when another litre passed """
    async def _switchcheck(self):
        last_checked_pin_state = self._pin.value()  # Get initial state

        # Poll for a pin change
        while True:
            state = self._pin.value()
            if state != last_checked_pin_state:
                # State has changed: act on it now.
                last_checked_pin_state = state
                if state == 0:
                    self._another_litre_passed()

            # Ignore further state changes until switch has settled
            await asyncio.sleep_ms(Counter.debounce_ms)

ಸಂಪರ್ಕ ಬೌನ್ಸ್ ಅನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಲು 25ms ವಿಳಂಬದ ಅಗತ್ಯವಿದೆ, ಮತ್ತು ಅದೇ ಸಮಯದಲ್ಲಿ ಕಾರ್ಯವು ಎಷ್ಟು ಬಾರಿ ಎಚ್ಚರಗೊಳ್ಳುತ್ತದೆ ಎಂಬುದನ್ನು ನಿಯಂತ್ರಿಸುತ್ತದೆ (ಈ ಕಾರ್ಯವು ನಿದ್ರಿಸುವಾಗ, ಇತರ ಕಾರ್ಯಗಳು ಚಾಲನೆಯಲ್ಲಿವೆ). ಪ್ರತಿ 25ms ಕಾರ್ಯವು ಎಚ್ಚರಗೊಳ್ಳುತ್ತದೆ, ಪಿನ್ ಅನ್ನು ಪರಿಶೀಲಿಸುತ್ತದೆ ಮತ್ತು ರೀಡ್ ಸ್ವಿಚ್ ಸಂಪರ್ಕಗಳನ್ನು ಮುಚ್ಚಿದ್ದರೆ, ನಂತರ ಮತ್ತೊಂದು ಲೀಟರ್ ಮೀಟರ್ ಮೂಲಕ ಹಾದುಹೋಗುತ್ತದೆ ಮತ್ತು ಇದನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಬೇಕಾಗಿದೆ.

    def _another_litre_passed(self):
        self._value += 1
        self._value_changed = True

        self._value_storage.write(self._value)

ಮುಂದಿನ ಲೀಟರ್ ಅನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವುದು ಕ್ಷುಲ್ಲಕವಾಗಿದೆ - ಕೌಂಟರ್ ಸರಳವಾಗಿ ಹೆಚ್ಚಾಗುತ್ತದೆ. ಸರಿ, ಹೊಸ ಮೌಲ್ಯವನ್ನು ಫ್ಲ್ಯಾಶ್ ಡ್ರೈವಿನಲ್ಲಿ ಬರೆಯುವುದು ಒಳ್ಳೆಯದು.

ಬಳಕೆಯ ಸುಲಭತೆಗಾಗಿ, "ಪ್ರವೇಶಕಗಳು" ಒದಗಿಸಲಾಗಿದೆ

    def value(self):
        self._value_changed = False
        return self._value

    def set_value(self, value):
        self._value = value
        self._value_changed = False

ಸರಿ, ಈಗ ನಾವು ಪೈಥಾನ್ ಮತ್ತು uasync ಲೈಬ್ರರಿಯ ಸಂತೋಷದ ಲಾಭವನ್ನು ಪಡೆದುಕೊಳ್ಳೋಣ ಮತ್ತು ಕಾಯಬಹುದಾದ ಕೌಂಟರ್ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ತಯಾರಿಸೋಣ (ನಾವು ಇದನ್ನು ರಷ್ಯನ್ ಭಾಷೆಗೆ ಹೇಗೆ ಅನುವಾದಿಸಬಹುದು? ನೀವು ನಿರೀಕ್ಷಿಸಬಹುದಾದದ್ದು?)

    def __await__(self):
        while not self._value_changed:
            yield from asyncio.sleep(0)

        return self.value()

    __iter__ = __await__  

ಇದು ಕೌಂಟರ್ ಮೌಲ್ಯವನ್ನು ನವೀಕರಿಸುವವರೆಗೆ ಕಾಯುವ ಅಂತಹ ಅನುಕೂಲಕರ ಕಾರ್ಯವಾಗಿದೆ - ಕಾರ್ಯವು ಕಾಲಕಾಲಕ್ಕೆ ಎಚ್ಚರಗೊಳ್ಳುತ್ತದೆ ಮತ್ತು _value_changed ಫ್ಲ್ಯಾಗ್ ಅನ್ನು ಪರಿಶೀಲಿಸುತ್ತದೆ. ಈ ಕಾರ್ಯದ ಬಗ್ಗೆ ತಂಪಾದ ವಿಷಯವೆಂದರೆ ಈ ಕಾರ್ಯವನ್ನು ಕರೆಯುವಾಗ ಕರೆ ಮಾಡುವ ಕೋಡ್ ನಿದ್ರಿಸಬಹುದು ಮತ್ತು ಹೊಸ ಮೌಲ್ಯವನ್ನು ಸ್ವೀಕರಿಸುವವರೆಗೆ ಮಲಗಬಹುದು.

ಅಡಚಣೆಗಳ ಬಗ್ಗೆ ಏನು?ಹೌದು. ವಾಸ್ತವವಾಗಿ ನಾನು ಪ್ರಯತ್ನಿಸಿದ ಮೊದಲ ವಿಷಯವೆಂದರೆ ಅಡಚಣೆಗಳು. ESP8266 ನಲ್ಲಿ, ನೀವು ಅಂಚಿನ ಅಡಚಣೆಯನ್ನು ಸಂಘಟಿಸಬಹುದು ಮತ್ತು ಪೈಥಾನ್‌ನಲ್ಲಿ ಈ ಅಡಚಣೆಗಾಗಿ ಹ್ಯಾಂಡ್ಲರ್ ಅನ್ನು ಸಹ ಬರೆಯಬಹುದು. ಈ ಅಡಚಣೆಯಲ್ಲಿ, ವೇರಿಯೇಬಲ್‌ನ ಮೌಲ್ಯವನ್ನು ನವೀಕರಿಸಬಹುದು. ಬಹುಶಃ, ಕೌಂಟರ್ ಗುಲಾಮರ ಸಾಧನವಾಗಿದ್ದರೆ ಇದು ಸಾಕಾಗುತ್ತದೆ - ಈ ಮೌಲ್ಯವನ್ನು ಕೇಳುವವರೆಗೆ ಕಾಯುವ ಒಂದು.

ದುರದೃಷ್ಟವಶಾತ್ (ಅಥವಾ ಅದೃಷ್ಟವಶಾತ್?) ನನ್ನ ಸಾಧನವು ಸಕ್ರಿಯವಾಗಿದೆ, ಅದು ಸ್ವತಃ MQTT ಪ್ರೋಟೋಕಾಲ್ ಮೂಲಕ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬೇಕು ಮತ್ತು EEPROM ಗೆ ಡೇಟಾವನ್ನು ಬರೆಯಬೇಕು. ಮತ್ತು ಇಲ್ಲಿ ನಿರ್ಬಂಧಗಳು ಕಾರ್ಯರೂಪಕ್ಕೆ ಬರುತ್ತವೆ - ನೀವು ಅಡಚಣೆಗಳಲ್ಲಿ ಮೆಮೊರಿಯನ್ನು ನಿಯೋಜಿಸಲು ಮತ್ತು ದೊಡ್ಡ ಸ್ಟಾಕ್ ಅನ್ನು ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ, ಅಂದರೆ ನೀವು ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸುವುದನ್ನು ಮರೆತುಬಿಡಬಹುದು. micropython.schedule() ನಂತಹ ಬನ್‌ಗಳು "ಸಾಧ್ಯವಾದಷ್ಟು ಬೇಗ" ಕೆಲವು ಕಾರ್ಯಗಳನ್ನು ಚಲಾಯಿಸಲು ನಿಮಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ, ಆದರೆ ಪ್ರಶ್ನೆಯು ಉದ್ಭವಿಸುತ್ತದೆ, "ಏನು ಪಾಯಿಂಟ್?" ನಾವು ಇದೀಗ ಕೆಲವು ರೀತಿಯ ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುತ್ತಿದ್ದರೆ ಮತ್ತು ನಂತರ ಒಂದು ಅಡಚಣೆಯು ಬರುತ್ತದೆ ಮತ್ತು ವೇರಿಯೇಬಲ್‌ಗಳ ಮೌಲ್ಯಗಳನ್ನು ಹಾಳುಮಾಡುತ್ತದೆ. ಅಥವಾ, ಉದಾಹರಣೆಗೆ, ನಾವು ಇನ್ನೂ ಹಳೆಯದನ್ನು ಬರೆಯದೇ ಇರುವಾಗ ಸರ್ವರ್‌ನಿಂದ ಹೊಸ ಕೌಂಟರ್ ಮೌಲ್ಯವು ಬಂದಿದೆ. ಸಾಮಾನ್ಯವಾಗಿ, ನೀವು ಸಿಂಕ್ರೊನೈಸೇಶನ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಬೇಕು ಅಥವಾ ಹೇಗಾದರೂ ವಿಭಿನ್ನವಾಗಿ ಹೊರಬರಬೇಕು.

ಮತ್ತು ಕಾಲಕಾಲಕ್ಕೆ ರನ್ಟೈಮ್ ದೋಷ: ಸ್ಟಾಕ್ ಪೂರ್ಣ ಕ್ರ್ಯಾಶ್‌ಗಳನ್ನು ನಿಗದಿಪಡಿಸಿ ಮತ್ತು ಏಕೆ ಎಂದು ಯಾರಿಗೆ ತಿಳಿದಿದೆ?

ಸ್ಪಷ್ಟ ಮತದಾನ ಮತ್ತು uasync ನೊಂದಿಗೆ, ಈ ಸಂದರ್ಭದಲ್ಲಿ ಅದು ಹೇಗಾದರೂ ಹೆಚ್ಚು ಸುಂದರ ಮತ್ತು ವಿಶ್ವಾಸಾರ್ಹವಾಗಿ ಹೊರಹೊಮ್ಮುತ್ತದೆ

ನಾನು EEPROM ನೊಂದಿಗೆ ಕೆಲಸವನ್ನು ಸಣ್ಣ ತರಗತಿಗೆ ತಂದಿದ್ದೇನೆ

class EEPROM():
    i2c_addr = const(80)

    def __init__(self, i2c):
        self.i2c = i2c
        self.i2c_buf = bytearray(4) # Avoid creation/destruction of the buffer on each call


    def read(self, eeprom_addr):
        self.i2c.readfrom_mem_into(self.i2c_addr, eeprom_addr, self.i2c_buf, addrsize=16)
        return ustruct.unpack_from("<I", self.i2c_buf)[0]    
        
    
    def write(self, eeprom_addr, value):
        ustruct.pack_into("<I", self.i2c_buf, 0, value)
        self.i2c.writeto_mem(self.i2c_addr, eeprom_addr, self.i2c_buf, addrsize=16)

ಪೈಥಾನ್‌ನಲ್ಲಿ, ಬೈಟ್‌ಗಳೊಂದಿಗೆ ನೇರವಾಗಿ ಕೆಲಸ ಮಾಡುವುದು ಕಷ್ಟ, ಆದರೆ ಬೈಟ್‌ಗಳನ್ನು ಮೆಮೊರಿಗೆ ಬರೆಯಲಾಗುತ್ತದೆ. ನಾನು ಯುಸ್ಟ್ರಕ್ಟ್ ಲೈಬ್ರರಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಪೂರ್ಣಾಂಕ ಮತ್ತು ಬೈಟ್‌ಗಳ ನಡುವಿನ ಪರಿವರ್ತನೆಯನ್ನು ಬೇಲಿ ಹಾಕಬೇಕಾಗಿತ್ತು.

I2C ಆಬ್ಜೆಕ್ಟ್ ಮತ್ತು ಮೆಮೊರಿ ಸೆಲ್‌ನ ವಿಳಾಸವನ್ನು ಪ್ರತಿ ಬಾರಿ ವರ್ಗಾಯಿಸದಿರಲು, ನಾನು ಎಲ್ಲವನ್ನೂ ಸಣ್ಣ ಮತ್ತು ಅನುಕೂಲಕರ ಕ್ಲಾಸಿಕ್‌ನಲ್ಲಿ ಸುತ್ತಿದ್ದೇನೆ

class EEPROMValue():
    def __init__(self, i2c, eeprom_addr):
        self._eeprom = EEPROM(i2c)
        self._eeprom_addr = eeprom_addr
        

    def read(self):
        return self._eeprom.read(self._eeprom_addr)


    def write(self, value):
        self._eeprom.write(self._eeprom_addr, value)

I2C ವಸ್ತುವನ್ನು ಈ ನಿಯತಾಂಕಗಳೊಂದಿಗೆ ರಚಿಸಲಾಗಿದೆ

i2c = I2C(freq=400000, scl=Pin(5), sda=Pin(4))

ನಾವು ಅತ್ಯಂತ ಆಸಕ್ತಿದಾಯಕ ಭಾಗಕ್ಕೆ ಬರುತ್ತೇವೆ - MQTT ಮೂಲಕ ಸರ್ವರ್ನೊಂದಿಗೆ ಸಂವಹನದ ಅನುಷ್ಠಾನ. ಸರಿ, ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಸ್ವತಃ ಕಾರ್ಯಗತಗೊಳಿಸುವ ಅಗತ್ಯವಿಲ್ಲ - ನಾನು ಅದನ್ನು ಇಂಟರ್ನೆಟ್ನಲ್ಲಿ ಕಂಡುಕೊಂಡಿದ್ದೇನೆ ಸಿದ್ಧ-ಸಿದ್ಧ ಅಸಮಕಾಲಿಕ ಅನುಷ್ಠಾನ. ಇದನ್ನೇ ನಾವು ಬಳಸುತ್ತೇವೆ.

ಲೈಬ್ರರಿ MQTTClient ಅನ್ನು ಆಧರಿಸಿದ CounterMQTTClient ವರ್ಗದಲ್ಲಿ ಎಲ್ಲಾ ಅತ್ಯಂತ ಆಸಕ್ತಿದಾಯಕ ವಿಷಯಗಳನ್ನು ಸಂಗ್ರಹಿಸಲಾಗಿದೆ. ಪರಿಧಿಯಿಂದ ಪ್ರಾರಂಭಿಸೋಣ

#####################################
# Class handles both counters and sends their status to MQTT
#####################################
class CounterMQTTClient(MQTTClient):

    blue_led = Pin(2, Pin.OUT, value = 1)
    button = Pin(0, Pin.IN)

    hot_counter = Counter(12, EEPROMValue(i2c, EEPROM_ADDR_HOT_VALUE))
    cold_counter = Counter(13, EEPROMValue(i2c, EEPROM_ADDR_COLD_VALUE))

ಇಲ್ಲಿ ನೀವು ಬೆಳಕಿನ ಬಲ್ಬ್ ಪಿನ್ಗಳು ಮತ್ತು ಗುಂಡಿಗಳು, ಹಾಗೆಯೇ ಶೀತ ಮತ್ತು ಬಿಸಿನೀರಿನ ಮೀಟರ್ ವಸ್ತುಗಳನ್ನು ರಚಿಸಬಹುದು ಮತ್ತು ಕಾನ್ಫಿಗರ್ ಮಾಡಬಹುದು.

ಪ್ರಾರಂಭದೊಂದಿಗೆ, ಎಲ್ಲವೂ ತುಂಬಾ ಕ್ಷುಲ್ಲಕವಲ್ಲ

    def __init__(self):
        self.internet_outage = True
        self.internet_outages = 0
        self.internet_outage_start = ticks_ms()

        with open("config.txt") as config_file:
            config['ssid'] = config_file.readline().rstrip()
            config['wifi_pw'] = config_file.readline().rstrip()
            config['server'] = config_file.readline().rstrip()
            config['client_id'] = config_file.readline().rstrip()
            self._mqtt_cold_water_theme = config_file.readline().rstrip()
            self._mqtt_hot_water_theme = config_file.readline().rstrip()
            self._mqtt_debug_water_theme = config_file.readline().rstrip()

        config['subs_cb'] = self.mqtt_msg_handler
        config['wifi_coro'] = self.wifi_connection_handler
        config['connect_coro'] = self.mqtt_connection_handler
        config['clean'] = False
        config['clean_init'] = False
        super().__init__(config)

        loop = asyncio.get_event_loop()
        loop.create_task(self._heartbeat())
        loop.create_task(self._counter_coro(self.cold_counter, self._mqtt_cold_water_theme))
        loop.create_task(self._counter_coro(self.hot_counter, self._mqtt_hot_water_theme))
        loop.create_task(self._display_coro())

mqtt_as ಲೈಬ್ರರಿಯ ಆಪರೇಟಿಂಗ್ ನಿಯತಾಂಕಗಳನ್ನು ಹೊಂದಿಸಲು, ವಿಭಿನ್ನ ಸೆಟ್ಟಿಂಗ್‌ಗಳ ದೊಡ್ಡ ನಿಘಂಟನ್ನು ಬಳಸಲಾಗುತ್ತದೆ - ಸಂರಚನೆ. ಹೆಚ್ಚಿನ ಡೀಫಾಲ್ಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ನಮಗೆ ಉತ್ತಮವಾಗಿವೆ, ಆದರೆ ಹಲವು ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ಹೊಂದಿಸಬೇಕಾಗಿದೆ. ಕೋಡ್‌ನಲ್ಲಿ ನೇರವಾಗಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬರೆಯದಿರಲು, ನಾನು ಅವುಗಳನ್ನು ಪಠ್ಯ ಫೈಲ್ config.txt ನಲ್ಲಿ ಸಂಗ್ರಹಿಸುತ್ತೇನೆ. ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಲೆಕ್ಕಿಸದೆಯೇ ಕೋಡ್ ಅನ್ನು ಬದಲಾಯಿಸಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ, ಹಾಗೆಯೇ ವಿವಿಧ ನಿಯತಾಂಕಗಳೊಂದಿಗೆ ಹಲವಾರು ಒಂದೇ ಸಾಧನಗಳನ್ನು ರಿವೆಟ್ ಮಾಡಿ.

ಕೋಡ್‌ನ ಕೊನೆಯ ಬ್ಲಾಕ್ ಸಿಸ್ಟಮ್‌ನ ವಿವಿಧ ಕಾರ್ಯಗಳನ್ನು ಪೂರೈಸಲು ಹಲವಾರು ಕೊರೂಟಿನ್‌ಗಳನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಸೇವೆಗಳು ಕೌಂಟರ್ ಮಾಡುವ ಕೊರೊಟಿನ್ ಇಲ್ಲಿದೆ

    async def _counter_coro(self, counter, topic):
        # Publish initial value
        value = counter.value()
        await self.publish(topic, str(value))

        # Publish each new value
        while True:
            value = await counter
            await self.publish_msg(topic, str(value))

ಕೊರೂಟಿನ್ ಹೊಸ ಕೌಂಟರ್ ಮೌಲ್ಯಕ್ಕಾಗಿ ಲೂಪ್‌ನಲ್ಲಿ ಕಾಯುತ್ತದೆ ಮತ್ತು ಅದು ಕಾಣಿಸಿಕೊಂಡ ತಕ್ಷಣ MQTT ಪ್ರೋಟೋಕಾಲ್ ಮೂಲಕ ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುತ್ತದೆ. ಕೌಂಟರ್ ಮೂಲಕ ನೀರು ಹರಿಯದಿದ್ದರೂ ಕೋಡ್‌ನ ಮೊದಲ ತುಣುಕು ಆರಂಭಿಕ ಮೌಲ್ಯವನ್ನು ಕಳುಹಿಸುತ್ತದೆ.

ಮೂಲ ವರ್ಗ MQTTClient ಸ್ವತಃ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, WiFi ಸಂಪರ್ಕವನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ ಮತ್ತು ಸಂಪರ್ಕವು ಕಳೆದುಹೋದಾಗ ಮರುಸಂಪರ್ಕಿಸುತ್ತದೆ. ವೈಫೈ ಸಂಪರ್ಕದ ಸ್ಥಿತಿಯಲ್ಲಿ ಬದಲಾವಣೆಗಳಿದ್ದಾಗ, ಲೈಬ್ರರಿಯು ವೈಫೈ_ಕನೆಕ್ಷನ್_ಹ್ಯಾಂಡ್ಲರ್‌ಗೆ ಕರೆ ಮಾಡುವ ಮೂಲಕ ನಮಗೆ ತಿಳಿಸುತ್ತದೆ

    async def wifi_connection_handler(self, state):
        self.internet_outage = not state
        if state:
            self.dprint('WiFi is up.')
            duration = ticks_diff(ticks_ms(), self.internet_outage_start) // 1000
            await self.publish_debug_msg('ReconnectedAfter', duration)
        else:
            self.internet_outages += 1
            self.internet_outage_start = ticks_ms()
            self.dprint('WiFi is down.')
            
        await asyncio.sleep(0)

ಕಾರ್ಯವನ್ನು ಉದಾಹರಣೆಗಳಿಂದ ಪ್ರಾಮಾಣಿಕವಾಗಿ ನಕಲಿಸಲಾಗಿದೆ. ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಇದು ಸ್ಥಗಿತಗಳ ಸಂಖ್ಯೆಯನ್ನು (internet_outages) ಮತ್ತು ಅವುಗಳ ಅವಧಿಯನ್ನು ಎಣಿಸುತ್ತದೆ. ಸಂಪರ್ಕವನ್ನು ಮರುಸ್ಥಾಪಿಸಿದಾಗ, ಐಡಲ್ ಸಮಯವನ್ನು ಸರ್ವರ್‌ಗೆ ಕಳುಹಿಸಲಾಗುತ್ತದೆ.

ಮೂಲಕ, ಕೊನೆಯ ನಿದ್ರೆ ಕಾರ್ಯವನ್ನು ಅಸಮಕಾಲಿಕವಾಗಿಸಲು ಮಾತ್ರ ಅಗತ್ಯವಿದೆ - ಗ್ರಂಥಾಲಯದಲ್ಲಿ ಇದನ್ನು ನಿರೀಕ್ಷಿಸಿ ಮೂಲಕ ಕರೆಯಲಾಗುತ್ತದೆ, ಮತ್ತು ದೇಹವು ಮತ್ತೊಂದು ನಿರೀಕ್ಷೆಯನ್ನು ಹೊಂದಿರುವ ಕಾರ್ಯಗಳನ್ನು ಮಾತ್ರ ಕರೆಯಬಹುದು.

ವೈಫೈಗೆ ಸಂಪರ್ಕಿಸುವುದರ ಜೊತೆಗೆ, ನೀವು MQTT ಬ್ರೋಕರ್ (ಸರ್ವರ್) ಗೆ ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗಿದೆ. ಲೈಬ್ರರಿಯು ಇದನ್ನು ಸಹ ಮಾಡುತ್ತದೆ ಮತ್ತು ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಿದಾಗ ಉಪಯುಕ್ತವಾದದ್ದನ್ನು ಮಾಡಲು ನಾವು ಅವಕಾಶವನ್ನು ಪಡೆಯುತ್ತೇವೆ

    async def mqtt_connection_handler(self, client):
        await client.subscribe(self._mqtt_cold_water_theme)
        await client.subscribe(self._mqtt_hot_water_theme)

ಇಲ್ಲಿ ನಾವು ಹಲವಾರು ಸಂದೇಶಗಳಿಗೆ ಚಂದಾದಾರರಾಗಿದ್ದೇವೆ - ಅನುಗುಣವಾದ ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುವ ಮೂಲಕ ಪ್ರಸ್ತುತ ಕೌಂಟರ್ ಮೌಲ್ಯಗಳನ್ನು ಹೊಂದಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಸರ್ವರ್ ಹೊಂದಿದೆ.

    def mqtt_msg_handler(self, topic, msg):
        topicstr = str(topic, 'utf8')
        self.dprint("Received MQTT message topic={}, msg={}".format(topicstr, msg))

        if topicstr == self._mqtt_cold_water_theme:
            self.cold_counter.set_value(int(msg))

        if topicstr == self._mqtt_hot_water_theme:
            self.hot_counter.set_value(int(msg))

ಈ ಕಾರ್ಯವು ಒಳಬರುವ ಸಂದೇಶಗಳನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ವಿಷಯವನ್ನು (ಸಂದೇಶದ ಶೀರ್ಷಿಕೆ) ಅವಲಂಬಿಸಿ, ಕೌಂಟರ್‌ಗಳಲ್ಲಿ ಒಂದರ ಮೌಲ್ಯಗಳನ್ನು ನವೀಕರಿಸಲಾಗುತ್ತದೆ

ಒಂದೆರಡು ಸಹಾಯಕ ಕಾರ್ಯಗಳು

    # Publish a message if WiFi and broker is up, else discard
    async def publish_msg(self, topic, msg):
        self.dprint("Publishing message on topic {}: {}".format(topic, msg))
        if not self.internet_outage:
            await self.publish(topic, msg)
        else:
            self.dprint("Message was not published - no internet connection")

ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಿದರೆ ಈ ಕಾರ್ಯವು ಸಂದೇಶವನ್ನು ಕಳುಹಿಸುತ್ತದೆ. ಯಾವುದೇ ಸಂಪರ್ಕವಿಲ್ಲದಿದ್ದರೆ, ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಲಾಗುತ್ತದೆ.

ಮತ್ತು ಇದು ಡೀಬಗ್ ಮಾಡುವ ಸಂದೇಶಗಳನ್ನು ಉತ್ಪಾದಿಸುವ ಮತ್ತು ಕಳುಹಿಸುವ ಅನುಕೂಲಕರ ಕಾರ್ಯವಾಗಿದೆ.

    async def publish_debug_msg(self, subtopic, msg):
        await self.publish_msg("{}/{}".format(self._mqtt_debug_water_theme, subtopic), str(msg))

ತುಂಬಾ ಪಠ್ಯ, ಮತ್ತು ನಾವು ಇನ್ನೂ ಎಲ್ಇಡಿ ಬ್ಲಿಂಕ್ ಮಾಡಿಲ್ಲ. ಇಲ್ಲಿ

    # Blink flash LED if WiFi down
    async def _heartbeat(self):
        while True:
            if self.internet_outage:
                self.blue_led(not self.blue_led()) # Fast blinking if no connection
                await asyncio.sleep_ms(200) 
            else:
                self.blue_led(0) # Rare blinking when connected
                await asyncio.sleep_ms(50)
                self.blue_led(1)
                await asyncio.sleep_ms(5000)

ನಾನು 2 ಮಿಟುಕಿಸುವ ವಿಧಾನಗಳನ್ನು ಒದಗಿಸಿದ್ದೇನೆ. ಸಂಪರ್ಕವು ಕಳೆದುಹೋದರೆ (ಅಥವಾ ಅದನ್ನು ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ), ಸಾಧನವು ತ್ವರಿತವಾಗಿ ಮಿಟುಕಿಸುತ್ತದೆ. ಸಂಪರ್ಕವನ್ನು ಸ್ಥಾಪಿಸಿದರೆ, ಸಾಧನವು ಪ್ರತಿ 5 ಸೆಕೆಂಡುಗಳಿಗೊಮ್ಮೆ ಮಿನುಗುತ್ತದೆ. ಅಗತ್ಯವಿದ್ದರೆ, ಇತರ ಮಿಟುಕಿಸುವ ವಿಧಾನಗಳನ್ನು ಇಲ್ಲಿ ಅಳವಡಿಸಬಹುದು.

ಆದರೆ ಎಲ್ಇಡಿ ಕೇವಲ ಪ್ಯಾಂಪರಿಂಗ್ ಆಗಿದೆ. ನಾವು ಪ್ರದರ್ಶನವನ್ನು ಗುರಿಯಾಗಿರಿಸಿಕೊಂಡಿದ್ದೇವೆ.

    async def _display_coro(self):
        display = SSD1306_I2C(128,32, i2c)
    
        while True:
            display.poweron()
            display.fill(0)
            display.text("COLD: {:.3f}".format(self.cold_counter.value() / 1000), 16, 4)
            display.text("HOT:  {:.3f}".format(self.hot_counter.value() / 1000), 16, 20)
            display.show()
            await asyncio.sleep(3)
            display.poweroff()

            while self.button():
                await asyncio.sleep_ms(20)

ನಾನು ಮಾತನಾಡುತ್ತಿರುವುದು ಇದನ್ನೇ - ಇದು ಕೊರೂಟಿನ್‌ಗಳೊಂದಿಗೆ ಎಷ್ಟು ಸರಳ ಮತ್ತು ಅನುಕೂಲಕರವಾಗಿದೆ. ಈ ಚಿಕ್ಕ ಕಾರ್ಯವು ಸಂಪೂರ್ಣ ಬಳಕೆದಾರರ ಅನುಭವವನ್ನು ವಿವರಿಸುತ್ತದೆ. ಕೊರೂಟಿನ್ ಬಟನ್ ಒತ್ತಲು ಕಾಯುತ್ತದೆ ಮತ್ತು 3 ಸೆಕೆಂಡುಗಳ ಕಾಲ ಪ್ರದರ್ಶನವನ್ನು ಆನ್ ಮಾಡುತ್ತದೆ. ಪ್ರದರ್ಶನವು ಪ್ರಸ್ತುತ ಮೀಟರ್ ವಾಚನಗೋಷ್ಠಿಯನ್ನು ತೋರಿಸುತ್ತದೆ.

ಇನ್ನೂ ಒಂದೆರಡು ಸಣ್ಣ ವಿಷಯಗಳು ಉಳಿದಿವೆ. ಈ ಸಂಪೂರ್ಣ ಉದ್ಯಮವನ್ನು (ಮರು) ಪ್ರಾರಂಭಿಸುವ ಕಾರ್ಯ ಇಲ್ಲಿದೆ. ಮುಖ್ಯ ಲೂಪ್ ಕೇವಲ ನಿಮಿಷಕ್ಕೊಮ್ಮೆ ವಿವಿಧ ಡೀಬಗ್ ಮಾಡುವ ಮಾಹಿತಿಯನ್ನು ಕಳುಹಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯವಾಗಿ, ನಾನು ಅದನ್ನು ಹಾಗೆಯೇ ಉಲ್ಲೇಖಿಸುತ್ತೇನೆ - ಹೆಚ್ಚು ಕಾಮೆಂಟ್ ಮಾಡುವ ಅಗತ್ಯವಿಲ್ಲ ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ

   async def main(self):
        while True:
            try:
                await self._connect_to_WiFi()
                await self._run_main_loop()
                    
            except Exception as e:
                self.dprint('Global communication failure: ', e)
                await asyncio.sleep(20)

    async def _connect_to_WiFi(self):
        self.dprint('Connecting to WiFi and MQTT')
        sta_if = network.WLAN(network.STA_IF)
        sta_if.connect(config['ssid'], config['wifi_pw'])
        
        conn = False
        while not conn:
            await self.connect()
            conn = True

        self.dprint('Connected!')
        self.internet_outage = False

    async def _run_main_loop(self):
        # Loop forever
        mins = 0
        while True:
            gc.collect()  # For RAM stats.
            mem_free = gc.mem_free()
            mem_alloc = gc.mem_alloc()

            try:
                await self.publish_debug_msg("Uptime", mins)
                await self.publish_debug_msg("Repubs", self.REPUB_COUNT)
                await self.publish_debug_msg("Outages", self.internet_outages)
                await self.publish_debug_msg("MemFree", mem_free)
                await self.publish_debug_msg("MemAlloc", mem_alloc)
            except Exception as e:
                self.dprint("Exception occurred: ", e)
            mins += 1

            await asyncio.sleep(60)

ಸರಿ, ವಿವರಣೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಲು ಇನ್ನೂ ಒಂದೆರಡು ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಸ್ಥಿರಾಂಕಗಳು

#####################################
# Constants and configuration
#####################################


config['keepalive'] = 60
config['clean'] = False
config['will'] = ('/ESP/Wemos/Water/LastWill', 'Goodbye cruel world!', False, 0)

MQTTClient.DEBUG = True

EEPROM_ADDR_HOT_VALUE = const(0)
EEPROM_ADDR_COLD_VALUE = const(4)

ಇದೆಲ್ಲವೂ ಹೀಗೆ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ

client = CounterMQTTClient()
loop = asyncio.get_event_loop()
loop.run_until_complete(client.main())

ನನ್ನ ನೆನಪಿಗೆ ಏನೋ ಆಯಿತು

ಆದ್ದರಿಂದ, ಎಲ್ಲಾ ಕೋಡ್ ಇದೆ. ನಾನು ಆಂಪಿ ಯುಟಿಲಿಟಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಫೈಲ್‌ಗಳನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಿದ್ದೇನೆ - ಅವುಗಳನ್ನು ಆಂತರಿಕ (ಇಎಸ್‌ಪಿ -07 ನಲ್ಲಿರುವ ಒಂದು) ಫ್ಲ್ಯಾಷ್ ಡ್ರೈವ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಲು ಮತ್ತು ನಂತರ ಅದನ್ನು ಸಾಮಾನ್ಯ ಫೈಲ್‌ಗಳಂತೆ ಪ್ರೋಗ್ರಾಂನಿಂದ ಪ್ರವೇಶಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಅಲ್ಲಿ ನಾನು mqtt_as, uasyncio, ssd1306 ಮತ್ತು ನಾನು ಬಳಸಿದ ಸಂಗ್ರಹಣೆಗಳ ಲೈಬ್ರರಿಗಳನ್ನು ಸಹ ಅಪ್‌ಲೋಡ್ ಮಾಡಿದ್ದೇನೆ (mqtt_as ಒಳಗೆ ಬಳಸಲಾಗಿದೆ).

ನಾವು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ ಮತ್ತು... ನಾವು ಮೆಮೊರಿ ದೋಷವನ್ನು ಪಡೆಯುತ್ತೇವೆ. ಇದಲ್ಲದೆ, ಮೆಮೊರಿ ನಿಖರವಾಗಿ ಎಲ್ಲಿ ಸೋರಿಕೆಯಾಗುತ್ತಿದೆ ಎಂಬುದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ನಾನು ಹೆಚ್ಚು ಪ್ರಯತ್ನಿಸಿದೆ, ನಾನು ಹೆಚ್ಚು ಡೀಬಗ್ ಮುದ್ರಣಗಳನ್ನು ಇರಿಸಿದೆ, ಈ ದೋಷವು ಮೊದಲೇ ಕಾಣಿಸಿಕೊಂಡಿತು. ಒಂದು ಚಿಕ್ಕ Google ಹುಡುಕಾಟವು ಮೈಕ್ರೊಕಂಟ್ರೋಲರ್ ತಾತ್ವಿಕವಾಗಿ ಕೇವಲ 30 kB ಮೆಮೊರಿಯನ್ನು ಹೊಂದಿದೆ ಎಂಬ ತಿಳುವಳಿಕೆಗೆ ಕಾರಣವಾಯಿತು, ಅದರಲ್ಲಿ 65 kB ಕೋಡ್ (ಲೈಬ್ರರಿಗಳನ್ನು ಒಳಗೊಂಡಂತೆ) ಸರಳವಾಗಿ ಹೊಂದಿಕೊಳ್ಳುವುದಿಲ್ಲ.

ಆದರೆ ಒಂದು ಮಾರ್ಗವಿದೆ. ಮೈಕ್ರೋಪೈಥಾನ್ ನೇರವಾಗಿ .py ಫೈಲ್‌ನಿಂದ ಕೋಡ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದಿಲ್ಲ ಎಂದು ಅದು ತಿರುಗುತ್ತದೆ - ಈ ಫೈಲ್ ಅನ್ನು ಮೊದಲು ಕಂಪೈಲ್ ಮಾಡಲಾಗಿದೆ. ಇದಲ್ಲದೆ, ಇದನ್ನು ನೇರವಾಗಿ ಮೈಕ್ರೊಕಂಟ್ರೋಲರ್‌ನಲ್ಲಿ ಸಂಕಲಿಸಲಾಗುತ್ತದೆ, ಬೈಟ್‌ಕೋಡ್ ಆಗಿ ಪರಿವರ್ತಿಸಲಾಗುತ್ತದೆ, ನಂತರ ಅದನ್ನು ಮೆಮೊರಿಯಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗುತ್ತದೆ. ಸರಿ, ಕಂಪೈಲರ್ ಕೆಲಸ ಮಾಡಲು, ನಿಮಗೆ ನಿರ್ದಿಷ್ಟ ಪ್ರಮಾಣದ RAM ಸಹ ಬೇಕಾಗುತ್ತದೆ.

ಸಂಪನ್ಮೂಲ-ತೀವ್ರವಾದ ಸಂಕಲನದಿಂದ ಮೈಕ್ರೋಕಂಟ್ರೋಲರ್ ಅನ್ನು ಉಳಿಸುವುದು ಟ್ರಿಕ್ ಆಗಿದೆ. ನೀವು ದೊಡ್ಡ ಕಂಪ್ಯೂಟರ್‌ನಲ್ಲಿ ಫೈಲ್‌ಗಳನ್ನು ಕಂಪೈಲ್ ಮಾಡಬಹುದು ಮತ್ತು ಸಿದ್ಧ ಬೈಟ್‌ಕೋಡ್ ಅನ್ನು ಮೈಕ್ರೊಕಂಟ್ರೋಲರ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಬಹುದು. ಇದನ್ನು ಮಾಡಲು, ನೀವು ಮೈಕ್ರೋಪೈಥಾನ್ ಫರ್ಮ್ವೇರ್ ಅನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ ಮತ್ತು ನಿರ್ಮಿಸಬೇಕು ಎಂಪಿ-ಕ್ರಾಸ್ ಉಪಯುಕ್ತತೆ.

ನಾನು ಮೇಕ್‌ಫೈಲ್ ಅನ್ನು ಬರೆಯಲಿಲ್ಲ, ಆದರೆ ಹಸ್ತಚಾಲಿತವಾಗಿ ಹೋಗಿ ಅಗತ್ಯವಿರುವ ಎಲ್ಲಾ ಫೈಲ್‌ಗಳನ್ನು (ಲೈಬ್ರರಿಗಳನ್ನು ಒಳಗೊಂಡಂತೆ) ಈ ರೀತಿಯಾಗಿ ಸಂಕಲಿಸಿದೆ

mpy-cross water_counter.py

.mpy ವಿಸ್ತರಣೆಯೊಂದಿಗೆ ಫೈಲ್‌ಗಳನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡುವುದು ಮಾತ್ರ ಉಳಿದಿದೆ, ಸಾಧನದ ಫೈಲ್ ಸಿಸ್ಟಮ್‌ನಿಂದ ಅನುಗುಣವಾದ .py ಅನ್ನು ಮೊದಲು ಅಳಿಸಲು ಮರೆಯುವುದಿಲ್ಲ.

ನಾನು ಪ್ರೋಗ್ರಾಂ (IDE?) ESPlorer ನಲ್ಲಿ ಎಲ್ಲಾ ಅಭಿವೃದ್ಧಿಯನ್ನು ಮಾಡಿದ್ದೇನೆ. ಮೈಕ್ರೋಕಂಟ್ರೋಲರ್‌ಗೆ ಸ್ಕ್ರಿಪ್ಟ್‌ಗಳನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲು ಮತ್ತು ತಕ್ಷಣವೇ ಅವುಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ. ನನ್ನ ವಿಷಯದಲ್ಲಿ, ಎಲ್ಲಾ ವಸ್ತುಗಳ ಎಲ್ಲಾ ತರ್ಕ ಮತ್ತು ರಚನೆಯು water_counter.py (.mpy) ಫೈಲ್‌ನಲ್ಲಿದೆ. ಆದರೆ ಇದೆಲ್ಲವೂ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಪ್ರಾರಂಭವಾಗಬೇಕಾದರೆ, ಪ್ರಾರಂಭದಲ್ಲಿ main.py ಎಂಬ ಫೈಲ್ ಕೂಡ ಇರಬೇಕು. ಇದಲ್ಲದೆ, ಇದು ನಿಖರವಾಗಿ .py ಆಗಿರಬೇಕು ಮತ್ತು .mpy ಅನ್ನು ಮೊದಲೇ ಸಂಕಲಿಸಬಾರದು. ಅದರ ಕ್ಷುಲ್ಲಕ ವಿಷಯಗಳು ಇಲ್ಲಿವೆ

import water_counter

ನಾವು ಅದನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ - ಎಲ್ಲವೂ ಕೆಲಸ ಮಾಡುತ್ತದೆ. ಆದರೆ ಉಚಿತ ಮೆಮೊರಿ ಆತಂಕಕಾರಿಯಾಗಿ ಚಿಕ್ಕದಾಗಿದೆ - ಸುಮಾರು 1 ಕೆಬಿ. ಸಾಧನದ ಕಾರ್ಯವನ್ನು ವಿಸ್ತರಿಸಲು ನಾನು ಇನ್ನೂ ಯೋಜನೆಗಳನ್ನು ಹೊಂದಿದ್ದೇನೆ ಮತ್ತು ಈ ಕಿಲೋಬೈಟ್ ನನಗೆ ಸ್ಪಷ್ಟವಾಗಿ ಸಾಕಾಗುವುದಿಲ್ಲ. ಆದರೆ ಈ ಪ್ರಕರಣಕ್ಕೂ ಒಂದು ಮಾರ್ಗವಿದೆ ಎಂದು ಅದು ಬದಲಾಯಿತು.

ವಿಷಯ ಇಲ್ಲಿದೆ. ಫೈಲ್‌ಗಳನ್ನು ಬೈಟ್‌ಕೋಡ್‌ಗೆ ಕಂಪೈಲ್ ಮಾಡಲಾಗಿದೆ ಮತ್ತು ಆಂತರಿಕ ಫೈಲ್ ಸಿಸ್ಟಮ್‌ನಲ್ಲಿ ವಾಸಿಸುತ್ತಿದ್ದರೂ, ವಾಸ್ತವದಲ್ಲಿ ಅವುಗಳನ್ನು ಇನ್ನೂ RAM ಗೆ ಲೋಡ್ ಮಾಡಲಾಗುತ್ತದೆ ಮತ್ತು ಅಲ್ಲಿಂದ ಕಾರ್ಯಗತಗೊಳಿಸಲಾಗುತ್ತದೆ. ಆದರೆ ಮೈಕ್ರೋಪೈಥಾನ್ ಫ್ಲಾಶ್ ಮೆಮೊರಿಯಿಂದ ನೇರವಾಗಿ ಬೈಟ್ಕೋಡ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು ಎಂದು ಅದು ತಿರುಗುತ್ತದೆ, ಆದರೆ ಇದಕ್ಕಾಗಿ ನೀವು ಅದನ್ನು ನೇರವಾಗಿ ಫರ್ಮ್ವೇರ್ಗೆ ನಿರ್ಮಿಸಬೇಕಾಗಿದೆ. ಇದು ಕಷ್ಟವೇನಲ್ಲ, ಆದರೂ ನನ್ನ ನೆಟ್‌ಬುಕ್‌ನಲ್ಲಿ ಸ್ವಲ್ಪ ಸಮಯ ತೆಗೆದುಕೊಂಡಿತು (ಅಲ್ಲಿ ಮಾತ್ರ ನಾನು ಲಿನಕ್ಸ್ ಅನ್ನು ಹೊಂದಿದ್ದೇನೆ).

ಅಲ್ಗಾರಿದಮ್ ಈ ಕೆಳಗಿನಂತಿರುತ್ತದೆ:

  • ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ ಮತ್ತು ಸ್ಥಾಪಿಸಿ ESP ಓಪನ್ SDK. ಈ ವಿಷಯವು ESP8266 ಗಾಗಿ ಪ್ರೋಗ್ರಾಂಗಳಿಗಾಗಿ ಕಂಪೈಲರ್ ಮತ್ತು ಲೈಬ್ರರಿಗಳನ್ನು ಜೋಡಿಸುತ್ತದೆ. ಯೋಜನೆಯ ಮುಖ್ಯ ಪುಟದಲ್ಲಿನ ಸೂಚನೆಗಳ ಪ್ರಕಾರ ಜೋಡಿಸಲಾಗಿದೆ (ನಾನು STANDALONE = ಹೌದು ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿದ್ದೇನೆ)
  • ಡೌನ್ಲೋಡ್ ಮಾಡಿ ಮೈಕ್ರೋಪೈಥಾನ್ ವಿಧಗಳು
  • ಮೈಕ್ರೋಪೈಥಾನ್ ಟ್ರೀ ಒಳಗೆ ಪೋರ್ಟ್‌ಗಳು/esp8266/ಮಾಡ್ಯೂಲ್‌ಗಳಲ್ಲಿ ಅಗತ್ಯವಿರುವ ಲೈಬ್ರರಿಗಳನ್ನು ಇರಿಸಿ
  • ಫೈಲ್ನಲ್ಲಿನ ಸೂಚನೆಗಳ ಪ್ರಕಾರ ನಾವು ಫರ್ಮ್ವೇರ್ ಅನ್ನು ಜೋಡಿಸುತ್ತೇವೆ ports/esp8266/README.md
  • ನಾವು ಫರ್ಮ್‌ವೇರ್ ಅನ್ನು ಮೈಕ್ರೋಕಂಟ್ರೋಲರ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡುತ್ತೇವೆ (ನಾನು ಇದನ್ನು ವಿಂಡೋಸ್‌ನಲ್ಲಿ ESP8266Flasher ಪ್ರೋಗ್ರಾಂಗಳು ಅಥವಾ Python esptool ಬಳಸಿ ಮಾಡುತ್ತೇನೆ)

ಅಷ್ಟೆ, ಈಗ 'ಆಮದು ssd1306' ಕೋಡ್ ಅನ್ನು ನೇರವಾಗಿ ಫರ್ಮ್‌ವೇರ್‌ನಿಂದ ಎತ್ತುತ್ತದೆ ಮತ್ತು ಇದಕ್ಕಾಗಿ RAM ಅನ್ನು ಸೇವಿಸಲಾಗುವುದಿಲ್ಲ. ಈ ಟ್ರಿಕ್‌ನೊಂದಿಗೆ, ನಾನು ಲೈಬ್ರರಿ ಕೋಡ್ ಅನ್ನು ಮಾತ್ರ ಫರ್ಮ್‌ವೇರ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಿದ್ದೇನೆ, ಆದರೆ ಮುಖ್ಯ ಪ್ರೋಗ್ರಾಂ ಕೋಡ್ ಅನ್ನು ಫೈಲ್ ಸಿಸ್ಟಮ್‌ನಿಂದ ಕಾರ್ಯಗತಗೊಳಿಸಲಾಗುತ್ತದೆ. ಫರ್ಮ್‌ವೇರ್ ಅನ್ನು ಮರುಸಂಕಲಿಸದೆ ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಸುಲಭವಾಗಿ ಮಾರ್ಪಡಿಸಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ. ಈ ಸಮಯದಲ್ಲಿ ನಾನು ಸುಮಾರು 8.5kb ಉಚಿತ RAM ಅನ್ನು ಹೊಂದಿದ್ದೇನೆ. ಇದು ಭವಿಷ್ಯದಲ್ಲಿ ಸಾಕಷ್ಟು ವಿಭಿನ್ನ ಉಪಯುಕ್ತ ಕಾರ್ಯಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ನಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸರಿ, ಸಾಕಷ್ಟು ಮೆಮೊರಿ ಇಲ್ಲದಿದ್ದರೆ, ನೀವು ಮುಖ್ಯ ಪ್ರೋಗ್ರಾಂ ಅನ್ನು ಫರ್ಮ್‌ವೇರ್‌ಗೆ ತಳ್ಳಬಹುದು.

ಹಾಗಾದರೆ ನಾವು ಈಗ ಅದರ ಬಗ್ಗೆ ಏನು ಮಾಡಬೇಕು?

ಸರಿ, ಹಾರ್ಡ್‌ವೇರ್ ಅನ್ನು ಬೆಸುಗೆ ಹಾಕಲಾಗಿದೆ, ಫರ್ಮ್‌ವೇರ್ ಬರೆಯಲಾಗಿದೆ, ಬಾಕ್ಸ್ ಅನ್ನು ಮುದ್ರಿಸಲಾಗುತ್ತದೆ, ಸಾಧನವು ಗೋಡೆಯ ಮೇಲೆ ಅಂಟಿಕೊಂಡಿರುತ್ತದೆ ಮತ್ತು ಸಂತೋಷದಿಂದ ಬೆಳಕಿನ ಬಲ್ಬ್ ಅನ್ನು ಮಿಟುಕಿಸುತ್ತದೆ. ಆದರೆ ಇದೀಗ ಅದು ಕಪ್ಪು ಪೆಟ್ಟಿಗೆಯಾಗಿದೆ (ಅಕ್ಷರಶಃ ಮತ್ತು ಸಾಂಕೇತಿಕವಾಗಿ) ಮತ್ತು ಇದು ಇನ್ನೂ ಕಡಿಮೆ ಬಳಕೆಯಾಗಿದೆ. ಸರ್ವರ್‌ಗೆ ಕಳುಹಿಸಲಾದ MQTT ಸಂದೇಶಗಳೊಂದಿಗೆ ಏನನ್ನಾದರೂ ಮಾಡುವ ಸಮಯ ಇದು.

ನನ್ನ "ಸ್ಮಾರ್ಟ್ ಹೋಮ್" ತಿರುಗುತ್ತಿದೆ ಪ್ರಮುಖ ವ್ಯವಸ್ಥೆ. MQTT ಮಾಡ್ಯೂಲ್ ಬಾಕ್ಸ್‌ನಿಂದ ಹೊರಬರುತ್ತದೆ ಅಥವಾ ಆಡ್-ಆನ್ ಮಾರುಕಟ್ಟೆಯಿಂದ ಸುಲಭವಾಗಿ ಸ್ಥಾಪಿಸಲ್ಪಡುತ್ತದೆ - ನಾನು ಅದನ್ನು ಎಲ್ಲಿಂದ ಪಡೆದುಕೊಂಡೆ ಎಂದು ನನಗೆ ನೆನಪಿಲ್ಲ. MQTT ಸ್ವಾವಲಂಬಿ ವಿಷಯವಲ್ಲ - ನಿಮಗೆ ಕರೆಯಲ್ಪಡುವ ಅಗತ್ಯವಿದೆ. ಬ್ರೋಕರ್ - ಕ್ಲೈಂಟ್‌ಗಳಿಗೆ MQTT ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸುವ, ವಿಂಗಡಿಸುವ ಮತ್ತು ಫಾರ್ವರ್ಡ್ ಮಾಡುವ ಸರ್ವರ್. ನಾನು ಸೊಳ್ಳೆಯನ್ನು ಬಳಸುತ್ತೇನೆ, ಅದು (ಮೇಜರ್‌ಡೋಮೊ ನಂತಹ) ಅದೇ ನೆಟ್‌ಬುಕ್‌ನಲ್ಲಿ ಚಲಿಸುತ್ತದೆ.

ಸಾಧನವು ಒಮ್ಮೆಯಾದರೂ ಸಂದೇಶವನ್ನು ಕಳುಹಿಸಿದ ನಂತರ, ಮೌಲ್ಯವು ತಕ್ಷಣವೇ ಪಟ್ಟಿಯಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತದೆ.

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಈ ಮೌಲ್ಯಗಳನ್ನು ಈಗ ಸಿಸ್ಟಮ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳೊಂದಿಗೆ ಸಂಯೋಜಿಸಬಹುದು, ಅವುಗಳನ್ನು ಯಾಂತ್ರೀಕೃತಗೊಂಡ ಸ್ಕ್ರಿಪ್ಟ್‌ಗಳಲ್ಲಿ ಬಳಸಬಹುದು ಮತ್ತು ವಿವಿಧ ವಿಶ್ಲೇಷಣೆಗಳಿಗೆ ಒಳಪಡಿಸಬಹುದು - ಇವೆಲ್ಲವೂ ಈ ಲೇಖನದ ವ್ಯಾಪ್ತಿಯನ್ನು ಮೀರಿದೆ. ಆಸಕ್ತಿ ಹೊಂದಿರುವ ಯಾರಿಗಾದರೂ ನಾನು ಮೇಜರ್ಡೋಮೊ ವ್ಯವಸ್ಥೆಯನ್ನು ಶಿಫಾರಸು ಮಾಡಬಹುದು ಚಾನಲ್ ಎಲೆಕ್ಟ್ರಾನಿಕ್ಸ್ ಇನ್ ಲೆನ್ಸ್ — ಸ್ನೇಹಿತರೊಬ್ಬರು ಸ್ಮಾರ್ಟ್ ಹೋಮ್ ಅನ್ನು ಸಹ ನಿರ್ಮಿಸುತ್ತಿದ್ದಾರೆ ಮತ್ತು ಸಿಸ್ಟಮ್ ಅನ್ನು ಹೊಂದಿಸುವ ಬಗ್ಗೆ ಸ್ಪಷ್ಟವಾಗಿ ಮಾತನಾಡುತ್ತಾರೆ.

ನಾನು ನಿಮಗೆ ಒಂದೆರಡು ಗ್ರಾಫ್‌ಗಳನ್ನು ತೋರಿಸುತ್ತೇನೆ. ಇದು ದೈನಂದಿನ ಮೌಲ್ಯಗಳ ಸರಳ ಗ್ರಾಫ್ ಆಗಿದೆ

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ
ರಾತ್ರಿ ವೇಳೆ ಬಹುತೇಕರು ನೀರು ಬಳಸದೇ ಇರುವುದು ಕಂಡು ಬರುತ್ತಿದೆ. ಒಂದೆರಡು ಬಾರಿ ಯಾರಾದರೂ ಶೌಚಾಲಯಕ್ಕೆ ಹೋದರು, ಮತ್ತು ರಿವರ್ಸ್ ಆಸ್ಮೋಸಿಸ್ ಫಿಲ್ಟರ್ ಪ್ರತಿ ರಾತ್ರಿಗೆ ಒಂದೆರಡು ಲೀಟರ್ಗಳನ್ನು ಹೀರಿಕೊಳ್ಳುತ್ತದೆ ಎಂದು ತೋರುತ್ತದೆ. ಬೆಳಿಗ್ಗೆ, ಬಳಕೆ ಗಮನಾರ್ಹವಾಗಿ ಹೆಚ್ಚಾಗುತ್ತದೆ. ನಾನು ಸಾಮಾನ್ಯವಾಗಿ ಬಾಯ್ಲರ್ನಿಂದ ನೀರನ್ನು ಬಳಸುತ್ತೇನೆ, ಆದರೆ ನಂತರ ನಾನು ಸ್ನಾನ ಮಾಡಲು ಬಯಸುತ್ತೇನೆ ಮತ್ತು ತಾತ್ಕಾಲಿಕವಾಗಿ ನಗರ ಬಿಸಿನೀರಿಗೆ ಬದಲಾಯಿಸಿದೆ - ಇದು ಕೆಳಭಾಗದ ಗ್ರಾಫ್ನಲ್ಲಿಯೂ ಸಹ ಸ್ಪಷ್ಟವಾಗಿ ಗೋಚರಿಸುತ್ತದೆ.

ಈ ಗ್ರಾಫ್‌ನಿಂದ ನಾನು ಟಾಯ್ಲೆಟ್‌ಗೆ ಹೋಗಲು 6-7 ಲೀಟರ್ ನೀರು ಬೇಕು, ಸ್ನಾನ ಮಾಡಲು 20-30 ಲೀಟರ್ ಬೇಕು, ಪಾತ್ರೆ ತೊಳೆಯಲು ಸುಮಾರು 20 ಲೀಟರ್ ಬೇಕು ಮತ್ತು ಸ್ನಾನಕ್ಕೆ 160 ಲೀಟರ್ ಬೇಕು ಎಂದು ಕಲಿತಿದ್ದೇನೆ. ನನ್ನ ಕುಟುಂಬವು ದಿನಕ್ಕೆ 500-600 ಲೀಟರ್ಗಳಷ್ಟು ಎಲ್ಲೋ ಬಳಸುತ್ತದೆ.

ವಿಶೇಷವಾಗಿ ಕುತೂಹಲ ಹೊಂದಿರುವವರಿಗೆ, ನೀವು ಪ್ರತಿಯೊಂದು ಮೌಲ್ಯದ ದಾಖಲೆಗಳನ್ನು ನೋಡಬಹುದು

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಟ್ಯಾಪ್ ತೆರೆದಾಗ, ನೀರು 1 ಸೆಕೆಂಡಿಗೆ ಸುಮಾರು 5 ಲೀಟರ್ ವೇಗದಲ್ಲಿ ಹರಿಯುತ್ತದೆ ಎಂದು ಇಲ್ಲಿಂದ ನಾನು ಕಲಿತಿದ್ದೇನೆ.

ಆದರೆ ಈ ರೂಪದಲ್ಲಿ ಅಂಕಿಅಂಶಗಳು ಬಹುಶಃ ನೋಡಲು ತುಂಬಾ ಅನುಕೂಲಕರವಾಗಿಲ್ಲ. Majordomo ದಿನ, ವಾರ ಮತ್ತು ತಿಂಗಳ ಮೂಲಕ ಬಳಕೆಯ ಚಾರ್ಟ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಹೊಂದಿದೆ. ಇಲ್ಲಿ, ಉದಾಹರಣೆಗೆ, ಬಾರ್‌ಗಳಲ್ಲಿ ಬಳಕೆಯ ಗ್ರಾಫ್ ಆಗಿದೆ

ನಾವು ನೀರಿನ ಮೀಟರ್ ಅನ್ನು ಸ್ಮಾರ್ಟ್ ಮನೆಗೆ ಸಂಪರ್ಕಿಸುತ್ತೇವೆ

ಇಲ್ಲಿಯವರೆಗೆ ನನ್ನ ಬಳಿ ಕೇವಲ ಒಂದು ವಾರದ ಡೇಟಾ ಇದೆ. ಒಂದು ತಿಂಗಳಲ್ಲಿ, ಈ ಗ್ರಾಫ್ ಹೆಚ್ಚು ಸೂಚಕವಾಗಿರುತ್ತದೆ - ಪ್ರತಿ ದಿನವೂ ಪ್ರತ್ಯೇಕ ಕಾಲಮ್ ಇರುತ್ತದೆ. ನಾನು ಹಸ್ತಚಾಲಿತವಾಗಿ ನಮೂದಿಸುವ ಮೌಲ್ಯಗಳಿಗೆ ಹೊಂದಾಣಿಕೆಗಳಿಂದ ಚಿತ್ರವು ಸ್ವಲ್ಪ ಹಾಳಾಗುತ್ತದೆ (ಅತಿದೊಡ್ಡ ಕಾಲಮ್). ಮತ್ತು ನಾನು ಮೊದಲ ಮೌಲ್ಯಗಳನ್ನು ತಪ್ಪಾಗಿ ಹೊಂದಿಸಿದ್ದೇನೆಯೇ, ಸುಮಾರು ಒಂದು ಘನ ಕಡಿಮೆ, ಅಥವಾ ಇದು ಫರ್ಮ್‌ವೇರ್‌ನಲ್ಲಿ ದೋಷವಾಗಿದೆಯೇ ಮತ್ತು ಎಲ್ಲಾ ಲೀಟರ್‌ಗಳನ್ನು ಎಣಿಸಲಾಗಿಲ್ಲವೇ ಎಂಬುದು ಇನ್ನೂ ಸ್ಪಷ್ಟವಾಗಿಲ್ಲ. ಹೆಚ್ಚು ಸಮಯ ಬೇಕು.

ಗ್ರಾಫ್‌ಗಳಿಗೆ ಇನ್ನೂ ಕೆಲವು ಮ್ಯಾಜಿಕ್, ವೈಟ್‌ವಾಶಿಂಗ್, ಪೇಂಟಿಂಗ್ ಅಗತ್ಯವಿದೆ. ಬಹುಶಃ ಡೀಬಗ್ ಮಾಡುವ ಉದ್ದೇಶಗಳಿಗಾಗಿ ನಾನು ಮೆಮೊರಿ ಬಳಕೆಯ ಗ್ರಾಫ್ ಅನ್ನು ಸಹ ನಿರ್ಮಿಸುತ್ತೇನೆ - ಅಲ್ಲಿ ಏನಾದರೂ ಸೋರಿಕೆಯಾಗುತ್ತಿದ್ದರೆ. ಇಂಟರ್ನೆಟ್ ಇಲ್ಲದಿರುವಾಗ ಬಹುಶಃ ನಾನು ಹೇಗಾದರೂ ಅವಧಿಗಳನ್ನು ಪ್ರದರ್ಶಿಸುತ್ತೇನೆ. ಸದ್ಯಕ್ಕೆ ಇದೆಲ್ಲ ವಿಚಾರಗಳ ಮಟ್ಟದಲ್ಲಿದೆ.

ತೀರ್ಮಾನಕ್ಕೆ

ಇಂದು ನನ್ನ ಅಪಾರ್ಟ್ಮೆಂಟ್ ಸ್ವಲ್ಪ ಚುರುಕಾಗಿದೆ. ಅಂತಹ ಸಣ್ಣ ಸಾಧನದೊಂದಿಗೆ, ಮನೆಯಲ್ಲಿ ನೀರಿನ ಬಳಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಲು ನನಗೆ ಹೆಚ್ಚು ಅನುಕೂಲಕರವಾಗಿರುತ್ತದೆ. ಮೊದಲು ನಾನು "ಮತ್ತೆ, ನಾವು ಒಂದು ತಿಂಗಳಲ್ಲಿ ಸಾಕಷ್ಟು ನೀರು ಸೇವಿಸಿದ್ದೇವೆ" ಎಂದು ಕೋಪಗೊಂಡಿದ್ದರೆ, ಈಗ ನಾನು ಈ ಸೇವನೆಯ ಮೂಲವನ್ನು ಕಂಡುಹಿಡಿಯಬಹುದು.

ಮೀಟರ್‌ನಿಂದ ಒಂದು ಮೀಟರ್ ದೂರದಲ್ಲಿದ್ದರೆ ಪರದೆಯ ಮೇಲಿನ ರೀಡಿಂಗ್‌ಗಳನ್ನು ನೋಡಲು ಕೆಲವರು ವಿಚಿತ್ರವೆನಿಸಬಹುದು. ಆದರೆ ಬಹಳ ದೂರದ ಭವಿಷ್ಯದಲ್ಲಿ, ನಾನು ಮತ್ತೊಂದು ಅಪಾರ್ಟ್ಮೆಂಟ್ಗೆ ಹೋಗಲು ಯೋಜಿಸುತ್ತೇನೆ, ಅಲ್ಲಿ ಹಲವಾರು ನೀರಿನ ರೈಸರ್ಗಳು ಇರುತ್ತವೆ, ಮತ್ತು ಮೀಟರ್ಗಳು ಸ್ವತಃ ಲ್ಯಾಂಡಿಂಗ್ನಲ್ಲಿವೆ. ಆದ್ದರಿಂದ ರಿಮೋಟ್ ಓದುವ ಸಾಧನವು ತುಂಬಾ ಉಪಯುಕ್ತವಾಗಿದೆ.

ಸಾಧನದ ಕಾರ್ಯವನ್ನು ವಿಸ್ತರಿಸಲು ಸಹ ನಾನು ಯೋಜಿಸುತ್ತೇನೆ. ನಾನು ಈಗಾಗಲೇ ಮೋಟಾರು ಕವಾಟಗಳನ್ನು ನೋಡುತ್ತಿದ್ದೇನೆ. ಈಗ, ಬಾಯ್ಲರ್ ಅನ್ನು ನಗರದ ನೀರಿಗೆ ಬದಲಾಯಿಸಲು, ನಾನು ತಲುಪಲು ಕಷ್ಟವಾದ ಸ್ಥಳದಲ್ಲಿ 3 ಟ್ಯಾಪ್‌ಗಳನ್ನು ತಿರುಗಿಸಬೇಕಾಗಿದೆ. ಅನುಗುಣವಾದ ಸೂಚನೆಯೊಂದಿಗೆ ಒಂದು ಗುಂಡಿಯೊಂದಿಗೆ ಇದನ್ನು ಮಾಡಲು ಹೆಚ್ಚು ಅನುಕೂಲಕರವಾಗಿರುತ್ತದೆ. ಸರಿ, ಸಹಜವಾಗಿ, ಸೋರಿಕೆಯ ವಿರುದ್ಧ ರಕ್ಷಣೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಇದು ಯೋಗ್ಯವಾಗಿದೆ.

ಲೇಖನದಲ್ಲಿ ನಾನು ESP8266 ಆಧಾರಿತ ಸಾಧನದ ನನ್ನ ಆವೃತ್ತಿಯನ್ನು ವಿವರಿಸಿದೆ. ನನ್ನ ಅಭಿಪ್ರಾಯದಲ್ಲಿ, ನಾನು ಕೊರೊಟೀನ್‌ಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಮೈಕ್ರೋಪೈಥಾನ್ ಫರ್ಮ್‌ವೇರ್‌ನ ಅತ್ಯಂತ ಆಸಕ್ತಿದಾಯಕ ಆವೃತ್ತಿಯೊಂದಿಗೆ ಬಂದಿದ್ದೇನೆ - ಸರಳ ಮತ್ತು ಒಳ್ಳೆಯದು. ಪ್ರಚಾರದ ಸಮಯದಲ್ಲಿ ನಾನು ಎದುರಿಸಿದ ಅನೇಕ ಸೂಕ್ಷ್ಮ ವ್ಯತ್ಯಾಸಗಳು ಮತ್ತು ನ್ಯೂನತೆಗಳನ್ನು ವಿವರಿಸಲು ನಾನು ಪ್ರಯತ್ನಿಸಿದೆ. ಬಹುಶಃ ನಾನು ಎಲ್ಲವನ್ನೂ ಹೆಚ್ಚು ವಿವರವಾಗಿ ವಿವರಿಸಿದ್ದೇನೆ; ವೈಯಕ್ತಿಕವಾಗಿ, ಓದುಗನಾಗಿ, ಹೇಳದೆ ಉಳಿದಿರುವುದನ್ನು ನಂತರ ಯೋಚಿಸುವುದಕ್ಕಿಂತ ಅನಗತ್ಯವಾದ ವಿಷಯವನ್ನು ಬಿಟ್ಟುಬಿಡುವುದು ನನಗೆ ಸುಲಭವಾಗಿದೆ.

ಎಂದಿನಂತೆ, ನಾನು ರಚನಾತ್ಮಕ ಟೀಕೆಗೆ ಮುಕ್ತನಾಗಿದ್ದೇನೆ.

ಮೂಲ ಕೋಡ್
ಸರ್ಕ್ಯೂಟ್ ಮತ್ತು ಬೋರ್ಡ್
ಕೇಸ್ ಮಾದರಿ

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ