النهاية. الجزء السابق .
جدول المحتويات:
جهاز استشعار خارجي. البرمجيات
تحدث عن البرنامج الخاص بجهاز الاستشعار في الخارج. بعد ذلك ، ستحصل على نظام كامل يمكنك تجربته بالفعل.
دعني أذكرك بأن الخادم عبارة عن وحدة مركزية منزلية يمكنها الاتصال بالإنترنت عبر WiFi ، والعميل عبارة عن مستشعر بعيد عن بُعد ينقل البيانات إلى الخادم عبر الأثير.
كود المصدر لكل من الخادم والعميل هنا .
يتم تزويد النصوص المصدر بتعليقات مفصلة.
لا يلزم تكوين أي شيء تقريبًا على العميل.
يتطلب جهاز إرسال الراديو nRF24L01 + ، وبشكل أدق مكتبة RadioHead ، تحديد عناوين الخادم والعميل. يتم توفير العناوين في حالة وجود أكثر من خادم وعميل واحد. العنوان هو أي عدد صحيح. عندما يرسل العميل حزمة بيانات إلى خادم ، فإنه يشير إلى الخادم الذي تستخدمه هذه الحزمة. الخادم ، مع معرفة عنوانه ، بدوره ، يحدد ما إذا كانت هذه الحزمة مخصصة لها.
لذلك ، يجب أن يكون SERVER_ADDRESS
على الخادم والعميل هو نفسه ، ولكن يجب أن يكون CLIENT_ADDRESS
للعملاء المختلفين مختلفين. بمعنى آخر ، إذا قمت بتوصيل مستشعر جديد آخر بنظامنا في المستقبل ، CLIENT_ADDRESS
تغيير CLIENT_ADDRESS
لذلك.
// #define SERVER_ADDRESS 10 #define CLIENT_ADDRESS 20 // !!!
يجب أن يكون RF_CHANNEL
قناة الراديو RF_CHANNEL
هو نفسه للجميع. افتراضياً هو 2. لقد قمت بتغيير الرقم الافتراضي ، يمكنك اختيار أي رقم آخر.
يجب تغيير إعدادات الفولتميتر لقياس جهد تزويد البطارية:
// , const float r1 = 100400; // 100K const float r2 = 9960; // 10K // // http://localhost/arduino-secret-true-voltmeter/ const float typVbg = 1.082; // 1.0 -- 1.2
لتوفير الطاقة ، يتم استخدام مكتبة الطاقة المنخفضة الوزن لـ Arduino .
فيما يلي قياسات الاستهلاك الفعلية لـ Arduino Pro Mini مع هذا المخرج:
- عادة 25mA
- عند العمل مع DHT نفسه
- مع الإرسال اللاسلكي 38 مللي أمبير
- في LowPower.idle 15 مللي أمبير
- في LowPower.powerdown 7.5 مللي أمبير
يأخذ العميل قياسات درجة الحرارة والرطوبة وجهد الإمداد ، ويجمع كل هذا في بنية بيانات ، ويرسل البيانات إلى الخادم و "ينام". إذا حدثت أخطاء أثناء النقل ، يتم تكرار النقل على الفور.
الخادم (مركزي ، وحدة منزلية) ، بدوره ، يتلقى البيانات ويؤكد الاستلام ويعالجها.
قاعدة بيانات ، MySQL ، PHP ، خادم WWW
بعد العمل ، لدينا تصميم وظيفي بالكامل لمحطة الطقس. ولكن الآن هناك عشرة سنتات من محطات الطقس ، لم تعد الحرف المحلية موضة. بعد كل شيء ، لدينا إنترنت الأشياء.
لذلك ، سنتحدث عن كيفية تنفيذ الوصول إلى الإنترنت الخاص بك ، وسنقوم بإرفاق قاعدة بيانات ووجه ويب بها إلى محطة الطقس الخاصة بنا.
بيان مشكلة "كاميرا الويب":
- استقبال وتخزين بيانات محطة الطقس: درجة الحرارة والرطوبة والضغط الجوي والجهد الكهربائي
- عرض هذه البيانات
- بناء الرسوم البيانية.
في هذه الحالة ، نحتاج إلى استضافة مع دعم Apache و PHP و MySQL مع وحدة mysqli. وتفي هذه الشروط بأي استضافة تقريبًا على كوكب الأرض. أو بدلاً من الاستضافة ، سيكون هناك جهاز كمبيوتر يلعب دور خادم متصل بجهاز توجيه شبكة منزلية والحصول على اتصال بالإنترنت.
إنشاء قاعدة بيانات
لنبدأ من البداية ، وبالتحديد بتصميم وإنشاء قاعدة البيانات.
قواعد البيانات هي عالمك ويمكنك دراستها لفترة طويلة ، لذلك سنتناول لفترة وجيزة فقط تلك الأشياء التي نحتاجها بشكل مباشر.
جميع سكربتات SQL موجودة في دليل weather-station/server/php-sql/
أين يبدأ تصميم قاعدة البيانات؟ مع تمثيل منطقي ومادي.
العرض المنطقي أو مخطط قاعدة البيانات:
- جدول درجة الحرارة والرطوبة DHT
- جدول بيانات استشعار الضغط ودرجة الحرارة BMP
- لا تحتوي الجداول المشار إليها على أي علاقات مع بعضها البعض ، وبشكل أدق ، لا حاجة إلى روابط.
يعتمد المخطط المادي على DBMS وأنواع بيانات محددة. من الأسهل التفكيك بمثال محدد. make_tables.sql
البرنامج النصي make_tables.sql
SQL المخططات المنطقية والمادية.
يجب أن يحتوي كل جدول على حقل نوع
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT
قد يختلف اسم الحقل في قواعد البيانات المختلفة ، ولكن هناك إحساس واحد فقط - هذا معرف فريد ، مفتاح تسجيل. بالنسبة للمستقبل ، إذا رأيت قاعدة بيانات في جداول لا تحتوي على مثل هذا العداد ، فيجب أن تعرف أن قاعدة البيانات هذه تم تصميمها من قبل شخص بعيد جدًا عن البرمجة ، وعلى الأرجح العلوم الإنسانية.
نقوم بتخزين البيانات من أجهزة الاستشعار من نفس النوع في جدول واحد ؛ لأجهزة الاستشعار من نوع آخر ، نقوم بإنشاء جدول آخر. هذا يعقد بشكل طفيف قاعدة البيانات وربط PHP بها ، ولكنه يبسط تمديد أو تعديل النظام بأكمله في المستقبل.
هناك جدولين في مشروعنا. يقوم جدول arduino_dht
بتخزين البيانات من أجهزة الاستشعار من نوع DHT (درجة الحرارة والرطوبة) ، arduino_bmp
جدول arduino_bmp
بتخزين البيانات من أجهزة الاستشعار من نوع BMP (درجة الحرارة والضغط). إذا كنت تريد في المستقبل أن يكون لديك ، على سبيل المثال ، مستشعر غاز أو كاشف حركة ، فقم بإنشاء جداول إضافية ، لا تكن كسولًا. إذا قمت بتوصيل مستشعر آخر من نوع DHT11 أو DHT22 ، فلن تحتاج إلى إنشاء جدول إضافي ، استخدم جدول arduino_dht
. آمل أن يكون المبدأ واضحًا: الكيان المادي المنفصل هو جدول منفصل.
إذا تم تخزين البيانات من العديد من أجهزة الاستشعار من نفس النوع في جدول ، فكيف يمكن تمييزها؟ للقيام بذلك ، أدخل حقلاً في كل جدول
idSensor INTEGER
في الواقع ، هذا هو CLIENT_ADDRESS
الذي قمنا بتسجيله في client/client.ino
لكل مثيل للعميل العميل البعيد وفي server/server.ino
المتصل مباشرةً بالخادم - الوحدة المركزية.
في الأنظمة الصناعية ، يجب أن يكون هناك جدول آخر - مراسلات idSensor
اللفظي idSensor
للقراءة البشرية. على سبيل المثال ، جهاز استشعار مع idSensor
= 2 هو "درجة الحرارة والرطوبة في الشقة" ، إلخ. لكن في مشروعنا لن نتعقد ، فقط تذكر أن:
- جهاز استشعار مع
idSensor
، فهو CLIENT_ADDRESS
، يساوي 11 - هذا هو جهاز استشعار المنزل على الخادم - الوحدة المركزية ، - جهاز استشعار مع
idSensor
، فهو أيضًا CLIENT_ADDRESS
، يساوي 20 - هذا هو أول عميل مستشعر يستند إلى النافذة (في مشروعنا والوحيد).
التالي. تخزن الجداول البيانات التالية:
- ipRemote - عنوان IP لمحطة الطقس (الخادم) التي جاءت البيانات منها ، وهو مفيد في التصحيح والمراقبة ،
- dateCreate - تاريخ وقت إنشاء السجل ،
- مللي - مفيد لتصحيح الأخطاء ، هذا هو الوقت بالمللي ثانية منذ بداية الرسم على اردوينو ،
- درجة حرارة - درجة حرارة
- رطوبة - رطوبة
- الجهد - جهد الإمداد ،
- ضغط - ضغط
- الأخطاء - عدد الأخطاء (غير مستخدم). كان الغرض منه تخزين عدد أخطاء الإرسال ، وما إلى ذلك ، حتى تتمكن من تقييم حالة النظام بأكمله عن بُعد.
كما ترى ، فإن arduino_dht
و arduino_bmp
للغاية ، والفرق هو فقط في مجالات الضغط والرطوبة ، وهناك رغبة في إلقاء كل شيء في كومة واحدة (جدول). لكن النموذج العادي الأول لا يأمر بذلك ، حاول العديد من المبرمجين المبتدئين الالتفاف عليه ، لكن لم ينجح أي منهم ، ولن ننجح. هذه هي الطريقة التي لا تلاحظ قانون الجاذبية الكونية ، في الوقت الحاضر قد يتحول.
جدول arduino_error_log
مفيد للتصحيح - إنه سجل الأخطاء ورسائل النظام الأخرى.
يوصف إنشاء قاعدة بيانات make_db.sql
بحقوق في make_db.sql
يتم ذلك مرة واحدة ، يمكن أن يأتي اسم قاعدة البيانات واسم المستخدم الخاص بك. وما يجب فعله بالضبط هو تعيين كلمة المرور الخاصة بك.
PHP وخادم الويب
يتم تخزين جميع إعدادات واجهة الويب في config.php
. تعديله وفقا لإعدادات قاعدة البيانات الخاصة بك.
اضبط منطقتك الزمنية بتنسيق PHP
date_default_timezone_set('Europe/Prague')
جميع المناطق الزمنية المتاحة موصوفة هنا .
قم بتعيين مفتاحك السري للوصول (كرقم) الذي يجب أن يتطابق مع SOURCE_KEY
الثابت من SOURCE_KEY
الرسم SOURCE_KEY
$access_key = '***KEY***';
في خادم الويب الخاص بنا لا يوجد إذن ، إدخال كلمة مرور ، وهذا من شأنه أن يعقد التصميم بأكمله. بالنسبة للنموذج الأولي ، هذا ليس ضروريًا. لذلك ، فإن كل الحماية مبنية على robots.txt
، وغياب index.php
ومفتاح السر هذا للوصول.
يقبل weather.php
النصي PHP الرئيسي طلب HTTP GET بسيط مع البيانات ويخزنه في جداول قاعدة البيانات المقابلة. إذا لم يتطابق المفتاح $access_key
، فسيتم رفض الطلب.
weather-view.php
استخدام weather-view.php
لعرض جداول البيانات ويحتوي على روابط تشعبية إلى نصوص برمجية أخرى لواجهة الويب. اتصل به على هذا النحو
http:
على سبيل المثال
http:
يعرض weather-view.php
تصنيفات بسيطة تحتاج فيها إلى تذكر ما يلي:
- المستشعر ذو المعرف 11 هو المستشعر المنزلي على الخادم ،
- المستشعر ذو المعرف 20 هو مستشعر النافذة.
يحتوي البرنامج النصي function.php
على وظائف مشتركة بين جميع نصوص PHP.
chart-dht.php
هي المسؤولة عن الرسوم البيانية باستخدام مخططات جوجل . هنا ، على سبيل المثال ، رسم بياني لجهد الإمداد لجهاز الاستشعار في الخارج. يرتفع الجهد في يوم مشمس بسبب البطارية الشمسية ، ثم يتم تفريغ مصدر الطاقة على البطاريات تدريجيًا.

export-dht.php
البيانات من جداول قاعدة بيانات MySQL إلى ملف CSV. لمزيد من الاستيراد والتحليل في جداول البيانات.
export-voltage.php
بيانات عن جهد الإمداد من مستشعر النافذة من قاعدة بيانات MySQL إلى ملف CSV. مفيد لتصحيح الأخطاء.
truncate.php
يمسح جميع الجداول ، أي يحذف جميع بياناتنا. مفيد لتصحيح الأخطاء. لا توجد روابط لهذا النص البرمجي من weather-view.php
، لذلك تحتاج إلى الاتصال به عبر رابط مباشر في شريط عنوان المتصفح الخاص بك مع $access_key
.
عند استقبال البيانات ، mysqli_real_escape_string()
الوظيفة mysqli_real_escape_string()
بشكل شائع لمنع القيم غير الصحيحة من الدخول إلى قاعدة البيانات.
لا تنس وضع robots.txt
في جذر موقعك لمنعه من الدخول إلى محركات البحث.
ESP8266 ، WiFi ونقل البيانات
والآن نعود إلى رسم server.ino
، إلى الجزء الذي يتصل بنقطة وصول WiFi ويرسل البيانات إلى خادم الويب.
كما كتبت بالفعل ، لم أتمكن من العثور على مكتبة عادية لـ Arduino للتحكم في وحدة ESP8266 باستخدام أوامر AT ، كان علي "المزرعة الجماعية" بنفسي. اسمحوا لي أيضًا أن أذكرك أنه يجب عليك تشغيل إصدار محدد من البرامج الثابتة في ESP8266-01. والآن عندما يكون كل شيء جاهزًا ، دعنا نرى كيف يعمل.
للوصول إلى خادم الويب في رسم server.ino
، تحتاج إلى تغيير هذه الثوابت
const String DEST_HOST = " "; // habr.com const String DEST_PORT = " "; // 80 const String DEST_URL = "/ /weather.php"; const String SOURCE_KEY= " "; // $access_key config.php
في server.ino
في وظيفة void setup()
الفارغ void setup()
، يتم تحويل ESP8266 أولاً إلى وضع المحطة ، أي يبدأ العمل كعميل WiFi
espSendCmd(«AT+CWMODE_CUR=1», «OK», 3000)
ثم الاتصال بنقطة الوصول
espState = espConnectToWiFi()
في حالة عدم حدوث الاتصال ، يتم تكرار المحاولة (مرة واحدة)
if ( espState != ESP_SUCCESS ) { delay(5000); Serial.println("WiFi not connected! Try again ..."); espConnectToWiFi(); }
ثم حدد وضع اتصال واحد TCP / IP
espSendCmd("AT+CIPMUX=0", "OK", 2000)
عند إرسال البيانات من أجهزة استشعار من نوع DHT إلى خادم الويب ، يتم استخدام وظيفة تشير إلى type=dht
البيانات على أنها type=dht
espSendData( "type=dht&t=" + String(dhtData.temperature) + "&h=" + String(dhtData.humidity) + "&v=" + String(dhtData.voltage) + "&s=" + String(CLIENT_ADDRESS) )
عند إرسال البيانات من أجهزة استشعار BMP إلى خادم ويب ، يتم استخدام نفس الوظيفة مع نوع البيانات المشار إليه type=bmp
espSendData( "type=bmp&t=" + String(temperature_bmp) + "&p=" + String(pressure_bmp) + "&s=" + String(CLIENT_ADDRESS) )
تقبل الدالة espSendData()
سلسلة طلب HTTP GET وترسلها إلى خادم الويب على النحو المنشود.
بداخله ، يتحقق espSendData()
من توفر وحدة ESP عن طريق إرسال الأمر "AT" ، ثم يتحقق من اتصال WiFi ويعيد الاتصال إذا لزم الأمر. ثم يتم إرسال البيانات وإغلاق اتصال TCP.
تطبيق Android
في الوقت الحاضر ، عندما يتمكن الجميع من وميض LED ، لن تفاجئ أي شخص بمحطة الطقس. ولكن إذا كانت المركبة تعرف كيفية التواصل مع الخادم عبر WiFi ، ولها وجه ويب وتطبيقات هاتف محمول ، فهذا شيء! نعني بالخادم هنا بالطبع خادم التطبيق ، أي في حالتنا ، هذا ملزم PHP و MySQL DBMS. لا يوجد ما يكفي من الكرز على الكعكة ، وبالتحديد تطبيق Android ، الذي سنكتبه الآن.
العمارة
بنية منصة برنامج محطة الطقس بأكملها بسيطة:
- يقوم جزء الخادم (الوحدة المركزية) لمحطة الطقس بجمع البيانات من عملاء أجهزة الاستشعار عن بُعد
- ثم ينقل البيانات إلى خادم الويب للتطبيقات ، مما يحفظ هذه البيانات في قاعدة البيانات
- يطلب تطبيق Android (أو أي تطبيق بعيد آخر: iOS ، متصفح) بيانات من خادم ويب ويعرضها على الشاشة.
على شاشة جهاز Android ، سنعرض أحدث قراءات أجهزة الاستشعار الحالية.
HTTP GET و JSON
السؤال الذي يحتاج إلى حل في المقام الأول هو كيف سيتم نقل البيانات من خادم الويب إلى تطبيق Android.
ليست هناك حاجة لاختراع أي شيء هنا ، فقد تم اختراع كل شيء من أجلنا بالفعل - وهما HTTP GET و JSON.
في حالتنا ، يمكن تجميع طلب GET البسيط لخادم الويب وتصحيحه يدويًا بينما لا يكون تطبيق Android جاهزًا بعد.
في Java و Android ، توجد مكتبات جاهزة لمعالجة البيانات بتنسيق JSON. JSON هو تنسيق نصي يمكن للمستخدمين قراءته ، وهو مفيد في تصحيح الأخطاء.
لإنشاء بيانات حالية من مستشعرات محطة الطقس ، أنشئ نص PHP جديدًا last-data-to-json.php على خادم الويب.
استدعاء البرنامج النصي:
http://<>/last-data-to-json.php?k=<access_key>
حيث <access_key>
، كما نتذكر ، هو مفتاح الوصول إلى قاعدة البيانات السرية.
مثال للاستجابة بتنسيق JSON:
{ "DHT 11":{ "idSensor":"11", "dateCreate":"2016-04-20 18:06:03", "temperature":"19", "humidity":"26", "voltage":"5.01" }, "DHT 20":{ "idSensor":"20", "dateCreate":"2016-04-18 07:36:26", "temperature":"10", "humidity":"26", "voltage":"3.7" }, "BMP 11":{ "idSensor":"11", "dateCreate":"2016-04-20 18:06:22", "temperature":"19", "pressure":"987.97" } }
يجب أن نتذكر أن لدينا 3 أجهزة استشعار. معرفهم ونوعهم (DHT أو BMP) مشفرون في كود محطة الطقس. هذه الطريقة في الترميز المتشدد غير صحيحة أيديولوجياً ، ولكن بالنسبة لنموذج أولي مرسوم على الركبة (حيث يلزم حل سريع وسهل) ، فهذا حل وسط معقول.
$idSensor = 11; // DHT $idSensor = 11; // BMP $idSensor = 20; // DHT
يأخذ last-data-to-json.php
أحدث البيانات من هذه المستشعرات غير المتجانسة من قاعدة البيانات last-data-to-json.php
بتنسيق JSON. يتم اختيار البيانات من قاعدة البيانات "من النهاية" بهذه الطريقة:
SELECT <> FROM <> ORDER BY id DESC LIMIT 1;
Android
سنكتب الآن تطبيق Android بسيطًا يطلب بيانات JSON ويستقبلها ويفك تشفيرها ويعرض المعلومات على الشاشة.
سيكون تطبيق Android الخاص بنا بسيطًا قدر الإمكان ، فقط جوهر التكنولوجيا. أبعد من ذلك حول هذا "الهيكل العظمي" سيكون من الممكن بالفعل اختتام "الجمال" المختلفة.
فيما يلي لقطة شاشة لما يجب أن ينتج عنه

كما ترى ، فإن واجهة المستخدم هي فقط Spartan ، استنادًا إلى LinearLayout ، لا شيء أكثر من ذلك.
في الجزء العلوي من TextView يظهر معرف أجهزة الاستشعار وبيانات الأرصاد الجوية الخاصة بهم. يبدأ الزر Refresh طلبًا ثانيًا لخادم الويب. بعد ذلك في EditText هو إعداد البرنامج الوحيد - هذا هو عنوان URL للطلب في النموذج
http://< >/last-data-to-json.php?k=<access_key>
ما الذي يجب ملاحظته؟
في البيان ، أضف خطوطًا تسمح بالإنترنت والتحقق من حالة اتصال الشبكة:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
العمل مع الشبكة وتلقي البيانات من الموقع على النحو التالي.
نستخدم AsyncTask لإنشاء مهمة خلفية منفصلة عن مؤشر ترابط واجهة المستخدم الرئيسي. تأخذ مهمة الخلفية هذه عنوان URL الخاص بالطلب وتستخدمه لإنشاء HttpURLConnection
.
بعد إنشاء الاتصال ، يقوم AsyncTask بتحميل محتويات صفحة الويب (JSON) على أنها InputStream. بعد ذلك ، يتم تحويل InputStream إلى سلسلة يتم فك تشفيرها باستخدام JSONObject ويتم عرضها في واجهة المستخدم باستخدام طريقة onPostExecute()
.
في MainActivity.java ، قم بتغيير عنوان URL إلى:
private static final String defUrl = "http://host/dir/last-data-to-json.php?k=< >";
سيتم استخدامه بشكل افتراضي في المرة الأولى التي تقوم فيها بتشغيل تطبيق Android.
الخاتمة
حسنا ، لقد نجح شيء ما بالفعل. ثم يمكنك تحسين شيء ما ، واستبدال شيء ما ، يمكنك التخلص من كل شيء ، ولكن أيضًا استعارة شيء ما.
نقطة استهلاك كبيرة منفصلة هي استهلاك الطاقة . أوصي بقراءة التعليقات على المنشورات حيث يوجد العديد من النصائح العملية.
إلى ما لا نهاية ... وما بعدها.