Muna haɗa mitar ruwa zuwa gida mai wayo

A wani lokaci, tsarin sarrafa kayan gida, ko "gida mai wayo" kamar yadda ake kira su, suna da tsada sosai kuma masu arziki ne kawai zasu iya samun su. A yau akan kasuwa zaku iya samun na'urori marasa tsada tare da na'urori masu auna firikwensin, maɓalli/masu kunna wuta da masu kunna wuta don sarrafa hasken wuta, kwasfa, samun iska, samar da ruwa da sauran masu amfani. Kuma ko da mafi karkataccen mutum na DIY zai iya shiga cikin kyakkyawa da haɗa na'urori don gida mai wayo akan farashi mara tsada.

Muna haɗa mitar ruwa zuwa gida mai wayo

Yawanci, na'urorin da aka tsara ko dai na'urori ne ko masu kunnawa. Suna sauƙaƙa aiwatar da al'amura kamar "lokacin da aka kunna firikwensin motsi, kunna fitilu" ko "maɓallin da ke kusa da fitowar yana kashe fitilu a cikin dukan ɗakin." Amma ko ta yaya abubuwa ba su yi aiki da telemetry ba. A mafi kyau, jadawali ne na zafin jiki da zafi, ko ikon nan take a takamaiman kanti.

Kwanan nan na shigar da mita ruwa tare da fitarwar bugun jini. Ga kowane lita da ta wuce ta mita, ana kunna maɓalli na reed kuma yana rufe lambar sadarwa. Abin da ya rage shi ne a manne wa wayoyi a yi kokarin samun fa'ida. Misali, tantance yawan ruwa ta awa da rana ta mako. Da kyau, idan akwai masu hawan ruwa da yawa a cikin ɗakin, to ya fi dacewa don ganin duk alamun yanzu akan allon daya fiye da hawa cikin niches masu wuyar isa tare da walƙiya.

A ƙasan yanke shine sigar na'urar da ta dogara da ESP8266, wacce ke ƙidayar bugun jini daga mita ruwa kuma tana aika karatu ta MQTT zuwa sabar gida mai kaifin baki. Za mu yi shiri a cikin micropython ta amfani da ɗakin karatu na uasyncio. Lokacin ƙirƙirar firmware, na gamu da matsaloli masu ban sha'awa da yawa, waɗanda zan tattauna a cikin wannan labarin. Tafi!

Makircin

Muna haɗa mitar ruwa zuwa gida mai wayo

Zuciyar da'irar gabaɗaya module ce akan microcontroller ESP8266. ESP-12 an shirya shi da farko, amma nawa ya zama mai lahani. Dole ne mu gamsu da tsarin ESP-07, wanda yake akwai. An yi sa'a, sun kasance iri ɗaya ne duka cikin sharuddan fil da ayyuka, kawai bambanci a cikin eriya - ESP-12 yana da ginanniyar ciki, yayin da ESP-07 yana da na waje. Koyaya, ko da ba tare da eriya ta WiFi ba, ana karɓar siginar a cikin gidan wanka na akai-akai.

Daidaitaccen tsarin wayoyi:

  • maɓallin sake saiti tare da cirewa da capacitor (kodayake duka biyun sun riga sun kasance a cikin tsarin)
  • An ja siginar kunnawa (CH_PD) zuwa wuta
  • An ja GPIO15 zuwa ƙasa. Ana buƙatar wannan kawai a farkon, amma har yanzu ba ni da abin da zan haɗa wa wannan ƙafar; Ba na buƙatarta kuma

Don sanya tsarin cikin yanayin firmware, kuna buƙatar gajeriyar kewayawa GPIO2 zuwa ƙasa, kuma don sanya shi mafi dacewa, na ba da maɓallin Boot. A cikin yanayin al'ada, ana ja wannan fil zuwa wuta.

Ana duba yanayin layin GPIO2 ne kawai a farkon aiki - lokacin da aka yi amfani da wutar lantarki ko kuma nan da nan bayan sake saiti. Don haka module ɗin ko dai yana yin takalma kamar yadda aka saba ko kuma ya shiga yanayin firmware. Da zarar an ɗora, ana iya amfani da wannan fil ɗin azaman GPIO na yau da kullun. To, tun da akwai maɓalli a can, za ku iya haɗa wani aiki mai amfani zuwa gare shi.

Don shirye-shirye da gyara kuskure zan yi amfani da UART, wanda ake fitarwa zuwa tsefe. Lokacin da ya cancanta, Ina kawai haɗa adaftar USB-UART a can. Kuna buƙatar kawai tuna cewa tsarin yana da ƙarfin 3.3V. Idan ka manta don canza adaftar zuwa wannan ƙarfin lantarki da samar da 5V, ƙirar za ta iya ƙonewa.

Ba ni da matsala game da wutar lantarki a cikin gidan wanka - wurin yana kusa da mita daga mita, don haka za a yi min wuta ta 220V. A matsayin tushen wutar lantarki zan sami ƙarami Saukewa: HLK-PM03 ta Tenstar Robot. Da kaina, Ina da wahala tare da analog da lantarki na lantarki, amma a nan akwai wutar lantarki da aka shirya a cikin karamin akwati.

Don siginar yanayin aiki, na ba da LED mai haɗawa zuwa GPIO2. Duk da haka, ban warware shi ba, saboda ... Tsarin ESP-07 ya riga yana da LED, kuma an haɗa shi da GPIO2. Amma bari ya kasance a kan allo, idan ina so in fitar da wannan LED zuwa akwati.

Bari mu ci gaba zuwa mafi ban sha'awa. Mitocin ruwa ba su da dabaru; ba za ka iya tambayar su don karatun yanzu ba. Iyakar abin da ke akwai a gare mu shine sha'awa - rufe lambobin sadarwa na reed canza kowace lita. Abubuwan da ake fitarwa na sauya reed suna haɗe zuwa GPIO12/GPIO13. Zan kunna resistor-up da shirye-shirye a cikin module.

Da farko, na manta da samar da resistors R8 da R9 kuma sigar allo na ba su da su. Amma tun da na riga na buga zane don kowa ya gani, yana da kyau a gyara wannan kulawa. Ana buƙatar masu tsayayya don kada su ƙone tashar jiragen ruwa idan firmware glitches kuma ya saita fil zuwa ɗaya, kuma reed ya canza wannan layin zuwa ƙasa (tare da matsakaicin iyakar 3.3V / 1000Ohm = 3.3mA zai gudana).

Lokaci ya yi da za a yi tunanin abin da za a yi idan wutar lantarki ta ƙare. Zaɓin farko shine buƙatar ƙimar ƙima ta farko daga uwar garken a farkon. Amma wannan zai buƙaci gagarumin rikitarwa na ƙa'idar musayar. Bugu da ƙari, aikin na'urar a cikin wannan yanayin ya dogara da yanayin uwar garken. Idan uwar garken bai fara ba bayan an kashe wutar lantarki (ko farawa daga baya), mitar ruwa ba zai iya buƙatar ƙimar farko ba kuma ba zai yi aiki daidai ba.

Don haka, na yanke shawarar aiwatar da ƙimar ƙima a cikin guntun ƙwaƙwalwar ajiya da aka haɗa ta I2C. Ba ni da wasu buƙatu na musamman don girman ƙwaƙwalwar walƙiya - kuna buƙatar adana lambobi 2 kawai (yawan lita bisa ga mita mai zafi da sanyi). Ko da mafi ƙanƙanta module zai yi. Amma kuna buƙatar kula da adadin rikodi na rikodi. Ga mafi yawan modules wannan shi ne 100 dubu cycles, ga wasu har zuwa miliyan.

Zai yi kama da cewa miliyan yana da yawa. Amma a cikin shekaru 4 na rayuwa a cikin ɗakina, na cinye ruwa kadan fiye da mita 500 na ruwa, wato lita dubu 500! Kuma 500 dubu records a flash. Kuma ruwan sanyi ne kawai. Kuna iya, ba shakka, sake siyar da guntu kowace shekara biyu, amma ya zama akwai kwakwalwan FRAM. Daga ra'ayi na shirye-shirye, wannan I2C EEPROM iri ɗaya ne, kawai tare da adadi mai yawa na sake rubutawa (daruruwan miliyoyin). Kawai dai har yanzu ba zan iya zuwa kantin sayar da irin waɗannan microcircuits ba, don haka a yanzu 24LC512 na yau da kullun zai tsaya.

Buga allon kewayawa

Da farko na shirya yin allo a gida. Saboda haka, an tsara allon a matsayin gefe ɗaya. Amma bayan da na shafe sa'a guda tare da ƙarfe na Laser da abin rufe fuska (ba wai ko ta yaya ba ne ba tare da shi ba), har yanzu na yanke shawarar yin odar allon daga Sinawa.

Muna haɗa mitar ruwa zuwa gida mai wayo

Kusan kafin yin odar allon, na fahimci cewa ban da guntuwar ƙwaƙwalwar ajiyar filasha, zan iya haɗa wani abu mai amfani ga bas ɗin I2C, kamar nuni. Abin da ainihin abin da za a fitar da shi har yanzu tambaya ce, amma yana buƙatar a bi ta kan allo. To, tun da zan yi odar alluna daga masana’anta, babu wata fa’ida da za a iya taƙaice kaina a kan allo mai gefe ɗaya, don haka layukan I2C ne kawai a gefen bayan allon.

Akwai kuma babbar matsala guda ɗaya game da wayoyi ta hanya ɗaya. Domin An zana allon a matsayin gefe ɗaya, don haka an tsara waƙa da kayan aikin SMD a gefe ɗaya, da kuma abubuwan da ake fitarwa, masu haɗawa da wutar lantarki a daya gefen. Lokacin da na karbi allunan bayan wata daya, na manta game da ainihin shirin kuma na sayar da duk abubuwan da ke gefen gaba. Kuma kawai a lokacin da aka zo sayar da wutar lantarki ya zama cewa ƙari da ragi an haɗa su a baya. Dole ne in yi noma da masu tsalle-tsalle. A cikin hoton da ke sama, na riga na canza wayoyi, amma ana canja wurin ƙasa daga wani ɓangare na allon zuwa wani ta hanyar fil na maɓallin Boot (ko da yake zai yiwu a zana waƙa a kan Layer na biyu).

Ya zama haka

Muna haɗa mitar ruwa zuwa gida mai wayo

Gidaje

Mataki na gaba shine jiki. Idan kana da firinta na 3D, wannan ba matsala ba ce. Ban damu da yawa ba - kawai na zana akwati mai girman daidai kuma na yi yanke a wuraren da suka dace. An haɗa murfin zuwa jiki tare da ƙananan ƙwanƙwasa kai tsaye.

Muna haɗa mitar ruwa zuwa gida mai wayo

Na riga na ambata cewa ana iya amfani da maɓallin Boot azaman maɓalli na gaba ɗaya - don haka za mu nuna shi a gaban panel. Don yin wannan, na zana "rijiya" na musamman inda maɓallin ke zaune.

Muna haɗa mitar ruwa zuwa gida mai wayo

A cikin wannan harka akwai kuma studs wanda aka sanya allon kuma an kiyaye shi tare da dunƙule M3 guda ɗaya (babu sauran sarari akan allon).

Na zaɓi nunin riga lokacin da na buga samfurin farko na shari'ar. Daidaitaccen mai karanta layi biyu bai dace da wannan yanayin ba, amma a ƙasa akwai nunin OLED SSD1306 128 × 32. Yana da ɗan ƙarami, amma ba dole ba ne in zuba ido a kowace rana - yana da yawa a gare ni.

Yin la'akari da wannan hanyar da kuma yadda za a fitar da wayoyi daga gare ta, na yanke shawarar liƙa nuni a tsakiyar akwati. Ergonomics, ba shakka, suna ƙasa da daidai - maɓallin yana saman, nuni yana ƙasa. Amma na riga na faɗi cewa ra'ayin haɗa nunin ya yi latti kuma na yi kasala don sake kunna allon don matsar da maɓallin.

An haɗa na'urar. Tsarin nuni yana manne da snot tare da manne mai zafi

Muna haɗa mitar ruwa zuwa gida mai wayo

Muna haɗa mitar ruwa zuwa gida mai wayo

Ana iya ganin sakamakon ƙarshe akan KDPV

Firmware

Bari mu matsa zuwa sashin software. Don ƙananan sana'a irin wannan, Ina matukar son amfani da Python (micropython) - lambar ta juya ta zama cikakke kuma mai fahimta. An yi sa'a, babu buƙatar sauka zuwa matakin rajista don fitar da microseconds - ana iya yin komai daga Python.

Da alama cewa komai yana da sauƙi, amma ba mai sauƙi ba - na'urar tana da ayyuka masu zaman kansu da yawa:

  • Mai amfani ya danna maɓallin kuma ya dubi nunin
  • Lita suna yin kaska da sabunta ƙima a cikin ƙwaƙwalwar filasha
  • Samfurin yana lura da siginar WiFi kuma yana sake haɗawa idan ya cancanta
  • To, ba tare da kwan fitila mai ƙyalli ba ba zai yiwu ba

Ba za ku iya ɗauka cewa ɗayan aikin bai yi aiki ba idan wani ya makale saboda wasu dalilai. Na riga na cika cacti a cikin wasu ayyukan kuma yanzu har yanzu ina ganin glitches a cikin salon "rasa wani lita saboda nuni yana sabuntawa a wannan lokacin" ko "mai amfani ba zai iya yin komai ba yayin da tsarin ke haɗawa zuwa. WiFi." Tabbas, ana iya yin wasu abubuwa ta hanyar katsewa, amma kuna iya fuskantar iyakancewa akan tsawon lokaci, kiran kira, ko canje-canjen da ba na atomic ba zuwa masu canji. To, lambar da ke yin komai da sauri ta juya zuwa mush.

В mafi tsanani aikin Na yi amfani da preemptive multitasking da FreeRTOS, amma a wannan yanayin samfurin ya zama mafi dacewa. coroutines da uasync dakunan karatu . Haka kuma, aiwatar da Python na coroutines abu ne mai ban mamaki kawai - ana yin komai cikin sauƙi kuma cikin dacewa ga mai tsara shirye-shirye. Kawai rubuta hikimar ku, kawai gaya mani a waɗanne wuraren za ku iya canzawa tsakanin rafi.

Ina ba da shawarar yin nazarin bambance-bambance tsakanin aikin riga-kafi da gasa multitasking a matsayin batun zaɓi. Yanzu bari a karshe mu matsa zuwa ga code.

#####################################
# 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

Kowane counter ana sarrafa shi ta misalin ajin Counter. Da farko, an cire ƙimar ƙima ta farko daga EEPROM (darajar_storage) - wannan shine yadda dawo da bayan gazawar wutar lantarki.

An ƙaddamar da fil ɗin tare da ginanniyar haɓakawa zuwa wutar lantarki: idan an rufe maɓallin reed, layin ba shi da sifili, idan layin yana buɗe, an ja shi zuwa wutar lantarki kuma mai sarrafawa ya karanta ɗaya.

Ana kuma ƙaddamar da wani aiki na daban a nan, wanda zai jefa kuri'a. Kowane counter zai gudanar da nasa aikin. Ga lambar ta

    """ 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)

Ana buƙatar jinkiri na 25ms don tace bounce lamba, kuma a lokaci guda yana daidaita sau nawa aikin ya tashi (yayin da wannan aikin ke barci, sauran ayyuka suna gudana). Kowane 25ms aikin yana farkawa, bincika fil ɗin kuma idan lambobin sadarwa na reed sun rufe, to wata lita ta wuce ta cikin mita kuma ana buƙatar sarrafa wannan.

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

        self._value_storage.write(self._value)

Gudanar da lita na gaba ba komai bane - ma'aunin yana ƙaruwa kawai. To, zai yi kyau a rubuta sabuwar ƙima akan faifan filasha.

Don sauƙin amfani, ana ba da “masu shiga”

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

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

To, yanzu bari mu yi amfani da abubuwan jin daɗin Python da ɗakin karatu na uasync kuma mu yi abin da ake jira (ta yaya za mu fassara wannan zuwa Rashanci? Wanda za ku iya tsammani?)

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

        return self.value()

    __iter__ = __await__  

Wannan aiki ne mai dacewa wanda ke jira har sai an sabunta ƙimar ƙididdiga - aikin yana farkawa daga lokaci zuwa lokaci kuma yana bincika tutar _value_changed. Abin sha'awa game da wannan aikin shine lambar kiran na iya yin barci yayin kiran wannan aikin kuma barci har sai an karɓi sabon ƙima.

Me game da katsewa?Eh, a wannan lokacin za ku iya tururuwa da ni, kuna cewa ku da kanku kuka faɗi game da katsewa, amma a zahiri kun yi ƙuri'a na wawa. A gaskiya katsewa shine abu na farko da na gwada. A cikin ESP8266, zaku iya tsara katse baki, har ma da rubuta mai kula da wannan katsewa cikin Python. A cikin wannan katsewa, ana iya sabunta ƙimar maɓalli. Wataƙila, wannan zai isa idan ma'aunin ya kasance na'urar bawa - wanda ke jira har sai an nemi wannan ƙimar.

Abin baƙin ciki (ko aka yi sa'a?) na'urar ta tana aiki, dole ne ita kanta ta aika saƙonni ta hanyar ka'idar MQTT kuma ta rubuta bayanai zuwa EEPROM. Kuma a nan ƙuntatawa sun shiga wasa - ba za ku iya rarraba ƙwaƙwalwar ajiya a cikin katsewa ba kuma amfani da babban tari, wanda ke nufin za ku iya mantawa game da aika saƙonni akan hanyar sadarwa. Akwai buns kamar micropython.schedule () da ke ba ku damar gudanar da wasu ayyuka "da wuri-wuri," amma tambayar ta taso, "menene ma'anar?" Menene idan muna aika wani nau'in saƙo a yanzu, sannan sai katsewa ya shigo ya lalata ƙimar ma'auni. Ko, alal misali, sabuwar ƙima ta zo daga uwar garken yayin da ba mu riga mun rubuta tsohuwar ba. Gabaɗaya, kuna buƙatar toshe aiki tare ko fita daga ciki ta wata hanya daban.

Kuma daga lokaci zuwa lokaci Kuskuren Runtime: jadawalin tari cikakken hadarurruka kuma wa ya san me yasa?

Tare da fayyace zabe da uasync, a cikin wannan yanayin ko ta yaya ya zama mafi kyau da abin dogaro

Na kawo aiki tare da EEPROM zuwa ƙaramin aji

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)

A Python, yana da wahala a yi aiki kai tsaye da bytes, amma bytes ne aka rubuta zuwa ƙwaƙwalwar ajiya. Dole ne in katanga juyawa tsakanin lamba da bytes ta amfani da ɗakin karatu na ustruct.

Don kada in canza wurin abin I2C da adireshin tantanin ƙwaƙwalwar ajiya kowane lokaci, na nannade shi duka a cikin ƙaramin ƙarami mai dacewa.

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)

Abun I2C da kansa an ƙirƙira shi tare da waɗannan sigogi

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

Mun zo ga mafi ban sha'awa sashi - aiwatar da sadarwa tare da uwar garke ta hanyar MQTT. To, babu buƙatar aiwatar da yarjejeniya kanta - Na same ta akan Intanet aiwatar da asynchronous da aka shirya. Wannan shi ne abin da za mu yi amfani da shi.

Ana tattara duk abubuwan da suka fi ban sha'awa a cikin aji na CounterMQTTClient, wanda ya dogara akan ɗakin karatu MQTTClient. Bari mu fara daga gefe

#####################################
# 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))

Anan zaku iya ƙirƙira da daidaita fitilun fitilu da maɓalli, da abubuwa masu sanyi da ruwan zafi.

Tare da farawa, ba duk abin da ke da mahimmanci ba

    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())

Don saita sigogin aiki na ɗakin karatu na mqtt_as, ana amfani da babban ƙamus na saitunan daban-daban - config. Yawancin saitunan tsoho suna da kyau a gare mu, amma yawancin saituna suna buƙatar saita su a sarari. Don kada in rubuta saitunan kai tsaye a cikin lambar, Ina adana su a cikin fayil ɗin rubutu config.txt. Wannan yana ba ku damar canza lambar ba tare da la'akari da saitunan ba, kazalika da rivet na'urori iri ɗaya tare da sigogi daban-daban.

Tushe na ƙarshe na lambar yana farawa da yawa coroutines don yin ayyuka daban-daban na tsarin. Misali, a nan akwai coroutine wanda ke yin kirgawa

    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))

Corotine yana jira a cikin madauki don sabon ƙima kuma, da zarar ya bayyana, yana aika sako ta hanyar ka'idar MQTT. Lambar lambar farko tana aika ƙimar farko ko da babu ruwa yana gudana ta cikin ma'aunin.

Ajin tushe MQTTClient yana hidima da kansa, yana fara haɗin WiFi kuma yana sake haɗawa lokacin da haɗin ya ɓace. Lokacin da aka sami canje-canje a yanayin haɗin WiFi, ɗakin karatu yana sanar da mu ta hanyar kiran 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)

An kwafi aikin da gaskiya daga misalai. A wannan yanayin, yana ƙididdige adadin fita (internet_outages) da tsawon lokacin su. Lokacin da aka dawo da haɗin, ana aika lokacin aiki zuwa uwar garken.

Af, ana buƙatar barcin ƙarshe kawai don yin aikin asynchronous - a cikin ɗakin karatu ana kiran shi ta hanyar jira, kuma kawai ayyukan da jikinsu ya ƙunshi wani jira za a iya kira.

Baya ga haɗawa da WiFi, kuna buƙatar kafa haɗin kai zuwa dillalin MQTT (uwar garken). Laburaren yana yin haka kuma, kuma muna samun damar yin wani abu mai amfani lokacin da aka kafa haɗin

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

Anan muna biyan kuɗi zuwa saƙonni da yawa - uwar garken yanzu yana da ikon saita ƙimar ƙima ta yanzu ta hanyar aika saƙon da ya dace.

    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))

Wannan aikin yana aiwatar da saƙonni masu shigowa, kuma dangane da batun ( take saƙon), ana sabunta ƙimar ɗayan ƙididdiga.

Ayyukan mataimaka biyu

    # 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")

Wannan aikin yana aika saƙo idan haɗin yana kafa. Idan babu haɗi, ana watsi da saƙon.

Kuma wannan kawai aiki ne mai dacewa wanda ke haifar da aika saƙonnin kuskure.

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

Rubutu da yawa, kuma ba mu ƙyale LED ba tukuna. nan

    # 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)

Na bayar da yanayin kyaftawa guda 2. Idan haɗin ya ɓace (ko kuma kawai ana kafa shi), na'urar za ta yi lumshewa da sauri. Idan an kafa haɗin, na'urar tana lumshe ido sau ɗaya a kowane sakan 5. Idan ya cancanta, ana iya aiwatar da wasu hanyoyin kyaftawa anan.

Amma LED ɗin yana da ƙarfi kawai. Mun kuma nufa kan nunin.

    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)

Wannan shine abin da nake magana game da shi - yadda sauƙi da dacewa yake tare da coroutines. Wannan ɗan ƙaramin aikin yana bayyana GWANIN ƙwarewar mai amfani. Corotine yana jira kawai don danna maɓallin kuma ya kunna nuni na daƙiƙa 3. Nuni yana nuna karatun mita na yanzu.

Har yanzu akwai sauran ƙananan abubuwa guda biyu. Ga aikin da (sake) ya fara wannan kasuwancin gaba ɗaya. Babban madauki kawai yana aika bayanai daban-daban na kuskure sau ɗaya a minti daya. Gabaɗaya, na faɗi shi kamar yadda yake - Bana tsammanin akwai buƙatar yin sharhi da yawa

   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)

To, ma'aurata ƙarin saituna da ma'auni don kammala bayanin

#####################################
# 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)

Duk yana farawa kamar haka

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

Wani abu ya faru da ƙwaƙwalwara

Don haka, duk lambar tana nan. Na loda fayilolin ta amfani da ampy utility - yana ba ku damar loda su zuwa na ciki (wanda ke cikin ESP-07 kanta) filashin filasha sannan ku sami damar shiga shirin azaman fayiloli na yau da kullun. A can kuma na loda mqtt_as, uasyncio, ssd1306 da dakunan karatu da na yi amfani da su (amfani cikin mqtt_as).

Mun kaddamar da ... Mun sami Memory Error. Bugu da ƙari, da ƙarin ƙoƙarin fahimtar inda ainihin ƙwaƙwalwar ajiya ke yoyo, mafi yawan kwafin da na sanya, da farko wannan kuskuren ya bayyana. Wani ɗan gajeren bincike na Google ya kai ni ga fahimtar cewa microcontroller yana da, a ka'ida, 30 kB na ƙwaƙwalwar ajiya kawai, wanda 65 kB na lambar (ciki har da ɗakin karatu) ba zai iya dacewa ba.

Amma akwai mafita. Ya zama micropython baya aiwatar da lamba kai tsaye daga fayil ɗin .py - wannan fayil ɗin an haɗa shi da farko. Bugu da ƙari, an haɗa shi kai tsaye a kan microcontroller, ya juya zuwa bytecode, wanda aka adana a cikin ƙwaƙwalwar ajiya. To, don mai tarawa ya yi aiki, kuna buƙatar takamaiman adadin RAM.

Dabarar ita ce a ceci microcontroller daga tarin kayan aiki. Kuna iya tattara fayilolin akan babbar kwamfuta kuma ku loda shirye-shiryen bytecode cikin microcontroller. Don yin wannan, kuna buƙatar saukar da firmware micropython kuma gina mpy-cross mai amfani.

Ban rubuta Makefile ba, amma da hannu na bi kuma na tattara duk mahimman fayiloli (ciki har da dakunan karatu) wani abu kamar haka

mpy-cross water_counter.py

Duk abin da ya rage shine a loda fayiloli tare da tsawo na .mpy, kar a manta da fara share .py daidai daga tsarin fayil ɗin na'urar.

Na yi duk ci gaba a cikin shirin (IDE?) ESPlorer. Yana ba ku damar loda rubutun zuwa microcontroller kuma nan da nan aiwatar da su. A cikin yanayina, duk dabaru da ƙirƙirar dukkan abubuwa suna cikin fayil ɗin water_counter.py (.mpy). Amma domin duk wannan ya fara kai tsaye, dole ne kuma a sami fayil mai suna main.py a farkon. Bugu da ƙari, ya kamata ya zama daidai .py, kuma ba a riga an haɗa shi .mpy ba. Anan ga abubuwan da ke cikin sa marasa mahimmanci

import water_counter

Mun kaddamar da shi - komai yana aiki. Amma ƙwaƙwalwar ajiyar kyauta tana da ban tsoro - kusan 1kb. Har yanzu ina da shirye-shiryen fadada aikin na'urar, kuma wannan kilobyte bai isa gare ni ba. Amma sai ya zama akwai mafita ga wannan harka kuma.

Ga abin. Ko da yake an tattara fayilolin zuwa cikin bytecode kuma suna zaune akan tsarin fayil na ciki, a gaskiya har yanzu ana loda su cikin RAM kuma ana aiwatar da su daga can. Amma ya zama cewa micropython na iya aiwatar da bytecode kai tsaye daga ƙwaƙwalwar filasha, amma don wannan kuna buƙatar gina shi kai tsaye a cikin firmware. Ba shi da wahala, kodayake ya ɗauki ɗan lokaci kaɗan akan netbook dina (a can ne kawai na sami Linux).

Algorithm shine kamar haka:

  • Zazzage kuma shigar ESP Buɗe SDK. Wannan abu yana haɗa mai tarawa da ɗakunan karatu don shirye-shirye don ESP8266. An tattara bisa ga umarnin kan babban shafin aikin (Na zaɓi STANDALONE = saitin eh)
  • Saukewa nau'in micropython
  • Sanya dakunan karatu da ake buƙata a tashar jiragen ruwa/esp8266/modules a cikin bishiyar micropython
  • Muna tattara firmware bisa ga umarnin da ke cikin fayil ɗin tashar jiragen ruwa/esp8266/README.md
  • Muna loda firmware zuwa microcontroller (Ina yin wannan akan Windows ta amfani da shirye-shiryen ESP8266Flasher ko Python esptool)

Shi ke nan, yanzu 'shigo da ssd1306' zai ɗaga lambar kai tsaye daga firmware kuma ba za a cinye RAM don wannan ba. Tare da wannan dabarar, na loda lambar ɗakin karatu kawai a cikin firmware, yayin da ake aiwatar da babban lambar shirin daga tsarin fayil. Wannan yana ba ku damar sauya shirin cikin sauƙi ba tare da sake haɗa firmware ba. A halin yanzu ina da kusan 8.5kb na RAM kyauta. Wannan zai ba mu damar aiwatar da ayyuka daban-daban masu amfani a nan gaba. To, idan babu isasshen ƙwaƙwalwar ajiya kwata-kwata, to zaku iya tura babban shirin cikin firmware.

To me ya kamata mu yi game da shi yanzu?

Ok, an siyar da kayan aikin, an rubuta firmware, an buga akwatin, na'urar tana makale a bango kuma cikin farin ciki tana lumshe fitila. Amma a yanzu duk akwatin baƙar fata ne (a zahiri kuma a zahiri) kuma har yanzu yana da ɗan amfani. Lokaci ya yi da za a yi wani abu tare da saƙonnin MQTT waɗanda aka aika zuwa uwar garken.

"Gidan wayo" na yana jujjuyawa Majordomo tsarin. Modulin MQTT ko dai yana fitowa daga cikin akwatin, ko kuma an shigar dashi cikin sauƙi daga kasuwar ƙara - Ban tuna inda na samo shi ba. MQTT ba abu ne mai wadatar kai ba - kuna buƙatar abin da ake kira. dillali - uwar garken da ke karba, rarrabawa da tura saƙonnin MQTT zuwa abokan ciniki. Ina amfani da sauro, wanda (kamar majordomo) ke gudana akan kwamfutar tafi-da-gidanka ɗaya.

Bayan na'urar ta aika sako aƙalla sau ɗaya, ƙimar za ta bayyana nan da nan a cikin jerin.

Muna haɗa mitar ruwa zuwa gida mai wayo

Wadannan dabi'u za a iya danganta su da abubuwa na tsarin, ana iya amfani da su a cikin rubutun atomatik da kuma yin nazari daban-daban - duk abin da ya wuce iyakar wannan labarin. Zan iya ba da shawarar tsarin majordomo ga duk mai sha'awar tashar Electronics A Lens - aboki kuma yana gina gida mai wayo kuma yana magana a fili game da kafa tsarin.

Zan nuna muku hotuna guda biyu. Wannan jadawali ne mai sauƙi na ƙimar yau da kullun

Muna haɗa mitar ruwa zuwa gida mai wayo
Ana iya ganin kusan babu wanda ya yi amfani da ruwan da daddare. Sau biyu wani ya tafi bayan gida, kuma da alama tace reverse osmosis yana tsotsar lita biyu a kowane dare. Da safe, amfani yana ƙaruwa sosai. Yawancin lokaci ina amfani da ruwa daga tukunyar jirgi, amma sai na so in yi wanka kuma na canza zuwa ruwan zafi na ɗan lokaci - wannan kuma yana bayyane a cikin jadawali na ƙasa.

Daga wannan jadawali na koyi cewa shiga bayan gida yana buƙatar lita 6-7 na ruwa, yin wanka yana buƙatar lita 20-30, wanka yana buƙatar kimanin lita 20, wanka yana buƙatar lita 160. Iyalina suna cinye kusan lita 500-600 kowace rana.

Ga waɗanda ke da sha'awar musamman, zaku iya duba bayanan ga kowane ƙimar kowane mutum

Muna haɗa mitar ruwa zuwa gida mai wayo

Daga nan na koyi cewa idan famfo ya buɗe, ruwa yana gudana a cikin gudun kusan lita 1 a cikin 5 s.

Amma a cikin wannan nau'i ƙididdiga na yiwuwa ba su dace sosai don dubawa ba. Majordomo kuma yana da ikon duba jadawalin amfani da rana, sati da wata. Anan, alal misali, akwai jadawali na amfani a sanduna

Muna haɗa mitar ruwa zuwa gida mai wayo

Ya zuwa yanzu ina da bayanai kawai na mako guda. A cikin wata guda, wannan jadawali zai zama mafi nuni - kowace rana za ta sami ginshiƙi daban. Hoton ya ɗan lalace ta hanyar daidaitawa ga ƙimar da na shigar da hannu (mafi girma shafi). Kuma har yanzu ba a fayyace ko na saita ƙimar farko ba daidai ba, kusan cube ƙasa, ko kuma wannan kwaro ne a cikin firmware kuma ba duk lita ne aka ƙidaya ba. Bukatar karin lokaci.

Hotunan da kansu har yanzu suna buƙatar wasu sihiri, farar fata, zanen. Wataƙila zan kuma gina jadawali na amfani da ƙwaƙwalwar ajiya don dalilai na ɓarna - idan wani abu yana yawo a wurin. Wataƙila ko ta yaya zan nuna lokutan lokacin da babu Intanet. A yanzu, duk wannan yana kan matakin ra'ayoyi.

ƙarshe

Yau gidana ya zama dan wayo. Tare da irin wannan ƙananan na'ura, zai zama mafi dacewa a gare ni don saka idanu akan yawan ruwa a cikin gidan. Idan a baya na yi fushi da "sake, mun cinye ruwa mai yawa a cikin wata daya," yanzu zan iya samun tushen wannan amfani.

Wasu na iya zama da ban mamaki kallon karatun da ke kan allo idan ta kasance nisa da mita kanta. Amma a cikin ba da nisa nan gaba, na yi shirin matsawa zuwa wani Apartment, inda za a samu da yawa ruwa risers, da kuma mita da kansu za su fi yiwuwa a located a kan saukowa. Don haka na'urar karatu mai nisa za ta kasance da amfani sosai.

Na kuma yi shirin faɗaɗa aikin na'urar. Na riga na duba bawuloli masu motsi. Yanzu, don canza tukunyar jirgi zuwa ruwan birni, Ina buƙatar kunna famfo 3 a cikin wuri mai wuyar isa. Zai fi dacewa don yin wannan tare da maɓalli ɗaya tare da madaidaicin nuni. To, ba shakka, yana da daraja aiwatar da kariya daga leaks.

A cikin labarin na bayyana sigar na'urar ta dangane da ESP8266. A ganina, na fito da sigar micropython firmware mai ban sha'awa ta amfani da coroutines - mai sauƙi da kyau. Na yi ƙoƙari na kwatanta da yawa daga cikin kurakurai da gazawar da na ci karo da su a lokacin yakin neman zabe. Wataƙila na yi bayanin komai dalla-dalla; da kaina, a matsayina na mai karatu, yana da sauƙi a gare ni in tsallake abubuwan da ba dole ba fiye da tunanin abin da aka bari ba a faɗi ba.

Kamar ko da yaushe, Ina buɗewa ga suka mai ma'ana.

Source
kewaye da allo
Samfurin hali

source: www.habr.com

Add a comment