واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

هڪ دفعي، گهر آٽوميشن سسٽم، يا "سمارٽ هوم" جيئن اهي اڪثر سڏيا ويندا هئا، تمام گهڻو قيمتي هئا ۽ صرف امير انهن کي برداشت ڪري سگهي ٿو. اڄ مارڪيٽ تي توهان سينسر، بٽڻ/سوئچز ۽ لائٽنگ، ساکٽ، وينٽيليشن، واٽر سپلائي ۽ ٻين صارفين کي ڪنٽرول ڪرڻ لاءِ ايڪٽيوٽرز سان گڏ ڪافي سستا ڪٽ ڳولي سگهو ٿا. ۽ ايستائين جو سڀ کان وڌيڪ ڪڙي وارو DIY ماڻهو خوبصورتي ۾ شامل ٿي سگهي ٿو ۽ هڪ سستي قيمت تي سمارٽ گهر لاءِ ڊوائيس گڏ ڪري سگهي ٿو.

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

عام طور تي، تجويز ڪيل ڊوائيسز يا ته سينسر يا عمل ڪندڙ آهن. اهي منظرنامي تي عمل ڪرڻ آسان بڻائين ٿا جهڙوڪ ”جڏهن موشن سينسر شروع ٿئي ٿو ، لائٽون آن ڪريو“ يا ”نڪرن جي ويجهو سوئچ پوري اپارٽمنٽ ۾ روشنيون بند ڪري ٿو. پر ڪنهن به طرح شيون ٽيليميٽري سان ڪم نه ڪيون. بهترين طور تي، اهو درجه حرارت ۽ نمي جو گراف آهي، يا هڪ مخصوص دڪان تي فوري طاقت.

مون تازو ئي پلس آئوٽ سان واٽر ميٽر انسٽال ڪيا. هر ليٽر لاءِ جيڪو ميٽر مان گذري ٿو، ريڊ سوئچ چالو ٿئي ٿو ۽ رابطي کي بند ڪري ٿو. رڳو ڪم باقي بچيو آهي ته تارن کي چمڪائڻ ۽ ان مان فائدو حاصل ڪرڻ جي ڪوشش ڪجي. مثال طور، هفتي جي ڪلاڪ ۽ ڏينهن ذريعي پاڻي جي استعمال جو تجزيو ڪريو. خير، جيڪڏهن اپارٽمنٽ ۾ ڪيترائي واٽر ريزر آهن، ته پوء اهو وڌيڪ آسان آهي ته هڪ اسڪرين تي سڀني موجوده اشارن کي ڏسڻ لاء هڪ ٽارچ سان مشڪل سان پهچڻ جي جاء تي چڙهڻ جي ڀيٽ ۾.

ڪٽ هيٺان منهنجو نسخو آهي هڪ ڊيوائس جو ESP8266 تي ٻڌل آهي، جيڪو پاڻي جي ميٽرن مان دال ڳڻائي ٿو ۽ MQTT ذريعي سمارٽ هوم سرور ڏانهن ريڊنگ موڪلي ٿو. اسان مائڪروپيٿون ۾ پروگرام ڪنداسين uasyncio لائبريري استعمال ڪندي. جڏهن فرم ویئر ٺاهي، مون کي ڪيترن ئي دلچسپ مشڪلاتن ۾ آيو، جنهن تي آئون هن مضمون ۾ پڻ بحث ڪندس. وڃ!

هي منصوبو

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

سڄي سرڪٽ جي دل ESP8266 مائڪرو ڪنٽرولر تي هڪ ماڊل آهي. ESP-12 اصل ۾ رٿابندي ڪئي وئي، پر منھنجو ناقص نڪتو. اسان کي ESP-07 ماڊل سان گڏ مواد هجڻ گهرجي، جيڪو موجود هو. خوشقسمتيءَ سان، اهي پنن ۽ ڪارڪردگيءَ جي لحاظ کان ٻئي ساڳيا آهن، رڳو فرق اينٽينا ۾ آهي - ESP-12 وٽ هڪ بلٽ ان آهي، جڏهن ته ESP-07 وٽ هڪ خارجي آهي. تنهن هوندي به، وائي فائي اينٽينا کان سواء، منهنجي غسل خاني ۾ سگنل عام طور تي ملي ٿي.

معياري ماڊل وائرنگ:

  • پل اپ ۽ ڪيپيسٽر سان گڏ بٽڻ کي ري سيٽ ڪريو (جيتوڻيڪ ٻئي ماڊل اڳ ۾ ئي اندر آهن)
  • فعال سگنل (CH_PD) کي طاقت تائين پهچايو ويو آهي
  • GPIO15 زمين ڏانهن ڇڪيو ويو آهي. اهو صرف شروع ۾ گهربل آهي، پر مون وٽ اڃا تائين هن ٽنگ سان ڳنڍڻ لاء ڪجهه ناهي؛ مون کي هاڻي ان جي ضرورت ناهي

ماڊل کي فرم ويئر موڊ ۾ رکڻ لاءِ، توهان کي GPIO2 کي زمين تي شارٽ سرڪٽ ڪرڻ جي ضرورت آهي، ۽ ان کي وڌيڪ آسان بڻائڻ لاءِ، مون هڪ بوٽ بٽڻ مهيا ڪيو آهي. عام حالت ۾، هي پن طاقت ڏانهن ڇڪيو ويندو آهي.

GPIO2 لائن جي حالت صرف آپريشن جي شروعات ۾ چيڪ ڪئي وئي آهي - جڏهن پاور لاڳو ٿئي ٿي يا فوري طور تي ريٽ ڪرڻ کان پوء. تنهن ڪري ماڊل يا ته عام طور تي بوٽ ڪري ٿو يا فرم ويئر موڊ ۾ وڃي ٿو. هڪ دفعو لوڊ ٿيڻ بعد، هي پن هڪ باقاعده GPIO طور استعمال ڪري سگهجي ٿو. خير، ڇاڪاڻ ته اتي اڳ ۾ ئي هڪ بٽڻ موجود آهي، توهان ان سان ڪجهه مفيد فنڪشن ڳنڍي سگهو ٿا.

پروگرامنگ ۽ ڊيبگنگ لاءِ مان استعمال ڪندس UART، جيڪو ٻاھر نڪرندو آھي ھڪڙي ڪمب ۾. جڏهن ضروري هجي ته، آئون صرف اتي هڪ USB-UART اڊاپٽر سان ڳنڍيو. توهان کي صرف ياد رکڻ جي ضرورت آهي ته ماڊل 3.3V طرفان طاقتور آهي. جيڪڏهن توهان هن وولٽيج تي اڊاپٽر کي تبديل ڪرڻ ۽ 5V جي فراهمي کي وساري ڇڏيو، ماڊل گهڻو ڪري سڙي ويندو.

مون کي غسل خاني ۾ بجلي سان ڪو مسئلو ناهي - آئوٽ ليٽ ميٽرن کان اٽڪل هڪ ميٽر تي واقع آهي، تنهنڪري مون کي 220V طرفان طاقت ڏني ويندي. جيئن ته هڪ طاقت جو ذريعو مون وٽ هڪ ننڍڙو هوندو بلاڪ HLK-PM03 Tenstar روبوٽ طرفان. ذاتي طور تي، مون وٽ اينالاگ ۽ پاور اليڪٽرانڪس سان ڏکيو وقت آهي، پر هتي هڪ ننڍڙي صورت ۾ تيار ڪيل پاور سپلائي آهي.

آپريٽنگ موڊس کي سگنل ڏيڻ لاءِ، مون GPIO2 سان ڳنڍيل LED مهيا ڪئي. تنهن هوندي، مون ان کي رد نه ڪيو، ڇاڪاڻ ته ... ESP-07 ماڊل اڳ ۾ ئي هڪ LED آهي، ۽ اهو پڻ GPIO2 سان ڳنڍيل آهي. پر ان کي بورڊ تي رکڻ ڏيو، ان صورت ۾ جيڪڏهن مان هن ايل اي ڊي کي ڪيس ۾ آئوٽ ڪرڻ چاهيان ٿو.

اچو ته سڀ کان دلچسپ حصو ڏانهن وڃو. پاڻي جي ميٽرن جو ڪوبه منطق ناهي؛ توهان انهن کي موجوده پڙهڻ لاءِ نه پڇي سگهو. اسان وٽ صرف هڪ شيءِ موجود آهي تسلسل - هر ليٽر ريڊ سوئچ جي رابطن کي بند ڪرڻ. منهنجا ريڊ سوئچ آئوٽ GPIO12/GPIO13 سان ڳنڍيل آهن. مان پل اپ ريزسٽر کي پروگرام طور ماڊل جي اندر فعال ڪندس.

شروعات ۾، مون کي resistors R8 ۽ R9 مهيا ڪرڻ وساريو ۽ بورڊ جو منهنجو نسخو نه آهي. پر جيئن ته مان پوسٽ ڪري رهيو آهيان ڊاگرام هر ڪنهن لاءِ ڏسڻ لاءِ ، اهو هن نگراني کي درست ڪرڻ جي قابل آهي. رزسٽرن جي ضرورت آھي ته جيئن بندرگاھ کي ساڙي نه وڃي جيڪڏھن فرم ویئر گليٽس ڪري ۽ پن کي ھڪڙي تي سيٽ ڪري، ۽ ريڊ سوئچ ھن لڪير کي زمين تي شارٽ ڪري ٿو (ريزيسٽر سان وڌ ۾ وڌ 3.3V/1000Ohm = 3.3mA وهندو).

اهو سوچڻ جو وقت آهي ته جيڪڏهن بجلي هلي وڃي ته ڇا ڪجي. پهريون اختيار اهو آهي ته شروع ۾ سرور کان ابتدائي انسداد قدرن جي درخواست ڪرڻ. پر اهو بدلي پروٽوڪول جي هڪ اهم پيچيدگي جي ضرورت هوندي. ان کان علاوه، هن معاملي ۾ ڊوائيس جي ڪارڪردگي سرور جي حالت تي منحصر آهي. جيڪڏهن سرور شروع نه ٿيو ته پاور بند ٿيڻ کان پوء (يا بعد ۾ شروع ڪيو ويو)، پاڻي جو ميٽر ابتدائي قدرن جي درخواست ڪرڻ جي قابل نه هوندو ۽ صحيح ڪم نه ڪندو.

تنهن ڪري، مون I2C ذريعي ڳنڍيل ميموري چپ ۾ انسداد جي قيمتن کي بچائڻ جو فيصلو ڪيو. مون وٽ فليش ميموري جي سائيز لاءِ ڪا خاص گهرج نه آهي - توهان کي صرف 2 انگن کي بچائڻ جي ضرورت آهي (گرم ۽ ٿڌو پاڻي جي ميٽر جي مطابق ليٽر جو تعداد). جيتوڻيڪ ننڍو ماڊل به ڪندو. پر توهان کي رڪارڊنگ چڪر جي تعداد تي ڌيان ڏيڻ جي ضرورت آهي. اڪثر ماڊلز لاءِ هي 100 هزار چڪر آهي، ڪجهه لاءِ هڪ لک تائين.

اهو لڳي ٿو ته هڪ ملين تمام گهڻو آهي. پر منهنجي اپارٽمنٽ ۾ رهڻ جي 4 سالن دوران، مون 500 ڪعبي ميٽر پاڻي کان ٿورو وڌيڪ استعمال ڪيو، اهو 500 هزار ليٽر آهي! ۽ فليش ۾ 500 هزار رڪارڊ. ۽ اهو صرف ٿڌو پاڻي آهي. توهان ڪري سگهو ٿا، يقينا، چپ هر ٻن سالن ۾ ٻيهر وڪرو ڪري سگهو ٿا، پر اهو ظاهر ٿئي ٿو ته اتي FRAM چپس آهن. پروگرامنگ جي نقطي نظر کان، اهو ساڳيو I2C EEPROM آهي، صرف هڪ تمام وڏي تعداد ۾ ٻيهر لکندڙ سائيڪلن سان (سوين لکن). اهو صرف اهو آهي ته مان اڃا تائين اهڙي مائڪرو سرڪٽس سان دڪان تي پهچي نه سگهيو آهيان، تنهنڪري هاڻي لاء عام طور تي 24LC512 بيٺو.

ڇپيل سرڪٽ بورڊ

شروعات ۾، مون گھر ۾ بورڊ ٺاهڻ جي رٿابندي ڪئي. تنهن ڪري، بورڊ هڪ طرفي طور تي ٺهيل هئي. پر ليزر آئرن ۽ سولڊر ماسڪ سان هڪ ڪلاڪ گذارڻ کان پوءِ (اهو ڪنهن به طرح ان کان سواءِ ممڪن ناهي) ، مون اڃا تائين چينين کان بورڊ آرڊر ڪرڻ جو فيصلو ڪيو.

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

تقريباً بورڊ کي آرڊر ڪرڻ کان اڳ، مون محسوس ڪيو ته فليش ميموري چپ کان علاوه، مان I2C بس لاءِ ڪا ٻي مفيد شيءِ ڳنڍي سگھان ٿو، جهڙوڪ ڊسپلي. ان کي صحيح طور تي ڇا ڪرڻو آهي اڃا تائين هڪ سوال آهي، پر ان کي بورڊ تي رستو ڏيڻ جي ضرورت آهي. خير، جيئن مان فئڪٽري مان بورڊ آرڊر ڪرڻ وڃي رهيو هوس، ان ڪري پاڻ کي هڪ طرفي بورڊ تائين محدود ڪرڻ جو ڪو به مقصد نه هو، تنهن ڪري I2C لائينون صرف بورڊ جي پوئين پاسي آهن.

هڪ طرفي وائرنگ سان گڏ هڪ وڏو مسئلو پڻ هو. ڇاڪاڻ ته بورڊ ھڪڙي طرفي طور ٺاھيو ويو آھي، تنھنڪري ٽريڪ ۽ SMD اجزاء ھڪڙي پاسي رکيل آھن، ۽ ٻاھرين اجزاء، ڪنيڪٽر ۽ پاور سپلائي ٻئي طرف. جڏهن مون کي هڪ مهيني بعد بورڊ مليا، مون اصل منصوبي جي باري ۾ وساري ڇڏيو ۽ سڀني حصن کي سامهون واري پاسي تي سولر ڪيو. ۽ صرف جڏهن پاور سپلائي کي سولڊرنگ ڪرڻ آيو ته اهو ظاهر ٿيو ته پلس ۽ مائنس ريورس ۾ وائرڊ هئا. مون کي جمپرن سان فارم ڪرڻو پيو. مٿي ڏنل تصوير ۾، مون اڳ ۾ ئي وائرنگ کي تبديل ڪري ڇڏيو آهي، پر زمين کي بورڊ جي هڪ حصي کان ٻئي کي بوٽ بٽڻ جي پنن ذريعي منتقل ڪيو ويو آهي (جيتوڻيڪ اهو ممڪن هوندو ته ٻئي پرت تي ٽريڪ ٺاهي).

اهو هن طرح ظاهر ٿيو

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

گھر

ايندڙ قدم جسم آهي. جيڪڏهن توهان وٽ 3D پرنٽر آهي، اهو مسئلو ناهي. مون تمام گهڻو پريشان نه ڪيو - مون صرف صحيح سائيز جو هڪ دٻو ٺاهيو ۽ صحيح هنڌن تي ڪٽي آئوٽ ٺاهيو. ڪپڙا ننڍڙن خود-ٽيپنگ اسڪرو سان جسم سان ڳنڍيل آهي.

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

مون اڳ ۾ ئي ذڪر ڪيو آهي ته بوٽ بٽڻ کي عام مقصد واري بٽڻ طور استعمال ڪري سگهجي ٿو - تنهنڪري اسان ان کي فرنٽ پينل تي ڏيکارينداسين. هن کي ڪرڻ لاء، مون هڪ خاص "چڱو" ٺاهي ڇڏيو جتي بٽڻ رهي ٿو.

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

ڪيس جي اندر اهڙا اسٽوڊ پڻ آهن جن تي بورڊ نصب ٿيل آهي ۽ هڪ واحد M3 اسڪرو سان محفوظ ڪيو ويو آهي (بورڊ تي وڌيڪ جاء نه هئي)

مون اڳ ۾ ئي ڊسپلي چونڊيو جڏهن مون ڪيس جو پهريون نمونو ورزن ڇپايو. هڪ معياري ٻه-لائن پڙهندڙ هن معاملي ۾ مناسب نه هو، پر تري ۾ هڪ OLED ڊسپلي SSD1306 128 × 32 هو. اهو ٿورڙو ننڍڙو آهي، پر مون کي هر روز ان کي ڏسڻ جي ضرورت ناهي- اهو مون لاء تمام گهڻو آهي.

هن طريقي سان اندازو لڳايو ۽ اهو ڪيئن تار ان مان روٽ ڪيو ويندو، مون فيصلو ڪيو ته ڊسپلي کي ڪيس جي وچ ۾ لٺ. Ergonomics، يقينا، برابر هيٺ آهن - بٽڻ مٿي تي آهي، ڊسپلي هيٺئين پاسي آهي. پر مون اڳ ۾ ئي چيو هو ته ڊسپلي کي ڳنڍڻ جو خيال تمام دير سان آيو ۽ مان بٽڻ کي منتقل ڪرڻ لاءِ بورڊ کي ٻيهر وائر ڪرڻ ۾ تمام سست هو.

ڊوائيس گڏ ٿيل آهي. ڊسپلي ماڊل گرم گلو سان snot ڏانهن چپ ڪيو ويو آهي

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

آخري نتيجو ڏسي سگھجي ٿو KDPV تي

ڪاريئر

اچو ته سافٽ ويئر جي حصي ڏانهن وڃو. ھن جھڙن ننڍڙن دستورن لاءِ، مان واقعي پٿون (مائڪروپيٿون) - ڪوڊ تمام ٺھيل ۽ سمجھڻ وارو آھي. خوشقسمتيء سان، مائڪرو سيڪنڊن کي نچوض ڪرڻ لاء رجسٽري سطح تي وڃڻ جي ڪا ضرورت ناهي - سڀ ڪجھ ڪري سگهجي ٿو Python کان.

اهو لڳي ٿو ته هر شيء سادو آهي، پر بلڪل سادو ناهي - ڊوائيس ڪيترن ئي آزاد ڪمن ۾ آهي:

  • صارف بٽڻ کي ڇڪي ٿو ۽ ڊسپلي کي ڏسي ٿو
  • فليش ميموري ۾ ليٽر ٽِڪ ۽ اپڊيٽ ويلز
  • ماڊل وائي فائي سگنل جي نگراني ڪندو آهي ۽ ضروري هجي ته ٻيهر ڳنڍيندو آهي
  • خير، چمڪندڙ روشني بلب کان سواء اهو ناممڪن آهي

توهان اهو فرض نه ٿا ڪري سگهو ته هڪ فنڪشن ڪم نه ڪيو جيڪڏهن ٻيو هڪ ڪجهه سببن لاء پڪو آهي. مون اڳ ۾ ئي ٻين پروجيڪٽن ۾ ڪيڪٽي ڀريو آهي ۽ هاڻي مون کي اڃا تائين ”مس ڪيو هڪ ٻيو ليٽر“ جي انداز ۾ خرابيون نظر اچن ٿيون ڇاڪاڻ ته ڊسپلي ان وقت اپڊيٽ ٿي رهي هئي“ يا ”استعمال ڪندڙ ڪجهه به نٿو ڪري سگهي جڏهن ته ماڊل سان ڳنڍي رهيو آهي. وائي فائي“ يقينن، ڪجھ شيون مداخلت ذريعي ڪري سگھجن ٿيون، پر توھان ھلائي سگھو ٿا حدن تي مدت، ڪالن جي نستي، يا متغيرن ۾ غير ائٽمي تبديليون. خير، اهو ڪوڊ جيڪو سڀ ڪجهه ڪري ٿو جلدي موش ۾ بدلجي ٿو.

В وڌيڪ سنجيده منصوبو مون استعمال ڪيو کلاسک پريمپٽيو ملٽي ٽاسڪنگ ۽ فري آر ٽي او ايس، پر هن معاملي ۾ ماڊل وڌيڪ موزون ثابت ٿيو. coroutines ۽ uasync لائبريريون . ان کان علاوه، ڪوروٽينن جي پٿون تي عمل درآمد صرف حيرت انگيز آهي - هر شي پروگرامر لاء آسان ۽ آسان طور تي ڪيو ويندو آهي. بس پنهنجو منطق لکو، بس مون کي ٻڌايو ته ڪهڙن هنڌن تي توهان اسٽريم جي وچ ۾ مٽائي سگهو ٿا.

مان صلاح ڏيان ٿو ته هڪ اختياري مضمون جي طور تي اڳڀرائي ۽ مقابلي واري ملٽي ٽاسڪنگ جي وچ ۾ فرق جو مطالعو ڪريو. هاڻي اچو ته آخرڪار ڪوڊ ڏانهن وڃو.

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

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

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

هر ڪائونٽر کي ڪائونٽر ڪلاس جي مثال سان سنڀاليو ويندو آهي. سڀ کان پهريان، شروعاتي ڪائونٽر ويليو EEPROM (value_storage) مان ڪڍيو ويو آهي - اهو ڪيئن آهي وصولي پاور ناڪامي کان پوء محسوس ٿئي ٿي.

پن کي پاور سپلائي لاءِ بلٽ ان پل اپ سان شروع ڪيو ويو آهي: جيڪڏهن ريڊ سوئچ بند آهي، لائن صفر آهي، جيڪڏهن لائن کليل آهي، اها پاور سپلائي ڏانهن ڇڪي ويندي آهي ۽ ڪنٽرولر هڪ پڙهي ٿو.

هتي هڪ الڳ ٽاسڪ پڻ شروع ڪيو ويو آهي، جيڪو پن کي پول ڪندو. هر ڪائونٽر پنهنجو ڪم هلائيندو. هتي هن جو ڪوڊ آهي

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

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

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

رابطي جي اچ وڃ کي فلٽر ڪرڻ لاءِ 25ms جي دير جي ضرورت آهي، ۽ ساڳئي وقت اهو ضابطو رکي ٿو ته ڪم ڪيترو وقت جاڳي ٿو (جڏهن هي ڪم سمهي رهيو آهي، ٻيا ڪم هلندڙ آهن). هر 25ms تي فنڪشن جاڳي ٿو، پن کي چيڪ ڪري ٿو ۽ جيڪڏهن ريڊ سوئچ رابطا بند آهن، ته پوءِ هڪ ٻيو ليٽر ميٽر مان گذري چڪو آهي ۽ ان تي عمل ڪرڻ جي ضرورت آهي.

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

        self._value_storage.write(self._value)

ايندڙ ليٽر کي پروسيس ڪرڻ معمولي آهي - انسداد صرف وڌائي ٿو. خير، اهو سٺو لڳندو ته نئين قيمت کي فليش ڊرائيو تي لکڻ.

استعمال جي آسانيءَ لاءِ، ”رسائيندڙ“ مهيا ڪيا ويا آهن

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

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

خير، ھاڻي اچو ته پائٿون ۽ uasync لائبريري جي لذتن مان فائدو وٺون ۽ ھڪ انتظار لائق جوابي اعتراض ٺاھيون (اسان ھن کي روسي ۾ ڪيئن ترجمو ڪري سگھون ٿا؟ جنھن جي توھان توقع ڪري سگھو ٿا؟)

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

        return self.value()

    __iter__ = __await__  

هي هڪ اهڙو آسان فنڪشن آهي جيڪو انتظار ڪري ٿو جيستائين ڪائونٽر ويليو اپڊيٽ نه ٿئي - فنڪشن وقت وقت کان جاڳي ٿو ۽ _value_changed پرچم کي چيڪ ڪري ٿو. هن فنڪشن جي سٺي ڳالهه اها آهي ته ڪالنگ ڪوڊ هن فنڪشن کي ڪال ڪندي سمهي سگهي ٿو ۽ ننڊ اچي سگهي ٿو جيستائين نئين قيمت وصول نه ٿئي.

مداخلتن بابت ڇا؟ها، هن موقعي تي توهان مون کي ٽرول ڪري سگهو ٿا، اهو چوڻ آهي ته توهان پاڻ کي مداخلت بابت چيو، پر حقيقت ۾ توهان هڪ بيوقوف پن پول ڪيو. اصل ۾ مداخلت پهرين شيءِ آهي جنهن جي مون ڪوشش ڪئي. ESP8266 ۾، توهان منظم ڪري سگهو ٿا هڪ ايج مداخلت، ۽ حتي لکو هڪ هينڊلر هن مداخلت لاءِ پٿون ۾. ھن مداخلت ۾، ھڪڙي متغير جي قيمت کي اپڊيٽ ڪري سگھجي ٿو. شايد، اهو ڪافي هوندو جيڪڏهن ڪائونٽر هڪ غلام ڊيوائس هجي - هڪ جيڪو انتظار ڪري جيستائين اهو هن قيمت لاءِ پڇيو وڃي.

بدقسمتي سان (يا خوشقسمتيءَ سان؟) منهنجو ڊيوائس فعال آهي، ان کي پاڻ MQTT پروٽوڪول ذريعي نياپا موڪلڻ گهرجن ۽ EEPROM ڏانهن ڊيٽا لکڻ گهرجن. ۽ هتي پابنديون راند ۾ اچن ٿيون - توهان مداخلت ۾ ميموري مختص نٿا ڪري سگهو ۽ هڪ وڏو اسٽيڪ استعمال ڪريو، جنهن جو مطلب آهي ته توهان نيٽ ورڪ تي پيغام موڪلڻ جي باري ۾ وساري سگهو ٿا. هتي micropython.schedule() جهڙا بنس آهن جيڪي توهان کي ڪجهه فنڪشن هلائڻ جي اجازت ڏين ٿا ”جيئن جلد ممڪن ٿي سگهي“، پر سوال ٿو پيدا ٿئي ته ”ڇا ڳالهه آهي؟ ڇا جيڪڏهن اسان هن وقت ڪجهه قسم جو پيغام موڪلي رهيا آهيون، ۽ پوء هڪ مداخلت اچي ٿو ۽ متغير جي قدرن کي خراب ڪري ٿو. يا، مثال طور، سرور مان هڪ نئون ڪائونٽر ويل آيو آهي جڏهن ته اسان اڃا تائين پراڻي کي نه لکيو هو. عام طور تي، توهان کي هم وقت سازي کي بلاڪ ڪرڻ يا ان مان نڪرڻ جي ضرورت آهي ڪنهن به طرح مختلف.

۽ وقت بوقت 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 ۾، بائيٽ سان سڌو ڪم ڪرڻ ڏکيو آهي، پر اهو بائيٽ آهي جيڪو ميموري ڏانهن لکيو ويو آهي. مون کي ustruct لائبريري استعمال ڪندي انٽيجر ۽ بائيٽ جي وچ ۾ تبديلي کي باهه ڏيڻي هئي.

هر دفعي I2C اعتراض ۽ ميموري سيل جي ايڊريس کي منتقل نه ڪرڻ لاء، مون اهو سڀ ڪجهه هڪ ننڍڙي ۽ آسان کلاسک ۾ لپي ڇڏيو.

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

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


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

I2C اعتراض پاڻ انهن پيراگراف سان ٺهيل آهي

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

اسان اچون ٿا سڀ کان دلچسپ حصو - MQTT ذريعي سرور سان رابطي جو عمل. خير، پروٽوڪول پاڻ کي لاڳو ڪرڻ جي ڪا ضرورت ناهي - مون ان کي انٽرنيٽ تي مليو تيار ٿيل هم وقت ساز عمل. اھو اھو آھي جيڪو اسان استعمال ڪنداسين.

سڀ کان وڌيڪ دلچسپ شيون CounterMQTTClient ڪلاس ۾ گڏ ڪيون ويون آهن، جيڪو لائبريري MQTTClient تي ٻڌل آهي. اچو ته دائري کان شروع ڪريون

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

فنڪشن ايمانداري سان مثالن مان نقل ڪيو ويو آهي. انهي صورت ۾، اهو شمار ڪري ٿو بندن جو تعداد (انٽرنيٽ_ آئوٽ) ۽ انهن جي مدت. جڏهن ڪنيڪشن بحال ٿئي ٿو، هڪ بيڪار وقت سرور ڏانهن موڪليو ويو آهي.

رستي ۾، آخري ننڊ جي ضرورت آهي صرف فنڪشن کي غير مطابقت ڏيڻ لاء - لائبريري ۾ ان کي await سڏيو ويندو آهي، ۽ صرف انهن فنڪشن کي سڏي سگهجي ٿو جن جي جسم ۾ ٻيو انتظار شامل آهي.

وائي فائي سان ڳنڍڻ کان علاوه، توهان کي پڻ MQTT بروکر (سرور) سان ڪنيڪشن قائم ڪرڻ جي ضرورت آهي. لئبرري به ائين ڪري ٿي، ۽ اسان کي موقعو ملي ٿو ته ڪجه مفيد ڪم ڪرڻ جو جڏهن ڪنيڪشن قائم ٿئي

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

ھتي اسان ڪيترن ئي پيغامن جي رڪنيت حاصل ڪريون ٿا - سرور کي ھاڻي موجوده جوابي قدرن کي ترتيب ڏيڻ جي صلاحيت آھي لاڳاپيل پيغام موڪلڻ سان.

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

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

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

هي فنڪشن ايندڙ پيغامن تي عمل ڪري ٿو، ۽ موضوع تي منحصر ڪري ٿو (پيغام جو عنوان)، ڳڻپيندڙن مان هڪ جا قدر اپڊيٽ ڪيا ويا آهن

مددگار ڪم جو هڪ جوڙو

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

هي فنڪشن هڪ پيغام موڪلي ٿو جيڪڏهن ڪنيڪشن قائم آهي. جيڪڏهن ڪو ڪنيڪشن نه آهي، پيغام کي نظر انداز ڪيو ويندو.

۽ اهو صرف هڪ آسان فنڪشن آهي جيڪو ٺاهي ٿو ۽ ڊيبگنگ پيغام موڪلي ٿو.

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

تمام گهڻو متن، ۽ اسان اڃا تائين هڪ ايل اي ڊي کي نه ڦوڪيو آهي. هتي

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

مون مهيا ڪيو آهي 2 چمڪندڙ موڊ. جيڪڏهن ڪنيڪشن گم ٿي ويو آهي (يا اهو صرف قائم ٿي رهيو آهي)، ڊوائيس جلدي ڦوڪيندو. جيڪڏهن ڪنيڪشن قائم ٿئي ٿي، ڊوائيس هر 5 سيڪنڊن ۾ هڪ ڀيرو چمڪي ٿو. جيڪڏهن ضروري هجي ته، ٻين چمڪندڙ طريقن کي هتي لاڳو ڪري سگهجي ٿو.

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

اھو اھو آھي جيڪو مان ڳالھائي رھيو ھو - اھو ڪيترو سادو ۽ آسان آھي ڪوروٽين سان. هي ننڍڙو فنڪشن سڄي صارف جي تجربي کي بيان ڪري ٿو. ڪوروٽين صرف بٽڻ کي دٻائڻ جو انتظار ڪري ٿو ۽ 3 سيڪنڊن لاءِ ڊسپلي کي آن ڪري ٿو. ڊسپلي موجوده ميٽر ريڊنگ ڏيکاري ٿو.

اڃا ڪجھ ٿورڙي شيون باقي آهن. هتي اهو فنڪشن آهي جيڪو (ٻيهر) هن سڄي ڪاروبار کي شروع ڪري ٿو. مکيه لوپ صرف هڪ منٽ ۾ هڪ ڀيرو مختلف ڊيبگنگ معلومات موڪلي ٿو. عام طور تي، مان ان جو حوالو ڏيان ٿو جيئن اهو آهي - مان نه ٿو سمجهان ته تمام گهڻو تبصرو ڪرڻ جي ضرورت آهي

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

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

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

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

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

            await asyncio.sleep(60)

خير، وضاحت مڪمل ڪرڻ لاءِ ڪجھ وڌيڪ سيٽنگون ۽ مستقلون

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


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

MQTTClient.DEBUG = True

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

اهو سڀ ڪجهه هن طرح شروع ٿئي ٿو

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

منهنجي يادگيري کي ڪجهه ٿيو

تنهن ڪري، سڀ ڪوڊ اتي آهي. مون فائلن کي اپلوڊ ڪيو ايمپي يوٽيليٽي استعمال ڪندي - اهو توهان کي اجازت ڏئي ٿو ته انهن کي اندروني (اي ايس پي-07 ۾ هڪ) فليش ڊرائيو تي اپلوڊ ڪريو ۽ پوءِ پروگرام مان ان کي رسائي حاصل ڪريو باقاعده فائلن وانگر. اتي مون پڻ اپ لوڊ ڪيو mqtt_as, uasyncio, ssd1306 ۽ گڏ ڪيل لائبريريون جيڪي مون استعمال ڪيون آھن (استعمال ٿيل mqtt_as اندر).

اسان لانچ ڪيو ۽... اسان کي MemoryError ملي ٿي. ان کان علاوه، وڌيڪ مون کي سمجهڻ جي ڪوشش ڪئي ته ميموري ڪٿي لڪي رهي هئي، وڌيڪ ڊيبگ پرنٽ مون رکيا، اڳ ۾ هي غلطي ظاهر ٿي. هڪ مختصر گوگل سرچ مون کي سمجھڻ جي هدايت ڪئي ته مائڪرو ڪنٽرولر وٽ، اصولي طور تي، صرف 30 kB ميموري آهي، جنهن ۾ 65 kB ڪوڊ (بشمول لائبريريون) آسان نه ٿي سگھن.

پر اتي هڪ طريقو آهي. اهو ظاهر ٿئي ٿو ته micropython ڪوڊ سڌو سنئون هڪ .py فائل مان عمل نٿو ڪري - هي فائل پهرين مرتب ٿيل آهي. ان کان علاوه، اهو سڌو مائڪرو ڪنٽرولر تي مرتب ڪيو ويو آهي، بائيٽ ڪوڊ ۾ تبديل ڪيو ويو آهي، جيڪو پوء ميموري ۾ ذخيرو ٿيل آهي. خير، ڪمپيلر ڪم ڪرڻ لاءِ، توهان کي به هڪ خاص مقدار جي رام جي ضرورت آهي.

چال اهو آهي ته مائڪرو ڪنٽرولر کي بچائڻ لاءِ وسيلا-گھڻي تاليف کان. توھان فائلن کي ھڪڙي وڏي ڪمپيوٽر تي گڏ ڪري سگھوٿا ۽ تيار ٿيل بائيٽ ڪوڊ کي مائڪرو ڪنٽرولر ۾ اپ لوڊ ڪري سگھو ٿا. هن کي ڪرڻ لاء، توهان کي ڊائون لوڊ ڪرڻ جي ضرورت آهي micropython firmware ۽ تعمير mpy-ڪراس افاديت.

مون ميڪفائل نه لکيو، پر دستي طور تي سڀني ضروري فائلن کي گڏ ڪيو ۽ گڏ ڪيو (بشمول لائبريريون) ڪجهه هن طرح

mpy-cross water_counter.py

باقي اهو آهي ته فائلن کي اپلوڊ ڪرڻ .mpy ايڪسٽينشن سان، نه وسارجي ته پهرين ڊيوائس جي فائيل سسٽم مان لاڳاپيل .py کي حذف ڪرڻ.

مون پروگرام ۾ تمام ترقي ڪئي (IDE؟) ESPlorer. اهو توهان کي اجازت ڏئي ٿو اپلوڊ اسڪرپٽس کي مائڪرو ڪنٽرولر ڏانهن ۽ فوري طور تي عمل ڪريو. منهنجي صورت ۾، سڀني شين جي منطق ۽ تخليق water_counter.py (.mpy) فائل ۾ واقع آهي. پر اهو سڀ ڪجهه پاڻمرادو شروع ڪرڻ لاءِ، اتي پڻ هڪ فائل هجڻ گهرجي جنهن کي main.py سڏيو وڃي ٿو شروع ۾. ان کان علاوه، اهو بلڪل .py هجڻ گهرجي، ۽ نه اڳ ۾ مرتب ٿيل .mpy. هتي ان جو ننڍڙو مواد آهي

import water_counter

اسان ان کي لانچ ڪيو - سڀ ڪجھ ڪم ڪري ٿو. پر مفت ياداشت خطرناڪ حد تائين ننڍي آهي - اٽڪل 1kb. مون وٽ اڃا تائين ڊوائيس جي ڪارڪردگي کي وڌائڻ جو منصوبو آهي، ۽ هي ڪلوبائيٽ واضح طور تي مون لاء ڪافي ناهي. پر اهو ظاهر ٿيو ته هن ڪيس لاء پڻ هڪ طريقو آهي.

هتي جي ڳالهه آهي. جيتوڻيڪ فائلن کي بائيٽ ڪوڊ ۾ مرتب ڪيو ويو آهي ۽ اندروني فائل سسٽم تي رهائش پذير آهن، حقيقت ۾ اهي اڃا تائين رام ۾ لوڊ ڪيا ويا آهن ۽ اتان کان عمل ڪيو ويو آهي. پر اهو ظاهر ٿئي ٿو ته مائڪروپيٿون بائيٽ ڪوڊ کي سڌو سنئون فليش ميموري مان عمل ڪري سگهي ٿو، پر ان لاء توهان کي ان کي سڌو سنئون فرم ويئر ۾ ٺاهڻ جي ضرورت آهي. اهو ڏکيو نه آهي، جيتوڻيڪ اهو منهنجي نيٽ بڪ تي ڪافي وقت ورتو (صرف اتي مون وٽ لينڪس آهي).

الورورٿم هن ريت آهي:

  • ڊائون لوڊ ۽ انسٽال ڪريو ESP اوپن SDK. هي شيءَ ESP8266 لاءِ پروگرامن لاءِ گڏ ڪرڻ وارو ۽ لائبريريون گڏ ڪري ٿي. پروجيڪٽ جي مکيه صفحي تي ڏنل هدايتن جي مطابق گڏ ڪيو ويو (مون چونڊيو STANDALONE = ها سيٽنگ)
  • ڊائون لوڊ ڪريو micropython جا قسم
  • گھربل لئبريري کي بندرگاهن/esp8266/ماڊيول ۾ micropython وڻ جي اندر رکو
  • اسان فائل ۾ ڏنل هدايتن جي مطابق firmware کي گڏ ڪريون ٿا بندرگاهن/esp8266/README.md
  • اسان فرم ویئر کي مائڪرو ڪنٽرولر تي اپلوڊ ڪندا آهيون (آئون اهو Windows تي ESP8266Flasher پروگرامن يا Python esptool استعمال ڪندي ڪندو آهيان)

اهو ئي آهي، هاڻي 'import ssd1306' ڪوڊ سڌو سنئون firmware مان کڻندو ۽ ان لاءِ رام استعمال نه ڪيو ويندو. هن چال سان، مون فرم ویئر ۾ صرف لائبريري ڪوڊ اپ لوڊ ڪيو، جڏهن ته مکيه پروگرام ڪوڊ فائل سسٽم مان عمل ڪيو ويو آهي. هي توهان کي اجازت ڏئي ٿو آساني سان پروگرام کي تبديل ڪرڻ کان سواءِ فرم ویئر کي ٻيهر. هن وقت مون وٽ اٽڪل 8.5kb مفت ريم آهي. اهو اسان کي مستقبل ۾ ڪافي مختلف مفيد ڪارڪردگي کي لاڳو ڪرڻ جي اجازت ڏيندو. خير، جيڪڏهن اتي ڪافي ميموري نه آهي، ته پوء توهان کي دٻائي سگهو ٿا مکيه پروگرام firmware ۾.

پوء اسان کي ان بابت ڇا ڪرڻ گهرجي؟

ٺيڪ آهي، هارڊويئر سولڊر ٿيل آهي، فرم ویئر لکيل آهي، باڪس ڇپيل آهي، ڊيوائس ڀت تي رکيل آهي ۽ خوشيءَ سان روشنيءَ جو بلب چمڪي ٿو. پر ھاڻي اھو سڀ ھڪڙو ڪارو باڪس آھي (لفظي ۽ علامتي طور تي) ۽ اھو اڃا تائين ٿورو استعمال جو آھي. اهو وقت آهي ڪجهه ڪرڻ جو MQTT پيغام جيڪي سرور ڏانهن موڪليا ويا آهن.

منهنجو ”سمارٽ گهر“ هلي رهيو آهي ميجرڊومو سسٽم. MQTT ماڊل يا ته دٻي مان نڪرندو آهي، يا آساني سان انسٽال ٿيل آهي ايڊ-آن مارڪيٽ مان - مون کي ياد ناهي ته مون اهو ڪٿان حاصل ڪيو. MQTT هڪ خودمختاري شيء نه آهي - توهان کي هڪ نالي جي ضرورت آهي. بروکر - هڪ سرور جيڪو وصول ڪري ٿو، ترتيب ڏئي ٿو ۽ موڪلي ٿو MQTT پيغامن کي ڪلائنٽ ڏانهن. مان مچھر استعمال ڪريان ٿو، جيڪو (جهڙوڪ majordomo) ساڳي نيٽ بڪ تي هلندو آهي.

ڊوائيس کان پوء گهٽ ۾ گهٽ هڪ ڀيرو پيغام موڪلي ٿو، قيمت فوري طور تي لسٽ ۾ ظاهر ٿيندو.

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

اهي قيمتون هاڻي سسٽم جي شين سان لاڳاپيل ٿي سگهن ٿيون، اهي آٽوميشن اسڪرپٽ ۾ استعمال ڪري سگھجن ٿيون ۽ مختلف تجزين جي تابع ٿي سگهن ٿيون - اهي سڀئي هن مضمون جي دائري کان ٻاهر آهن. مان سفارش ڪري سگهان ٿو majordomo سسٽم هر ڪنهن کي دلچسپي چينل اليڪٽرانڪس لينس ۾ - هڪ دوست پڻ سمارٽ گهر ٺاهي رهيو آهي ۽ واضح طور تي سسٽم کي ترتيب ڏيڻ بابت ڳالهائيندو آهي.

مان صرف توهان کي ڪجهه گراف ڏيکاريندس. هي روزاني قدرن جو هڪ سادي گراف آهي

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ
اهو ڏسي سگهجي ٿو ته تقريبا ڪو به رات جو پاڻي استعمال نه ڪيو. ٻه ڀيرا ڪو ماڻهو ٽوائلٽ ڏانهن ويو، ۽ اهو لڳي ٿو ته ريورس osmosis فلٽر في رات ٻه ليٽر چوسي ٿو. صبح جو، واپرائڻ خاص طور تي وڌي ٿو. مان عام طور تي بوائلر مان پاڻي استعمال ڪندو آهيان، پر پوءِ مون غسل ڪرڻ چاهيو ۽ عارضي طور تي شهر جي گرم پاڻي ڏانهن رخ ڪيو - اهو پڻ هيٺئين گراف ۾ واضح طور تي نظر اچي ٿو.

هن گراف مان مون کي معلوم ٿيو ته ٽوائلٽ وڃڻ لاءِ 6-7 ليٽر پاڻي گهرجي، شاور وٺڻ لاءِ 20-30 ليٽر، برتن ڌوئڻ لاءِ 20 ليٽر ۽ غسل ڪرڻ لاءِ 160 ليٽر گهرجن. منهنجو خاندان روزانو تقريباً 500-600 ليٽر استعمال ڪري ٿو.

انهن لاءِ جيڪي خاص طور تي تجسس وارا آهن، توهان هر فرد جي قيمت لاءِ رڪارڊ ڏسي سگهو ٿا

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

هتان مان معلوم ٿيو ته جڏهن نلڪو کليل هوندو آهي ته پاڻي تقريباً 1 ليٽر في 5 سيڪنڊن جي رفتار سان وهندو آهي.

پر هن فارم ۾ انگ اکر شايد ڏسڻ لاء بلڪل آسان نه آهن. Majordomo پڻ ڏسڻ جي صلاحيت رکي ٿو واپرائڻ چارٽ ڏينهن، هفتي ۽ مهيني طرفان. هتي، مثال طور، بار ۾ واپرائڻ گراف آهي

واٽر ميٽر کي سمارٽ گهر سان ڳنڍڻ

هينئر تائين مون وٽ صرف هڪ هفتي لاءِ ڊيٽا آهي. هڪ مهيني ۾، هي گراف وڌيڪ اشارو ٿيندو - هر روز هڪ الڳ ڪالم هوندو. تصوير ٿوري خراب ٿي وئي آهي ترتيبن جي ترتيب سان جيڪي آئون دستي طور داخل ڪيان ٿو (وڏي ڪالمن). ۽ اهو اڃا تائين واضح ناهي ته ڇا مون غلط طور تي پهريون قدر مقرر ڪيو، تقريبا هڪ ڪعب گهٽ، يا ڇا اهو فرم ویئر ۾ هڪ بگ آهي ۽ سڀ ليٽر نه ڳڻيا ويا. وڌيڪ وقت جي ضرورت آهي.

گراف پاڻ کي اڃا به ڪجهه جادو، اڇو ڌوئڻ، مصوري جي ضرورت آهي. شايد مان ڊيبگنگ جي مقصدن لاءِ ياداشت جي استعمال جو گراف پڻ ٺاهيندس - صورت ۾ اتي ڪجهه لڪي رهيو آهي. ٿي سگهي ٿو ته آئون ڪنهن به وقت ان دور کي ڏيکاريندس جڏهن انٽرنيٽ نه هئي. هينئر تائين، اهو سڀ ڪجهه خيالن جي سطح تي آهي.

ٿڪل

اڄ منهنجو اپارٽمينٽ ٿورڙو هوشيار ٿي ويو آهي. اهڙي ننڍڙي ڊوائيس سان، مون کي گهر ۾ پاڻي جي استعمال جي نگراني ڪرڻ لاء وڌيڪ آسان ٿيندو. جيڪڏهن اڳ ۾ مون کي ڪاوڙ هئي ته "ٻيهر، اسان هڪ مهيني ۾ تمام گهڻو پاڻي استعمال ڪيو،" هاڻي مان هن واپرائڻ جو ذريعو ڳولي سگهان ٿو.

ڪجھ کي شايد اھو عجيب لڳندو آھي ته اسڪرين تي پڙھندڙن کي ڏسڻ ۾ جيڪڏھن اھو ميٽر کان ھڪ ميٽر پري آھي. پر تمام گهڻو پري نه مستقبل ۾، مان هڪ ٻئي اپارٽمنٽ ڏانهن وڃڻ جو ارادو ڪريان ٿو، جتي اتي ڪيترائي واٽر ريزر هوندا، ۽ ميٽر پاڻ گهڻو ڪري لينڊنگ تي واقع هوندا. تنهنڪري ريموٽ ريڊنگ ڊيوائس تمام ڪارآمد ثابت ٿيندي.

مان پڻ ڊوائيس جي ڪارڪردگي کي وڌائڻ جو منصوبو ڪريان ٿو. مان اڳ ۾ ئي موٽرائيز والوز کي ڏسي رهيو آهيان. ھاڻي، بوائلر کي شھر جي پاڻيءَ ۾ تبديل ڪرڻ لاءِ، مون کي 3 نلن کي پھچڻ جي سخت جاءِ تي ڦيرائڻو پوندو. اهو هڪ بٽڻ سان لاڳاپيل اشاري سان اهو ڪرڻ لاء وڌيڪ آسان ٿيندو. يقينن، اهو ليک جي خلاف تحفظ کي لاڳو ڪرڻ جي قابل آهي.

آرٽيڪل ۾ مون بيان ڪيو آهي منهنجي هڪ ڊوائيس جو نسخو ESP8266 تي ٻڌل آهي. منهنجي خيال ۾، مان هڪ تمام دلچسپ نسخو کڻي آيو آهيان micropython firmware جو استعمال ڪندي ڪوروٽين - سادو ۽ سٺو. مون ڪوشش ڪئي ته ڪيترن ئي نزاڪتن ۽ نقصن کي بيان ڪرڻ جي ڪوشش ڪئي، جيڪي مون کي مهم دوران سامهون آيون. شايد مون هر شيءِ کي تمام گهڻي تفصيل سان بيان ڪيو آهي؛ ذاتي طور تي، هڪ پڙهندڙ جي حيثيت سان، مون لاءِ اهو آسان آهي ته غير ضروري شين کي ڇڏي ڏيڻ بجاءِ بعد ۾ اهو سوچڻ جي ته ڇا نه چيو ويو آهي.

هميشه وانگر، مان تعميري تنقيد لاء کليل آهيان.

ذريعو
سرڪٽ ۽ بورڊ
ڪيس ماڊل

جو ذريعو: www.habr.com

تبصرو شامل ڪريو