السبت، 20 نوفمبر 2021

مراقبة مستويات ثاني أكسيد الكربون والتحكم في تدفق الهواء باستخدام محطة Wio

 يراقب هذا الجهاز مستوى ثاني أكسيد الكربون في غرفة المعيشة أو غرفة النوم ويتحكم في مروحة تهوية لتحسين تدفق الهواء.



الأشياء المستخدمة في هذا المشروع
مكون الأجهزة

Wio Terminal: ATSAMD51 Core with Realtek
seeed grove relay
Seeed Grove - مستشعر ثاني أكسيد الكربون ودرجة الحرارة والرطوبة - SCD41
Generic مروحة تعمل بالطاقة USB
أسلاك العبور (عامة)

قصة
ملخص
ثاني أكسيد الكربون (CO2) هو رابع أكثر الغازات وفرة في الغلاف الجوي للأرض. يعتبر ثاني أكسيد الكربون نتيجة ثانوية لوظيفة الخلية الطبيعية عندما يتم استنشاقه خارج الجسم. كما يتم إنتاجه عند حرق الوقود الأحفوري أو تحلل الغطاء النباتي. يمكن أن تحتوي التربة السطحية في بعض الأحيان على تركيزات عالية من هذا الغاز ، من النباتات المتحللة أو التغيرات الكيميائية في الصخور الأساسية.

نقيس مستوى ثاني أكسيد الكربون بوحدات جزء في المليون. يخبرنا هذا الرقم عن عدد أجزاء ثاني أكسيد الكربون الموجودة في مليون جزء من الهواء. على سبيل المثال ، إذا كان ثاني أكسيد الكربون يبلغ 800 جزء في المليون ، فهذا يعني أنه في مليون جزء من الهواء يوجد 800 جسيم من ثاني أكسيد الكربون.

يمكن أن ينتج عن التعرض لثاني أكسيد الكربون مجموعة متنوعة من الآثار الصحية. قد يشمل ذلك الصداع ، والدوخة ، والأرق ، والشعور بالوخز أو الوخز بالإبر ، وصعوبة التنفس ، والتعرق ، والتعب ، وزيادة معدل ضربات القلب ، وارتفاع ضغط الدم ، والغيبوبة ، والاختناق ، والتشنجات.

مستويات ثاني أكسيد الكربون في الهواء والمشاكل الصحية المحتملة هي:

400 جزء في المليون: متوسط ​​مستوى الهواء الخارجي.
400-1000 جزء في المليون: المستوى النموذجي الموجود في الأماكن المشغولة مع تبادل هواء جيد.
1000-2000 جزء في المليون: المستوى المرتبط بشكاوى النعاس وسوء الهواء.
2000-5000 جزء في المليون: المستوى المرتبط بالصداع والنعاس والهواء الراكد ، الذي لا معنى له ، وخانق. قد يحدث أيضًا ضعف التركيز وفقدان الانتباه وزيادة معدل ضربات القلب والغثيان الطفيف.
5000 جزء في المليون: يشير هذا إلى ظروف جوية غير معتادة حيث يمكن أيضًا وجود مستويات عالية من الغازات الأخرى. يمكن أن يحدث سمية أو نقص الأكسجين. هذا هو حد التعرض المسموح به للتعرضات اليومية في مكان العمل.
40000 جزء في المليون: هذا المستوى ضار على الفور بسبب نقص الأكسجين.
في هذا المشروع ، قمت ببناء جهاز بسيط ومحمول باستخدام Seeed Wio Terminal الذي يعرض مستوى ثاني أكسيد الكربون الداخلي ودرجة الحرارة والنسبة المئوية للرطوبة النسبية على شاشة LCD الخاصة به. عندما يتم تجاوز مستوى ثاني أكسيد الكربون بقيمة حدية محددة ، يبدأ الجرس المدمج في إصدار صفير ويتم تشغيل مروحة تهوية تعمل بجهد 5 فولت عبر USB للحفاظ على استمرار الدورة وتقليل مستويات ثاني أكسيد الكربون. هذا الجهاز مفيد خاصة أثناء النوم عندما يمكن أن يرتفع مستوى ثاني أكسيد الكربون بسبب ضعف دوران الهواء ويمكن أن يؤثر على الصحة.

تم تصميم هذا المشروع وفقًا لمتطلباتي الخاصة في غرفة النوم حيث تأثر تدفق الهواء بشدة ولكن لم يكن لدي أي فكرة عنه وبعد العمل في مشروع آخر لجمع البيانات تم الكشف عن أن دوران الهواء في غرفة النوم لم يكن جيدًا وأن مستوى ثاني أكسيد الكربون كان في ازدياد خلال الليل.

إعداد الأجهزة
سنستخدم مستشعر Grove CO2 (SCD41) لقياس مستوى ثاني أكسيد الكربون. SCD41 من Sensirion عبارة عن مستشعر ثاني أكسيد الكربون عالي الجودة قائم على الصور الصوتية قادر على اكتشاف 0 إلى 40000 جزء في المليون بدقة عالية تزيد عن 400-5000 جزء في المليون ± (40 جزء في المليون + 5٪).





o التحكم في مروحة التهوية ، سنستخدم Grove Relay الذي يتم تشغيله بواسطة 5V من رؤوس Wio الطرفية ذات 40 سنًا. يتم استخدام فاصل USB الصغير B لتوصيل المروحة ومصدر الطاقة من Grove Relay. الاتصال الأرضي مأخوذ من رؤوس Wio Terminal. يمكن العثور على مخطط الأسلاك في قسم المخططات.




بيئة التطوير
تم تطوير التطبيق وتصنيفه ووميضه باستخدام Arduino IDE. يرجى تنزيل أحدث إصدار من Arduino IDE واتباع التعليمات للتثبيت من هنا: https://www.arduino.cc/en/software. لتثبيت مكتبة Wio Terminal board ، افتح Arduino IDE ، وانقر فوق ملف> تفضيلات ، وانسخ عنوان URL أدناه إلى عناوين URL الإضافية لـ Boards Manager:





انقر فوق أدوات> لوحة> مدير مجلس الإدارة والبحث في Wio Terminal وانقر فوق تثبيت.





لتثبيت مكتبة مستشعر Grove CO2 (SCD41) ، انقر فوق Tools> Manage Libraries ... لفتح Library Manager والبحث في Sensirion I2C Scd4x وانقر فوق تثبيت..



لا نحتاج إلى تثبيت أي مكتبة لـ Grove Relay التي تعمل بواسطة دبابيس GPIO الرقمية.

الشفرة
#include <SPI.h>
#include <Wire.h>
#include <TFT_eSPI.h>
#include <SensirionI2CScd4x.h>

#include "icon_thermometer.h"
#include "icon_humidity.h"
#include "icon_co2.h"

#define CO2_THRESHOLD 1200

SensirionI2CScd4x scd4x;
TFT_eSPI tft = TFT_eSPI();

unsigned int prev_time = 0;
bool alarm = false;

void printUint16Hex(uint16_t value)
{
Serial.print(value < 4096 ? "0" : "");
Serial.print(value < 256 ? "0" : "");
Serial.print(value < 16 ? "0" : "");
Serial.print(value, HEX);
}

void printSerialNumber(uint16_t serial0, uint16_t serial1, uint16_t serial2)
{
Serial.print("Serial: 0x");
printUint16Hex(serial0);
printUint16Hex(serial1);
printUint16Hex(serial2);
Serial.println();
}

void setup() {

Serial.begin(115200);

pinMode(WIO_5S_PRESS, INPUT_PULLUP);
pinMode(WIO_BUZZER, OUTPUT);
pinMode(D0, OUTPUT); // Relay
digitalWrite(D0, LOW);

tft.init();
tft.setRotation(3);
tft.setTextFont(4);
tft.fillScreen(TFT_BLACK);

Wire.begin();
uint16_t error;
char errorMessage[256];

scd4x.begin(Wire);

// stop potentially previously started measurement
error = scd4x.stopPeriodicMeasurement();
if (error) {
Serial.print("Error trying to execute stopPeriodicMeasurement(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
tft.print(errorMessage);
}

uint16_t serial0;
uint16_t serial1;
uint16_t serial2;

error = scd4x.getSerialNumber(serial0, serial1, serial2);
if (error) {
Serial.print("Error trying to execute getSerialNumber(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
tft.print(errorMessage);
} else {
printSerialNumber(serial0, serial1, serial2);
}

// Start Measurement
error = scd4x.startPeriodicMeasurement();
if (error) {
Serial.print("Error trying to execute startPeriodicMeasurement(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
tft.print(errorMessage);
}

Serial.println("Waiting for first measurement... (5 sec)");
tft.setCursor(100, 80);
tft.print("Waiting...");
delay(5000);
tft.fillScreen(TFT_BLACK);
tft.drawXBitmap(20, 20, icon_co2_bits, icon_co2_width, icon_co2_height, TFT_YELLOW);
tft.drawXBitmap(20, 90, icon_therm_bits, icon_therm_width, icon_therm_height, TFT_RED);
tft.drawXBitmap(20, 160, icon_hum_bits, icon_hum_width, icon_hum_height, TFT_CYAN);

}

uint16_t prev_co2 = 0;
void loop()
{

unsigned long curr_time = millis();

if ((curr_time - prev_time) > 5000) {
prev_time = curr_time;

uint16_t error;
char errorMessage[256];

// Read Measurement
uint16_t co2;
float temperature;
float humidity;

error = scd4x.readMeasurement(co2, temperature, humidity);
if (error) {
Serial.print("Error trying to execute readMeasurement(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
tft.print(errorMessage);
} else if (co2 == 0) {
Serial.println("Invalid sample detected, skipping.");
} else {
if (co2 > CO2_THRESHOLD) {
alarm = true;
} else {
alarm = false;
}
Serial.print("Co2:");
Serial.print(co2);
Serial.print("\t");
Serial.print("Temperature:");
Serial.print(temperature);
Serial.print("\t");
Serial.print("Humidity:");
Serial.println(humidity);

// clear previous value by setting black font color
tft.setTextFont(6);
tft.setCursor(90, 30);
tft.setTextColor(TFT_BLACK, TFT_BLACK);
tft.print(prev_co2);
tft.setTextFont(4);
tft.print("ppm");

tft.setTextFont(6);
tft.setCursor(90, 30);
tft.setTextColor(TFT_YELLOW, TFT_BLACK);
tft.print(co2);
tft.setTextFont(4);
tft.print("ppm");
prev_co2 = co2;

char temp[5];
sprintf(temp, "%0.1f", temperature);
tft.setCursor(90, 100);
tft.setTextFont(6);
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.print(temp);
tft.setTextFont(4);
tft.print("`C");

char hum[5];
sprintf(hum, "%0.1f", humidity);
tft.setCursor(90, 170);
tft.setTextFont(6);
tft.setTextColor(TFT_CYAN, TFT_BLACK);
tft.print(hum);
tft.setTextFont(4);
tft.print("RH");
}
}


if (digitalRead(WIO_5S_PRESS) == LOW) {
alarm = false;
}

if (alarm) {
analogWrite(WIO_BUZZER, 128);
delay(1000);
analogWrite(WIO_BUZZER, 0);
delay(700);
digitalWrite(D0, HIGH); // Relay Switch on
} else {
digitalWrite(D0, LOW); // Relay Switch off
}

delay(300);
}

يمكن تنزيل حزمة الأكواد من مستودع Github: https://github.com/metanav/WioTerminal_CO2_Monitoring/archive/refs/heads/main.zip. بعد التنزيل ، قم بفك ضغط الحزمة وافتح Wio_Terminal_CO2_Monitor / Wio_Terminal_CO2_Monitor.ino رسم تخطيطي في Arduino IDE وانقر على Sketch> تحميل لتجميع / تحميل البرنامج الثابت.

عرض
يتم تحديث قراءات المستشعر إلى شاشة Wio Terminal LCD بفاصل 5 دقائق. تم تنزيل صور الرموز المجانية لثاني أكسيد الكربون ودرجة الحرارة والرطوبة من Flaticon وتم تحويلها إلى X BitMap (XBM) ، وهو تنسيق صورة ثنائية نص عادي ، باستخدام برنامج Convertio



استنتاج
يحتوي هذا الجهاز على العديد من الاحتمالات الأخرى مثل أنه يمكننا جمع بيانات المستشعر البيئي المتسلسل الزمني وحفظها باستخدام وحدة بطاقة SD المدمجة والتي يمكن استخدامها لمزيد من التحليل لاتجاهات مستويات ثاني أكسيد الكربون أو العثور على الحالات الشاذة. يمكن توصيله بالخدمات السحابية باستخدام وحدة Wifi المدمجة.

أود أن أشكر SeeedStudio لتصنيع مثل هذه الخيارات الرائعة من أجهزة الاستشعار البيئية مثل وحدات Grove التي يسهل دمجها في معظم لوحات التطوير باستخدام موصل Grove أو Qwiic / Stemma باستخدام محول. أيضًا ، Wio Terminal هي لوحة تطوير صديقة للمبتدئين للنماذج الأولية السريعة













الجمعة، 12 نوفمبر 2021

كاميرا حرارية تعمل بالذكاء الاصطناعي للتخييم الآمن

 يمكن لنموذج TinyML الذي يقوم بتشغيل Wio Terminal تحديد ما إذا كان الحيوان أو الإنسان يقترب حتى في الظلام وتنبيه المعسكر.




الأشياء المستخدمة في هذا المشروع
مكونات الأجهزة


تطبيقات البرمجيات والخدمات عبر الإنترنت

Arduino Software (IDE)

Edge Impulse

قصة
المشكلة
أحب التخييم لكنني لست "من عشاق التخييم" ، فأنا عادة ما أخيم مرة أو مرتين في السنة مع عائلتي. ولكن هناك عددًا من المتحمسين للتخييم الذين يذهبون إلى أعماق الغابة. في حين أن التخييم في أعماق الغابة مليء بالمغامرات ، فهناك خطر من الحيوانات البرية مثل الدب والذئب وما إلى ذلك. هناك أجهزة لتتبع الحيوانات البرية باستخدام الكاميرا ولكن المشكلة تكمن في أن الكاميرا لا تعمل في الظلام. وفي معظم الحالات ، تهاجم الحيوانات البرية المعسكر في الليل.

كيف يمكننا حلها؟
نحتاج إلى جهاز يمكن أن يعمل في الظلام وينبه المعسكر عند اقتراب أي حيوان بري. لا يمكننا استخدام الكاميرا العادية لهذا الغرض. نحتاج إلى شيء يمكن أن يعمل بدون ضوء مثل الكاميرا الحرارية.

الحل هو العربة
تقديم العربة المجهزة بكاميرا Grove MLX90640 IR الحرارية ومحطة Wio من Seeed. يتنبأ نموذج tinyML يعمل على محطة Wio إذا كان هناك أي حيوان أو إنسان يقترب. إذا تم الكشف عنها ، يتم إرسال البيانات إلى موضوع AWS IoT.







لقد قمت ببناء نموذج ML باستخدام Edge Impulse Studio. اعتبارًا من كتابة هذا المشروع (نوفمبر 2021) ، لا يدعم EI تغذية الكاميرا الحرارية لجمع البيانات خارج الصندوق ، لذلك يتم جمع البيانات من محطة Wio وإعادة توجيهها إلى Edge Impulse لبناء النموذج. عملية جمع البيانات مستوحاة من مشروع نافين على الهاكر.

إنشاء مشروع الذكاء العاطفي
توجه إلى حساب EI الخاص بك وقم بإنشاء مشروع جديد. انتقل إلى علامة التبويب "المفاتيح" وأضف مفتاح HMAC جديدًا. انسخ المفتاح في مكان ما ، ستحتاج إليه لاحقًا.


جمع البيانات
تحمل الكاميرا الحرارية بالأشعة تحت الحمراء مجموعة 32x24 من المستشعرات الحرارية (MLX90640) ، ويمكنها الكشف عن درجة حرارة الأشياء من على بعد أقدام بدقة ± 1.5 ℃. من أجل الحصول على الصورة الحرارية بسهولة ، يتم استخدام بروتوكول I2C للحصول على صورة منخفضة الدقة من الكاميرا. ستكون البيانات عبارة عن مصفوفة من 32 × 24 وهي 768 قيمة درجة حرارة. MLX90640 متصل بمحطة Wio عبر منفذ I2C وقد أدخلت بطاقة SD لالتقاط القراءات في ملف CSV. تُستخدم الأزرار الثلاثة الموجودة على Wio Terminal لتسمية الفئات الثلاثة

أ- الحيوان ، ب- الإنسان ، ج- الخلفية

استخدم البرنامج WIO_Camper_Data_Collector.ino لجمع البيانات. قم بتحميل هذا البرنامج وابدأ في جمع البيانات.

بعد جمع البيانات ، قم بإزالة بطاقة SD من Wio Terminal وإدخالها في جهاز الكمبيوتر الخاص بك. يجب أن تشاهد ملفات CVS على النحو التالي.


يحتوي ملف ach على 768 قيمة مفصولة بفواصل.



انسخ جميع الملفات إلى الدليل المسمى خام ضمن بيانات المجلد. ثم قم بتشغيل برنامج imager.py الذي سينشئ عرضًا مرئيًا للبيانات ضمن مجلد / data / visual.

python3 imager.py


هذه الخطوة اختيارية. يساعدك على عرض بيانات csv بتنسيق صورة ولكن لا علاقة له بتدريب النموذج.


إعادة توجيه البيانات
هذا حقا جزء مثير للاهتمام. يدعم معيد توجيه البيانات Edge Impulse البيانات الأولية للسلاسل الزمنية فقط. لكن بيانات الكاميرا الحرارية ليست سلسلة زمنية. بدلاً من ذلك ، فهي عبارة عن مصفوفة من 32 × 24 بها 768 قيمة منفصلة. سننظر في هذا على أنه بيانات سلسلة زمنية 768 أحادية القناة بفاصل 1 ميكروثانية. ستساعدك الصورة أدناه على تصور ما أتحدث عنه



ستلاحظ أن صورة واحدة (768 قيمة) يتم تمثيلها على أنها بيانات سلسلة زمنية بفاصل 1 مللي ثانية. أنت تعرف الآن كيف نريد تنسيق بياناتنا قبل تحميلها إلى Edge Impulse. لنفعلها اذا.

افتح data-formatter.py والصق مفتاح HMAC الذي حصلت عليه مسبقًا. ثم قم بتشغيل البرنامج.
python3 data-formatter.py

سيقوم هذا البرنامج بإنشاء ملف json لكل ملف من ملفات cvs وتخزينها في مجلد / data / formatted_data. يمكنك أن ترى أدناه أن القيم يتم تمثيلها على أنها بيانات سلاسل زمنية بفاصل زمني قدره 1 ثانية. فقط قناة بيانات المستشعر هي درجة الحرارة.


نظرًا لأنك أعددت البيانات ، سنستخدم Edge Impulse CLI لتحميل البيانات. تحتاج إلى تثبيت CLI. اتبع هذا البرنامج التعليمي لإعداد CLI.

القرص المضغوط في مجلد formatted_data وتنفيذ الأمر أدناه.
edge-impulse-uploader --category split *.json
يجب أن يؤدي هذا إلى تحميل جميع بيانات json إلى مشروع Edge Impulse الخاص بك ضمن صفحة "الحصول على البيانات".


بناء النموذج

نظرًا لأننا قمنا بجمع البيانات ، فلنقم ببناء نموذجنا وتدريبه. انتقل إلى صفحة "إنشاء الدافع".


انقر فوق "إضافة كتلة إدخال" ، اختر "بيانات السلاسل الزمنية". قم بتعيين كل من حجم النافذة وحجم زيادة النافذة على 768 مللي ثانية. هل تتذكر أن بيانات json الخاصة بنا تحتوي على 768 قيمة بفاصل 1 مللي ثانية؟

بعد ذلك ، انقر فوق "إضافة كتلة معالجة" ، واختر "بيانات أولية".

ثم ، انقر فوق "إضافة كتلة تعلم" ، واختر التصنيف (Keras) واحفظ الدافع.


انتقل إلى صفحة "البيانات الأولية" ، واحتفظ بالإعدادات الافتراضية وانتقل إلى "NN Classifier" ، واضبط دورة التدريب ومعدل التعلم. حاول ألا تفرط في النموذج. إذا كان نموذجك لا يعمل بشكل جيد ، فحاول جمع المزيد من البيانات وإعادة التدريب.

قم بتنزيل مكتبة Arduino
انتقل إلى صفحة "النشر" ، واختر "Arduino" وابني. سيؤدي هذا إلى تنزيل المكتبة كملف مضغوط. قم باستيراد هذه المكتبة إلى Arduino IDE. أفترض أن اسم مشروعك هو "camper" وأن ملف مكتبة arduino الخاص بك يجب أن يكون camper_inferencing.h



قم بإعداد AWS IoT
في المرحلة الأولى من هذا المشروع ، أقوم بإرسال البيانات إلى AWS IoT باستخدام اتصال WiFi. لجعل محطة Wio متصلة بشبكة wifi ، تحتاج إلى تحديث البرامج الثابتة للجهاز. العملية بسيطة للغاية. اتبع هذه التعليمات.

للاتصال بـ AWS ، تحتاج إلى إنشاء "شيء" والاتصال بـ "الشيء" باستخدام الشهادات. كتب Seeed studio برنامج بيثون فائدة سيخلق جميع الموارد من أجلك. اتبع هذا. لدي مشروع آخر شرحت فيه إعداد AWS. يمكنك الرجوع إلى هذا المشروع.

سيخرج create_thing.py الشهادة والمفتاح الخاص على الجهاز. انسخها والصقها في ملف cogfig.h.
#ifndef _CONFIG_H_
#define _CONFIG_H_

// TODO ADD YOUR CONFIGURATION HERE
// WiFi and MQTT configuration
static auto constexpr WIFI_SSID = "";
static auto constexpr WIFI_PASSWORD = "";

// DHCP client id
static auto constexpr CLIENT_ID = "CLIENTID";
// hostname of your MQTT ATS endpoint
static auto constexpr HOST_ADDRESS = "xxxxxxx-ats.iot.us-east-1.amazonaws.com";

static auto constexpr TOPIC_NAME = "camper";
static auto constexpr ALERT_TOPIC_NAME = "camper_alerts";

// "AWS root CA1 and CA2 (RSA)", see
// https://docs.aws.amazon.com/iot/latest/developerguide/managing-device-certs.html#server-authentication

static auto constexpr aws_root_ca_pem = "CA_Root_Certificate";

// certificate and private key for the thing. See README.md for details
// and use the create_thing.py script to create certificate and key.
// "The certificate for this thing"
auto constexpr certificate_pem_crt = "";
auto constexpr private_pem_key= "";
#endif
تحتاج أيضًا إلى إدخال بيانات اعتماد wifi وعنوان مضيف AWS IoT. بعد إجراء التغيير ، قم بتحميل برنامج WIO_Camper_Inference.ino إلى محطة wio.

سيرسل الجهاز البيانات كل دقيقة إلى موضوع AWS IoT ، كما سيصدر الجهاز رنينًا عند اكتشاف حيوان أو إنسان.


نظرًا لوجود البيانات في AWS ، يمكنك فعل الكثير من هنا. مثل إرسال البيانات إلى dynamodb ، قم بتشغيل بعض التحليلات ، واستخدم Amazon Pinpoint لإرسال إشعار الدفع إلى الهاتف المحمول ، وإرسال رسالة نصية إلى هاتفك.

المرحلة الثانية
كما يمكنك أن تتخيل ، فإن الاعتماد على wifi ليس حلاً جيدًا هنا لأن الجهاز سيكون خارج شبكة wifi المنزلية في الغالب. لدي خطط قليلة

بدلاً من إرسال محطة wio للبيانات مباشرة إلى AWS ، يمكنني إنشاء تطبيق جوال يتصل بمحطة Wio عبر البلوتوث وإرسال البيانات إلى تطبيق الهاتف المحمول. سيقوم تطبيق الهاتف المحمول بعد ذلك بإرسال البيانات إلى AWS باستخدام cognito. لقد فعلت شيئًا مشابهًا في مشروع صديقي.
يمكنني إزالة تبعية wifi أو الاتصال الخلوي تمامًا وإرسال البيانات إلى شبكة LoRa (TTN أو Helium) مباشرةً من الجهاز. ستقوم TTN أو Helium بتفويض الرسالة إلى AWS IoT. لقد أنجزت مشروعًا مشابهًا من قبل