جدول المحتويات:

سهولة إنترنت الأشياء: التقاط بيانات الطقس عن بُعد: الأشعة فوق البنفسجية ودرجة حرارة الهواء والرطوبة: 7 خطوات
سهولة إنترنت الأشياء: التقاط بيانات الطقس عن بُعد: الأشعة فوق البنفسجية ودرجة حرارة الهواء والرطوبة: 7 خطوات

فيديو: سهولة إنترنت الأشياء: التقاط بيانات الطقس عن بُعد: الأشعة فوق البنفسجية ودرجة حرارة الهواء والرطوبة: 7 خطوات

فيديو: سهولة إنترنت الأشياء: التقاط بيانات الطقس عن بُعد: الأشعة فوق البنفسجية ودرجة حرارة الهواء والرطوبة: 7 خطوات
فيديو: الإمكانات التقنية ليس لها حدود، انظر بنفسك 2024, يوليو
Anonim
سهولة إنترنت الأشياء: التقاط بيانات الطقس عن بُعد: الأشعة فوق البنفسجية ودرجة حرارة الهواء والرطوبة
سهولة إنترنت الأشياء: التقاط بيانات الطقس عن بُعد: الأشعة فوق البنفسجية ودرجة حرارة الهواء والرطوبة

في هذا البرنامج التعليمي ، سنلتقط البيانات البعيدة مثل الأشعة فوق البنفسجية (الأشعة فوق البنفسجية) ودرجة حرارة الهواء والرطوبة. ستكون هذه البيانات مهمة للغاية وسيتم استخدامها في محطة طقس كاملة في المستقبل.

يوضح مخطط الكتلة ما سنحصل عليه في النهاية.

صورة
صورة

الخطوة 1: BoM - فاتورة المواد

NodeMCU (ESP8266-12E) - 9.00 دولارًا أمريكيًا

مستشعر الرطوبة ودرجة الحرارة (DHT22) - 10.00 دولار أمريكي

مستشعر الأشعة فوق البنفسجية - 4.00 دولار أمريكي

OLED 12.00 دولار أمريكي

اللوح - 1.00 دولار أمريكي

الخطوة الثانية: مستشعر الأشعة فوق البنفسجية التناظري

جهاز استشعار الأشعة فوق البنفسجية
جهاز استشعار الأشعة فوق البنفسجية
جهاز استشعار الأشعة فوق البنفسجية
جهاز استشعار الأشعة فوق البنفسجية
جهاز استشعار الأشعة فوق البنفسجية
جهاز استشعار الأشعة فوق البنفسجية

يولد مستشعر الأشعة فوق البنفسجية هذا ناتجًا تناظريًا يتناسب مع الأشعة فوق البنفسجية الموجودة في طيف استشعار الضوء. يستخدم الثنائي الضوئي للأشعة فوق البنفسجية (استنادًا إلى نيتريد الغاليوم) ، والذي يمكنه اكتشاف نطاق 240-370 نانومتر من الضوء (الذي يغطي UVB ومعظم طيف UVA). يكون مستوى الإشارة من الثنائي الضوئي صغيرًا جدًا ، في مستوى النانو أمبير ، لذلك تحتوي الوحدة على مضخم تشغيلي لتضخيم الإشارة إلى مستوى فولت أكثر قابلية للقراءة (0 إلى 1 فولت).

يمكن تشغيل المستشعر و op-amp ، عن طريق توصيل VCC بـ 3.3VDC (أو 5VDC) و GND بأرضية الطاقة. يمكن الحصول على الإشارة التناظرية من دبوس OUT.

سيكون ناتجها بالميليفولت وستتم قراءته بواسطة الإدخال التناظري لـ NodeMCU الخاص بنا. بمجرد القراءة ، يجب علينا "تحويل" (أو "تعيين") للقيم ليتم التعامل معها بشكل أفضل من خلال الشفرة. يمكننا القيام بذلك باستخدام الوظيفة readSensorUV ():

/ * اقرأ مستشعر الأشعة فوق البنفسجية بالسيارات واستدعاء حساب مؤشر الأشعة فوق البنفسجية * /

readSensorUV () باطل {بايت numOfReadings = 5 ؛ dataSensorUV = 0 ؛ لـ (int i = 0 ؛ i <numOfReadings ؛ i ++) {dataSensorUV + = analogRead (sensorUVPin) ؛ تأخير (200) ؛ } dataSensorUV / = numOfReadings ؛ dataSensorUV = (dataSensorUV * (3.3 / 1023.0)) * 1000 ؛ Serial.println (dataSensorUV) ؛ indexCalculate () ، }

بمجرد حصولنا على بيانات الأشعة فوق البنفسجية ، يمكننا بسهولة حساب مؤشر الأشعة فوق البنفسجية كما هو محدد في الجدول أعلاه. دالة indexCalculate () ستفعل ذلك لنا:

/ * حساب مؤشر الأشعة فوق البنفسجية * /

indexCalculate () باطل {if (dataSensorUV <227) indexUV = 0 ؛ وإلا إذا كان (227 <= dataSensorUV && dataSensorUV <318) indexUV = 1 ؛ وإلا إذا كان (318 <= dataSensorUV && dataSensorUV <408) indexUV = 2 ؛ وإلا إذا كان (408 <= dataSensorUV && dataSensorUV <503) indexUV = 3 ؛ وإلا إذا كان (503 <= dataSensorUV && dataSensorUV <606) indexUV = 4 ؛ وإلا إذا كان (606 <= dataSensorUV && dataSensorUV <696) indexUV = 5 ؛ وإلا إذا كان (696 <= dataSensorUV && dataSensorUV <795) indexUV = 6 ؛ وإلا إذا كان (795 <= dataSensorUV && dataSensorUV <881) indexUV = 7 ؛ وإلا إذا كان (881 <= dataSensorUV && dataSensorUV <976) indexUV = 8 ؛ وإلا إذا كان (976 <= dataSensorUV && dataSensorUV <1079) indexUV = 9 ؛ وإلا إذا كان (1079 <= dataSensorUV && dataSensorUV <1170) indexUV = 10 ؛ آخر indexUV = 11 ؛ }

الخطوة 3: تثبيت شاشة: OLED

تركيب شاشة: OLED
تركيب شاشة: OLED
تركيب شاشة: OLED
تركيب شاشة: OLED

لأغراض الاختبار ، سنقوم بتضمين OLED على مقياس الأشعة فوق البنفسجية لدينا (هذه الخطوة اختيارية تمامًا).

من المقبول استخدام Serial Monitor أثناء الاختبارات ، ولكن ماذا يحدث عندما تستخدم نماذجك الأولية بعيدًا عن جهاز الكمبيوتر الخاص بك في وضع مستقل؟ لذلك ، دعنا نثبِّت شاشة OLED ، SSD1306 ، وهي الخصائص الرئيسية:

  • حجم العرض: 0.96"
  • I2C IIC SPI المسلسل
  • 128 × 64
  • شاشة OLED LCD بيضاء

اتبع الرسم التخطيطي الكهربائي وقم بتوصيل 4 دبابيس من OLED الخاص بنا:

  • يذهب VCC إلى 3.3V
  • يذهب GND إلى الأرض
  • ينتقل SCL إلى NodeMCU (GPIO 2) ==> D4
  • تنتقل SDA إلى NodeMCU (GPIO 0) ==> D3

بمجرد توصيل الشاشة ، فلنقم بتنزيل وتثبيت مكتبتها على Arduino IDE: "ESP8266 OLED Driver لشاشة SSD1306" التي طورها Daniel Eichhorn (تأكد من أنك تستخدم الإصدار 3.0.0 أو أكبر!).

قم بتثبيت المكتبة على Arduino IDE الخاص بك ، والذي يمكن العثور عليه على SSD1306Wire.h

بمجرد إعادة تشغيل IDE ، يجب أن تكون المكتبة مثبتة بالفعل.

تدعم المكتبة بروتوكول I2C للوصول إلى شاشة OLED باستخدام مكتبة Wire.h المدمجة:

/ * OLED * /

# تضمين "SSD1306Wire.h" # تضمين "Wire.h" const int I2C_DISPLAY_ADDRESS = 0x3c ؛ const int SDA_PIN = 0 ؛ const int SCL_PIN = 2 ؛ عرض SSD1306Wire (I2C_DISPLAY_ADDRESS ، SDA_PIN ، SCL_PIN) ؛

دعنا ندرج بعض واجهات برمجة التطبيقات المهمة التي سيتم استخدامها مع شاشة OLED الخاصة بنا. يمكن العثور على القائمة الكاملة في GITHub الموضح أعلاه.

أ. التحكم في العرض:

الحرف الأول الباطل () ؛ // تهيئة الشاشة

عرض باطل (باطل) ؛ // قم بتشغيل العرض على شاشة باطلة (باطل) ؛ // قم بإيقاف تشغيل الشاشة باطل (باطل) ؛ // امسح فراغ المخزن المؤقت للبكسل المحلي flipScreenVertically () ؛ // اقلب الشاشة رأسًا على عقب

ب. عمليات النص:

drawString باطلة (int16_t x، int16_t y، String text) ؛ // (xpos، ypos، "Text")

setFont باطلة (const char * fontData) ؛ // يعين الخط الحالي.

الخطوط الافتراضية المتوفرة:

  • ArialMT_Plain_10 ،
  • ArialMT_Plain_16 ،

  • ArialMT_Plain_24

بمجرد تثبيت كل من OLED نفسها ومكتبتها ، دعنا نكتب برنامجًا بسيطًا لاختباره. أدخل الكود أدناه على IDE الخاص بك ، يجب أن تكون النتيجة عرضًا كما هو موضح في الصورة أعلاه:

* OLED * /

# تضمين "SSD1306Wire.h" # تضمين "Wire.h" const int I2C_DISPLAY_ADDRESS = 0x3c ؛ const int SDA_PIN = 0 ؛ const int SCL_PIN = 2 ؛ عرض SSD1306Wire (I2C_DISPLAY_ADDRESS ، SDA_PIN ، SCL_PIN) ؛ إعداد باطل () {Serial.begin (115200) ؛ إعداد الشاشة()؛ } void loop () {} / * بدء وعرض بيانات الإعداد على OLED * / void displaySetup () {display.init () ؛ // تهيئة شاشة العرض. clear () ؛ // مسح شاشة العرض. FlipScreenVertically () ؛ // اقلب الشاشة رأسًا على عقب. // ضع البيانات على الشاشة Serial.println ("بدء اختبار العرض") ؛ display.setFont (ArialMT_Plain_24) ، display.drawString (30، 0، "OLED") ؛ // (xpos، ypos، "Text") display.setFont (ArialMT_Plain_16) ؛ display.drawString (18 ، 29 ، "بدأ الاختبار") ؛ display.setFont (ArialMT_Plain_10) ، display.drawString (10، 52، "Serial BaudRate:")؛ display.drawString (90، 52، String (11500)) ؛ display.display () ، // ضع البيانات على تأخير العرض (3000) ؛ }

يمكن تنزيل البرنامج أعلاه من جيثب الخاص بي:

NodeMCU_OLED_Test

الخطوة 4: مقياس الأشعة فوق البنفسجية المحلي

مقياس الأشعة فوق البنفسجية المحلي
مقياس الأشعة فوق البنفسجية المحلي
مقياس الأشعة فوق البنفسجية المحلي
مقياس الأشعة فوق البنفسجية المحلي

الآن ، بعد تثبيت شاشة OLED ، يمكننا توصيل بطارية وإجراء بعض الاختبارات عن بُعد باستخدام "مقياس الأشعة فوق البنفسجية" الخاص بنا

#define SW_VERSION "UV_Sensor_V.1"

/ * مستشعر الأشعة فوق البنفسجية * / # مستشعر تعريف UVPin A0 int dataSensorUV = 0 ؛ مؤشر int indexUV = 0 ؛ / * OLED * / # تضمين "SSD1306Wire.h" # تضمين "Wire.h" const int I2C_DISPLAY_ADDRESS = 0x3c ؛ const int SDA_PIN = 0 ؛ const int SCL_PIN = 2 ؛ عرض SSD1306Wire (I2C_DISPLAY_ADDRESS ، SDA_PIN ، SCL_PIN) ؛ إعداد باطل () {Serial.begin (115200) ؛ إعداد الشاشة()؛ } حلقة فارغة () {readSensorUV () ؛ displayUV () ، تأخير (1000) ؛ } / * بدء وعرض بيانات الإعداد على OLED * / void displaySetup () {display.init () ؛ // تهيئة شاشة العرض. clear () ؛ // مسح شاشة العرض. FlipScreenVertically () ؛ // اقلب الشاشة رأسًا على عقب. // ضع البيانات على الشاشة Serial.println ("بدء اختبار مستشعر الأشعة فوق البنفسجية") ؛ display.setFont (ArialMT_Plain_24) ، display.drawString (10، 0، "MJRoBot") ؛ display.setFont (ArialMT_Plain_16) ، display.drawString (0، 29، "UV Sensor Test")؛ display.setFont (ArialMT_Plain_10) ، display.drawString (0، 52، "SW Ver.:")؛ display.drawString (45، 52، SW_VERSION) ؛ display.display () ، تأخير (3000) ؛ } / * اقرأ مستشعر الأشعة فوق البنفسجية بالسيارات واستدعاء حساب مؤشر الأشعة فوق البنفسجية * / باطل readSensorUV () {byte numOfReadings = 5 ؛ dataSensorUV = 0 ؛ لـ (int i = 0 ؛ i <numOfReadings ؛ i ++) {dataSensorUV + = analogRead (sensorUVPin) ؛ تأخير (200) ؛ } dataSensorUV / = numOfReadings ؛ dataSensorUV = (dataSensorUV * (3.3 / 1023.0)) * 1000 ؛ Serial.println (dataSensorUV) ؛ indexCalculate () ، } / * حساب مؤشر UV * / void indexCalculate () {if (dataSensorUV <227) indexUV = 0 ؛ وإلا إذا كان (227 <= dataSensorUV && dataSensorUV <318) indexUV = 1 ؛ وإلا إذا كان (318 <= dataSensorUV && dataSensorUV <408) indexUV = 2 ؛ وإلا إذا كان (408 <= dataSensorUV && dataSensorUV <503) indexUV = 3 ؛ وإلا إذا كان (503 <= dataSensorUV && dataSensorUV <606) indexUV = 4 ؛ وإلا إذا كان (606 <= dataSensorUV && dataSensorUV <696) indexUV = 5 ؛ وإلا إذا كان (696 <= dataSensorUV && dataSensorUV <795) indexUV = 6 ؛ وإلا إذا كان (795 <= dataSensorUV && dataSensorUV <881) indexUV = 7 ؛ وإلا إذا كان (881 <= dataSensorUV && dataSensorUV <976) indexUV = 8 ؛ وإلا إذا كان (976 <= dataSensorUV && dataSensorUV <1079) indexUV = 9 ؛ وإلا إذا كان (1079 <= dataSensorUV && dataSensorUV <1170) indexUV = 10 ؛ آخر indexUV = 11 ؛ } / * عرض قيم الأشعة فوق البنفسجية على OLED المحلي * / void displayUV () {display.clear ()؛ display.setFont (ArialMT_Plain_16) ، display.drawString (20، 0، "UV Sensor")؛ display.drawString (0، 23، "UV (mV):")؛ display.drawString (80، 23، String (dataSensorUV)) ؛ display.drawString (0، 48، "مؤشر الأشعة فوق البنفسجية:") ؛ display.setFont (ArialMT_Plain_24) ، display.drawString (82، 42، String (indexUV)) ؛ display.display () ، }

يمكن تنزيل الكود أعلاه من GitHun الخاص بي: NodeMCU_UV_Sensor_OLED.ino

الخطوة 5: تركيب DHT22 لقياس درجة حرارة الهواء والرطوبة

تركيب DHT22 لقياس درجة حرارة الهواء والرطوبة
تركيب DHT22 لقياس درجة حرارة الهواء والرطوبة
تركيب DHT22 لقياس درجة حرارة الهواء والرطوبة
تركيب DHT22 لقياس درجة حرارة الهواء والرطوبة

يعد DHT22 (أو شقيقه DHT11) أحد أكثر أجهزة الاستشعار استخدامًا لالتقاط بيانات الطقس ، وهو مستشعر رقمي للرطوبة النسبية ودرجة الحرارة. يستخدم مستشعر رطوبة بالسعة وثرمستور لقياس الهواء المحيط ويبث إشارة رقمية على دبوس البيانات (لا حاجة إلى دبابيس إدخال تمثيلية).

يجب أن يتم تشغيل المستشعر بين 3.3 فولت و 5 فولت وسيعمل من -40 درجة مئوية إلى +80 درجة مئوية بدقة +/- 0.5 درجة مئوية لدرجة الحرارة و +/- 2٪ للرطوبة النسبية. من المهم أيضًا أن تضع في اعتبارك أن فترة الاستشعار هي في المتوسط 2 ثانية (الحد الأدنى من الوقت بين القراءات). يوفر موقع Adafruit الكثير من المعلومات حول كل من DHT22 وشقيقه DHT11. لمزيد من التفاصيل ، يرجى زيارة صفحة البرنامج التعليمي DHT22 / 11.

يحتوي DHT22 على 4 دبابيس (التي تواجه المستشعر ، والدبوس 1 هو أقصى اليسار):

  1. VCC (سنقوم بالاتصال بـ 3.3 فولت من NodeMCU) ؛
  2. البيانات خارج ؛
  3. غير متصل و
  4. أرضي.

بمجرد أن تستخدم المستشعر عادةً على مسافات أقل من 20 مترًا ، يجب توصيل المقاوم 10K بين دبابيس Data و VCC. سيتم توصيل دبوس الإخراج بـ NodeMCU pin D3 (انظر الرسم البياني أعلاه). بمجرد تثبيت المستشعر في وحدتنا ، قم بتنزيل مكتبة DHT من مستودع Adafruit GitHub وقم بتثبيتها في ملف مكتبة Arduino. بمجرد إعادة تحميل Arduino IDE الخاص بك ، يجب تثبيت "مكتبة مستشعر DHT".

في بداية الكود ، يجب تضمين الأسطر:

/ * DHT22 * /

# تضمين "DHT.h" # تعريف DHTPIN D2 # تعريف DHTTYPE DHT22 DHT dht (DHTPIN ، DHTTYPE) ؛ همهمة عائمة = 0 ؛ درجة حرارة تعويم = 0 ؛

سيتم إنشاء وظيفة جديدة لقراءة المستشعر:

/ * الحصول على بيانات DHT * /

getDhtData باطل (باطل) {float tempIni = temp؛ تعويم humIni = همهمة ؛ temp = dht.readTemperature () ؛ الرطوبة = dht.readHumidity () ؛ if (isnan (hum) || isnan (temp)) // تحقق مما إذا كانت أي قراءات قد فشلت والخروج مبكرًا (للمحاولة مرة أخرى). {Serial.println ("فشل القراءة من مستشعر DHT!") ؛ temp = tempIni ؛ همهمة = humIni ؛ إرجاع؛ }}

يمكن تنزيل الكود الكامل بما في ذلك مستشعرات UV و DHT من GitHub: NodeMCU_UV_DHT_Sensor_OLED

الخطوة 6: إرسال البيانات إلى ThingSpeak.com

إرسال البيانات إلى ThingSpeak.com
إرسال البيانات إلى ThingSpeak.com
إرسال البيانات إلى ThingSpeak.com
إرسال البيانات إلى ThingSpeak.com
إرسال البيانات إلى ThingSpeak.com
إرسال البيانات إلى ThingSpeak.com

حتى الآن ، استخدمنا NodeMCU ESP12-E فقط كلوحة Arduino عادية وعادية. بالطبع ، لقد "خدشنا" فقط الإمكانات الحقيقية لهذه الشريحة الصغيرة المذهلة والآن حان وقت الانطلاق إلى الجنة! أو أفضل للنجوم! إيه … إلى السحابة! ؛-)

هيا نبدأ!

  1. أولاً ، يجب أن يكون لديك حساب في ThinkSpeak.com
  2. اتبع التعليمات لإنشاء قناة ولاحظ معرف القناة ومفتاح واجهة برمجة التطبيقات للكتابة
  3. قم بتحديث الكود أدناه بشبكة WiFi وبيانات اعتماد Thinkspeak
  4. قم بتشغيل البرنامج على IDE

دعونا نعلق على أجزاء الكود الأكثر أهمية:

أولاً ، دعنا نتصل بمكتبة ESP8266 ، ونحدد عميل WiFi ، ونحدد بيانات اعتماد جهاز التوجيه المحلي و Thinkspeak:

/ * ESP12-E و Thinkspeak * /

# تضمين عميل WiFiClient ؛ const char * MY_SSID = "معرّف SSD الخاص بك هنا" ؛ const char * MY_PWD = "كلمة مرورك هنا" ؛ const char * TS_SERVER = "api.thingspeak.com" ؛ String TS_API_KEY = "مفتاح واجهة برمجة تطبيقات CHANNEL WRITE" ؛

ثانيًا ، لنقم بتضمين مكتبة مهمة جدًا لمشاريع إنترنت الأشياء: SimpleTimer.h:

/ * TIMER * /

# تضمين مؤقت SimpleTimer ؛

ثالثًا ، أثناء الإعداد () ، سنبدأ الاتصال التسلسلي ، واستدعاء الوظيفة connectWiFi () وتحديد المؤقتات. لاحظ أن سطر التعليمات البرمجية: timer.setInterval (60000L، sendDataTS)؛ سوف تستدعي الوظيفة sendDataTS () كل 60 ثانية ، من أجل تحميل البيانات إلى قناة ThinkSpeak.

الإعداد باطل()

{… Serial.begin (115200) ، تأخير (10) ؛ … connectWifi () ؛ timer.setInterval (60000L، sendDataTS) ، …}

أخيرًا وليس آخرًا ، أثناء الحلقة () ، الأمر الوحيد المطلوب هو بدء المؤقت وهذا كل شيء!

حلقة فارغة()

{… timer.run () ، // يبدأ SimpleTimer}

أدناه ، يمكنك رؤية الوظيفتين المهمتين المستخدمتين للتعامل مع اتصالات Thinkspeak:

اتصال ESP12-E بشبكة WiFi الخاصة بك:

/***************************************************

* توصيل WiFi ************************************************* *** / void connectWifi () {Serial.print ("Connecting to" + * MY_SSID) ؛ WiFi.begin (MY_SSID ، MY_PWD) ؛ while (WiFi.status ()! = WL_CONNECTED) {delay (1000) ؛ Serial.print (".") ؛ } Serial.println ("") ؛ Serial.println ("WiFi متصل") ؛ Serial.println ("") ؛ }

إرسال البيانات ESP12-E إلى ThinkSpeak:

/***************************************************

* إرسال البيانات إلى قناة Thinkspeak ********************************************** ****** / void sendDataTS (باطل) {if (client.connect (TS_SERVER، 80)) {String postStr = TS_API_KEY؛ postStr + = "& field1 ="؛ postStr + = String (dataSensorUV) ؛ postStr + = "& field2 ="؛ postStr + = سلسلة (indexUV) ؛ postStr + = "& field3 =" ؛ postStr + = سلسلة (درجة الحرارة) ؛ postStr + = "& field4 =" ؛ postStr + = سلسلة (همهمة) ؛ postStr + = "\ r / n / r / n"؛ client.print ("POST / update HTTP / 1.1 / n") ؛ client.print ("المضيف: api.thingspeak.com / n") ؛ client.print ("الاتصال: إغلاق / n") ؛ client.print ("X-THINGSPEAKAPIKEY:" + TS_API_KEY + "\ n") ؛ client.print ("نوع المحتوى: application / x-www-form-urlencoded / n") ؛ client.print ("طول المحتوى:") ؛ client.print (postStr.length ()) ؛ client.print ("\ n / n") ؛ client.print (postStr) ؛ تأخير (1000) ؛ } أرسلت ++ ؛ client.stop () ؛ }

يمكن العثور على الكود الكامل على جيثب الخاص بي: NodeMCU_UV_DHT_Sensor_OLED_TS_EXT

بمجرد تحميل الرمز إلى NodeMCU الخاص بك. لنقم بتوصيل بطارية خارجية وإجراء بعض القياسات تحت أشعة الشمس. وضعت محطة التحكم عن بعد على السطح وبدأت في التقاط البيانات على موقع ThingSpeak.com كما هو موضح في الصور أعلاه.

الخطوة 7: الخاتمة

استنتاج
استنتاج

كما هو الحال دائمًا ، آمل أن يساعد هذا المشروع الآخرين في العثور على طريقهم إلى عالم الإلكترونيات المثير!

للحصول على التفاصيل والرمز النهائي ، يرجى زيارة مستودع GitHub الخاص بي: RPi-NodeMCU-Weather-Station

لمزيد من المشاريع ، يرجى زيارة مدونتي: MJRoBot.org

ابقوا متابعين! البرنامج التعليمي التالي سنرسل البيانات من محطة طقس بعيدة إلى محطة مركزية ، بناءً على خادم ويب Raspberry Pi:

صورة
صورة

Saludos من جنوب العالم!

نراكم في بلدي التعليمات القادمة!

شكرا لك،

مارسيلو

موصى به: