တစ်ချိန်က၊ အိမ်အလိုအလျောက်စနစ်များ သို့မဟုတ် ၎င်းတို့ကို မကြာခဏခေါ်လေ့ရှိသည့် "စမတ်အိမ်" သည် အလွန်စျေးကြီးပြီး ချမ်းသာသူများသာ ၎င်းတို့ကို တတ်နိုင်ခဲ့သည်။ ယနေ့စျေးကွက်တွင် အလင်းရောင်၊ ခြေစွပ်များ၊ လေဝင်လေထွက်၊ ရေပေးဝေမှုနှင့် အခြားစားသုံးသူများကို ထိန်းချုပ်ရန်အတွက် အာရုံခံကိရိယာများ၊ ခလုတ်များ/ခလုတ်များ နှင့် 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 ဖြင့်ပါဝါပေးလိမ့်မည်။ ပါဝါရင်းမြစ်တစ်ခုအနေနဲ့ ကျွန်တော့်မှာ အသေးစားတစ်ခုရှိမယ်။ Tenstar Robot မှ ကိုယ်တိုင်ကိုယ်ကျ၊ ကျွန်ုပ်တွင် analog နှင့် ပါဝါအီလက်ထရွန်းနစ်ပစ္စည်းများအတွက် အခက်တွေ့နေရသော်လည်း ဤနေရာတွင် အဆင်သင့်လုပ်ထားသော ပါဝါထောက်ပံ့မှုလေးတစ်ခုဖြစ်သည်။
အချက်ပြသည့် လည်ပတ်မှုမုဒ်များအတွက် ကျွန်ုပ်သည် 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 ကို အရမ်းကြိုက်ပါတယ် () - ကုဒ်သည် အလွန်ကျစ်လျစ်ပြီး နားလည်နိုင်သည်။ ကံကောင်းထောက်မစွာ၊ microseconds ကိုညှစ်ထုတ်ရန်အတွက် မှတ်ပုံတင်အဆင့်သို့ဆင်းရန် မလိုအပ်ပါ - အရာအားလုံးကို Python မှလုပ်ဆောင်နိုင်သည်။
အရာအားလုံးသည် ရိုးရှင်းသော်လည်း အလွန်ရိုးရှင်းပုံရသည် - စက်တွင် သီးခြားလုပ်ဆောင်ချက်များစွာ ပါရှိသည်။
- အသုံးပြုသူသည် ခလုတ်ကိုနှိပ်၍ မျက်နှာပြင်ကို ကြည့်ရှုသည်။
- flash memory တွင် လီတာတန်ဖိုးများကို အမှတ်ခြစ်ပြီး အပ်ဒိတ်လုပ်ပါ။
- မော်ဂျူးသည် WiFi အချက်ပြမှုကို စောင့်ကြည့်ပြီး လိုအပ်ပါက ပြန်လည်ချိတ်ဆက်သည်။
- ကောင်းပြီ၊ မှိတ်တုတ်မှိတ်တုတ်မီးသီးမပါဘဲမဖြစ်နိုင်ဘူး။
အခြားတစ်ခုသည် အကြောင်းတစ်ခုခုကြောင့် ပိတ်မိပါက လုပ်ဆောင်မှုတစ်ခု အလုပ်မလုပ်ဟု သင်ယူဆနိုင်မည်မဟုတ်ပေ။ အခြားပရောဂျက်များတွင် ကျွန်ုပ်၏ cacti ဖြည့်သွင်းထားပြီးသားဖြစ်ပြီး ယခုအချိန်တွင် "မျက်နှာပြင်ကို အပ်ဒိတ်လုပ်နေသောကြောင့် အခြားလီတာလွတ်သွားသောကြောင့်" သို့မဟုတ် " module နှင့်ချိတ်ဆက်နေချိန်တွင် အသုံးပြုသူသည် ဘာမှမလုပ်နိုင်တော့ပါ။ ဝိုင်ဖိုင်။" ဟုတ်ပါတယ်၊ အချို့အရာများကို အနှောင့်အယှက်များမှတစ်ဆင့် လုပ်ဆောင်နိုင်သော်လည်း ကြာချိန်၊ ဖုန်းခေါ်ဆိုမှုများတွင် အသိုက်အမြုံ သို့မဟုတ် အက်တမ်မဟုတ်သော ပြောင်းလဲမှုများကို ကိန်းရှင်များအတွက် ကန့်သတ်ချက်များအဖြစ် သင်ကြုံတွေ့နိုင်သည်။ ကောင်းပြီ၊ အရာအားလုံးကိုလုပ်ဆောင်သောကုဒ်သည် လျင်မြန်စွာ မှိုအဖြစ်သို့ ပြောင်းလဲသွားသည်။
В classic preemptive multitasking နဲ့ FreeRTOS ကိုသုံးခဲ့တယ်၊ ဒါပေမယ့် ဒီအခြေအနေမှာ model က ပိုသင့်တော်လာတယ် . ထို့အပြင်၊ Python ၏ coroutines များကို အကောင်အထည်ဖော်ခြင်းသည် ရိုးရိုးရှင်းရှင်း အံ့သြစရာကောင်းသည် - အရာအားလုံးသည် ပရိုဂရမ်မာအတွက် ရိုးရှင်းလွယ်ကူစွာ လုပ်ဆောင်ပါသည်။ သင့်ကိုယ်ပိုင် ယုတ္တိဗေဒကို ရေးပါ၊ လမ်းကြောင်းများကြားတွင် သင်ပြောင်းနိုင်သည့်နေရာများကို ပြောပြပါ။
ကြိုတင်မဲနှင့် အပြိုင်အဆိုင်အလုပ်များလုပ်ခြင်းအကြား ခြားနားချက်များကို စိတ်ကြိုက်ရွေးချယ်နိုင်သောဘာသာရပ်အဖြစ် လေ့လာရန် အကြံပြုအပ်ပါသည်။ ကဲ နောက်ဆုံးတော့ ကုဒ်ကို ဆက်ကြည့်ရအောင်။
#####################################
# 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 မှာ အောက်ပါအတိုင်းဖြစ်သည် ။
- ဒေါင်းလုဒ်လုပ်ပြီး ထည့်သွင်းပါ။ . ဤအရာသည် ESP8266 အတွက် ပရိုဂရမ်များအတွက် compiler နှင့် libraries များကို စုစည်းထားသည်။ ပရောဂျက်၏ ပင်မစာမျက်နှာရှိ ညွှန်ကြားချက်များအတိုင်း စုစည်းထားသည် (ကျွန်တော် STANDALONE=yes ဆက်တင်ကို ရွေးချယ်ခဲ့သည်)
- download,
- လိုအပ်သောစာကြည့်တိုက်များကို micropython သစ်ပင်အတွင်းတွင် ports/esp8266/modules တွင်ထားပါ။
- ဖိုင်အတွင်းရှိ ညွှန်ကြားချက်များအတိုင်း ကျွန်ုပ်တို့သည် Firmware ကို စုစည်းထားသည်။
- ကျွန်ုပ်တို့သည် မိုက်ခရိုကွန်ထရိုးသို့ ဖိုင်းဝဲကို အပ်လုဒ်လုပ်သည် (ကျွန်တော် ESP8266Flasher ပရိုဂရမ်များ သို့မဟုတ် Python esptool ကို အသုံးပြု၍ Windows တွင် ၎င်းကို ပြုလုပ်သည်)
ဒါပါပဲ၊ အခု 'import ssd1306' က ကုဒ်ကို firmware ကနေ တိုက်ရိုက် ရုတ်သိမ်းလိုက်မှာဖြစ်ပြီး ဒီအတွက် RAM ကို သုံးစွဲမှာ မဟုတ်ပါဘူး။ ဤလှည့်ကွက်ဖြင့် ကျွန်ုပ်သည် ဖိုင်စနစ်မှ ပင်မပရိုဂရမ်ကုဒ်ကို လုပ်ဆောင်နေစဉ်တွင် စာကြည့်တိုက်ကုဒ်ကို Firmware တွင်သာ တင်လိုက်ပါသည်။ ၎င်းသည် သင့်အား Firmware အား ပြန်လည်ပေါင်းစည်းခြင်းမပြုဘဲ ပရိုဂရမ်ကို အလွယ်တကူ ပြင်ဆင်နိုင်စေပါသည်။ လောလောဆယ် ကျွန်တော့်မှာ 8.5kb free RAM ရှိတယ်။ ၎င်းသည် ကျွန်ုပ်တို့အား အနာဂတ်တွင် မတူညီသော အသုံးဝင်သော လုပ်ဆောင်နိုင်စွမ်းများစွာကို အကောင်အထည်ဖော်နိုင်စေမည်ဖြစ်သည်။ ကောင်းပြီ၊ လုံလောက်သော memory မရှိပါက၊ ပင်မပရိုဂရမ်ကို Firmware သို့ တွန်းပို့နိုင်သည်။
ဒါနဲ့ ပတ်သက်ပြီး အခု ဘာလုပ်သင့်လဲ။
အိုကေ၊ ဟာ့ဒ်ဝဲကို ဂဟေဆော်ထားပြီး၊ ဖာမ်းဝဲလ်ကို ရေးမှတ်ထားပြီး၊ ဘောက်စ်ကို ရိုက်နှိပ်ထားပြီး၊ စက်ပစ္စည်းသည် နံရံပေါ်တွင် ကပ်နေပြီး မီးသီးကို ပျော်ရွှင်စွာ မှိတ်ထားသည်။ သို့သော် ယခုအချိန်တွင် ၎င်းသည် အနက်ရောင်သေတ္တာ (စာသားနှင့် ပုံသဏ္ဍာန်အရ) ဖြစ်ပြီး ၎င်းသည် အသုံးနည်းဆဲဖြစ်သည်။ ဆာဗာသို့ပေးပို့သော MQTT မက်ဆေ့ချ်များဖြင့် တစ်ခုခုလုပ်ဆောင်ရန် အချိန်ရောက်ပါပြီ။
ကျွန်ုပ်၏ "စမတ်အိမ်" လည်ပတ်နေပါသည်။ . MQTT module သည် box မှထွက်လာသည် သို့မဟုတ် add-on စျေးကွက်မှအလွယ်တကူတပ်ဆင်ထားသည် - ကျွန်ုပ်ဘယ်ကရသည်ကိုမမှတ်မိပါ။ MQTT သည် မိမိဘာသာ ဖူလုံသော အရာမဟုတ်ပါ - သင်လိုအပ်သော အရာကို ခေါ်ပါသည်။ ပွဲစား - MQTT မက်ဆေ့ဂျ်များကို လက်ခံရရှိ၊ ခွဲထုတ်ကာ ဖောက်သည်များထံ ပေးပို့သော ဆာဗာတစ်ခု။ ကျွန်ုပ်သည် တူညီသော netbook ပေါ်တွင် အလုပ်လုပ်သော ( majordomo ကဲ့သို့ ) ခြင်ကိုသုံးပါသည်။
စက်ပစ္စည်းသည် အနည်းဆုံးတစ်ကြိမ် မက်ဆေ့ချ်ပို့ပြီးနောက်၊ တန်ဖိုးသည် စာရင်းထဲတွင် ချက်ချင်းပေါ်လာမည်ဖြစ်သည်။

ဤတန်ဖိုးများကို ယခုအခါ စနစ်အရာဝတ္တုများနှင့် ဆက်စပ်နိုင်ပြီဖြစ်ပြီး ၎င်းတို့ကို အလိုအလျောက်စနစ်ဆိုင်ရာ Script များတွင် အသုံးပြုနိုင်ပြီး အမျိုးမျိုးသော ခွဲခြမ်းစိတ်ဖြာမှုများကို လုပ်ဆောင်နိုင်သည် - အားလုံးသည် ဤဆောင်းပါး၏ အတိုင်းအတာထက်ကျော်လွန်ပါသည်။ စိတ်ပါဝင်စားသူတိုင်းအတွက် majordomo စနစ်အား ကျွန်ုပ်အကြံပြုနိုင်ပါသည်။ — သူငယ်ချင်းတစ်ဦးသည် စမတ်အိမ်တစ်လုံးကိုလည်း တည်ဆောက်နေပြီး စနစ်ထည့်သွင်းခြင်းနှင့်ပတ်သက်၍ ရှင်းလင်းစွာပြောဆိုနေပါသည်။
ဂရပ်အချို့ကို ငါပြမယ်။ ၎င်းသည် နေ့စဉ်တန်ဖိုးများ၏ ရိုးရှင်းသောဂရပ်ဖြစ်သည်။

ညဘက်တွင် ရေကို မည်သူမျှ အသုံးမပြုကြကြောင်း တွေ့နိုင်သည်။ တစ်စုံတစ်ယောက်သည် အိမ်သာသို့ နှစ်ကြိမ်သွားခဲ့ပြီး၊ ပြောင်းပြန် osmosis filter သည် တစ်ညလျှင် နှစ်လီတာ စုပ်ယူသွားပုံရသည်။ မနက်ခင်းမှာ စားသုံးမှု သိသိသာသာ တိုးလာပါတယ်။ ကျွန်ုပ်သည် ဘွိုင်လာမှရေကို အများအားဖြင့် အသုံးပြုသော်လည်း၊ ထို့နောက်တွင် ရေချိုးပြီး မြို့တွင်းရေပူသို့ ခေတ္တပြောင်းချင်ခဲ့သည် - ၎င်းကို အောက်ဖော်ပြပါ ဂရပ်တွင် ရှင်းရှင်းလင်းလင်း မြင်နိုင်သည်။
အိမ်သာတက်ဖို့ ရေ 6-7 လီတာ လိုအပ်တယ်၊ ရေချိုးရင် 20-30 လီတာ၊ ပန်းကန်ဆေးဖို့ 20 လီတာ လိုအပ်တယ်၊ ရေချိုးရင် 160 လီတာ လိုအပ်တယ်ဆိုတာ ဒီဂရပ်ကနေ လေ့လာခဲ့တယ်။ ကျွန်တော့်မိသားစုက တစ်နေ့ကို လီတာ ၅၀၀-၆၀၀ လောက် စားသုံးတယ်။
အထူးသဖြင့် စူးစမ်းလိုသူများအတွက်၊ တစ်ဦးချင်းစီတန်ဖိုးအတွက် မှတ်တမ်းများကို ကြည့်ရှုနိုင်ပါသည်။

ဘုံဘိုင်ဖွင့်သောအခါ ရေသည် 1 စက္ကန့်လျှင် 5 လီတာခန့်အမြန်နှုန်းဖြင့်စီးဆင်းကြောင်းကို ဤနေရာမှ ကျွန်ုပ်သိရှိခဲ့ရသည်။
ဒါပေမယ့် ဒီပုံစံက စာရင်းဇယားတွေကို ကြည့်ရတာ သိပ်အဆင်မပြေဘူး။ Majordomo သည် နေ့၊ အပတ်နှင့်လအလိုက် စားသုံးမှုဇယားများကို ကြည့်ရှုနိုင်သည်။ ဤတွင်၊ ဥပမာ၊ ဘားများရှိ စားသုံးမှုဂရပ်တစ်ခုဖြစ်သည်။

အခုထိ ကျွန်တော့်မှာ ဒေတာတွေ တစ်ပတ်လောက်ပဲ ရှိသေးတယ်။ တစ်လတွင်၊ ဤဂရပ်သည် ပို၍ ညွှန်ပြလိမ့်မည် - တစ်နေ့လျှင် သီးခြားကော်လံတစ်ခု ရှိပါမည်။ ကျွန်ုပ်ကိုယ်တိုင်ထည့်သွင်းသောတန်ဖိုးများ (အကြီးဆုံးကော်လံ) ကို ချိန်ညှိခြင်းဖြင့် ပုံသည် အနည်းငယ် ပျက်စီးသွားပါသည်။ ပြီးတော့ ပထမတန်ဖိုးတွေကို တစ်တုံးနီးပါး နည်းအောင် မှားယွင်းသတ်မှတ်ထားသလား၊ ဒါမှမဟုတ် ဒါက Firmware ထဲက ချို့ယွင်းချက်တစ်ခုဖြစ်ပြီး လီတာအားလုံးကို ရေမတွက်ထားဘူးဆိုတာတော့ ရှင်းရှင်းလင်းလင်း မသိရသေးပါဘူး။ အချိန်ပိုလိုတယ်။
ဂရပ်များကိုယ်တိုင်က မှော်ပညာ၊ ဆေးသုတ်ခြင်း၊ ပန်းချီဆွဲရန် လိုအပ်နေသေးသည်။ အမှားရှာရန် ရည်ရွယ်ချက်အတွက် မန်မိုရီသုံးစွဲမှု ဂရပ်ဖ်ကိုလည်း တည်ဆောက်မည် ဖြစ်ကောင်းဖြစ်နိုင်သည်- ထိုနေရာတွင် တစ်စုံတစ်ခု ပေါက်ကြားသွားပါက၊ အင်တာနက်မရှိသည့်အချိန်ကာလများကို တစ်နည်းနည်းဖြင့် ဖော်ပြနိုင်မည်ဖြစ်သည်။ လောလောဆယ်တော့ ဒါတွေအားလုံးက စိတ်ကူးအဆင့်မှာ ရှိတယ်။
ကောက်ချက်
ဒီနေ့ ငါ့တိုက်ခန်းက နည်းနည်း စမတ်ကျလာတယ်။ ထိုကဲ့သို့သော သေးငယ်သောကိရိယာဖြင့် အိမ်တွင်းရေသုံးစွဲမှုကို စောင့်ကြည့်ရန် ကျွန်ုပ်အတွက် ပို၍အဆင်ပြေပါလိမ့်မည်။ အကယ်၍ ကျွန်ုပ်သည် စောစောက "နောက်တစ်ကြိမ်၊ တစ်လအတွင်း ရေများစွာ သုံးစွဲခဲ့သည်" ဟူသော စကားကို ကျွန်ုပ် ဒေါသထွက်ခဲ့လျှင် ယခု ဤစားသုံးမှု၏ အရင်းအမြစ်ကို ကျွန်ုပ် ရှာဖွေနိုင်ပြီဖြစ်သည်။
မီတာကိုယ်နှိုက်နှင့် တစ်မီတာအကွာတွင် ဖန်သားပြင်ပေါ်ရှိ စာကိုကြည့်လျှင် အချို့က ထူးဆန်းသည်ဟု ထင်နိုင်သည်။ ဒါပေမယ့် သိပ်မဝေးတဲ့အနာဂတ်မှာ၊ ရေအတက်အကျများစွာရှိမယ့် တခြားတိုက်ခန်းကို ပြောင်းရွှေ့ဖို့ စီစဉ်ထားပြီး မီတာတွေက ဆင်းသက်ရာမှာ ဖြစ်နိုင်ချေများပါတယ်။ ဒါကြောင့် အဝေးထိန်းစာဖတ်ကိရိယာဟာ အလွန်အသုံးဝင်ပါလိမ့်မယ်။
စက်ပစ္စည်း၏ လုပ်ဆောင်နိုင်စွမ်းကို ချဲ့ထွင်ရန်လည်း စီစဉ်နေပါသည်။ မော်တော်ဆိုင်ကယ် အဆို့ရှင်တွေကို ကြည့်နေပြီ။ ယခုအခါ ဘွိုင်လာကို မြို့ရေသို့ပြောင်းရန်၊ လက်လှမ်းမီရန် ခက်ခဲသောနေရာတစ်ခုတွင် ပိုက်ခေါင်း ၃ ခုဖွင့်ရန် လိုအပ်ပါသည်။ သက်ဆိုင်ရာ ညွှန်ပြချက်ဖြင့် ခလုတ်တစ်ခုတည်းဖြင့် ပြုလုပ်ရန် ပိုမိုအဆင်ပြေမည်ဖြစ်သည်။ ဟုတ်ပါတယ်၊ ယိုစိမ့်မှုမှကာကွယ်မှုကို အကောင်အထည်ဖော်ရကျိုးနပ်ပါတယ်။
ဆောင်းပါးတွင် ESP8266 ကိုအခြေခံ၍ ကျွန်ုပ်၏စက်ပစ္စည်းဗားရှင်းကို ဖော်ပြခဲ့သည်။ ကျွန်ုပ်၏အမြင်အရ၊ ကျွန်ုပ်သည် coroutines ကိုအသုံးပြု၍ အလွန်စိတ်ဝင်စားစရာကောင်းသော micropython firmware ဗားရှင်းကို ထွက်ပေါ်လာခဲ့သည် - ရိုးရှင်းပြီး ကောင်းမွန်ပါသည်။ လှုံ့ဆော်မှုအတွင်း ကြုံတွေ့ခဲ့ရသော ကွဲလွဲချက်များနှင့် ချို့ယွင်းချက်များစွာကို ဖော်ပြရန် ကြိုးစားခဲ့သည်။ ကျွန်တော်သည် အရာအားလုံးကို အသေးစိတ်အလွန်အကျွံဖော်ပြလိုက်ခြင်းဖြစ်ကောင်းဖြစ်နိုင်သည်၊ ပုဂ္ဂိုလ်ရေးအရ စာဖတ်သူတစ်ဦးအနေဖြင့် မလိုအပ်သောအရာများကို နောက်မှမပြောဘဲထားခဲ့သည့်အရာကို ပြန်စဉ်းစားရန်ထက် ကျွန်ုပ်အတွက် မလိုအပ်သောအရာများကို ကျော်ဖြတ်ရန် ပို၍လွယ်ကူပါသည်။
အမြဲလိုလို အပြုသဘောဆောင်တဲ့ ဝေဖန်မှုတွေကို ရင်ဖွင့်တယ်။
source: www.habr.com
