áá áşááťáááşáá áĄáááşáĄáááŻáĄááťáąáŹááşá áá áşááťáŹá¸ áááŻáˇáááŻááş áááşá¸áááŻáˇááᯠáááźáŹááááąáŤáşááąáˇáážááááˇáş "á áááşáĄáááş" áááş áĄáá˝ááşá áťáąá¸ááźáŽá¸ááźáŽá¸ ááťááşá¸ááŹáá°ááťáŹá¸áᏠáááşá¸áááŻáˇááᯠáááşáááŻááşáá˛áˇáááşá áááąáˇá áťáąá¸áá˝ááşáá˝ááş áĄáááşá¸ááąáŹááşá ááźáąá á˝ááşááťáŹá¸á ááąáááşááąáá˝ááşá ááąááąá¸ááąáážáŻáážááˇáş áĄááźáŹá¸á áŹá¸ááŻáśá¸áá°ááťáŹá¸ááᯠááááşá¸ááťáŻááşáááşáĄáá˝ááş áĄáŹááŻáśááśááááááŹááťáŹá¸á áááŻááşááťáŹá¸/áááŻááşááťáŹá¸ áážááˇáş actuators ááťáŹá¸ááŤáážáááąáŹ á áťáąá¸áááşááŹááąáŹááááááŹáĄá áŻáśáĄáááşááᯠáááşáážáŹáá˝áąáˇáááŻááşááŤáááşá áĄááááşáĄááŹááŻáśá¸ DIY áááşáááş á áťáąá¸áááşááŹááąáŹ á áťáąá¸áážáŻááşá¸ááźááˇáş á áááşáĄáááşáĄáá˝ááş áĄáážááŻááşáážááˇáş á ááşáá ášá ááşá¸ááťáŹá¸ááᯠáááşáááşáááŻááşáááş á
ááŻáśáážááşáĄáŹá¸ááźááˇáşá áĄáááŻááźáŻááŹá¸áááˇáşááááááŹááťáŹá¸áááş áĄáŹááŻáśááśááááááŹááťáŹá¸ áááŻáˇáááŻááş áážáŻáśáˇááąáŹáşááąá¸áááˇáşáĄááŹááťáŹá¸ááźá
áşáááşá áááşá¸áááŻáˇáááş "áá˝áąáˇááťáŹá¸áážáŻáĄáŹááŻáśááśááááááŹáááŻáĄá
ááťááŻá¸ááąáŹáĄááŤá ááŽá¸ááťáŹá¸áááŻáá˝ááˇáşááŤ" áááŻáˇáááŻááş "áááŻááşáááşá¸áá
áşááŻááŻáśá¸áážááá˝ááşááąáŤááşáĄááŽá¸áážááááŻááşáááş ááŽá¸ááááşáá˝áŹá¸áááş" áá˛áˇáááŻáˇááąáŹ áĄááźáąáĄááąááťáŹá¸ááᯠáĄááąáŹááşáĄáááşááąáŹáşáááş áá˝ááşáá°á
áąáááşá áááŻáˇááąáŹáş áááşááŽááŽááŹááźááˇáş áá
áşá
áŻáśáá
áşáᏠáĄáááşáááźáąáá˛áˇááŤá áĄááąáŹááşá¸ááŻáśá¸áážáŹá áááşá¸áááş áĄáá°ááťáááşáážááˇáş á
ááŻáááŻááşá¸áá ááááş (áááŻáˇ) ááááťááąáŹ áá˝ááşááąáŤááşáá
áşááŻáážá ááťááşááźááşá¸ááŤááŤááźá
áşáááşá
áááźáŹááąá¸ááŽá ááťá˝ááşáŻááşáááş áá˝áąá¸ááŻááşáážáŻááşá¸áĄáá˝ááşááźááˇáş ááąááŽááŹááᯠáááşáááşáá˛áˇáááşá ááŽááŹááźááşáá˝áŹá¸ááąáŹááŽááŹáááŻááşá¸áĄáá˝ááş Reed switch áááş áĄáááşáááşááźáŽá¸ áĄáááşáĄáá˝ááşááᯠááááşáááşá ááŻááşá ááŹááťááşááŹá áááŻááşááŹááźááŻá¸áá˝áąááᯠáá˝ááşáááşááźáŽá¸ áĄááťááŻá¸áĄááźááşááĄáąáŹááş ááźááŻá¸á áŹá¸ááŤá áĽáááŹáĄáŹá¸ááźááˇáşá áá áşáááşá ááŹááŽáážááˇáş ááąáˇáĄáááŻááş ááąááŻáśá¸á á˝á˛áážáŻááᯠáááŻááşá¸ááźáŹá¸á áááşááźáŹááŤá ááąáŹááşá¸ááźáŽá áááŻááşáááşá¸áá˝ááş water risers áĄááťáŹá¸áĄááźáŹá¸áážáááąááŤáá áááşáážáááşááŹááşááŽá¸ááźááˇáşááąáŹááşáážááááşáááşáá˛ááąáŹááąááŹááťáŹá¸áááŻáˇáááşááźááşá¸áááş screen áá áşááŻááąáŤáşáá˝ááşáááşáážááá˝ážááşááááşá¸áĄáŹá¸ááŻáśá¸áááŻááźááˇáşáážáŻáááşáááŻáááŻáĄáááşááźáąáááşá
ááźááşááąáŹááşáážáŻáĄáąáŹááşáá˝ááş ESP8266 áááŻáĄááźáąááśááŹá¸áááˇáş ááťá˝ááşáŻááşáááŹá¸áážááşá¸áááş ááąááŽááŹááž áá˛ááťááŻá¸á
áŻáśááťáŹá¸ááᯠááąáá˝ááşáᏠMQTT áážáá
áşáááˇáş smart home ááŹááŹáááŻáˇ ááąá¸áááŻáˇáááˇáş ááááááŹáá
áşááŻááźá
áşáááşá uasyncio á
áŹááźááˇáşáááŻááşááᯠáĄááŻáśá¸ááźáŻá micropython ááźááˇáş ááááŻááááşááŻááşááŤáááşá Firmware áááŻáááşááŽá¸ááąáŹáĄááŤáá˝ááşá ááťá˝ááşáŻááşáááşá¤ááąáŹááşá¸ááŤá¸áá˝ááşáá˝áąá¸áá˝áąá¸áááˇáşá
áááşáááşá
áŹá¸áá˝ááşáĄáááşáĄáá˛ááťáŹá¸á
á˝áŹáááŻáá˝áąáˇáá˛áˇááááşá áá˝áŹá¸!
áĄá áŽáĄá ááş
ááŹá¸áá
áşáá
áşááŻááŻáśá¸ááážááŻáśá¸áááş ESP8266 microcontroller áážá module áá
áşááŻááźá
áşáááşá ESP-12 ááᯠáá°áá á
áŽá
ááşáá˛áˇááąáŹáşáááşá¸ áááŻááşá¸ ááťá˝ááşáá˝ááşá¸áá˝áŹá¸áá˛áˇáááşá ááááŻááşááąáŹ ESP-07 module áážááˇáş ááťá˝ááşáŻááşáááŻáˇ ááťáąáááşááąáááŤáááşá ááśááąáŹááşá¸ááąáŹááşáá
á˝áŹá áááşá¸áááŻáˇáááş áááşááśááŤááşááťáŹá¸áážááˇáş ááŻááşááąáŹááşáááŻááşá
á˝ááşá¸áĄá áá°ááŽáááşá áá
áşááŻáááşá¸ááąáŹááźáŹá¸ááŹá¸ááťááşáážáŹ áĄááşáááşááŹáá˝ááşááźá
áşáááş - ESP-12 áá˝ááş built-in áá
áşááŻááŤáážáááźáŽá¸ ESP-07 áá˝ááş ááźááşááá
áşááŻáážááááşá áááŻáˇááąáŹáşá WiFi áĄááşááŹááŹááážááááˇáşáááŻááş ááťá˝ááşáŻááşáááąááťááŻá¸áááşá¸áážá áĄááťááşááźáážáŻááᯠááŻáśáážááşáĄáááŻááşá¸ áááşááśááážáááŤáááşá
ááŻáśáážááş module áááŻááşááŹááźááŻá¸ááťáŹá¸
- áá˝á˛áĄáŹá¸áážááˇáş ááŹááŹá áŽááŹááźááˇáş ááźááşáááşáááşáážááşáááş áááŻááş (áážá áşááŻááŻáśá¸áááş ááąáŹáşááťá°á¸áĄáá˝ááşá¸áá˝ááş áážááážááˇáşááąááąáŹáşáááşá¸)
- áá˝ááˇáşááŹá¸áááˇáş áĄááťááşááź (CH_PD) ááᯠááŤááŤáĄáá áá˝á˛áááşááŹá¸áááşá
- GPIO15 ááᯠááźáąááźááşááąáŤáşáááŻáˇ áá˝á˛áááşáááŻááşáááşá ááŤá áĄá áážáŹáᏠáááŻáĄááşááąáááˇáş ááŽááźáąááąáŹááşáá˛áˇ áá˝á˛áááŻáˇ ááŹááž ááážáááąá¸ááŤáá°á¸á áĄá˛ááŤááᯠááááŻáĄááşááąáŹáˇááŤáá°á¸á
module ááᯠfirmware ááŻááşáá˝ááşáááˇáşáááşá áááşáááş GPIO2 áááşáááşá¸áááŻáááşáááŻááźáŽá¸ áááŻáááŻáĄáááşááźáąá áąáááşáĄáá˝ááşá ááťá˝ááşáŻááşáááş Boot áááŻááşááᯠááąá¸ááŹá¸ááŤáááşá ááŻáśáážááşáĄááźáąáĄááąáá˝ááşá á¤áááşááᯠááŤááŤáááŻáˇ áá˝á˛ááŻááşáááşá
GPIO2 áááŻááşá¸ááĄááźáąáĄááąááᯠáááşáááşáážáŻáĄá áá˝ááşáᏠá á áşááąá¸áááş - ááŤááŤáĄááŻáśá¸ááźáŻáááˇáşáĄá፠áááŻáˇáááŻááş ááźááşáááşáááşáážááşááźáŽá¸ááąáŹááşááťááşááťááşá¸á á áşááąá¸áááşá áááŻáˇááźáąáŹááˇáş module áááş ááŻáśáážááşáĄáááŻááşá¸ boot áááşáááş áááŻáˇáááŻááş firmware ááŻááşáááŻáˇ ááąáŹááşáá˝áŹá¸ááŤáááşá áááşááźáŽá¸áááşáážááˇáşá á¤áááşááśááŤááşááᯠááŻáśáážááş GPIO áĄááźá áş áĄááŻáśá¸ááźáŻáááŻááşáááşá ááąáŹááşá¸ááźáŽá áĄá˛ááŽáážáŹ áááŻááşáá áşááŻáážáááźáŽá¸ááŹá¸áááŻáˇá áĄááŻáśá¸áááşáá˛áˇ function áá áşááťááŻáˇááᯠáĄá˛ááŤáá˛áˇáá˝á˛áááŻáˇáááŤáááşá
ááááŻááááşááąá¸áá˝á˛ááźááşá¸áážááˇáş áĄáážáŹá¸ááźááşáááşááźááşá¸áĄáá˝ááş ááťá˝ááşáŻááşáááş ááźáŽá¸áá áşááŻáááŻáˇ áĄáá˝ááşááźá áşáááˇáş UART ááᯠáĄááŻáśá¸ááźáŻááŤáááşá áááŻáĄááşááąáŹáĄááŤáá˝ááşá USB-UART adapter ááᯠáááŻááąááŹáá˝ááş ááťáááşáááşááŤá module áááş 3.3V ááźááˇáş ááŤááŤáážáááźáąáŹááşá¸ áážááşááŹá¸ááŹá¸áááş áááŻáĄááşááŤáááşá áĄáááşááŹáĄáŹá¸ á¤áááŻáˇáĄáŹá¸áážááˇáş 5V ááąáŹááşááśáˇáááş ááąáˇááťáąáŹáˇááŤáá ááąáŹáşááťá°á¸áááş ááąáŹááşááťá˝ááşá¸áá˝áŹá¸áá˝ááşáážááááşá
ááŤááąááťááŻá¸áááşá¸áá˛áážáŹááťážááşá
á
áşááŽá¸ááźáżááŹááážáááŤáá°á¸ - áá˝ááşááąáŤááşáááşááŽááŹáážáá
áşááŽááŹáĄáá˝áŹáá˝ááşáááşáážáááąáŹááźáąáŹááˇáşááŤáááş 220V ááźááˇáşááŤááŤááąá¸ááááˇáşáááşá ááŤááŤáááşá¸ááźá
áşáá
áşááŻáĄááąáá˛áˇ ááťá˝ááşááąáŹáˇáşáážáŹ áĄááąá¸á
áŹá¸áá
áşááŻáážááááşá
áĄááťááşááźáááˇáş áááşáááşáážáŻááŻááşááťáŹá¸áĄáá˝ááş ááťá˝ááşáŻááşáááş GPIO2 áážááˇáş ááťáááşáááşááŹá¸ááąáŹ LED áá áşááŻááᯠááąá¸ááŹá¸ááŤáááşá ááŤááąáááˇáş ááŤá áĄá˛ááŤááᯠáááźáŻááşá¸áá°á¸áááŻááąáŹáˇ... ESP-07 ááąáŹáşááťá°á¸áá˝ááş LED ááŤáážáááźáŽá¸ááźá áşáᏠGPIO2 áááŻáááşá¸ ááťáááşáááşááŹá¸áááşá ááŤááąáááˇáş áᎠLED ááᯠáĄááŻáśá¸áážáŹ ááŻááşááťááşáááşááąáŹáˇ áĄá˛ááŤááᯠááŻááşááąáŤáşáážáŹ ááŹá¸áááŻááşááŤá
á áááşáááşá áŹá¸á ááŹáĄááąáŹááşá¸ááŻáśá¸áĄáááŻááşá¸ááᯠáááşáá˝áŹá¸ááźááĄáąáŹááşá ááąááŽááŹáá˝ááş ááŻáášááááážáááŤá áááşáážááááşáážáŻáááş áááşá¸áááŻáˇááᯠáááşááąáŹááşá¸áááŻáááááŤá ááťá˝ááşáŻááşáááŻáˇáĄáá˝ááş áá áşááŻáááşá¸ááąáŹ áĄááŹáážáŹ áá˝ááşá¸áĄáŹá¸ááťáŹá¸ááźá áşáááş - ááŽááŹáááŻááşá¸áá˝ááş Reed switch á áĄáááşáĄáá˝ááşááťáŹá¸ááᯠááááşááŤá ááťá˝ááşáŻááşá reed switch output ááťáŹá¸ááᯠGPIO12/GPIO13 áážááˇáş ááťáááşáááşááŹá¸áááşá ááąáŹáşááťá°á¸áĄáá˝ááşá¸áá˝ááş áá˝á˛áá°ááśáááŻááşáááşáĄáŹá¸ ááááŻááááşá áá áşááźááˇáş áá˝ááˇáşááŤáááşá
áĄá áááŻááşá¸áá˝ááşá ááťá˝ááşáŻááşáááş resistors R8 áážááˇáş R9 áááŻááąá¸ááąáŹááşáááşááąáˇáá˝áŹá¸áᏠááťá˝ááşáŻááşáááŻááşááŹá¸áážááşá¸áá˝ááş áááşá¸áááŻáˇáááŤáááşááŤá ááŤááąáááˇáş áá°áááŻááşá¸ááźááşáááŻááşá áąáááˇáş ááŻáśááźááşá¸ááᯠááŤáááşááŹá¸ááźáŽá¸ááźá áşáááŻáˇ ááŽááźáŽá¸ááźááşáážáŻááᯠááźáŻááźááşáááˇáşáááşá Firmware ááťááŻáˇáá˝ááşá¸ááźáŽá¸ áááşááśááŤááşááᯠáááşáážááşááąá¸ááŤá ááááşáááşá¸ááᯠááŽá¸áááąáŹááşá áąáááş Resistors ááťáŹá¸ áááŻáĄááşááźáŽá¸ Reed switch áááş á¤áááŻááşá¸ááᯠááźáąááźááşáááŻáˇ áááŻá áąáááş ( resistor áááş áĄááťáŹá¸ááŻáśá¸ 3.3V/1000Ohm = 3.3mA á áŽá¸áááşá¸ááŤáááş)á
ááťážááşá á áşááŽá¸ááźááşáááş ááŹááŻááşáááá˛áááŻáᏠá ááşá¸á áŹá¸áááŻáˇáĄááťáááşááąáŹááşááźáŽá ááááá˝áąá¸ááťááşáážáŻáážáŹ á áááşááťáááşáá˝ááş ááŹááŹááž áááŚá¸ áááşááźááşáááşáááŻá¸ááťáŹá¸ááᯠááąáŹááşá¸áááŻáááşááźá áşáááşá ááŤááąáááˇáş ááŤá áá˛áážááşááąá¸ááááŻáááŻááąáŹáá˛áˇ ááááŹáááşáážáŹá¸áá˛áˇ áážáŻááşáá˝áąá¸áážáŻáá˝áą áááŻáĄááşááŤááááˇáşáááşá áááŻáˇáĄááźááşá á¤ááá ášá áá˝ááşá ááşáá ášá ááşá¸áá á˝ááşá¸ááąáŹááşáááşáááşááŹááŹááĄááźáąáĄááąááąáŤáşáá˝ááşáá°áááşáááşá ááŤááŤááááşááźáŽá¸ááąáŹááş ááŹááŹááž áá áááşááŤá (áááŻáˇáááŻááş ááąáŹááşáááŻááşá¸áá˝ááş á áááşáá˛áˇáááş)á ááąááŽááŹáááş áááŚá¸áááşáááŻá¸ááťáŹá¸ááᯠááąáŹááşá¸áááŻáááŻááşáááşáááŻááşáááˇáşáĄááźááş áážááşáááşá á˝áŹáĄááŻááşáááŻááşááŤá
áááŻáˇááźáąáŹááˇáşá I2C áážáá áşáááˇáş ááťáááşáááşááŹá¸ááąáŹ Memory ááťá áşááşáá áşááŻáá˝ááş ááąáŹááşááŹáááşáááŻá¸ááťáŹá¸ááᯠááááşá¸áááşá¸áááş ááŻáśá¸ááźááşáá˛áˇáááşá ááťá˝ááşáŻááşáá˝ááş flash memory áĄáá˝ááşáĄá áŹá¸áĄáá˝ááş áĄáá°á¸áááŻáĄááşááťááşááťáŹá¸ááážáá፠- áááşáááş ááśááŤááş á ááŻáśá¸ (ááąáá°áážááˇáşááąáĄáąá¸ááŽááŹáĄáááŻááş ááŽááŹáĄááąáĄáá˝ááş) ááᯠááááşá¸áááşá¸áááş áááŻáĄááşááŤáááşá áĄááąá¸ááŻáśá¸ module áá˝áąááąáŹááş ááŻááşááŤááááˇáşáááşá ááŤááąáááˇáş áĄááśáá˝ááşá¸áá˛áˇ áĄááźáááşáĄááąáĄáá˝ááşááᯠáĄáŹááŻáśá ááŻááşáááŻáˇ áááŻááŤáááşá module áĄááťáŹá¸á áŻáĄáá˝ááş áááşá¸áááş 2 cycles ááźá áşááźáŽá¸ áĄááťááŻáˇáááş áá áşáááşá¸áĄááááźá áşáááşá
áá áşáááşá¸á áĄááťáŹá¸ááźáŽá¸áááŻáˇ áááşáááááˇáşáááşá ááŤááąáááˇáş ááŤáˇáááŻááşáááşá¸áážáŹááąáááŻááşáᏠ4 áážá áşááŹááŹááĄáá˝ááşá¸áážáŹ ááą 500 ááŻáááŽááŹáááş áááşá¸áááşá¸áááŻááąáŹááşáá˛áˇáááşá áĄá˛ááŤá 500 ááŽááŹáážááááşá áážááˇáş flash áá˝ááş 500 áážááşáááşá¸ááťáŹá¸á áĄá˛ááŤá ááąáĄáąá¸áá˛á áááşáááş áážá áşáĄáááşá¸áááşááźáŹáááŻááşá¸ ááťá áşááşááᯠááźááşáááşááąáŹááşá¸ááťáááŻááşááąáŹáşáááşá¸ FRAM ááťá áşááşááťáŹá¸ áážáááąáááşááᯠáá˝áąáˇáááŤáááşá ááááŻááááşá¸áááşá¸áážáŻááąáŹááˇáşáážááźááˇáşááťážááş á¤áĄááŹáááş áĄáá˝ááşááťáŹá¸ááźáŹá¸ááąáŹ ááźááşáááşááąá¸á ááşáááşá¸ááťáŹá¸ (áááşá¸ááŹáážááˇáşááťáŽ) ááźááˇáşáᏠI2C EEPROM áážááˇáş áá°ááŽááŤáááşá áááŻáááŻáˇááąáŹ microcircuits ááťáŹá¸ááźááˇáş á áááŻá¸áááŻááşáááŻáˇ ááťá˝ááşáŻááşáááąáŹááşáááŻááşááąá¸ááąáŹááźáąáŹááˇáş áááŻáĄááťáááşáá˝ááş ááŻáśáážááş 24LC512 áááş áááşááąááŤáááşá
ááŻáśáážáááşááŹá¸áá áşááŻááş
áĄá áááąáŹáˇ áĄáááşáážáŹ ááŻááşááŻááşáááŻáˇ á áááşáá°á¸ááŹá¸áááşá áááŻáˇááźáąáŹááˇáş ááŻááşááźáŹá¸ááᯠáá áşáááşáááşááŻáśá áśááźááˇáş ááźáŻááŻááşááŹá¸áááşá ááŤááąáááˇáş ááąááŹááśáá˛áˇ áááąááťááşáážáŹááŻáśá¸áá áşááŻáá˛áˇ áá áşááŹááŽááąáŹááşááźáŹááźáŽá¸ááąáŹááş (áĄá˛ááŤáááŤáá˛áá˛áˇ áĄáááşáááźáąááŤáá°á¸)á áááŻááşá ááťááşááźáŹá¸áá˝áąááᯠáážáŹáá°áááŻáˇ ááŻáśá¸ááźááşáááŻááşááąá¸áááşá
ááŻááşáááŻááážáŹáá°ááŽááŽá¸ááŤá¸áá˝ááş flash memory chip áĄááźááş display áá˛áˇáááŻáˇááąáŹ I2C bus áážááˇáş áĄááźáŹá¸áĄááŻáśá¸áááşááąáŹ áĄááŹáá
áşááŻááᯠááťáááşáááşáááŻááşáááşááᯠááťá˝ááşááąáŹáşááŹá¸áááşáá˛áˇáááşá áááşá¸ááᯠáááşáááŻáˇááŻááşááąá¸ááááşááᯠáĄáááĄááť ááąá¸áá˝ááşá¸ááŻááşááąááąá¸ááąáŹáşáááşá¸ áááşá¸ááᯠááŻááşáĄáá˝á˛áˇááąáŤáşáá˝ááş ááźááşáááşá¸áááş áááŻáĄááşáááşá ááąáŹááşá¸ááźáŽá á
ááşááŻáśáááą ááŻááşáá˝áą áážáŹáá°ááąáŹáˇáážáŹáááŻááąáŹáˇ áááŻááˇáşáááŻáááŻááş áá
áşáááşááŻááşááŻááşáážáŹ áááˇáşáááşááŹá¸áááŻáˇ ááŹáĄááźáąáŹááşá¸ááž ááážááá°á¸á ááŤááźáąáŹááˇáş I2C áááŻááşá¸áá˝áąá ááŻááşáá˛áˇ áĄááąáŹááşáááşáážáŹ áá
áşááŻáááşá¸ááŤáá˛á
áá áşáááşá¸ááąáŹááşá¸ áááŻááşááŹááźááŻá¸áá˛áˇ áááşáááşááźáŽá¸ ááźáŽá¸ááŹá¸áá˛áˇ ááźáżááŹáá áşááŻáááşá¸ áážááá˛áˇááŤáááşá ááŹááźá áşáááŻáˇáá˛áááŻááąáŹáˇ ááŻááşáĄáŹá¸ áá áşáááşáááşááąá¸áá˝á˛ááŹá¸ááąáŹááźáąáŹááˇáş áááşá¸ááťáŹá¸áážááˇáş SMD áĄá áááşáĄáááŻááşá¸ááťáŹá¸ááᯠáá áşáááşáá˝ááş ááŹá¸áážááááş á áŽá ááşááŹá¸ááźáŽá¸ áĄááźáŹá¸áá áşáááşáá˝ááş áĄáá˝ááşáĄá áááşáĄáááŻááşá¸ááťáŹá¸á ááťáááşáááşááááááŹááťáŹá¸áážááˇáş ááŤááŤááąáŹááşááśáˇáážáŻáááŻáˇááᯠááŹá¸áážááááş á áŽá ááşááŹá¸áááşá áá áşááĄááźáŹáá˝ááş ááťá˝ááşáŻááşáááş ááťááşááźáŹá¸ááťáŹá¸ááᯠáááşááśááážáááąáŹáĄá፠áá°ááĄá áŽáĄá ááşááᯠááąáˇáá˝áŹá¸áᏠáážáąáˇáááşáážá áĄá áááşáĄáááŻááşá¸áĄáŹá¸ááŻáśá¸ááᯠáááąááąáŹáşááŤáááşá ááŤááŤááąáŹááşááśáˇáážáŻááᯠáááąáááşááąáŹáĄááŤááž áĄááąáŤááşá¸áážááˇáş áĄááŻááşáááş ááźáąáŹááşá¸ááźááşáááŻáˇ áááŻááşááŹááźááŻá¸áá˝ááşááŹá¸ááźáąáŹááşá¸ áá˝ááşááąáŤáşááŹáááşá jumpers áá˝áąáá˛áˇ áááşááŻááşáá˛áˇááááşá áĄáááşááŻáśáá˝ááşá ááťá˝ááşáŻááşáááş áááŻááşááŹááźááŻá¸ááᯠááźáąáŹááşá¸ááŹá¸ááźáŽá¸ááźá áşááąáŹáşáááşá¸ ááźáąááᯠááŻááşá áĄá áááşáĄáááŻááşá¸áá áşááŻááž ááąáŹáˇáááŻááşá ááśááťáŹá¸áážáá áşáááˇáş ááźáąááŹá¸áĄáŹá¸ áá˝ážá˛ááźáąáŹááşá¸ááąá¸áááş (ááŻááááĄáá˝ážáŹáá˝ááş ááźáąááŹááśáá˝á˛áááş ááźá áşáááŻááşááąáŹáşáááşá¸)á
á¤áá˛áˇáááŻáˇ áá˝ááşááŹáá˛áˇáááşá
áĄáááşááŹ
ááąáŹááşáá áşáááˇáşá ááášááŹáááŻááşá áááˇáşáá˝ááş 3D ááááşááŹáážáááŤá ááźáżááŹáááŻááşááŤá ááťá˝ááşááąáŹáş ááááşá áááşááááşá áŹá¸áá°á¸ - áážááşáááşáá˛áˇ áĄáá˝ááşáĄá áŹá¸ ááąáŹááşá áşáá áşááŻááᯠáá˝á˛ááźáŽá¸ áážááşáááşáá˛áˇ ááąááŹáá˝áąáážáŹ ááźááşááąáŹááşáážáŻáá˝áą ááŻááşáá˛áˇáááşá áĄááŻáśá¸ááᯠááąá¸áááşááąáŹ self-tapping screws ááťáŹá¸ááźááˇáş áááŻááşáááşáážááˇáş áá˝á˛ááŹá¸áááşá
Boot áááŻááşááᯠááąáá°ááťáááşáá˝ááşááťááşáááŻááşáĄááźá
áş ááŻáśá¸áááŻááşáááşáááŻáᏠááťá˝ááşááąáŹáşááźáąáŹááŹá¸ááźáŽá¸ááŹá¸ááŤá ááŤááźáąáŹááˇáş ááťá˝ááşááąáŹáşáááŻáˇá áĄá˛ááŤááᯠáážáąáˇááąáŹááşáážáŹ ááźááŤáááşá ááŤáááŻááŻááşáááŻáˇá áááŻááşáááşáážááá˛áˇ áĄáá°á¸ "ááąáá˝ááşá¸" ááᯠááŤáá˝á˛áá˛áˇáááşá
Case áĄáá˝ááşá¸áá˝ááş ááŻááşááᯠM3 áááşáĄá°áá
áşááŻáááşá¸ááźááˇáş áááşáááşááźáŽá¸ ááŻáśááźáŻáśáĄáąáŹááşááźáŻááŻááşááŹá¸ááąáŹ á
áááŻá¸ááťáŹá¸ááŤáážáááŤáááş (ááŻááşááąáŤáşáá˝ááş ááąááŹááážáááąáŹáˇááŤ)
Case á áááááŻáśá¸ááá°ááŹááŹá¸áážááşá¸ááᯠáááŻááşáážáááşááąáŹáĄááŤáá˝ááş ááąáŹáşááźááźáŽá¸ááŹá¸ ááťááşáážáŹááźááşááᯠáá˝áąá¸ááťááşáá˛áˇáááşá á áśáážá áşáááŻááşá¸á áŹáááşáá°áááş á¤ááá ášá áážááˇáş áááŻááşááŽáážáŻááážáááąáŹáşáááşá¸ áĄáąáŹááşááźáąáá˝ááş OLED ááťááşáážáŹááźááş SSD1306 128Ă32 áážááááşá áááşá¸áááşá¸ááąá¸ááąáááˇáş ááąáˇáááŻááşá¸ááźááˇáşááąáááŻáˇ ááááŻááŤáá°á¸âááŤá ááŤáˇáĄáá˝ááş áĄáááşá¸ááťáŹá¸áááşá
ááŽáááşá¸áá˛áˇ áááŻááşááŹááźááŻá¸áá˝áą áááşááᯠááźááşáááşá¸ááááşáááŻááŹááᯠáá˝áąá¸ááźááˇáşááąáŹáˇ ááťááşáážáŹááźááşááᯠáááşááŹá¸áááŻáˇ ááŻáśá¸ááźááşáááŻááşáááşá Ergonomicsá ááŻááşááŤáááşáá áá°ááŽáááş - áááŻááşáááşáĄááąáŤáşáá˝ááşáážáááźáŽá¸á áĄáąáŹááşááźáąáá˝ááşáážááááşá ááŤááąáááˇáş ááťááşáážáŹááźááşááᯠáá˝á˛ááťáááşáááŻáˇ á áááşáá°á¸á áĄáááşá¸ááąáŹááşááťáá˝áŹá¸ááźáŽáááŻáˇ ááźáąáŹááŹá¸ááźáŽá¸ááŹá¸ áááŻááşáááŻáá˝ážáąáˇáááŻáˇ ááŻááşááᯠááźááşááťáááşáááŻáˇ ááťááşá¸áááşá
á ááşááᯠáááşáááşááŹá¸áááşá display module ááᯠááąáŹáşáá°ááźááˇáş áážááşááťáąá¸áá˝ááş áááşááŹá¸áááşá
ááąáŹááşááŻáśá¸ááááşááᯠKDPV áá˝ááşáá˝áąáˇáááŻááşááŤáááşá
áá˝ááşá¸ááźááşá¸
ááąáŹáˇááşáá˛áĄáááŻááşá¸ááᯠáááşáá˝áŹá¸ááĄáąáŹááşá ááŽááᯠáááşáážáŻáááŹááąá¸áá˝áąáĄáá˝ááş Python ááᯠáĄáááşá¸ááźááŻááşááŤáááş (
áĄááŹáĄáŹá¸ááŻáśá¸áááş áááŻá¸áážááşá¸ááąáŹáşáááşá¸ áĄáá˝ááşáááŻá¸áážááşá¸ááŻáśááááş - á ááşáá˝ááş ááŽá¸ááźáŹá¸ááŻááşááąáŹááşááťááşááťáŹá¸á á˝áŹ ááŤáážááááşá
- áĄááŻáśá¸ááźáŻáá°áááş áááŻááşáááŻáážáááşá ááťááşáážáŹááźááşááᯠááźááˇáşáážáŻáááşá
- flash memory áá˝ááş ááŽááŹáááşáááŻá¸ááťáŹá¸ááᯠáĄáážááşááźá áşááźáŽá¸ áĄááşááááşááŻááşááŤá
- ááąáŹáşááťá°á¸áááş WiFi áĄááťááşááźáážáŻááᯠá áąáŹááˇáşááźááˇáşááźáŽá¸ áááŻáĄááşááŤá ááźááşáááşááťáááşáááşáááşá
- ááąáŹááşá¸ááźáŽá áážáááşááŻááşáážáááşááŻááşááŽá¸ááŽá¸áááŤáá˛áááźá áşáááŻááşáá°á¸á
áĄááźáŹá¸áá áşááŻáááş áĄááźáąáŹááşá¸áá áşááŻááŻááźáąáŹááˇáş ááááşááááŤá ááŻááşááąáŹááşáážáŻáá áşáᯠáĄááŻááşáááŻááşáᯠáááşáá°ááááŻááşáááşáááŻááşááąá áĄááźáŹá¸áááąáŹááťááşááťáŹá¸áá˝ááş ááťá˝ááşáŻááşá cacti ááźááˇáşáá˝ááşá¸ááŹá¸ááźáŽá¸ááŹá¸ááźá áşááźáŽá¸ áááŻáĄááťáááşáá˝ááş "ááťááşáážáŹááźááşááᯠáĄááşááááşááŻááşááąááąáŹááźáąáŹááˇáş áĄááźáŹá¸ááŽááŹáá˝ááşáá˝áŹá¸ááąáŹááźáąáŹááˇáş" áááŻáˇáááŻááş " module áážááˇáşááťáááşáááşááąááťáááşáá˝ááş áĄááŻáśá¸ááźáŻáá°áááş ááŹáážáááŻááşáááŻááşááąáŹáˇááŤá áááŻááşáááŻááşá" ááŻááşááŤáááşá áĄááťááŻáˇáĄááŹááťáŹá¸ááᯠáĄáážáąáŹááˇáşáĄáážááşááťáŹá¸áážáá áşáááˇáş ááŻááşááąáŹááşáááŻááşááąáŹáşáááşá¸ ááźáŹááťáááşá ááŻááşá¸ááąáŤáşáááŻáážáŻááťáŹá¸áá˝ááş áĄáááŻááşáĄááźáŻáś áááŻáˇáááŻááş áĄááşáááşáááŻááşááąáŹ ááźáąáŹááşá¸áá˛áážáŻááťáŹá¸ááᯠááááşá¸áážááşááťáŹá¸áĄáá˝ááş áááˇáşáááşááťááşááťáŹá¸áĄááźá áş áááşááźáŻáśáá˝áąáˇáááŻááşáááşá ááąáŹááşá¸ááźáŽá áĄááŹáĄáŹá¸ááŻáśá¸áááŻááŻááşááąáŹááşááąáŹááŻááşáááş ááťááşááźááşá á˝áŹ áážááŻáĄááźá áşáááŻáˇ ááźáąáŹááşá¸áá˛áá˝áŹá¸áááşá
Đ
ááźááŻáááşáá˛áážááˇáş áĄááźááŻááşáĄáááŻááşáĄááŻááşááťáŹá¸ááŻááşááźááşá¸áĄááźáŹá¸ ááźáŹá¸ááŹá¸ááťááşááťáŹá¸ááᯠá áááşááźááŻááşáá˝áąá¸ááťááşáááŻááşááąáŹááŹááŹáááşáĄááźá áş ááąáˇááŹáááş áĄááźáśááźáŻáĄááşááŤáááşá áᲠááąáŹááşááŻáśá¸ááąáŹáˇ ááŻááşááᯠáááşááźááˇáşááĄáąáŹááşá
#####################################
# 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
ááąáŹááşááŹáá áşááŻá áŽááᯠCounter class á áĽáááŹáá áşááŻááźááˇáş áááŻááşáá˝ááşáááşá ááááŚá¸á á˝áŹá áááŚá¸áááşááźááşáááşáááŻá¸ááᯠ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)
áĄáááşáĄáá˝ááş bounce ááᯠá á áşááŻááşáááş 25ms áážáąáŹááˇáşáážáąá¸áážáŻ áááŻáĄááşááźáŽá¸ áá áşááťáááşáááşá¸áážáŹáááş áááşá¸áááş ááŻááşáááşá¸ááᯠáážááŻá¸áááˇáşáĄááźáááşáážáŻááşá¸ááᯠááááşá¸áážáááąá¸áááş (á¤ááŻááşáááşá¸áááş áĄáááşááťáąáŹáşááąá ááşá áĄááźáŹá¸ááŻááşááąáŹááşá ááŹááťáŹá¸ ááŻááşááąáŹááşááąáááş)á 25ms áááŻááşá¸ function áááŻá¸ááŹááźáŽá¸ pin ááᯠá á áşááąá¸ááźáŽá¸ reed switch contacts ááťáŹá¸ááᯠááááşáá˝áŹá¸ááŤá áĄááźáŹá¸ liter áááş meter áááŻááźááşáá˝áŹá¸áᏠáááşá¸ááᯠá áŽááśááąáŹááşáá˝ááşáááşáááŻáĄááşááŤáááşá
def _another_litre_passed(self):
self._value += 1
self._value_changed = True
self._value_storage.write(self._value)
ááąáŹááşááŽááŹááᯠááŻááşááąáŹááşááźááşá¸áááş áĄááąá¸áĄáá˝á˛ááźá áşáááş - ááąáŹááşááŹáááş áááŻá¸ááŹááŤáááşá ááąáŹááşá¸ááźáŽá flash drive áá˝ááşáááşáááŻá¸áĄáá áşáááŻááąá¸ááźááşá¸áááşááąáŹááşá¸ááááˇáşáááşá
áĄááŻáśá¸ááźáŻááá˝ááşáá°á áąáááşáĄáá˝ááş "accessors" ááᯠááąá¸ááŹá¸ááŤáááşá
def value(self):
self._value_changed = False
return self._value
def set_value(self, value):
self._value = value
self._value_changed = False
áá˛á ááᯠPython áážááˇáş uasync á áŹááźááˇáşáááŻááşá áážá áşáááşáá˝ááşááťáŹá¸ááᯠáĄááŻáśá¸ááťááźáŽá¸ á áąáŹááˇáşáááŻááşá¸áááŻááşááąáŹ áááşááźááşáĄááŹááášááŻáá áşááŻááᯠááźáŻááŻááşáááŻááşááźááŤá ááŻáˇ (áááşá¸ááᯠááŻáážáŹá¸ááŹááŹáááŻáˇ ááťá˝ááşáŻááşáááŻáˇ áááşáááŻáˇááŹááŹááźááşáááŻáááŻááşááááşá¸á áááşááťážáąáŹáşáááˇáşáááŻááşáááˇáşáĄááŹ)
def __await__(self):
while not self._value_changed:
yield from asyncio.sleep(0)
return self.value()
__iter__ = __await__
á¤áááşáážáŹ ááąáŹááşááŹáááşáááŻá¸ááᯠáĄááşááááşááŻááşáááşáĄáá á áąáŹááˇáşáááąáŹ áĄáááşááźáąáááˇáşááŻááşááąáŹááşááťááşááźá áşáááş - ááŻááşááąáŹááşááťááşáááş áĄááŤáĄáŹá¸ááťáąáŹáşá á˝áŹáááŻá¸ááŹááźáŽá¸ _value_changed áĄááśááᯠá á áşááąá¸áááşá á¤ááŻááşááąáŹááşááťááşá áĄáááşá¸ááŻáśá¸áĄááťááşáážáŹ ááŻááşá¸ááąáŤáşáááŻáážáŻááŻááşáááş á¤ááŻááşááąáŹááşááťááşáááŻááąáŤáşáááŻá ááşáá˝ááş áĄáááşááťáąáŹáşáá˝áŹá¸áááŻááşááźáŽá¸ áááşáááŻá¸áĄáá áşáá áşááŻááážááááşáĄáá áĄáááşááťáąáŹáşáá˝áŹá¸áááŻááşáááşá
áĄáážáąáŹááˇáşáĄáážááşáá˝áąááąáŹáááŻááşáááşá ááŽáĄááťáááşáážáŹ áááşá¸áááŻááşáááŻááşá áĄáážáąáŹááˇáşáĄáážááşáá˝áąáĄááźáąáŹááşá¸ ááźáąáŹááźáŽá¸ ááŤáˇááᯠááááşáááŻáˇááááşá ááŤááąáááˇáş áááşáá˝áąáˇáážáŹ áááşá¸ áááŻááşáá˛áá˛áˇ áááşáá á áşáááşá¸áá áşáᯠááŻááşáá˛áˇáááşá áĄáážááşááááşááąáŹáˇ áážáąáŹááşáážááşááźááşá¸áá˝áąáᏠááŤááźááŻá¸á áŹá¸áá˛áˇáá˛áˇ áááááŻáśá¸áĄááŹááŤá ESP8266 áá˝ááş áááşáááş edge interrupt ááᯠá áŻá ááşá¸áááŻááşááźáŽá¸ Python áá˝ááş á¤ááźáŹá¸ááźááşáážáŻáĄáá˝ááş áááŻááşáá˝ááşáá°áááŻáááş ááąá¸ááŹá¸áááŻááşáááşá á¤áážáąáŹááˇáşáážááşáážáŻáá˝ááşá ááááşá¸áážááşáá áşááŻááááşáááŻá¸ááᯠáá˝ááşá¸ááśáááŻááşáááşá ááąáŹááşááŹáááş slave device ááźá áşáá˛áˇááťážááş á¤áááşáááŻá¸ááᯠááąáŹááşá¸áááˇáşáĄááťáááşáĄáá á áąáŹááˇáşááááˇáşáĄáᏠááźá áşááąáŹááşá¸ááźá áşáááŻááşáááşá
ááśáááąáŹááşá¸á á˝áŹáᲠ(áááŻáˇáááŻááş ááśááąáŹááşá¸ááąáŹááşáá á˝áŹáááş?) ááťá˝ááşáŻááşáá ááşáá ášá ááşá¸áááş áááşááźá˝ááąááŤáááşá áááşá¸áááş MQTT ááááŻáááŻááąáŹáážáá áşáááˇáş áááşááąáˇááťáşááťáŹá¸ááąá¸áááŻáˇáᏠEEPROM áááŻáˇ ááąááŹááąá¸ááąá¸ááááşááźá áşáááşá á¤ááąááŹáá˝ááş áááˇáşáááşááťááşááťáŹá¸ ááąáŤáşááŹáááş - áááşáááş ááźáŹá¸ááźááşááťáŹá¸áá˝ááş áážááşááŹááşááᯠáá˝á˛ááąááąá¸ááźáŽá¸ ááźáŽá¸ááŹá¸ááąáŹ stack ááᯠáĄááŻáśá¸ááźáŻá ááááŤá áááŻáááŻáááşáážáŹ áááşáááş áá˝ááşáááşááąáŤáşáážá áááşááąáˇááťáşááťáŹá¸ ááąá¸áááŻáˇááźááşá¸ááᯠááąáˇáá˝áŹá¸áááŻááşáááşá micropython.schedule() áá˛áˇáááŻáˇááąáŹ ááŻááşááąáŹááşááťááşáĄááťááŻáˇááᯠâáááşáááŻááşáááťáž áĄááźááşááŻáśá¸â ááŻááşááąáŹááşáááŻááşá áąáááˇáş buns ááťáŹá¸ááŤáážáááąáŹáşáááşá¸á âááŹáĄááťááşáá˛â áᯠááąá¸á ááŹáážáááŹááŤáááşá áĄáááşá ááťá˝ááşáŻááşáááŻáˇáááş áááŻáĄááťáááşáá˝ááş áááşááąáˇááşáťáá áşááťááŻá¸ááťááŻá¸ áááŻáˇááąááŤáá áááŻáˇááąáŹááş ááźáŹá¸ááźááşáá áşááŻáááşááŹááźáŽá¸ variable ááťáŹá¸á áááşáááŻá¸ááťáŹá¸ááᯠááŻáá°áá˝áŹá¸ááŤá ááŹááźá áşáááşáááşá¸á áááŻáˇáááŻááş áĽáááŹá ááťá˝ááşáŻááşáááŻáˇáááş áĄááąáŹááşá¸ááᯠáááąá¸ááŹá¸ááąá¸áᲠááŹááŹááž áááşááźááşáááşáááŻá¸áĄáá áşáá áşáᯠááąáŹááşááŹáááşá ááąáá°ááťáĄáŹá¸ááźááˇáşá áááşáááş áááşáá°ááźáŻááźááşá¸ááᯠááááşáááŻáˇáááş áááŻáˇáááŻááş áááşá¸ááᯠáá áşáááşá¸áááşá¸ááźááˇáş áá˝á˛ááźáŹá¸á á˝áŹ áá˝ááşáá˝áŹá¸áááş áááŻáĄááşáááşá
ááśáááşááśá፠RuntimeError- áĄá áŻáĄá ááşá¸ áĄááźááˇáşááťááşááťááźááşá¸ááᯠáĄááťáááşáááŹá¸áá˝á˛ááźáŽá¸ áĄáááşááźáąáŹááˇáşáááŻáááşááᯠáááşáá°ááááááşá¸á
ááááťááźááşááŹá¸ááąáŹáá˛ááąá¸ááźááşá¸áážááˇáş 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)
Python áá˝ááşá áááşá¸áááş bytes áážááˇáş áááŻááşáááŻááşáĄááŻááşááŻááşáááş áááşáá˛ááąáŹáşáááşá¸ áááşá¸áááş memory áá˝ááşááąá¸ááŹá¸ááąáŹ bytes ááźá áşáááşá Ustruct á áŹááźááˇáşáááŻááşááᯠáĄááŻáśá¸ááźáŻá ááááşá¸ááźááˇáşáážááˇáş áááŻááşááťáŹá¸áĄááźáŹá¸ ááźáąáŹááşá¸áá˛ááźááşá¸ááᯠááŹááśááŹá¸áá˛áˇááááşá
I2C áĄááŹááášááŻáážááˇáş memory cell áááááşá áŹááᯠáĄááťáááşáááŻááşá¸ áá˝ážá˛ááźáąáŹááşá¸ááźááşá¸áááźáŻáááşá ááťá˝ááşáŻááşáááş áááşá¸áĄáŹá¸ ááąá¸áááşááźáŽá¸ áĄáááşááźáąááąáŹ ááášááááşááźááˇáş ááŻááşáááŻá¸ááŹá¸áááşá
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 á áá°áááşá¸áááşáááşáĄááťáŹá¸á áŻáááş ááťá˝ááşáŻááşáááŻáˇáĄáá˝ááş ááąáŹááşá¸áá˝ááşááąáŹáşáááşá¸ áááşáááşááťáŹá¸á á˝áŹááᯠáĄáá°á¸ááááşáááşáážááşááŹá¸áááş áááŻáĄááşááŤáááşá ááŻááşáá˝ááş áááşáááşááťáŹá¸ááᯠáááŻááşáááŻááşáááąá¸áááşá áááşá¸áááŻáˇááᯠá áŹááŹá¸áááŻááş 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 ááťáááşáááşáážáŻááᯠá áááşáᏠááťáááşáááşáážáŻ ááťáąáŹááşááŻáśá¸áá˝áŹá¸ááąáŹáĄá፠ááźááşáááşááťáááşáááşáááşá WiFi ááťáááşáááşáážáŻáĄááźáąáĄááąáá˝ááş áĄááźáąáŹááşá¸áĄáá˛ááťáŹá¸áážáááŹááąáŹáĄááŤá á áŹááźááˇáşáááŻááşáááş wifi_connection_handler áááŻááąáŤáşáááŻááźááşá¸ááźááˇáş ááťá˝ááşáŻááşáááŻáˇáĄáŹá¸ áĄááźáąáŹááşá¸ááźáŹá¸ááŤáááşá
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) áážááˇáş áááşá¸áááŻáˇáááźáŹááťáááşáááŻáˇááᯠááąáá˝ááşáááşá ááťáááşáááşáážáŻááᯠááźááşáááşááá°ááąáŹáĄááŤá áĄáŹá¸áááşááťáááşááᯠááŹááŹáááŻáˇ ááąá¸áááŻáˇáááşá
á ááŹá¸áá ááşá ááŻááşááąáŹááşááťááşááᯠáááŽáá˝ážááşá áąáááşáĄáá˝ááş ááąáŹááşááŻáśá¸áĄáááşá ááşááźááşá¸ááᯠáááŻáĄááşáááş - á áŹááźááˇáşáááŻááşáá˝ááş áááşá¸ááᯠá áąáŹááˇáşááťážáąáŹáşááźááşá¸áážáá áşáááˇáş ááąáŤáşááźáŽá¸ ááášááŹáááŻááşáá˝ááş áĄááźáŹá¸á áąáŹááˇáşáááŻááşá¸ááąááąáŹ ááŻááşááąáŹááşááťááşááťáŹá¸áááŻáᏠááąáŤáşáááŻááşáááşá
WiFi áááŻáˇ ááťáááşáááşááźááşá¸áĄááźááşá áááşáááş 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))
á áŹááŹá¸áĄáááşá¸ááťáŹá¸ááźáŽá¸ LED ááᯠááťááşááąáŹááşááááşáááąá¸ááŤáá°á¸á ááŽáážáŹ
# 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 á áášáááˇáşáááŻááşá¸ áá áşááźáááş ááťááşááąáŹááşáááşááŤáááşá áááŻáĄááşááŤá áĄááźáŹá¸ááąáŹ áážáááşááŻááşáážáááşááŻááşááŻááşááťáŹá¸ááᯠá¤ááąááŹáá˝ááş áĄááąáŹááşáĄáááşááąáŹáşáááŻááşááŤáááşá
ááŤááąáááˇáş LED á áááşáááşáááşáááşááŤáá˛á áááşá¸ááťááşá¸ááźááážáŻáááŻáááşá¸ áááşáá˝ááşááŤáááşá
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)
ááŤá ááŤááźáąáŹááąááŹáᲠ- ááŻááşáááŻá¸ááŻááşá ááşáá˝áąáážáŹ áááşááąáŹááşáááŻá¸áážááşá¸ááźáŽá¸ áĄáááşááźáąáá˛á á¤ááŻááşááąáŹááşááťááşáááşáááş áĄááŻáśá¸ááźáŻáá° áĄáá˝áąáˇáĄááźáŻáś ENTIRE ááᯠááąáŹáşááźáááşá ááąáŹáşáááŻá¸áááşá¸áááş áááŻááşááᯠáážáááşáááş á áąáŹááˇáşáááŻááşá¸ááźáŽá¸ ááťááşáážáŹááźááşááᯠá á áášáááˇáşááźáŹ áá˝ááˇáşáááşá ááťááşáážáŹááźááşáááş áááşáážáááŽááŹáááşááźááşá¸ááᯠááźááááşá
áĄááąá¸áĄáá˝ážáŹá¸ááąá¸áá˝áą ááťááşááŤááąá¸áááşá á¤áááşáážáŹ á¤ááŻááşáááşá¸áá áşááŻááŻáśá¸ááᯠ(ááźááşáááş) á áááşáááˇáş ááŻááşááąáŹááşááťááşááźá áşáááşá áááşááá˝ááşá¸áááşáááş áĄááťááŻá¸ááťááŻá¸ááąáŹ áĄáážáŹá¸áážáŹááźááşááźááşá¸áááŻááşáᏠáĄááťááşáĄáááşááťáŹá¸ááᯠáá áşáááá áşááťážááş áá áşááźáááşáᏠááąá¸áááŻáˇáááşá ááąáá°ááťáĄáŹá¸ááźááˇáşá ááťá˝ááşáŻááşáááş áááşá¸ááᯠáááŻá¸ááŹá¸ááŹá¸áááş- áĄáá˝ááşáĄááťá˝áś áážááşááťááşááąá¸áááş ááááŻáĄááşáᯠááááşááŤá
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())
ááŤáˇáážááşááŹááşáážáŹ áá áşááŻááŻááźá áşáá˛áˇááŹá
ááŽááąáŹáˇ ááŻááşáá˝áą áĄááŻááşáážááááşá ampy utility ááᯠáĄááŻáśá¸ááźáŻá áááŻááşááťáŹá¸ááᯠááťá˝ááşáŻááş áĄááşááŻááşáááşáá˛áˇáááş - áááşá¸áááş áááşá¸áááŻáˇáĄáŹá¸ áĄáá˝ááşá¸áááŻááşá¸ (ESP-07 áááŻááşáááŻááş) flash drive áááŻáˇ áĄááşááŻááşááŻááşáááŻááşááźáŽá¸ áááşá¸ááᯠááŻáśáážááşáááŻááşááťáŹá¸áĄááźá áş ááááŻááááşááž áááşááąáŹááşááźááˇáşáážáŻáááŻááşáááşá áĄá˛ááŽáážáŹ ááťá˝ááşááąáŹáşáĄááŻáśá¸ááźáŻáá˛áˇáá˛áˇ mqtt_asá uasyncioá ssd1306 áá˛áˇ collections libraries (mqtt_as áá˛áážáŹááŻáśá¸ááŤáááş)
ááťá˝ááşáŻááşáááŻáˇ á áááşáááŻááşáááşáážááˇáş... ááťá˝ááşáŻááşáááŻáˇáááş MemoryError áá áşáᯠááážáááŤáááşá áááŻáˇáĄááźááşá áááşáááŻááŽááąáŤááşááźáŹá¸áááˇáşááąááŹááᯠáĄáááĄááťááŹá¸áááşáááş áááŻááźááŻá¸á áŹá¸ááąá ááťá˝ááşáŻááşáááş áĄáážáŹá¸áážáŹááźááşááááˇáşááťáŹá¸ ááťáŹá¸ááťáŹá¸áááşááąá á¤áĄáážáŹá¸áááş á áąáŹááąááąááźá áşáááşá áááŻááąáŹááşá¸ááąáŹ Google áážáŹáá˝áąáážáŻáá áşááŻá áááŻááşááááŻáá˝ááşááááŻááŹáá˝ááş áá°áĄáŹá¸ááźááˇáş 30 kB ááŹáážáááąáŹ ááŻááş (libraries ááťáŹá¸áĄááŤáĄáááş) ááŻááş 65 kB (á áŹááźááˇáşáááŻááşááťáŹá¸áĄááŤáĄáááş) áááŻá¸áážááşá¸á á˝áŹ áĄáśááááşáááŻááşááąáŹáˇááźáąáŹááşá¸ ááŹá¸áááşááŹá áąáááşá
ááŤááąáááˇáş áá˝ááşáááşá¸áážááááşá micropython áááş .py áááŻááşááž ááŻááşááᯠáááŻááşáááŻááşááŻááşááąáŹááşááźááşá¸ááážáááźáąáŹááşá¸ áá˝áąáˇáážáááááş - á¤áááŻááşááᯠáŚá¸á á˝áŹá áŻá ááşá¸ááŹá¸áááşá áááŻáˇáĄááźááşá áááşá¸ááᯠmicrocontroller áá˝ááş áááŻááşáááŻááşá áŻá ááşá¸ááźáŽá¸ memory áá˝ááş ááááşá¸áááşá¸ááŹá¸áááˇáş bytecode áĄááźá áşááźáąáŹááşá¸áááşá ááąáŹááşá¸ááźáŽá compiler áĄááŻááşááŻááşáááşáĄáá˝ááş áááşáááş áĄááťááŻáˇááąáŹ RAM áááŹááááşá¸ áááŻáĄááşááŤáááşá
áážááˇáşáá˝ááşáážáŹ áĄáááşá¸áĄááźá
áş-ááťáŹá¸ááąáŹ á
áŻá
ááşá¸áážáŻááž microcontroller ááᯠáááşáááşáááşááźá
áşáááşá ááźáŽá¸ááŹá¸ááąáŹáá˝ááşááťá°ááŹááąáŤáşáá˝ááş áááŻááşááťáŹá¸ááᯠá
áŻá
ááşá¸áááŻááşááźáŽá¸ áĄáááşáááˇáşááŻááşááŹá¸ááąáŹ bytecode ááᯠáááŻááşááááŻáá˝ááşááááŻááŹáááŻáˇ áĄááşááŻááşááŻááşáááŻááşááŤáááşá ááŽáááŻááŻááşáááŻáˇá micropython firmware áááŻááąáŤááşá¸ááŻááşááŻááşááźáŽá¸ build ááŻááşáááŤáááşá
ááťá˝ááşááąáŹáş Makefile ááᯠáááąá¸ááŹá¸ááąáááˇáş ááŽáááŻááťááŻá¸ áááŻáĄááşáá˛áˇ áááŻááşáá˝áą (á áŹááźááˇáşáááŻááşáá˝áą áĄááŤáĄáááş) áĄáŹá¸ááŻáśá¸ááᯠáááŻááşáááŻááş ááźááşáááşá¸ááźáŽá¸ ááźáŻá áŻáá˛áˇáááşá
mpy-cross water_counter.py
ááťááşáááşáážáŹ .mpy áááŻá¸ááťá˛áˇáážáŻááźááˇáş áááŻááşááťáŹá¸ááᯠáĄááşááŻááşááŻááşáááşááźá áşááźáŽá¸á áááşáááŻááşáᏠ.py ááᯠá ááşáá ášá ááşá¸á áááŻááşá áá áşááž áŚá¸á á˝áŹááťááşáááş áááąáˇááťáąáŹáˇááŤá
ááááŻááááş (IDE?) ESPlorer áá˝ááş áá˝áśáˇááźááŻá¸áááŻá¸áááşáážáŻáĄáŹá¸ááŻáśá¸ááᯠááŤááŻááşáá˛áˇáááşá áááşá¸áááş áááˇáşáĄáŹá¸ microcontroller áá˝ááş script ááťáŹá¸ááᯠáĄááşááŻááşááŻááşááźáŽá¸ áááşá¸áááŻáˇááᯠááťááşááťááşá¸ááŻááşááąáŹááşáááŻááşá áąááŤáááşá ááŤáˇááá ášá áá˝ááşá áĄááŹááášááŻáĄáŹá¸ááŻáśá¸á ááŻáášáááážááˇáş áááşááŽá¸áážáŻáĄáŹá¸ááŻáśá¸áááş water_counter.py (.mpy) áááŻááşáá˝ááş áááşáážááááşá áááŻáˇááąáŹáş á¤áĄááŹáĄáŹá¸ááŻáśá¸ááᯠáĄáááŻáĄááťáąáŹááşá áááşáááŻááşáááşá á áááşááŹáá˝ááş main.py ááŻááąáŤáşááąáŹ áááŻááşáá áşááŻáááşá¸ áážááááŤáááşá áááŻáˇáĄááźááşá áááşá¸áááş áĄáááĄááť .py ááźá áşáááˇáşááźáŽá¸ ááźááŻáááşááźáŻá áŻááŹá¸ááąáŹ .mpy áááŻááşááŤá á¤áááşáážáŹ áááşá¸ááĄááąá¸áĄáá˝á˛áĄááźáąáŹááşá¸áĄááŹááťáŹá¸ááźá áşáááşá
import water_counter
ááťá˝ááşáŻááşáááŻáˇáááş áááşá¸ááᯠá áááşáááŻááşáááş - áĄááŹáĄáŹá¸ááŻáśá¸ áĄáááşááźáąááŤáááşá áááŻáˇááąáŹáş áĄááá˛áˇáážááşááŹááşáááş ááźáąáŹááşá ááŹááąáŹááşá¸ááąáŹááşáĄáąáŹááş ááąá¸áááşáááş - 1kb áááˇáşá ááťá˝ááşáŻááşáá˝ááş á ááşáá ášá ááşá¸á ááŻááşááąáŹááşáááŻááşá á˝ááşá¸ááᯠááťá˛áˇáá˝ááşáááş áĄá áŽáĄá ááşáážáááąááąá¸ááźáŽá¸ á¤ááŽáááŻáááŻááşáááş ááťá˝ááşáŻááşáĄáá˝ááş áááŻáśááąáŹááşááąáŹáˇáááşáážáŹ áááşáážáŹá¸ááŤáááşá ááŤááąáááˇáş ááŽááá ášá áĄáá˝ááş áá˝ááşááąáŤááşáááşá¸ áážááááşáááŻáˇ áááşááŤáááşá
á¤áá˝ááşáĄááťááşá áááŻááşááťáŹá¸ááᯠbytecode ááźááˇáşá áŻá ááşá¸ááźáŽá¸ internal file system áá˝ááşáááşáážáááąáŹáşáááşá¸á áááşáá˝áąáˇáá˝ááşáááşá¸áááŻáˇááᯠRAM áá˛áááŻáˇáááˇáşáá˝ááşá¸ááźáŽá¸áááŻáážááŻááşááąáŹááşáá˛ááźá áşáááşá áááŻáˇááąáŹáş micropython áááş flash memory ááž bytecode ááᯠáááŻááşáááŻááşááŻááşááąáŹááşáááŻááşááąáŹáşáááşá¸ áááşá¸áĄáá˝ááş áááşá¸ááᯠfirmware áá˝ááş áááŻááşáááŻááşáááşááąáŹááşáááş áááŻáĄááşááŤáááşá ááťá˝ááşáŻááşá netbook áá˝ááş áĄááťáááşáĄáááşá¸áááşááźáŹááąáŹáşáááşá¸ (áááŻááąááŹáá˝ááş ááťá˝ááşáŻááşá Linux áážááá˛áˇáááş)á
algorithm áážáŹ áĄáąáŹááşááŤáĄáááŻááşá¸ááźá áşáááş á
- ááąáŤááşá¸ááŻááşááŻááşááźáŽá¸ áááˇáşáá˝ááşá¸ááŤá
ESP SDK áááŻáá˝ááˇáşááŤá . á¤áĄááŹáááş ESP8266 áĄáá˝ááş ááááŻááááşááťáŹá¸áĄáá˝ááş compiler áážááˇáş libraries ááťáŹá¸ááᯠá áŻá ááşá¸ááŹá¸áááşá áááąáŹááťááşá áááşáá áŹááťááşáážáŹáážá áá˝ážááşááźáŹá¸ááťááşááťáŹá¸áĄáááŻááşá¸ á áŻá ááşá¸ááŹá¸áááş (ááťá˝ááşááąáŹáş STANDALONE=yes áááşáááşááᯠáá˝áąá¸ááťááşáá˛áˇáááş) - download,
micropython áĄááťááŻá¸áĄá áŹá¸ááťáŹá¸ - áááŻáĄááşááąáŹá áŹááźááˇáşáááŻááşááťáŹá¸ááᯠmicropython áá áşáááşáĄáá˝ááşá¸áá˝ááş ports/esp8266/modules áá˝ááşááŹá¸ááŤá
- áááŻááşáĄáá˝ááşá¸áážá áá˝ážááşááźáŹá¸ááťááşááťáŹá¸áĄáááŻááşá¸ ááťá˝ááşáŻááşáááŻáˇáááş Firmware ááᯠá
áŻá
ááşá¸ááŹá¸áááşá
ports/esp8266/README.md - ááťá˝ááşáŻááşáááŻáˇáááş áááŻááşááááŻáá˝ááşááááŻá¸áááŻáˇ áááŻááşá¸áá˛ááᯠáĄááşááŻááşááŻááşáááş (ááťá˝ááşááąáŹáş ESP8266Flasher ááááŻááááşááťáŹá¸ áááŻáˇáááŻááş Python esptool ááᯠáĄááŻáśá¸ááźáŻá Windows áá˝ááş áááşá¸ááᯠááźáŻááŻááşáááş)
ááŤááŤáá˛á áĄáᯠ'import ssd1306' á ááŻááşááᯠfirmware áááą áááŻááşáááŻááş ááŻááşááááşá¸áááŻááşáážáŹááźá áşááźáŽá¸ ááŽáĄáá˝ááş RAM ááᯠááŻáśá¸á á˝á˛áážáŹ áááŻááşááŤáá°á¸á á¤áážááˇáşáá˝ááşááźááˇáş ááťá˝ááşáŻááşáááş áááŻááşá áá áşááž áááşáááááŻááááşááŻááşááᯠááŻááşááąáŹááşááąá ááşáá˝ááş á áŹááźááˇáşáááŻááşááŻááşááᯠFirmware áá˝ááşáᏠáááşáááŻááşááŤáááşá áááşá¸áááş áááˇáşáĄáŹá¸ Firmware áĄáŹá¸ ááźááşáááşááąáŤááşá¸á ááşá¸ááźááşá¸áááźáŻáᲠááááŻááááşááᯠáĄáá˝ááşááá° ááźááşáááşáááŻááşá áąááŤáááşá ááąáŹááąáŹáááş ááťá˝ááşááąáŹáˇáşáážáŹ 8.5kb free RAM áážááááşá áááşá¸áááş ááťá˝ááşáŻááşáááŻáˇáĄáŹá¸ áĄááŹáááşáá˝ááş ááá°ááŽááąáŹ áĄááŻáśá¸áááşááąáŹ ááŻááşááąáŹááşáááŻááşá á˝ááşá¸ááťáŹá¸á á˝áŹááᯠáĄááąáŹááşáĄáááşááąáŹáşáááŻááşá áąáááşááźá áşáááşá ááąáŹááşá¸ááźáŽá ááŻáśááąáŹááşááąáŹ memory ááážáááŤáá áááşáááááŻááááşááᯠFirmware áááŻáˇ áá˝ááşá¸áááŻáˇáááŻááşáááşá
ááŤáá˛áˇ áááşáááşááźáŽá¸ áĄáᯠááŹááŻááşáááˇáşáá˛á
áĄááŻááąá ááŹáˇááşáá˛ááᯠáááąááąáŹáşááŹá¸ááźáŽá¸á ááŹááşá¸áá˛ááşááᯠááąá¸áážááşááŹá¸ááźáŽá¸á ááąáŹááşá áşááᯠáááŻááşáážáááşááŹá¸ááźáŽá¸á á ááşáá ášá ááşá¸áááş ááśááśááąáŤáşáá˝ááş áááşááąááźáŽá¸ ááŽá¸ááŽá¸ááᯠááťáąáŹáşáá˝ážááşá á˝áŹ áážáááşááŹá¸áááşá áááŻáˇááąáŹáş áááŻáĄááťáááşáá˝ááş áááşá¸áááş áĄáááşááąáŹááşááąáášáᏠ(á áŹááŹá¸áážááˇáş ááŻáśááášááŹááşáĄá) ááźá áşááźáŽá¸ áááşá¸áááş áĄááŻáśá¸áááşá¸áá˛ááźá áşáááşá ááŹááŹáááŻáˇááąá¸áááŻáˇááąáŹ MQTT áááşááąáˇááťáşááťáŹá¸ááźááˇáş áá áşááŻááŻááŻááşááąáŹááşáááş áĄááťáááşááąáŹááşááŤááźáŽá
ááťá˝ááşáŻááşá "á
áááşáĄáááş" áááşáááşááąááŤáááşá
á ááşáá ášá ááşá¸áááş áĄáááşá¸ááŻáśá¸áá áşááźáááş áááşááąáˇááťáşáááŻáˇááźáŽá¸ááąáŹááşá áááşáááŻá¸áááş á áŹáááşá¸áá˛áá˝ááş ááťááşááťááşá¸ááąáŤáşááŹáááşááźá áşáááşá
á¤áááşáááŻá¸ááťáŹá¸ááᯠáááŻáĄá፠á
áá
áşáĄááŹááášááŻááťáŹá¸áážááˇáş áááşá
ááşáááŻááşááźáŽááźá
áşááźáŽá¸ áááşá¸áááŻáˇááᯠáĄáááŻáĄááťáąáŹááşá
áá
áşáááŻááşáᏠScript ááťáŹá¸áá˝ááş áĄááŻáśá¸ááźáŻáááŻááşááźáŽá¸ áĄááťááŻá¸ááťááŻá¸ááąáŹ áá˝á˛ááźááşá¸á
áááşááźáŹáážáŻááťáŹá¸ááᯠááŻááşááąáŹááşáááŻááşáááş - áĄáŹá¸ááŻáśá¸áááş á¤ááąáŹááşá¸ááŤá¸á áĄáááŻááşá¸áĄááŹáááşááťáąáŹáşáá˝ááşááŤáááşá á
áááşááŤáááşá
áŹá¸áá°áááŻááşá¸áĄáá˝ááş majordomo á
áá
áşáĄáŹá¸ ááťá˝ááşáŻááşáĄááźáśááźáŻáááŻááşááŤáááşá
ááááşáĄááťááŻáˇááᯠááŤááźáááşá áááşá¸áááş ááąáˇá ááşáááşáááŻá¸ááťáŹá¸á áááŻá¸áážááşá¸ááąáŹááááşááźá áşáááşá
ááááşáá˝ááş ááąááᯠáááşáá°ááťáž áĄááŻáśá¸áááźáŻááźááźáąáŹááşá¸ áá˝áąáˇáááŻááşáááşá áá
áşá
áŻáśáá
áşááąáŹááşáááş áĄáááşááŹáááŻáˇ áážá
áşááźáááşáá˝áŹá¸áá˛áˇááźáŽá¸á ááźáąáŹááşá¸ááźááş osmosis filter áááş áá
áşáááťážááş áážá
áşááŽáᏠá
áŻááşáá°áá˝áŹá¸ááŻáśááááşá ááááşáááşá¸áážáŹ á
áŹá¸ááŻáśá¸áážáŻ ááááááŹáᏠáááŻá¸ááŹááŤáááşá ááťá˝ááşáŻááşáááş áá˝ááŻááşááŹáážááąááᯠáĄááťáŹá¸áĄáŹá¸ááźááˇáş áĄááŻáśá¸ááźáŻááąáŹáşáááşá¸á áááŻáˇááąáŹááşáá˝ááş ááąááťááŻá¸ááźáŽá¸ ááźááŻáˇáá˝ááşá¸ááąáá°áááŻáˇ ááąáášáááźáąáŹááşá¸ááťááşáá˛áˇáááş - áááşá¸ááᯠáĄáąáŹááşááąáŹáşááźá፠ááááşáá˝ááş áážááşá¸áážááşá¸áááşá¸áááşá¸ ááźááşáááŻááşáááşá
áĄáááşááŹáááşáááŻáˇ ááą 6-7 ááŽáᏠáááŻáĄááşáááşá ááąááťááŻá¸áááş 20-30 ááŽááŹá áááşá¸áááşááąá¸áááŻáˇ 20 ááŽáᏠáááŻáĄááşáááşá ááąááťááŻá¸áááş 160 ááŽáᏠáááŻáĄááşáááşáááŻáᏠááŽááááşáááą ááąáˇááŹáá˛áˇáááşá ááťá˝ááşááąáŹáˇáşááááŹá¸á áŻá áá áşááąáˇááᯠááŽáᏠá áá-ááá ááąáŹááş á áŹá¸ááŻáśá¸áááşá
áĄáá°á¸áááźááˇáş á á°á¸á ááşá¸áááŻáá°ááťáŹá¸áĄáá˝ááşá áá áşáŚá¸ááťááşá¸á áŽáááşáááŻá¸áĄáá˝ááş áážááşáááşá¸ááťáŹá¸ááᯠááźááˇáşáážáŻáááŻááşááŤáááşá
ááŻáśáááŻááşáá˝ááˇáşááąáŹáĄá፠ááąáááş 1 á
áášáááˇáşááťážááş 5 ááŽááŹáááˇáşáĄááźááşáážáŻááşá¸ááźááˇáşá
áŽá¸áááşá¸ááźáąáŹááşá¸ááᯠá¤ááąááŹááž ááťá˝ááşáŻááşáááážááá˛áˇááááşá
ááŤááąáááˇáş ááŽááŻáśá áśá á áŹáááşá¸áááŹá¸áá˝áąááᯠááźááˇáşááᏠááááşáĄáááşáááźáąáá°á¸á Majordomo áááş ááąáˇá áĄáááşáážááˇáşááĄáááŻááş á áŹá¸ááŻáśá¸áážáŻáááŹá¸ááťáŹá¸ááᯠááźááˇáşáážáŻáááŻááşáááşá á¤áá˝ááşá áĽáááŹá ááŹá¸ááťáŹá¸áážá á áŹá¸ááŻáśá¸áážáŻááááşáá áşááŻááźá áşáááşá
áĄááŻáá ááťá˝ááşááąáŹáˇáşáážáŹ ááąááŹáá˝áą áá
áşáááşááąáŹááşáᲠáážáááąá¸áááşá áá
áşááá˝ááşá á¤ááááşáááş áááŻá áá˝ážááşááźááááˇáşáááş - áá
áşááąáˇááťážááş ááŽá¸ááźáŹá¸ááąáŹáşááśáá
áşáᯠáážáááŤáááşá ááťá˝ááşáŻááşáááŻááşáááŻááşáááˇáşáá˝ááşá¸ááąáŹáááşáááŻá¸ááťáŹá¸ (áĄááźáŽá¸ááŻáśá¸ááąáŹáşááś) ááᯠááťáááşáážáááźááşá¸ááźááˇáş ááŻáśáááş áĄáááşá¸áááş ááťááşá
áŽá¸áá˝áŹá¸ááŤáááşá ááźáŽá¸ááąáŹáˇ ááááááşáááŻá¸áá˝áąááᯠáá
áşááŻáśá¸ááŽá¸ááŤá¸ áááşá¸áĄáąáŹááş áážáŹá¸áá˝ááşá¸áááşáážááşááŹá¸áááŹá¸á ááŤáážáááŻááş ááŤá Firmware áá˛á ááťááŻáˇáá˝ááşá¸ááťááşáá
áşááŻááźá
áşááźáŽá¸ ááŽááŹáĄáŹá¸ááŻáśá¸ááᯠááąááá˝ááşááŹá¸áá°á¸áááŻááŹááąáŹáˇ áážááşá¸áážááşá¸áááşá¸áááşá¸ ááááááąá¸ááŤáá°á¸á áĄááťáááşáááŻáááŻáááşá
ááááşááťáŹá¸áááŻááşáááŻááşá áážáąáŹáşáááŹá ááąá¸ááŻááşááźááşá¸á áááşá¸ááťáŽáá˝á˛áááş áááŻáĄááşááąááąá¸áááşá áĄáážáŹá¸áážáŹáááş áááşáá˝ááşááťááşáĄáá˝ááş áááşáááŻááŽááŻáśá¸á á˝á˛áážáŻ ááááşááşáááŻáááşá¸ áááşááąáŹááşáááş ááźá áşááąáŹááşá¸ááźá áşáááŻááşáááş- áááŻááąááŹáá˝ááş áá áşá áŻáśáá áşáᯠááąáŤááşááźáŹá¸áá˝áŹá¸ááŤáá áĄááşááŹáááşááážááááˇáşáĄááťáááşááŹáááťáŹá¸ááᯠáá áşáááşá¸áááşá¸ááźááˇáş ááąáŹáşááźáááŻááşáááşááźá áşáááşá ááąáŹááąáŹáááşááąáŹáˇ ááŤáá˝áąáĄáŹá¸ááŻáśá¸á á áááşáá°á¸áĄáááˇáşáážáŹ áážááááşá
ááąáŹááşááťááş
ááŽááąáˇ ááŤáˇáááŻááşáááşá¸á áááşá¸áááşá¸ á áááşááťááŹáááşá áááŻáá˛áˇáááŻáˇááąáŹ ááąá¸áááşááąáŹááááááŹááźááˇáş áĄáááşáá˝ááşá¸ááąááŻáśá¸á á˝á˛áážáŻááᯠá áąáŹááˇáşááźááˇáşáááş ááťá˝ááşáŻááşáĄáá˝ááş áááŻááĄáááşááźáąááŤááááˇáşáááşá áĄáááşá ááťá˝ááşáŻááşáááş á áąáŹá áąáŹá "ááąáŹááşáá áşááźáááşá áá áşááĄáá˝ááşá¸ ááąááťáŹá¸á á˝áŹ ááŻáśá¸á á˝á˛áá˛áˇáááş" áá°ááąáŹ á ááŹá¸ááᯠááťá˝ááşáŻááş ááąáŤááá˝ááşáá˛áˇááťážááş ááᯠá¤á áŹá¸ááŻáśá¸áážáŻá áĄáááşá¸áĄááźá áşááᯠááťá˝ááşáŻááş áážáŹáá˝áąáááŻááşááźáŽááźá áşáááşá
ááŽááŹáááŻááşáážááŻááşáážááˇáş áá áşááŽááŹáĄáá˝áŹáá˝ááş áááşááŹá¸ááźááşááąáŤáşáážá á áŹáááŻááźááˇáşááťážááş áĄááťááŻáˇá áá°á¸áááşá¸áááşáᯠáááşáááŻááşáááşá ááŤááąáááˇáş ááááşáááąá¸áá˛áˇáĄááŹáááşáážáŹá ááąáĄáááşáĄááťááťáŹá¸á á˝áŹáážááááˇáş áááźáŹá¸áááŻááşáááşá¸ááᯠááźáąáŹááşá¸áá˝ážáąáˇáááŻáˇ á áŽá ááşááŹá¸ááźáŽá¸ ááŽááŹáá˝áąá áááşá¸áááşááŹáážáŹ ááźá áşáááŻááşááťáąááťáŹá¸ááŤáááşá ááŤááźáąáŹááˇáş áĄááąá¸ááááşá¸á áŹáááşááááááŹáᏠáĄáá˝ááşáĄááŻáśá¸áááşááŤááááˇáşáááşá
á ááşáá ášá ááşá¸á ááŻááşááąáŹááşáááŻááşá á˝ááşá¸ááᯠááťá˛áˇáá˝ááşáááşáááşá¸ á áŽá ááşááąááŤáááşá ááąáŹáşááąáŹáşáááŻááşáááş áĄáááŻáˇáážááşáá˝áąááᯠááźááˇáşááąááźáŽá áááŻáĄá፠áá˝ááŻááşááŹááᯠááźááŻáˇááąáááŻáˇááźáąáŹááşá¸áááşá áááşáážááşá¸ááŽáááş áááşáá˛ááąáŹááąááŹáá áşááŻáá˝ááş áááŻááşááąáŤááşá¸ á ááŻáá˝ááˇáşáááş áááŻáĄááşááŤáááşá áááşáááŻááşáᏠáá˝ážááşááźááťááşááźááˇáş áááŻááşáá áşááŻáááşá¸ááźááˇáş ááźáŻááŻááşáááş áááŻáááŻáĄáááşááźáąáááşááźá áşáááşá ááŻááşááŤáááşá áááŻá áááˇáşáážáŻáážááŹáá˝ááşáážáŻááᯠáĄááąáŹááşáĄáááşááąáŹáşáááťááŻá¸áááşááŤáááşá
ááąáŹááşá¸ááŤá¸áá˝ááş ESP8266 áááŻáĄááźáąááśá ááťá˝ááşáŻááşáá ááşáá ášá ááşá¸ááŹá¸áážááşá¸ááᯠááąáŹáşááźáá˛áˇáááşá ááťá˝ááşáŻááşááĄááźááşáĄáá ááťá˝ááşáŻááşáááş coroutines áááŻáĄááŻáśá¸ááźáŻá áĄáá˝ááşá áááşáááşá áŹá¸á ááŹááąáŹááşá¸ááąáŹ micropython firmware ááŹá¸áážááşá¸ááᯠáá˝ááşááąáŤáşááŹáá˛áˇáááş - áááŻá¸áážááşá¸ááźáŽá¸ ááąáŹááşá¸áá˝ááşááŤáááşá áážáŻáśáˇááąáŹáşáážáŻáĄáá˝ááşá¸ ááźáŻáśáá˝áąáˇáá˛áˇáááąáŹ áá˝á˛áá˝á˛ááťááşááťáŹá¸áážááˇáş ááťááŻáˇáá˝ááşá¸ááťááşááťáŹá¸á á˝áŹááᯠááąáŹáşááźáááş ááźááŻá¸á áŹá¸áá˛áˇáááşá ááťá˝ááşááąáŹáşáááş áĄááŹáĄáŹá¸ááŻáśá¸ááᯠáĄááąá¸á áááşáĄáá˝ááşáĄááťá˝áśááąáŹáşááźáááŻááşááźááşá¸ááźá áşááąáŹááşá¸ááźá áşáááŻááşáááşá ááŻáášáááŻááşááąá¸áĄá á áŹáááşáá°áá áşáŚá¸áĄááąááźááˇáş ááááŻáĄááşááąáŹáĄááŹááťáŹá¸ááᯠááąáŹááşáážáááźáąáŹáá˛ááŹá¸áá˛áˇáááˇáşáĄááŹááᯠááźááşá ááşá¸á áŹá¸áááşáááş ááťá˝ááşáŻááşáĄáá˝ááş ááááŻáĄááşááąáŹáĄááŹááťáŹá¸ááᯠááťáąáŹáşááźááşáááş áááŻááá˝ááşáá°ááŤáááşá
áĄááźá˛áááŻááᯠáĄááźáŻáááąáŹááąáŹááşáá˛áˇ ááąáááşáážáŻáá˝áąááᯠáááşáá˝ááˇáşáááşá
source: www.habr.com