Մենք ստեղծում ենք դարպաս Wi-Fi-ի և LoRa-ի միջև UDP-ի համար

Ես ունեի մանկական երազանք — յուրաքանչյուր տնային «առանցWiFi» устройство կապել ցանցին, այսինքն ՝ IP-հասցե և պորտ տալ: Մի ժամանակ ես հասկացա, որ մի կողմից չեմ կարող սպասել, պետք է վերցնել և անել:
Տեխնիկական առաջադրանք
Դարպասը պետք է լինի M5Stack, որի վրա տեղադրված է LoRa մոդուլ (նկար 1): Դարպասը կսահմանվի Wi-Fi ցանցին, որտեղ DHCP միջոցով կստանա տեղական IP-հասցե: Դարպասը որոշակի ժամանակաշրջաններում պետք է հեռարձակվի «LoRa-էթերում» իր անունը (անալոգ SSID Wi-Fi-ի համար) և թույլատրված պորտերի շրջանակը, որպեսզի այլ սարքեր իմանան, որ կա մի ցանց, որով կարելի է միանալ և որ հստակագույնը տոմսանիշի անկման ժամանակ կարող են ընտրել ազատ պորտ: Քանի որ սա կլինի պրոտոտիպ, հաստատումը այս անգամ չի իրականացվի: Նոր կլիենտ սարքերը գտնելով հասանելի LoRa ցանցը, կփոխանցեն այն ընտրած պորտը: Երբ դարպասը ստանում է նոր կլիենտից պորտ, ստուգում է, արդյոք այն ազատ է, եթե այո, նոր կլիենտը կերգի և կսկսի լսել տվյալ պորտը իր սեփական ասինխրոն UDP սերվերում: Հաստատման ժամանակ կլիենտը կստանա համաձայնություն կամ մերժում հայտավորված պորտի օգտագործման համար: Ս işl կարևորագույն գործընթացը պատկերված է աղյուսակ 1-ում:

Նկար 1
Աղյուսակ 1
կողմ
ուղղություն և տվյալներ
կողմ
սեսիա
[ կլիենտ ]
<— ազդանշան-հայտարարություն —
[ դարպաս ]
0xA1
[ կլիենտ ]
— ընտրված պորտ —>
[ դարպաս ]
0xB1
[ կլիենտ ]
<— համաձայնություն կամ մերժում —
[ դարպաս ]
0xA2
[ կլիենտ ]
— UDP-փաթեթ —>
[ դարպաս ]
0xB2
[ կլիենտ ]
<— UDP-փաթեթ —
[ դարպաս ]
0xA3
[ ցանց ]
<— UDP-փաթեթ —
[ դարպաս ]
0xC1
Իմ առաջ սեղանին տարածված են տարբեր մոդուլներ M5Stack-ի համար և հոգնած են: Դавайте վերցնենք LoR’u և զվարճանանք դրա հետ: Այս մոդուլների գաղափարը հրաշալի է! Ինչ կարող եմ ասել այստեղ: Բայց ես ունեմ առաջին մոդուլներից, որոնք ունեն սարսափելի встроенная антенна, выполненная на гибкой печатной плате и приклеенная к боковой стенке корпуса. Ես անցել եմ մեկ անգամ գետնին փորձարկումներ таких модулов (можно посмотреть на русскоязычном канале на YouTube):

Արժե նշեմ, որ ստիպված էի հեռացնել այս անկյունները և ստանդարտ ոլորուն ատենաների փոխանցել, որոնք գալիս են Ra-01-ի հետ: Այցելելով այսպիսի համապատասխանությունները, հաղորդակցության հեռավորությունը զգալիորեն բարելավել է, բայց ի հայտ է եկել կողմնակի պահ — ատենան ունի մեծ տրամագիծ, քան մոդուլների միջև թույլատրված հեռավորությունը: Ծրագրի ընթացքում ստիպված էի հրաժարվել ավարտական մոդուլից:
Առաջին դժվարություններ синхронной тугости
Տեսք, վերցրու գրադարան WiFiUdp.h, որտեղ ամեն ինչ կա UDP-սերվերի հարմարավետ գոյության համար, բայց ոչ: Գրադարանի դիզայնը նախատեսված է սինխրոյի սերվեր ստեղծելու համար, որը, խորապես ցավալի, չի կարող միաժամանակ սպասարկել մի քանի կապեր մեկ потокում: Այստեղից այդ գրադարանը չի համապատասխանում ներկա խնդրին: Պետք էր շատ բաժակ թեյ խմել և փնտրել գրադարանը, որը թույլ կտա ստեղծել ասինխրոն UDP-սերվեր, որը կարող է սատարել շատ կապեր միաժամանակ: Այդպիսի գրադարանը գտնվեց — AsyncUDP.h. Ի՞նչն է տարբերությունը համաժամեցված սերվերի և ասինխրոն սերվերի միջև: Եկեք անդրադառնանք վեց իրադարձությունների, որոնք պատկերում են 2-րդ նկարում սockets-ների աշխատանքը։

Նկար 2
Առաջին դերերում՝
Ատոն դերում Socket;
Թ鸟 դերում Միացումը;
Լիացիկ դերում Նյութեր.
Ազգ A. Համաժամեցված Socket առանց таймаутона
Ատոնը կկանգնի մինչ Թ鸟ը նրան չի հասցնի Լիացիկը।
Ազգ B. Համաժամեցված Socket таймаուտով
Ատոնը սպասում է Թ鸟ի կողմից պայմանավորված ժամանակը, և եթե նա ժամանակին չդառնա, ապա Ատոնը կգնա։
Ազգ C. Համաժամեցված Socket բազմաբլոկում
Ատոնը համակարգում է և դիտում է, ինչպես Թ鸟ները ինքնուրույն բերում Լիացիկները։
Ազգ D. Ասինխրոն Socket (երբ դեռ ոչինչ չի ստացվել)
Ատոնը զբաղվել է նախընտրած զբաղմունքներով, բայց չի մոռանում Թ鸟ների մասին։
Ազգ E. Ասինխրոն Socket (երբ կա, ինչ ստանալ)
Ատոնը մի փոքր շեղվեց զբաղմունքներից, որպեսզի ընդունի Լիացիկը Թ鸟ից։
Ազգ F. Ասինխրոն Socket բազմաբլոկում
Ատոնը զբաղվել է իր գործերով և դիտում է, ինչպես Թ鸟ները ինքնուրույն բերում Լիացիկները։
Եթե դուք ուշադիր էիք, ապա հաստատ պիտի նկատեիք, որ Թ鸟ների քաշերը յուրաքանչյուր ազգում ունեն որոշակի գույն։ Եվ այսինչ պատճառով։ Ա զն A և B սերվերում կա միայն մեկ Socket։ Ա զն C-ում աշխատում են արդեն երկու Sockets: Ա սֆ D, E և F-ում արդեն երեք Sockets են։ «Ինչու այստեղ երկու, իսկ այնտեղ երեք» — կհարցնեք դուք։ Սա պայմանագրային 2 և 3 է, իրականում, 2-ի փոխարեն կարող է լինել 20, իսկ 3-ի փոխարեն 200։ Գործողությունը ցույց տալ, որ ասինխրոն Sockets-ները այնքան էլ չեն ազդի սարքավորումների վրա, ինչքան համաժամեցվածները։
Որքան ինչին տեղ է զբաղեցնում?
Եկեք դիտենք 1-ին աղյուսակը, որտեղ ներկայացված է UDP փաթեթի կառուցվածքը և մտածենք, ինչ կարող ենք անել։
Աղյուսակ 1. UDP փաթեթի կառուցվածքը
Բիթեր
0 — 15
16 — 31
0-31
Առանց մատակարարի (Source port)
Ուղարկողի (Destination port)
32-63
Դատապարտման երկարությունը (Length)
Հսկում (Checksum)
64-...
Տվյալներ (Data)
Աղյուսակի սկզբին ավելացնենք ևս մեկ դաշտ Սեսիա (1 Բայթ). Սա բավարար է այս ծրագրի համար։ Սեսիայի հիման վրա սարքը կհասկանա, թե ինչ պետք է անել փաթեթի հետ արձանագրության։ Այժմ պիտի մտածենք սեսիաների կոդերը և գրենք դրանք 2-րդ աղյուսակում։
Աղյուսակ 2. Սեսիաների բացատրություն
Կոդ
Վերնագիր
Բացատրություն
0xA1
Մայակ
Գործն արձակել է LoRa-ցանցի անվան և թույլատրված պորտերի միջակայքով որոշակի ժամանակահատվածով։ Սա անհրաժեշտ է, որպեսզի նոր շահառուները տեսնեն հասանելի ցանց, իսկ ներկա շահառուները, երբ տվյալներ չկա, կարող են որոշել ազդանշանի մակարդակը։
0xB1
Դիմում
Երբ շահառուն հայտնաբերում է ցանցը, ապա նա ուղարկում է նախընտրած պորտը։
0xA2
Համաձայնություն կամ մերժում
Եթե շահառուի մատակարարված պորտը ազատ է, ապա սերվերը պատասխանում է համաձայնությամբ, իսկ հակառակ դեպքում՝ մերժմամբ։
0xB2
Up-լինք
Երբ շահառուն փոխանցում է UDP փաթեթը ապարատին։
0xA3
Down-լինք
Երբ ապարատը փոխանցում է UDP փաթեթը շահառուին։
0xC1
Up-լինքի շարունակություն
Երբ ապարատը ուղարկում է UDP փաթեթը տեղական ցանցում։
Լավ։ Այժմ հասկանանք նիստերի կազմը 3-րդ աղյուսակում։
Աղյուսակ 3։ Նիստեր
Նիստի անունը
Կազմ
Մայակ
Նիստի կոդ (1 Բայ) + LoRa ցանցի անուն (4 Բայ) + Սկսնակ պորտ (2 Բայ) + Վերջնական պորտ (2 Բայ)
Դիմում
Թ انتقالի կոդ (1 Բայ) + LoRa ցանցի անուն (4 Բայ) + Նախընտրված հեռախոսահամար (2 Բայ)
Համաձայնություն կամ մերժում
Թ انتقالի կոդ (1 Բայ) + LoRa ցանցի անուն (4 Բայ) + Նախընտրված հեռախոսահամար (2 Բայ) + Պատասխան (1 Բայ)
Up-լինք
Թ انتقالի կոդ (1 Բայ) + LoRa ցանցի անուն (4 Բայ) + Հեռավոր IP հասցե (4 Բայ) + Հեռավոր պորտ (2 Բայ) + Ներքին IP հասցե (4 Բայ) + Ներքին պորտ (2 Բայ) + Տվյալների չափը (2 Բայ) + Տվյալներ
Նվազման աղյուսակ
Թ انتقالի կոդ (1 Բայ) + LoRa ցանցի անուն (4 Բայ) + Հեռավոր IP հասցե (4 Բայ) + Հեռավոր պորտ (2 Բայ) + Ներքին IP հասցե (4 Բայ) + Ներքին պորտ (2 Բայ) + Տվյալների չափը (2 Բայ) + Տվյալներ
Up-լինքի շարունակություն
Հեռավոր IP հասցե (4 Բայ) + Հեռավոր պորտ (2 Բայ) + Տվյալների չափը (2 Բայ) + Տվյալներ
Բերեցի երկու հաճախորդներ Arduino-ի և M5Stack-ի համար։ Դրանց կարող եք տեսնել, թե ինչպես է դա աշխատում։ Ապահով բնակությանը խնդիր չկա, դաշտային փորձարկումներ դեռ չեմ կատարել։
Սկզբնական կոդը հասանելի է GitHub-ում ՝
Ապահով եկեք ավելին իմանալ M5Stack-ը և գնեք
Ընտրեք LoRa անլար մոդուլները M5Stack-ի համար
Շատ ուրախ կլինեմ, եթե այս նախագիծը ձեզ օգտակար լինի։ Շնորհակալություն ժամանակի համար։
Գրականության և (կամ) աղբյուրների ցուցակ՝
Ընտանիք: habr.com
