Kudala, ama-automation systems, noma “i-smart home” njengoba ayevame ukubizwa kanjalo, ayemba eqolo futhi izicebi kuphela ezazikwazi ukuzikhokhela. Namuhla emakethe ungathola amakhithi angabizi kakhulu anezinzwa, izinkinobho/ukushintsha kanye nama-actuator okulawula ukukhanya, amasokhethi, ukungena komoya, ukuhlinzekwa kwamanzi nabanye abathengi. Futhi ngisho nomuntu we-DIY ogwegwile kakhulu angakwazi ukuzibandakanya ebuhleni futhi ahlanganise amadivaysi endlu ehlakaniphile ngentengo engabizi.

Ngokuvamile, amadivayisi ahlongozwayo angaba izinzwa noma ama-actuator. Bakwenza kube lula ukusebenzisa izimo njengokuthi "uma inzwa yokunyakaza iqaliswa, khanyisa izibani" noma "iswishi eseduze nendawo yokuphuma ivala izibani kulo lonke ifulethi." Kodwa ngandlela-thile izinto azizange zisebenze nge-telemetry. Okungcono kakhulu, igrafu yezinga lokushisa nokuswakama, noma amandla asheshayo endaweni ethile.
Ngisanda kufaka amamitha amanzi ane-pulse output. Kulelo nalinye ilitha elidlula imitha, iswishi yomhlanga iyacushwa bese ivala othintana naye. Okusele okumele ukwenze wukubambelela ezintanjeni uzame ukuzuza kuzo. Isibonelo, hlaziya ukusetshenziswa kwamanzi ngehora nosuku lwesonto. Hhayi-ke, uma kukhona izikhuphukeli zamanzi ezimbalwa efulethini, khona-ke kulula kakhulu ukubona zonke izinkomba zamanje esikrinini esisodwa kunokukhuphuka ku-niches okunzima ukufinyelela kuzo ngethoshi.
Ngezansi kokusikiwe kunenguqulo yami yedivayisi esekelwe ku-ESP8266, ebala ama-pulses ukusuka kumamitha amanzi futhi ithumele ukufundwa nge-MQTT kuseva yasekhaya ehlakaniphile. Sizohlela nge-micropython sisebenzisa umtapo wezincwadi we-uasyncio. Lapho ngidala i-firmware, ngihlangabezane nobunzima obuningana ezithakazelisayo, engizobuye ngixoxe ngazo kulesi sihloko. Hamba!
Lolu hlelo

Inhliziyo yayo yonke isekethe iyimojula ku-ESP8266 microcontroller. I-ESP-12 yayihlelelwe ekuqaleni, kodwa eyami yabonakala inephutha. Kwadingeka saneliswe imojula ye-ESP-07, eyayitholakala. Ngenhlanhla, ziyafana zombili ngokwezikhonkwane kanye nokusebenza, umehluko kuphela ku-antenna - i-ESP-12 inokwakhelwe ngaphakathi, kuyilapho i-ESP-07 ineyangaphandle. Nokho, ngisho nangaphandle kwe-antenna ye-WiFi, isignali endlini yami yokugezela yamukelwa ngokuvamile.
Izintambo ezijwayelekile zemojuli:
- setha kabusha inkinobho ngokudonsa kanye ne-capacitor (yize kokubili sekungaphakathi kwemojuli)
- Isignali yokunika amandla (CH_PD) idonselwa phezulu emandleni
- I-GPIO15 idonselwa phansi. Lokhu kudingekile kuphela ekuqaleni, kodwa angikabi nalutho engingalunamathisela kulo mlenze; angisakudingi
Ukufaka imojula kumodi ye-firmware, udinga ukufinyeza i-GPIO2 phansi, futhi ukuyenza ibe lula, nginikeze inkinobho ye-Boot. Esimeni esijwayelekile, le phinikhodi idonselwa amandla.
Isimo somugqa we-GPIO2 sibhekwa kuphela ekuqaleni kokusebenza - lapho amandla esetshenziswa noma ngokushesha ngemva kokusetha kabusha. Ngakho-ke imojuli iqala njengokujwayelekile noma ingena kumodi ye-firmware. Uma isilayishiwe, le phinikhodi ingasetshenziswa njenge-GPIO evamile. Hhayi-ke, njengoba sekukhona inkinobho lapho, unganamathisela umsebenzi othile owusizo kuyo.
Ekuhleleni nasekulungiseni iphutha ngizosebenzisa i-UART, ephuma ekama. Uma kudingekile, ngivele ngixhume i-adaptha ye-USB-UART lapho. Udinga nje ukukhumbula ukuthi imojula inikwa amandla yi-3.3V. Uma ukhohlwa ukushintsha i-adaptha kule voltage futhi unikeze i-5V, imojuli cishe izosha.
Anginazinkinga ngogesi endlini yokugezela - i-outlet itholakala cishe imitha ukusuka kumamitha, ngakho-ke ngizonikwa amandla ngu-220V. Njengomthombo wamandla ngizoba nencane nguTenstar Robot. Ngokwami, nginesikhathi esinzima nge-analog namandla kagesi, kodwa nansi ukunikezwa kwamandla okwenziwe ngomumo esimweni esincane.
Ukuze usayine amamodi okusebenza, nginikeze i-LED exhunywe ku-GPIO2. Nokho, angizange ngiyikhulule, ngoba... Imojula ye-ESP-07 isivele ine-LED, futhi ixhunywe ku-GPIO2. Kodwa makube ebhodini, uma kwenzeka ngifuna ukukhipha le LED ecaleni.
Masiqhubekele engxenyeni ethakazelisa kakhulu. Amamitha amanzi awanawo umqondo; awukwazi ukuwabuza ukufundwa kwamanje. Okuwukuphela kwento esiyitholayo ama-impulses - ukuvala othintana nabo bokushintsha komhlanga njalo ilitha. Imiphumela yami yokushintsha umhlanga ixhunywe ku-GPIO12/GPIO13. Ngizonika amandla isiphikisa sokudonsa phezulu ngokohlelo ngaphakathi kwemojuli.
Ekuqaleni, ngikhohlwe ukunikeza ama-resistors u-R8 no-R9 futhi inguqulo yami yebhodi ayinazo. Kodwa njengoba sengivele ngithumela umdwebo ukuze wonke umuntu awubone, kufanelekile ukulungisa lokhu kwengamela. Ama-resistors ayadingeka ukuze ungashisi ichweba uma i-firmware iphazamiseka futhi isetha iphinikhodi eyodwa, futhi i-resis switch shorts lo mugqa phansi (nge-resistor enkulu engu-3.3V/1000Ohm = 3.3mA izogeleza).
Sekuyisikhathi sokucabanga ukuthi yini okufanele uyenze uma ugesi ucima. Inketho yokuqala ukucela amanani ekhawunta okuqala kuseva ekuqaleni. Kodwa lokhu kuzodinga inkinga ebalulekile yephrothokholi yokushintshanisa. Ngaphezu kwalokho, ukusebenza kwedivayisi kuleli cala kuncike esimweni seseva. Uma iseva ingaqalanga ngemva kokuba amandla evaliwe (noma aqalwe kamuva), imitha yamanzi ngeke ikwazi ukucela amanani okuqala futhi ngeke isebenze kahle.
Ngakho-ke, nginqume ukusebenzisa amanani aphikisayo wokulondoloza kumemori chip exhunywe nge-I2C. Anginazo izidingo ezikhethekile zosayizi wememori ye-flash - udinga kuphela ukulondoloza izinombolo ezi-2 (inani lamalitha ngokuya ngamamitha ashisayo nabandayo). Ngisho nemojuli encane kunazo zonke izokwenza. Kodwa udinga ukunaka inani lemijikelezo yokurekhoda. Kumamojula amaningi lokhu kuyimijikelezo eyizinkulungwane eziyi-100, kweminye ifinyelela esigidini.
Kungabonakala sengathi isigidi siningi. Kodwa phakathi neminyaka engu-4 ngihlala endlini yami, ngadla amanzi angaphezu kwama-cubic mitha angu-500, lawo angamalitha ayizinkulungwane ezingu-500! Futhi amarekhodi ayizinkulungwane ezingama-500 nge-flash. Futhi lawo amanzi abandayo nje. Yebo, ungaphinda uyithengise kabusha i-chip njalo eminyakeni embalwa, kodwa kuvela ukuthi kukhona ama-FRAM chips. Ngokombono wokuhlela, lena i-I2C EEPROM efanayo, kuphela enenani elikhulu kakhulu lemijikelezo yokubhala kabusha (amakhulu ezigidi). Ukuthi nje angikwazi ukufika esitolo ngama-microcircuits anjalo, ngakho-ke okwamanje i-24LC512 evamile izoma.
Ibhodi lesifunda eliphrintiwe
Ekuqaleni, ngahlela ukwenza ibhodi ekhaya. Ngakho-ke, ibhodi laklanywa njengohlangothi olulodwa. Kodwa ngemva kokuchitha ihora ngensimbi ye-laser kanye ne-mask ye-solder (ngandlela-thile ngeke ifike ngaphandle kwayo), ngisanquma uku-oda amabhodi avela kumaShayina.

Cishe ngaphambi koku-oda ibhodi, ngabona ukuthi ngaphezu kwe-flash memory chip, ngingaxhuma enye into ewusizo ebhasini le-I2C, njengesibonisi. Yini ngempela ongayikhipha kuyo kusewumbuzo, kodwa idinga ukuhanjiswa ebhodini. Hhayi-ke, njengoba bengizo-oda amabhodi efektri, kwakungekho phuzu lokuzikhawulela ebhodini elihlangothini olulodwa, ngakho-ke imigqa ye-I2C iyona kuphela engemuva kwebhodi.
Kuphinde kwaba nenkinga eyodwa enkulu ngezintambo zendlela eyodwa. Ngoba Ibhodi yadwetshwa njengohlangothi olulodwa, ngakho-ke amathrekhi kanye nezingxenye ze-SMD zazihlelwe ukuthi zibekwe ohlangothini olulodwa, kanye nezingxenye zokukhipha, izixhumi kanye nokunikezwa kwamandla ngakolunye. Lapho ngithola amabhodi ngemva kwenyanga, ngakhohlwa ngohlelo lwangempela futhi ngathengisa zonke izingxenye ezingaphambili. Futhi kuphela lapho kufika ekuthengiseni amandla kagesi kwavela ukuthi i-plus ne-minus yayixhunywe ngokuphambene. Kwadingeka ngilima ngama-jumpers. Esithombeni esingenhla, sengivele ngishintshile i-wiring, kodwa umhlabathi udluliselwa kusuka engxenyeni yebhodi kuya kwenye ngokusebenzisa izikhonkwane zenkinobho ye-Boot (nakuba kungenzeka ukudweba ithrekhi kungqimba lwesibili).
Kwaba kanje

Izindlu
Isinyathelo esilandelayo umzimba. Uma unephrinta ye-3D, lokhu akuyona inkinga. Angizange ngizihluphe kakhulu - ngivele ngadweba ibhokisi elinosayizi ofanele futhi ngenza ama-cutouts ezindaweni ezifanele. Isembozo sinamathiselwe emzimbeni ngezikulufo ezincane zokuzishaya.

Sengike ngasho ukuthi inkinobho yokuqalisa ingasetshenziswa njengenkinobho yenhloso evamile - ngakho-ke sizoyibonisa kuphaneli engaphambili. Ukwenza lokhu, ngidwebe "umthombo" okhethekile lapho kuhlala khona inkinobho.

Ngaphakathi kwekesi kukhona nezikhonkwane lapho ibhodi lifakwa futhi livikelwe ngesikulufa esisodwa se-M3 (sasingasekho isikhala ebhodini)
Ngikhethe isibonisi vele lapho ngiphrinta inguqulo yokuqala yesampula yekesi. Isifundi esijwayelekile semigqa emibili asizange singene kuleli cala, kodwa ngezansi bekunesibonisi se-OLED SSD1306 128×32. Kuncane kakhulu, kodwa akudingekile ukuba ngikugqolozele nsuku zonke—kungaphezu kwamandla ami.
Ngokubona ngale ndlela nokuthi izintambo zizohanjiswa kanjani kuyo, nginqume ukunamathisela isibonisi phakathi necala. I-ergonomics, yebo, ingaphansi kwe-par - inkinobho iphezulu, isibonisi singezansi. Kodwa besengivele ngasho ukuthi umqondo wokunamathisela isibonisi ufike sekwephuze kakhulu futhi ngivilapha kakhulu ukuxhuma kabusha ibhodi ukuze ngihambise inkinobho.
Idivayisi ihlanganisiwe. I-module yokubonisa inamathele ku-snot nge-glue eshisayo


Umphumela ungabonwa ku-KDPV
I-Firmware
Asiqhubekele engxenyeni yesofthiwe. Emisebenzini yezandla emincane kanje, ngithanda kakhulu ukusebenzisa iPython () - ikhodi ivela ihlangene kakhulu futhi iyaqondakala. Ngenhlanhla, asikho isidingo sokwehlela ezingeni lokubhalisa ukuze ukhiphe ama-microseconds - konke kungenziwa kusuka kuPython.
Kubonakala sengathi konke kulula, kodwa akulula kakhulu - idivayisi inemisebenzi eminingana ezimele:
- Umsebenzisi uchofoza inkinobho futhi abheke isibonisi
- Ama-liters aphawula futhi abuyekeze amanani kumemori ye-flash
- Imojula iqapha isignali ye-WiFi futhi ixhume kabusha uma kunesidingo
- Nokho, ngaphandle kwesibani esicwayizayo akunakwenzeka
Ngeke ucabange ukuthi umsebenzi owodwa awuzange usebenze uma omunye ubambekile ngesizathu esithile. Sengivele ngagcwala i-cacti kwamanye amaphrojekthi futhi manje ngisabona amaphutha esitayela "sokuphuthelwa elinye ilitha ngoba isibonisi besibuyekeza ngaleso sikhathi" noma "umsebenzisi akakwazi ukwenza lutho ngenkathi imojula ixhumeka WiFi.” Kunjalo, ezinye izinto zingenziwa ngokusebenzisa iziphazamiso, kodwa ungase uhlangabezane nemikhawulo ngesikhathi, ukufakwa kwezingcingo, noma izinguquko ezingezona ze-athomu eziguquguqukayo. Hhayi-ke, ikhodi eyenza yonke into ngokushesha iphenduka i-mush.
В Ngisebenzise i-multitasking ye-preemptive yakudala kanye ne-FreeRTOS, kodwa kulokhu imodeli ibonakale ifaneleka kakhulu. . Ngaphezu kwalokho, ukuqaliswa kwePython kwama-coroutines kuyamangaza nje - konke kwenziwa kalula futhi kalula kumhleli. Vele ubhale ukucabanga kwakho, vele ungitshele ukuthi iziphi izindawo ongashintsha kuzo phakathi kokusakaza.
Ngiphakamisa ukuthi kufundwe umehluko phakathi kwemisebenzi eminingi eyandulelayo kanye nokuncintisana njengesihloko ongasikhetha. Manje ake siqhubekele kukhodi.
#####################################
# 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 foreverIkhawunta ngayinye isingathwa isibonelo se-Counter class. Okokuqala, inani lokuqala le-counter likhishwa ku-EEPROM (value_storage) - lena yindlela yokuthola ngemva kokuqaliswa kokuhluleka kwamandla.
Iphinikhodi iqalwa ngokudonsa eyakhelwe ngaphakathi ekunikezeni amandla: uma ukushintshwa komhlanga kuvaliwe, umugqa unguziro, uma umugqa uvulekile, udonselwa phezulu kumandla kagesi futhi isilawuli sifunda esisodwa.
Umsebenzi ohlukile nawo wethulwa lapha, ozophenya iphini. Ikhawunta ngayinye izoqhuba umsebenzi wayo. Nali ikhodi yakhe
""" 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)Kudingeka ukubambezeleka okungu-25ms ukuze kuhlungwe ukugxuma kokuxhumana, futhi ngesikhathi esifanayo kulawula ukuthi umsebenzi uvuka kaningi kangakanani (ngenkathi lo msebenzi ulele, eminye imisebenzi iyasebenza). Njalo ngo-25ms umsebenzi uyavuka, uhlole iphinikhodi futhi uma izixhumi zokushintsha umhlanga zivaliwe, khona-ke elinye ilitha selidlulile kumitha futhi lokhu kudinga ukucutshungulwa.
def _another_litre_passed(self):
self._value += 1
self._value_changed = True
self._value_storage.write(self._value)Ukucubungula ilitha elilandelayo kuyinto encane - ikhawunta imane ikhule. Hhayi-ke, kungaba kuhle ukubhala inani elisha ku-flash drive.
Ukuze kube lula ukusetshenziswa, "abangena" banikezwa
def value(self):
self._value_changed = False
return self._value
def set_value(self, value):
self._value = value
self._value_changed = FalseNokho, manje ake sisebenzise injabulo ye-Python kanye nomtapo wezincwadi we-uasync futhi senze into elindelekile yokubala (singakuhumusha kanjani lokhu kusiRashiya? Leyo ongayilindela?)
def __await__(self):
while not self._value_changed:
yield from asyncio.sleep(0)
return self.value()
__iter__ = __await__ Lona umsebenzi olula kangaka olinda kuze kube yilapho inani eliphikisayo libuyekezwa - umsebenzi uyavuka ngezikhathi ezithile futhi uhlole ifulegi _value_changed. Into epholile ngalo msebenzi ukuthi ikhodi yokushaya ingalala ngenkathi ibiza lo msebenzi futhi ilale kuze kube yilapho kwamukelwe inani elisha.
Kuthiwani ngeziphazamiso?Yebo, kuleli qophelo ungangidonsa, uthi wena ngokwakho ushilo mayelana neziphazamiso, kodwa empeleni wenze iphinikhodi eyisiphukuphuku. Empeleni ukuphazamisa yinto yokuqala engizame ngayo. Ku-ESP8266, ungahlela ukuphazamiseka konqenqema, futhi ubhale nesibambi salokhu kuphazamiseka ku-Python. Kulokhu kuphazamiseka, inani lokuguquguquka lingabuyekezwa. Mhlawumbe, lokhu bekuyokwanela ukube ikhawunta bekuyithuluzi lesigqila - elilinda lize licelwe leli nani.
Ngeshwa (noma ngenhlanhla?) idivayisi yami iyasebenza, kufanele yona ngokwayo ithumele imilayezo ngephrothokholi ye-MQTT futhi ibhale idatha ku-EEPROM. Futhi lapha imikhawulo iqala ukusebenza - awukwazi ukwaba inkumbulo ngokuphazamiseka futhi usebenzise isitaki esikhulu, okusho ukuthi ungakhohlwa ngokuthumela imilayezo ngenethiwekhi. Kunamabhanisi afana ne-micropython.schedule() akuvumela ukuthi usebenzise umsebenzi othile “ngokushesha,” kodwa umbuzo ophakamayo, “yini iphuzu?” Kuthiwani uma sithumela uhlobo oluthile lomlayezo njengamanje, bese kuba nokuphazamiseka kungena futhi konakalise amanani okuguquguqukayo. Noma, isibonelo, inani elisha lokuphikisa lifikile livela kuseva ngesikhathi singakabhali esidala. Ngokuvamile, udinga ukuvimba ukuvumelanisa noma uphume kukho ngendlela ehlukile.
Futhi ngezikhathi ezithile i-RuntimeError: hlela ukuphahlazeka okugcwele kwesitaki futhi ubani owaziyo ukuthi kungani?
Ngokuvota okusobala kanye ne-uasync, kulesi simo ngandlela thile kuvela kukuhle kakhulu futhi kuthembekile
Ngeza nomsebenzi ne-EEPROM ekilasini elincane
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)Ku-Python, kunzima ukusebenza ngokuqondile ngama-byte, kodwa ama-byte abhalwe ngekhanda. Kwadingeka ngibiyele ukuguqulwa phakathi kwenani eliphelele namabhayithi ngisebenzisa umtapo wezincwadi we-ustruct.
Ukuze ngingadlulisi into ye-I2C kanye nekheli lememori yeseli njalo, ngikugoqe konke nge-classic encane futhi elula.
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)Into ye-I2C ngokwayo idalwe ngala mapharamitha
i2c = I2C(freq=400000, scl=Pin(5), sda=Pin(4))Sifika engxenyeni ethakazelisa kakhulu - ukuqaliswa kokuxhumana neseva nge-MQTT. Hhayi-ke, asikho isidingo sokusebenzisa iphrothokholi ngokwayo - ngiyithole ku-inthanethi . Yilokhu esizokusebenzisa.
Zonke izinto ezithakazelisa kakhulu ziqoqwa ekilasini le-CounterMQTTClient, elisekelwe kumtapo wezincwadi we-MQTTClient. Ake siqale emaphethelweni
#####################################
# 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))Lapha ungakha futhi ulungiselele izikhonkwane nezinkinobho zesibani, kanye nezinto zamamitha abandayo nashisayo.
Ngokuqalisa, akuyona yonke into encane kakhulu
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())Ukusetha imingcele yokusebenza yelabhulali ye-mqtt_as, isichazamazwi esikhulu sezilungiselelo ezihlukene sisetshenziswa - config. Iningi lezilungiselelo ezizenzakalelayo zilungile kithi, kodwa izilungiselelo eziningi zidinga ukusethwa ngokucacile. Ukuze ngingabhali izilungiselelo ngokuqondile kukhodi, ngizigcina kufayela lombhalo elithi config.txt. Lokhu kukuvumela ukuthi ushintshe ikhodi kungakhathaliseki izilungiselelo, futhi ukhiphe amadivayisi afanayo amaningana anemingcele ehlukene.
Ibhulokhi yokugcina yekhodi iqala ama-coroutine ambalwa ukuze asebenze imisebenzi ehlukahlukene yohlelo. Isibonelo, nansi i-coroutine ebalwa yizinsizakalo
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))I-coroutine ilinda ku-loop ngenani elisha eliphikisayo futhi, ngokushesha nje lapho livela, lithumela umlayezo nge-protocol ye-MQTT. Ucezu lokuqala lwekhodi luthumela inani lokuqala ngisho noma kungekho manzi agelezayo ekhawuntani.
I-base class MQTTClient iyazisebenzela yona, iqala uxhumano lwe-WiFi futhi ixhume kabusha lapho uxhumano kulahleka. Uma kukhona izinguquko esimweni soxhumano lwe-WiFi, umtapo wolwazi uyasazisa ngokushayela i-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)Umsebenzi ukopishwe ngokwethembeka ezibonelweni. Kulokhu, ibala inani lokucisha (internet_outages) kanye nobude bayo. Uma uxhumano lubuyiselwa, isikhathi sokungenzi lutho sithunyelwa kuseva.
Ngendlela, ukulala kokugcina kuyadingeka kuphela ukwenza umsebenzi u-asynchronous - emtatsheni wezincwadi ubizwa ngokuthi yi-ait, futhi imisebenzi kuphela umzimba wayo oqukethe okunye okulindelwe ingabizwa.
Ngaphezu kokuxhuma ku-WiFi, udinga futhi ukusungula ukuxhumana nomthengisi we-MQTT (iseva). Umtapo wolwazi nawo wenza lokhu, futhi sithola ithuba lokwenza okuthile okuwusizo lapho uxhumano selusunguliwe
async def mqtt_connection_handler(self, client):
await client.subscribe(self._mqtt_cold_water_theme)
await client.subscribe(self._mqtt_hot_water_theme)Lapha sibhalisela imilayezo eminingana - iseva manje inamandla okusetha amanani amanje aphikisayo ngokuthumela umlayezo ohambisanayo.
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))Lo msebenzi ucubungula imilayezo engenayo, futhi kuye ngesihloko (isihloko somlayezo), amanani enye yezinto zokubala ayabuyekezwa.
Imisebenzi embalwa yomsizi
# 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")Lolu hlelo lokusebenza luthumela umyalezo uma uxhumano lusunguliwe. Uma kungekho ukuxhumana, umlayezo uyazitshwa.
Futhi lokhu kuwumsebenzi olula nje okhiqiza futhi othumela imiyalezo yokususa iphutha.
async def publish_debug_msg(self, subtopic, msg):
await self.publish_msg("{}/{}".format(self._mqtt_debug_water_theme, subtopic), str(msg))
Umbhalo omningi, futhi asikakacwayizi i-LED okwamanje. Lapha
# 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)Nginikeze izindlela ezi-2 zokucwayiza. Uma uxhumano lulahlekile (noma lusanda kumiswa), idivayisi izocwayiza ngokushesha. Uma uxhumano selumisiwe, idivayisi icwayiza kanye njalo emizuzwaneni emi-5. Uma kunesidingo, ezinye izindlela zokucwayiza zingasetshenziswa lapha.
Kodwa i-LED ilula nje. Siphinde siqondise embukisweni.
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)Yilokhu ebengikhuluma ngakho - ukuthi kulula kangakanani futhi kulula kangakanani ngama-coroutines. Lo msebenzi omncane uchaza ulwazi lomsebenzisi LONKE. I-coroutine ivele ilinde ukuthi inkinobho icindezelwe bese ivula isibonisi imizuzwana emi-3. Isibonisi sibonisa ukufundwa kwamamitha wamanje.
Kusenezinto ezimbalwa ezisele. Nawu umsebenzi othi (kabusha) uqalise lonke leli bhizinisi. Iluphu eyinhloko ivele ithumele ulwazi oluhlukahlukene lokususa iphutha kanye ngomzuzu. Ngokuvamile, ngicaphuna njengoba injalo - angicabangi ukuthi sikhona isidingo sokuphawula kakhulu
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)Hhayi-ke, ezinye izilungiselelo ezimbalwa kanye nama-constants ukuze uqedele incazelo
#####################################
# 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)Konke kuqala kanje
client = CounterMQTTClient()
loop = asyncio.get_event_loop()
loop.run_until_complete(client.main())Kukhona okwenzekile enkumbulweni yami
Ngakho, yonke ikhodi ikhona. Ngilayishe amafayela ngisebenzisa insiza ye-ampy - ikuvumela ukuthi uwalayishe kwangaphakathi (leyo eku-ESP-07 uqobo) i-flash drive bese uyifinyelela kusuka kuhlelo njengamafayela ajwayelekile. Lapho ngiphinde ngalayisha imitapo yolwazi mqtt_as, uasyncio, ssd1306 kanye namaqoqo engiwasebenzisile (asetshenziswe ngaphakathi mqtt_as).
Sethula futhi... Sithola i-MemoryError. Ngaphezu kwalokho, lapho ngizama ukuqonda ukuthi inkumbulo yayivuza kuphi, lapho ngibeka khona amaphrinta okulungisa iphutha, leli phutha livele ekuqaleni. Usesho olufushane lwe-Google lwangiholela ekuqondeni ukuthi i-microcontroller, empeleni, inememori engu-30 kB kuphela, lapho amakhodi angu-65 kB (okuhlanganisa nemitapo yolwazi) angeke anele.
Kodwa ikhona indlela yokuphuma. Kuvele ukuthi i-micropython ayisebenzisi ikhodi ngokuqondile kufayela le-.py - leli fayela lihlanganiswa kuqala. Ngaphezu kwalokho, ihlanganiswa ngqo ku-microcontroller, iguqulwe ibe yi-bytecode, ebese igcinwa kumemori. Yebo, ukuze isihlanganisi sisebenze, udinga nenani elithile le-RAM.
Iqhinga liwukusindisa i-microcontroller ekuhlanganiseni okudinga izinsiza. Ungakwazi ukuhlanganisa amafayela kukhompuyutha enkulu futhi ulayishe i-bytecode eyenziwe ngomumo ku-microcontroller. Ukuze wenze lokhu, udinga ukulanda i-micropython firmware futhi wakhe .
Angizange ngibhale i-Makefile, kodwa ngidlule ngesandla futhi ngahlanganisa wonke amafayela adingekayo (kuhlanganise nemitapo yolwazi) into efana nale.
mpy-cross water_counter.pyOkusele nje ukulayisha amafayela ngesandiso se-.mpy, ungakhohlwa ukuqala ngokususa i-.py ehambisanayo ohlelweni lwamafayela lwedivayisi.
Ngenze konke ukuthuthukiswa ohlelweni (IDE?) ESPlorer. Ikuvumela ukuthi ulayishe izikripthi ku-microcontroller futhi uzenze ngokushesha. Endabeni yami, yonke ingqondo nokudalwa kwazo zonke izinto kutholakala kufayela elithi water_counter.py (.mpy). Kodwa ukuze konke lokhu kuqale ngokuzenzakalelayo, kufanele futhi kube nefayela elibizwa ngokuthi main.py ekuqaleni. Ngaphezu kwalokho, kufanele ibe ncamashi .py, futhi ingaqoqiwe ngaphambili .mpy. Nakhu okuqukethwe kwayo okungasho lutho
import water_counterSiyayethula - konke kuyasebenza. Kodwa inkumbulo yamahhala incane ngendlela esabekayo - cishe i-1kb. Ngisenezinhlelo zokwandisa ukusebenza kwedivayisi, futhi le kilobyte ngokusobala ayanele kimi. Kodwa kuvele ukuthi ikhona indlela yokuphuma kuleli cala.
Nansi into. Noma amafayela ehlanganiswa abe yi-bytecode futhi ahlala ohlelweni lwangaphakathi lwamafayela, empeleni asalayishwa ku-RAM futhi akhishwe lapho. Kodwa kuvela ukuthi i-micropython ingakwazi ukwenza i-bytecode ngokuqondile kwimemori ye-flash, kodwa ngenxa yalokhu udinga ukuyakha ngqo ku-firmware. Akunzima, nakuba kuthathe isikhathi eside ku-netbook yami (kuphela lapho ngathola khona i-Linux).
I-algorithm imi kanjena:
- Landa futhi ufake . Le nto ihlanganisa umdidiyeli nemitapo yolwazi yezinhlelo ze-ESP8266. Kuhlanganiswe ngokwemiyalo ekhasini eliyinhloko lephrojekthi (ngikhethe isethingi STANDALONE=yebo)
- Landa
- Beka amalabhulali adingekayo kumachweba/esp8266/module ngaphakathi kwesihlahla se-micropython
- Sihlanganisa i-firmware ngokusho kwemiyalelo efayeleni
- Silayisha i-firmware kusilawuli esincane (ngikwenza lokhu ku-Windows ngisebenzisa izinhlelo ze-ESP8266Flasher noma i-Python esptool)
Yilokho kuphela, manje 'ngenisa i-ssd1306' izophakamisa ikhodi ngokuqondile ku-firmware futhi i-RAM ngeke idliwe kulokhu. Ngaleli qhinga, ngilayishe kuphela ikhodi yelabhulali ku-firmware, kuyilapho ikhodi yohlelo eyinhloko ikhishwa ohlelweni lwefayela. Lokhu kukuvumela ukuthi uguqule kalula uhlelo ngaphandle kokubuyisela i-firmware. Okwamanje ngine-RAM engaba ngu-8.5kb yamahhala. Lokhu kuzosivumela ukuthi sisebenzise imisebenzi eminingi ewusizo esikhathini esizayo. Hhayi-ke, uma inkumbulo ingekho nhlobo, ungacindezela uhlelo oluyinhloko ku-firmware.
Ngakho-ke yini okufanele siyenze ngakho manje?
Kulungile, i-hardware ithengiswa, i-firmware ibhaliwe, ibhokisi liphrintiwe, idivayisi inamathele odongeni futhi ikhanya ngenjabulo isibani sokukhanya. Kodwa okwamanje konke kuyibhokisi elimnyama (ngokoqobo nangokomfanekiso) futhi lisasetshenziswa kancane. Isikhathi sokwenza okuthile ngemilayezo ye-MQTT ethunyelwa kuseva.
“Ikhaya lami elihlakaniphile” liyaqhubeka . Imojula ye-MQTT iphuma ebhokisini, noma ifakwa kalula isuka emakethe yezengezo - angikhumbuli ukuthi ngiyithathephi. I-MQTT akuyona into yokuzimela - udinga okuthiwa broker - iseva eyamukela, ihlunga futhi idlulisele imilayezo ye-MQTT kumakhasimende. Ngisebenzisa omiyane, okuthi (njenge-majordomo) esebenza ku-netbook efanayo.
Ngemva kokuthi idivayisi ithumele umlayezo okungenani kanye, inani lizovela ngokushesha ohlwini.

Lawa manani manje angahlotshaniswa nezinto zesistimu, angasetshenziswa kumaskripthi e-automation futhi angaphansi kokuhlaziya okuhlukahlukene - konke okungaphezu kwalesi sihloko. Ngingancoma uhlelo lwe-majordomo kunoma ubani onentshisekelo - umngane wakhe futhi wakha ikhaya elihlakaniphile futhi ukhuluma ngokucacile ngokusetha uhlelo.
Ngizokukhombisa amagrafu ambalwa. Lena igrafu elula yamanani ansuku zonke

Kuyabonakala ukuthi cishe akekho owayesebenzisa amanzi ebusuku. Izikhathi ezimbalwa othile waya endlini yangasese, futhi kubonakala sengathi isihlungi se-osmosis esibuyela emuva simunca amalitha ambalwa ngobusuku ngabunye. Ekuseni, ukusetshenziswa kwanda kakhulu. Ngivame ukusebenzisa amanzi asuka kubhayela, kodwa ngase ngifuna ukugeza futhi ngishintshele okwesikhashana emanzini ashisayo edolobha - lokhu kubonakala ngokucacile kugrafu engezansi.
Kule grafu ngafunda ukuthi ukuya endlini yangasese kudinga amalitha angu-6-7 amanzi, ukugeza kudinga amalitha angu-20-30, ukugeza izitsha kudinga amalitha angama-20, futhi ukugeza kudinga amalitha angu-160. Umndeni wami udla endaweni ethile cishe amalitha angama-500-600 ngosuku.
Kulabo abathanda ukwazi ikakhulukazi, ungabheka amarekhodi enani ngalinye

Kusukela lapha ngifunde ukuthi uma umpompi uvuliwe, amanzi ageleza ngesivinini esicishe sibe yilitha elingu-1 ngamasekhondi amahlanu.
Kodwa kuleli fomu izibalo cishe akulula kakhulu ukuzibheka. I-Majordomo iphinde ibe nekhono lokubuka amashadi okusetshenziswayo ngosuku, isonto nenyanga. Lapha, isibonelo, igrafu yokusetshenziswa kumabha

Kuze kube manje nginedatha yesonto kuphela. Ngenyanga, le grafu izoba yinkomba kakhudlwana - usuku ngalunye luzoba nekholomu ehlukile. Isithombe sonakaliswa kancane ukulungiswa kwamanani engiwafaka ngesandla (ikholomu enkulu kunazo zonke). Futhi akukacaci ukuthi ngabe ngibeke ngokungalungile amanani okuqala, cishe i-cube encane, noma ngabe lokhu kuyisiphazamisi ku-firmware futhi akuwona wonke amalitha abaliwe. Udinga isikhathi esengeziwe.
Amagrafu ngokwawo asadinga umlingo othile, ukucakwa, ukupenda. Mhlawumbe ngizophinde ngakhe igrafu yokusebenzisa inkumbulo ngezinjongo zokususa iphutha - uma kwenzeka kukhona okuvuzayo lapho. Mhlawumbe ngizobonisa izikhathi lapho ingekho i-inthanethi. Okwamanje, konke lokhu kusezingeni lemibono.
isiphetho
Namuhla ifulethi lami selihlakaniphe kancane. Ngomshini omncane kangaka, kuzoba lula kimi ukuqapha ukusetshenziswa kwamanzi endlini. Uma ngaphambili bengicasukele “futhi, sidle amanzi amaningi ngenyanga,” manje sengiyakwazi ukuthola umthombo walokhu kuphuza.
Abanye bangase bakuthole kuxaka ukubuka ukufundwa esibukweni uma kuyimitha kude nemitha ngokwayo. Kodwa esikhathini esizayo esingekude kakhulu, ngihlela ukuthuthela kwelinye ifulethi, lapho kuzoba khona izinyusi zamanzi eziningana, futhi amamitha ngokwawo cishe azobe etholakala endaweni yokuhlala. Ngakho idivayisi yokufunda ekude izoba usizo kakhulu.
Ngihlela nokwandisa ukusebenza kwedivayisi. Sengivele ngibheke amavalvu ezimoto. Manje, ukuze ngishintshele ibhayela emanzini edolobha, ngidinga ukuvula ompompi abangu-3 endaweni okunzima ukuyifinyelela. Kungaba lula kakhulu ukwenza lokhu ngenkinobho eyodwa enenkomba ehambisanayo. Yebo, kufanelekile ukusebenzisa ukuvikela ekuvuzeni.
Esihlokweni ngichaze inguqulo yami yedivayisi esekelwe ku-ESP8266. Ngokubona kwami, ngiqhamuke nenguqulo ethakazelisa kakhulu ye-micropython firmware usebenzisa ama-coroutines - alula futhi amnandi. Ngizamile ukuchaza amanuances amaningi kanye nokushiyeka engihlangabezane nakho ngesikhathi somkhankaso. Mhlawumbe ngichaze yonke into ngemininingwane eminingi kakhulu; ngokwami, njengomfundi, kulula kimi ukweqa izinto ezingadingekile kunokuba ngicabange kamuva ukuthi yini engashiyiwe.
Njengenhlalayenza, ngivulekele ukugxekwa okwakhayo.
Source: www.habr.com
