بوت کردن، اتصال به وای فای، درخواست سرور در کمتر از 1 ثانیه با ESP-01 🥖 تصادفی های جان مولر

ساخت دکمه سخت افزاری که به وای فای متصل می شود و درخواست را به سرور ارسال می کند با استفاده از آردوینو امکان پذیر است. کلیدهای چراغ (تقریبا) فوری هستند – اما کلیدهای وای فای ساده به راحتی 8 تا 10 ثانیه طول می کشد تا وصل شوند و جابجا شوند. چگونه آن زمان را کاهش می دهید؟ این رویکرد من است.

  1. اندازه گیری انتها به انتها – زمان پیش فرض چقدر است؟ آیا واقعا آنقدر بد است یا گاهی اوقات بد است؟
  2. به قطعات تقسیم شود
  3. قطعات را اندازه گیری کنید
  4. تعیین کنید کدام قسمت ها باید بهینه شوند و گزینه ها را امتحان کنید
  5. بهترین گزینه ها را با هم ترکیب کنید
  6. اشکال زدایی کنید که چرا کار نمی کند و دوباره امتحان کنید

رایانه ای که ما برای کار روی آن استفاده می کنیم ESP8266 مدل ESP-01 است. کوچک و ارزان است (MQTT زیرا یکی از تنظیمات متداول برای اتوماسیون خانگی است. همه اندازه‌گیری‌ها 10 بار انجام شد تا به پایداری آنها پی ببرید.

توجه: کد اینجا برای سال 2022 به روز و تجزیه و تحلیل شده است.

کد پیش فرض

کد پیش‌فرض اتصال و سوئیچ تقریباً به این صورت است (ساده شده):

#include 
#include 
#include 

WiFiClient wifi_client;
PubSubClient mqtt_client(wifi_client);

void setup() {
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_AUTH);
    while (WiFi.status() != WL_CONNECTED) { delay(100); }
    mqtt_client.setServer(MQTT_SERVER, 1883);
    if (mqtt_client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_AUTH)) {
        mqtt_client.publish(MQTT_TOPIC_ID, "hello");
    }
}

void loop() { }

جریان کلی این است که با استفاده از نام وای فای (WIFI_SSID) و رمز عبور (WIFI_AUTH) به وای فای متصل می شود، منتظر می ماند تا اتصال پایدار شود، سپس به سرور MQTT (MQTT_SERVER متصل می شود)، با MQTT_USER و MQTT_AUTH احراز هویت می شود، سپس پیامی ارسال می کند. به یک “موضوع” در سرور. اندازه گیری زمان در کد با بررسی تایمر میلی ثانیه قبل و بعد امکان پذیر است. چیزی که در اینجا نمی بینید زمان بوت است.

زمان بوت

برای اندازه‌گیری زمان راه‌اندازی، یکی از پایه‌های خروجی را به عنوان اولین مرحله در کد تغییر می‌دهم، سپس می‌توانم مدت زمان روشن شدن تا روشن شدن پین را با اسیلوسکوپ اندازه‌گیری کنم.

#include 

void setup() {
  pinMode(PIN_TEST, OUTPUT); 
  digitalWrite(PIN_TEST, HIGH); 
}

void loop() { }

تنظیمات اندازه گیری چیزی شبیه به این است:

ماشه را روی اتصال برق تنظیم کردم (بنابراین از آنجا شروع به شمارش می کند) و به صورت دستی اندازه گیری کردم که تغییر در پین خروجی کجا اتفاق می افتد.

زمان بندی:

  • زمان بوت: 124.3 میلی‌ثانیه (SD 1.9 میلی‌ثانیه) – زمان‌بندی مشابه با بردهای مختلف، واریانس کم
  • زمان Wifi + MQTT: 5312 میلی‌ثانیه (SD 3194 میلی‌ثانیه) – بسیار متغیر، زمان‌های سریع در حدود 1.7 ثانیه، زمان‌های آهسته حدود 9 ثانیه

9 ثانیه منتظر ماندن برای روشن شدن چراغ آزاردهنده است. من حتی 2 ثانیه صبر نمی کنم تا یک صفحه بارگذاری شود.

بهینه سازی

کندی از چند جا می آید:

  • ایجاد یک اتصال وای فای به زمان زیادی نیاز دارد (پوینت های دسترسی را اسکن کنید، بررسی کنید کدام یک از SSID نزدیکتر هستند، احراز هویت، یک آدرس IP دریافت کنید، اطلاعات شبکه را دریافت کنید)
  • اتصال به سرور به چندین مرحله نیز نیاز دارد (DNS، اتصال، احراز هویت – حتی در صورت استفاده از متن ساده MQTT)

بهینه‌سازی‌هایی که من به آنها نگاه کردم سعی کردند به کندترین مراحل رسیدگی کنند، بهینه‌سازی‌های بیشتر نیز ممکن است. برای وای فای، می‌توانید مستقیماً به یک ایستگاه پایه و کانال خاص متصل شوید و فرآیند اسکن و انتخاب را ذخیره کنید. نقطه ضعف این است که اگر در اطراف حرکت کنید، ممکن است با یک ایستگاه پایه غیربهینه یا خارج از محدوده مواجه شوید. یا، نقطه دسترسی شما ممکن است کانال ها را پرتاب کند و در نهایت به کانالی برسید که واقعا کار نمی کند.

بهینه سازی وای فای

زمان و گزینه ها به این صورت بود:

فقط وای فای:

  • به SSID متصل شوید، از DHCP استفاده کنید: 7473 میلی‌ثانیه (SD 105 میلی‌ثانیه) – به‌طور قابل توجهی کندتر از سریع‌ترین زمان‌های پایان به انتها، که نشان می‌دهد ممکن است دستگاه در حال انجام بهینه‌سازی‌هایی در آزمایش‌های سرتاسری باشد.
  • به SSID متصل شوید، از IP / DNS ثابت استفاده کنید: 1316ms (SD 33ms) – این قبلاً تا حدی قابل استفاده است. آیا DHCP خیلی کند است یا فقط راه اندازی آن بسیار کند است؟
  • به BSSID متصل شوید، از DHCP استفاده کنید: 201ms (SD 60ms) – چشمک می زند. این خوب است.
  • به BSSID متصل شوید، از IP / DNS ثابت استفاده کنید: 128ms (SD 0.4ms) – omg.

130 میلی ثانیه برای اتصال به وای فای بسیار شگفت انگیز است. به نظر می رسد من احتمالاً چیز مهمی را از دست داده ام، چرا لپ تاپ من این کار را نمی کند؟ من برش میدارم.

اضافه کردن MQTT:

  • Wifi با SSID، DHCP + MQTT به نام میزبان: 5312ms (SD 3194) – همانطور که در ابتدا ذکر شد
  • Wifi با SSID، IP ثابت + MQTT به آدرس IP: 1432ms (SD 217ms) – جستجوی DHCP و DNS زمان بر است، اما اینطور نیست که سرورها آدرس های IP را تغییر دهند.
  • فای با BSSID، IP ثابت + MQTT: خراب می شود:-/

به نظر می رسد، زمانی که شما BSSID را مشخص می کنید، کد وای فای واقعاً متصل نمی شود، فقط مانند آن عمل می کند. به طور خلاصه، این یک راه سریع برای عدم برقراری ارتباط است. مزاحم. اگرچه سریع است، شاید راهی برای کارکرد آن وجود داشته باشد.

راه حل به این نتیجه رسید که مانند ما بعد از اتصال دوباره وصل می شویم، که اتصال واقعی را انجام می دهد.

    // ...
    WiFi.config(IPAddress(data.ip_address),
        IPAddress(data.ip_gateway), IPAddress(data.ip_mask), 
        IPAddress(data.ip_dns1), IPAddress(data.ip_dns2));
    WiFi.begin(data.wifi_ssid, data.wifi_auth, 
        data.wifi_channel, data.wifi_bssid);
    WiFi.reconnect(); // actually connect
    uint32_t timeout = millis() + TIMEOUT; // await connection or time out
    while ((WiFi.status() != WL_CONNECTED) && (millis()timeout)) { delay(5); }
    return (WiFi.status() == WL_CONNECTED);

بهینه سازی MQTT

برای سرور MQTT، استفاده از IP استاتیک کمک سریعی است. می توانید DNS هاست MQTT را جستجو کنید و فقط آن را در حافظه پنهان ذخیره کنید.

    IPAddress mqtt_ip;
    int err = WiFi.hostByName(MQTT_SERVER, mqtt_ip);
    if (err==0) { 
        // couldn't get IP, we're doomed
        // it'll probably work next time though
    }

علاوه بر این، از آنجایی که MQTT از شی WiFiClient برای اتصال مجدد استفاده می‌کند، می‌توانیم از قبل به سرور متصل شویم و به طور بالقوه در آن زمان صرفه‌جویی کنیم (مشخص نیست که آیا این واقعاً تفاوتی ایجاد می‌کند یا خیر – شاید نه).

    // preconnect
    WiFiClient wclient;
    #define PRECONNECT_TIMEOUT 5000
    wclient.setTimeout(100);
    uint32_t timeout = millis() + PRECONNECT_TIMEOUT;
    while ((!wclient.connect(ip, port)) && (millis()timeout)) { delay(50); }

    // mqtt stuff
    PubSubClient mqtt_client(wclient);
    mqtt_client.setServer(data.mqtt_host_ip, data.mqtt_host_port);
    if (mqtt_client.connect(MQTT_CLIENT_ID, data.mqtt_user, data.mqtt_auth)) {
        mqtt_client.publish(topic, value);
        // other topics
    }

نتایج

کل زمان بندی با این تنظیمات برای یک سوئیچ (خوب، برای من) بسیار معقول است، سریعتر از بارگیری این صفحه.

  • زمان بوت شدن: 124.3ms (SD 1.9ms)
  • زمان از راه اندازی تا اتصال و ارسال: 474ms (SD 53ms)
  • زمان به‌روزرسانی تنظیمات (زمانی که اتصالات قطع می‌شود یا در راه‌اندازی اولیه): 7408 میلی‌ثانیه (SD 79 میلی‌ثانیه)

سخت افزار

(در پست دیگری نوشته خواهد شد.) من از یک سوئیچ برق گیره استفاده می کنم که از GPIO3 برای خاموش کردن کامل استفاده می کند و دستگاه را با باتری های 2xAA تغذیه می کند.

  • دکمه (> 120 میلی ثانیه) را فشار دهید تا روشن شود، متصل می شود، درخواست ارسال می کند، به طور خلاصه چشمک می زند.
  • اگر پاور نگه داشته شود، فلاش را دوباره راه اندازی می کند.
  • اگر حتی بیشتر نگه داشته شود، به‌روزرسانی‌های OTA را فعال می‌کند.

دستگاه یک موضوع برای چراغ‌های WLED و همچنین موضوعی برای Home Assistant ارسال می‌کند تا به آن بگوید فعال است (که ثبت شده است). ظاهراً چندین درخواست MQTT در یک جلسه به حداقل سربار نیاز دارند، بنابراین ارسال هر دو خوب است. برای فعال کردن ورود به سیستم Home Assistant، من از MQTT autodiscovery در جریان اولیه سازی مجدد استفاده می کنم. به همین خوبی می‌توانید یک وب سرور تصادفی را پینگ کنید، یک توییت ارسال کنید (به دردسرهای API توییتر توجه کنید)، درب گاراژ را باز کنید، یا کاری مفید انجام دهید.

مراحل بعدی

  • تجزیه و تحلیل زمان بندی دقیق تری انجام دهید.
  • بررسی کنید چه چیزی واقعاً از طریق شبکه ارسال شده است.
  • تحقیق کنید که آیا راهی برای کش کردن اتصال / احراز هویت سرور MQTT وجود دارد (شک این است که دست دادن تأیید اعتبار کمی طول می کشد)
  • از طریق TLS به MQTT بروید
  • مصرف برق را اندازه گیری کنید

همچنین مرحله واضح پاک کردن کد و رها کردن آن در Github :-).

نظرات / سوالات

در حال حاضر هیچ قابلیت نظر دادن در اینجا وجود ندارد. اگر می‌خواهید نظر بدهید، لطفاً از Mastodon استفاده کنید و من را (@[email protected]) در آنجا ذکر کنید. با تشکر!

صفحات مرتبط

Source link