ستناقش هذه المقالة وحدة استقبال إشارة nooLite الجديدة لـ Arduino و microcontrollers. ما الذي يميز هذه الوحدة؟ حتى الآن ، لم تكن هناك طرق لتلقي المعلومات من أجهزة الاستشعار والتحكم في نقل الإشارات من أجهزة التحكم عن بعد لنظام nooLite على وحدات التحكم الدقيقة و Arduino ، كان هذا الاحتمال موجودًا فقط لأجهزة الكمبيوتر التي تستخدم محولات USB خاصة.الآن ، مع إصدار وحدة MR1132 ، أصبح من الممكن تلقي بيانات حول درجة الحرارة والرطوبة والإضاءة ووجود الأشخاص في الغرفة من أجهزة الاستشعار اللاسلكية لنظام nooLite في رسوماتك على Arduino ، والقدرة على تتبع الأوامر الصادرة لوحدات الطاقة nooLite عن طريق مفاتيح التحكم عن بعد وأكثر من ذلك بكثير التي لم تكن متوفرة من قبل.في هذه المقالة ، سأخبرك عن تشغيل هذه الوحدة وأعطي رسمًا عمليًا ، يمكنك على أساسه إنشاء أجهزتك بسهولة على MR1132. في المقالات اللاحقة سوف أتحدث عن تكامل هذه الوحدة مع نظام Arduino Mega Server الشهير وعن الميزات الرائعة التي ستظهر فيما يتعلق بهذا التكامل.الوحدة
وحدة MR1132 تشبه إلى حد كبير شقيقها ، وحدة MT1132 (التي كانت هناك بالفعل دورة من المقالات على Gimetays واحد ، اثنان ، ثلاثة ). الفرق هو أن وحدة MT1132 هي جهاز إرسال ، وأن وحدة MR1132 هي جهاز استقبال ويمكن الحصول على أكبر تأثير عند استخدامها معًا.نقطة أخرى مهمة هي أن جهاز إرسال MT1132 عالمي ويعمل على حد سواء من 3.3 فولت ومن 5 فولت (مما يعني أنه يعمل مع وحدات تحكم 3.3 فولت ومع 5 فولت) ، وجهاز الاستقبال فقط من 5 V. يجب أن يؤخذ هذا في الاعتبار عند تصميم أجهزتك ، وإذا لزم الأمر ، استخدم منسقي المستوى المنطقي.
الاتصال بسيط مثل وحدة MT1132 - جهد الإمداد والأرض واتصالين RX و TX. يمكن سحب RTS إلى جهد الإمداد ، ولكن كل شيء يعمل بالنسبة لي حتى بدون توصيل هذا الإخراج.العمل
تعمل الوحدة عبر واجهة تسلسلية بسرعة 9600. تتلقى الوحدة أوامر من وحدة التحكم ، وتصدر بدورها البيانات المستلمة من الهواء (من أجهزة الاستشعار وأجهزة التحكم عن بعد nooLite).دعونا نلقي نظرة فاحصة على هذه النقطة ، بحيث يكون لديك فهم واضح لكيفية عمل هذه الوحدة.ترتبط جميع الأوامر التي يمكن أن ترسلها وحدة التحكم إلى الوحدة النمطية عبر الواجهة التسلسلية بأجهزة nooLite "الملزمة" أو "غير المقيدة" ، والتي ستتلقى الوحدة منها البيانات بعد ذلك. لا توجد أوامر تحكم أخرى لهذه الوحدة النمطية. على سبيل المثال ، قمت بربط مستشعر درجة الحرارة nooLite PT112 على القناة الصفرية (إجمالي 32 قناة ، وهو ما ينعكس في اسم الوحدة) وبعد ذلك ستبدأ الوحدة في تلقي البيانات من هذا المستشعر وإخراجها إلى الواجهة التسلسلية (حيث تتمثل مهمتنا في "التقاطها" واستخدامها من أجل الأهداف).إذا لم نعد بحاجة إلى تلقي البيانات من أي مستشعر ، فيمكننا إرسال أمر فصل (في هذه الحالة ، على القناة صفر) ولن يقوم جهاز الاستقبال بعد ذلك بتقديم معلومات إلى وحدة التحكم من هذا المستشعر.أما بالنسبة للمعلومات التي يتم تلقيها بواسطة وحدة MR1132 من أجهزة nooLite ، فهناك مستند منفصل يصف تنسيق جميع الأوامر الممكنة. نحن ، في سياق هذه السرد ، من هذه القائمة الشاملة ، سنهتم بفرق أجهزة استشعار درجة الحرارة والرطوبة والحركة. ستتم مناقشة هذه الأوامر بالتفصيل أدناه ، باستخدام الرسم كمثال.أجهزة الاستشعار
في تجاربنا ، سيتم استخدام ثلاثة أجهزة استشعار.
جهاز استشعار درجة الحرارة PT112 ومستشعر درجة الحرارة والرطوبة PT111. إنها تبدو متشابهة وتعمل بنفس الطريقة تمامًا ، والفرق هو أن PT112 تقدم فقط معلومات حول درجة الحرارة ، و PT111 تقدم معلومات حول درجة الحرارة والرطوبة. يمكن أن تعمل هذه المستشعرات إما في وضع مستشعر بسيط أو في وضع منظم الحرارة والرطوبة ، ولكننا مهتمون بوضع مستشعر بسيط.
المستشعر الثالث هو PM111. هذا مستشعر للحركة يمكنه التحكم مباشرة في وحدات الطاقة nooLite ، لكننا لن نهتم بنا إلا كمصدر للمعلومات حول حركة ووجود الأشخاص في الغرفة.تحكم
سيتم استخدام Arduino Mega 2560 كوحدة تحكم ، وواجهتين تسلسليتين - Serial (للتحكم في المعلومات المرئية) Serial2 (للتواصل مع وحدة الاستقبال). المسلسل 1 محجوز لوحدة الإرسال MT1132.
رسم
في قسم الإعداد () ، يتم تشغيل واجهتين ، ويتم عرض رسالة معلومات حول بداية الرسم التخطيطي ، ويتم إصدار أمر لربط أجهزة nooLite على القناة الصفرية. هذا أمر اختبار ويمكنك التعليق عليه أو استبداله بأمر آخر (على سبيل المثال ، الارتباطات على قناة أخرى أو إلغاء الربط).void setup() {
Serial.begin(9600);
Serial2.begin(9600);
Serial.println("*** Start sketch ***");
mrBind(0);
}
قبل العمل برسم تخطيطي ، تحتاج إلى تنفيذ بعض الخطوات الأولية ، وهي ربط المستشعرات بالوحدة بالطريقة التالية:PT112 - القناة صفرPT111 - القناة الأولىPM111 - القناة الثانيةلهذا تحتاج إلى تشغيل الرسم ثلاث مرات ، وتغيير أمر الربطmrBind(0);
mrBind(1);
mrBind(2);
وفي كل مرة اضغط على الزر الموجود على المستشعر المقابل. يجب القيام بذلك مرة واحدة فقط ، ثم يمكن التعليق على أمر الربط. أو بدلاً من ذلك ، ضع الأمر untie وقم بفك أي من أجهزة الاستشعار المرفقة.في قسم الحلقة () ، توجد وظيفة mrCheck () واحدة فقط ، وهي المسؤولة عن "التقاط" الرسائل من وحدة MR1132 من الواجهة التسلسلية Serial2.void mrCheck() {
if (Serial2.available() == 8) {
mrBuf[0] = Serial2.read();
mrBuf[1] = Serial2.read();
mrBuf[2] = Serial2.read();
mrBuf[3] = Serial2.read();
if (mrBuf[0] == 79 && mrBuf[1] == 75 && mrBuf[2] == 13 && mrBuf[3] == 10) {
Serial.println("OK");
} else {
mrBuf[4] = Serial2.read();
mrBuf[5] = Serial2.read();
mrBuf[6] = Serial2.read();
mrBuf[7] = Serial2.read();
mrNewData();
}
}
}
تملأ هذه الوظيفة صفيف mrBuf [8] بالبيانات الواردة من الوحدة أو ترسل إلى الرسالة التسلسلية "OK" الصادرة عن وحدة MR1132. علاوة على ذلك ، يتم تحليل محتويات الصفيف mrBuf [8] وفقًا لتنسيق البيانات لأوامر نظام nooLite ، ويتم تضمين وظائف الرسم المقابلة في ذلك.تستخرج وظيفة mrNewData () البيانات الرئيسية من مصفوفة mrBuf [8] ، وتبعاً للأمر الوارد ، تقوم بإخراج المعلومات الضرورية إلى المسلسل (القناة ، الأمر ، درجة الحرارة ، الرطوبة ، حالة بطارية المستشعر ، إلخ).void mrNewData() {
mrClearData();
mrPrintHeader();
mrSetBindState();
mrPrintBindState();
mrSetChannel();
mrPrintChannel();
mrSetCommand();
mrSetDatas();
switch (mrCommand) {
case 0:
Serial.print("PIR command: ");Serial.println("OFF");
break;
case 2:
Serial.print("PIR command: "); Serial.println("ON");
break;
case 21:
mrSetDeviceType();
mrPrintDeviceType();
if (mrDeviceType == 1) {
mrSetTemperature();
mrPrintTemperature();
}
if (mrDeviceType == 2) {
mrSetTemperature();
mrPrintTemperature();
mrSetHumidity();
mrPrintHumidity();
}
break;
default:
;
}
mrSetBatteryState();
}
تعمل الدوال التي تحتوي على كلمة طباعة باسمها في إخراج المعلومات إلى الواجهة التسلسلية للتحكم المرئي.تقوم الوظائف التالية بفك تشفير البيانات في مصفوفة mrBuf [8] ، وفقًا لتنسيق البيانات لأوامر نظام nooLite:mrSetTogl () - قيمة عداد الأوامر الواردةmrSetBindState () - حالة الوحدة (ملزم /عادي ) mrSetReceiveBit () - تحكم بت الاستقبال الأمر الجديدmrSetChannel () - رقم القناةmrSetCommand () - الأمرmrSetFormat () - تنسيق البياناتmrSetDeviceType () - نوع المستشعرmrSetDatas () - تعبئة أربعة بايتات من البياناتmrSetTemperature ()- الحصول على قيمة درجة الحرارةmrSetHumidity () - الحصول على قيمة الرطوبةmrSetBrightness () - الحصول على قيمة الإضاءةmrSetBatteryState () - حالة بطارية المستشعريمكنك الاطلاع على تفاصيل تنفيذ هذه الوظائف في رمز الرسم الكامل المرفق أدناه.هنا الرسم الكامل.كود رسم كامل// TX2 16
// RX2 17
// TX1 18
// RX1 19
// nooLite MR1132 data
byte mrBuf[8];
int mrTogl = -1;
int mrBindState = -1;
int mrReceiveBit = -1;
int mrChannel = -1;
int mrCommand = -1;
int mrFormat = -1;
int mrData0 = -1;
int mrData1 = -1;
int mrData2 = -1;
int mrData3 = -1;
int mrDeviceType = -1;
int mrBatteryState = -1;
int mrHumidity = -1;
int mrBrightness = -1;
float mrTemp = -1.0;
// nooLite MR1132 bind/unbind
void mrSerialChannel(byte ch) {
switch (ch) {
case 0: Serial.println («0»); break;
case 1: Serial.println («1»); break;
case 2: Serial.println («2»); break;
case 3: Serial.println («3»); break;
case 4: Serial.println («4»); break;
case 5: Serial.println («5»); break;
case 6: Serial.println («6»); break;
case 7: Serial.println («7»); break;
case 8: Serial.println («8»); break;
case 9: Serial.println («9»); break;
case 10: Serial.println(«10»); break;
case 11: Serial.println(«11»); break;
case 12: Serial.println(«12»); break;
case 13: Serial.println(«13»); break;
case 14: Serial.println(«14»); break;
case 15: Serial.println(«15»); break;
case 16: Serial.println(«16»); break;
case 17: Serial.println(«17»); break;
case 18: Serial.println(«18»); break;
case 19: Serial.println(«19»); break;
case 20: Serial.println(«20»); break;
case 21: Serial.println(«21»); break;
case 22: Serial.println(«22»); break;
case 23: Serial.println(«23»); break;
case 24: Serial.println(«24»); break;
case 25: Serial.println(«25»); break;
case 26: Serial.println(«26»); break;
case 27: Serial.println(«27»); break;
case 28: Serial.println(«28»); break;
case 29: Serial.println(«29»); break;
case 30: Serial.println(«30»); break;
case 31: Serial.println(«31»); break;
} // switch
} // mrSerialChannel( )
void mrSerial2Channel(byte ch) {
switch (ch) {
case 0: Serial2.print(«00»); break;
case 1: Serial2.print(«01»); break;
case 2: Serial2.print(«02»); break;
case 3: Serial2.print(«03»); break;
case 4: Serial2.print(«04»); break;
case 5: Serial2.print(«05»); break;
case 6: Serial2.print(«06»); break;
case 7: Serial2.print(«07»); break;
case 8: Serial2.print(«08»); break;
case 9: Serial2.print(«09»); break;
case 10: Serial2.print(«10»); break;
case 11: Serial2.print(«11»); break;
case 12: Serial2.print(«12»); break;
case 13: Serial2.print(«13»); break;
case 14: Serial2.print(«14»); break;
case 15: Serial2.print(«15»); break;
case 16: Serial2.print(«16»); break;
case 17: Serial2.print(«17»); break;
case 18: Serial2.print(«18»); break;
case 19: Serial2.print(«19»); break;
case 20: Serial2.print(«20»); break;
case 21: Serial2.print(«21»); break;
case 22: Serial2.print(«22»); break;
case 23: Serial2.print(«23»); break;
case 24: Serial2.print(«24»); break;
case 25: Serial2.print(«25»); break;
case 26: Serial2.print(«26»); break;
case 27: Serial2.print(«27»); break;
case 28: Serial2.print(«28»); break;
case 29: Serial2.print(«29»); break;
case 30: Serial2.print(«30»); break;
case 31: Serial2.print(«31»); break;
} // switch
} // mrSerial2Channel( )
void mrPrintBind(byte ch) {
Serial.print(«Bind on channel „);
mrSerialChannel(ch);
}
void mrBind(byte ch) {
mrPrintBind(ch);
Serial2.print(“bind_mode_cell_»);
mrSerial2Channel(ch);
Serial2.write(3); // End of Text — B00000011(BIN)
}
void mrPrintUnbind(byte ch) {
Serial.println(«Unbind on channel „);
mrSerialChannel(ch);
}
void mrUnbind(byte ch) {
mrPrintUnbind(ch);
Serial2.print(“clear_one_cell_»);
mrSerial2Channel(ch);
Serial2.write(3);
}
void mrBindStop() {
Serial.println(«Bind mode off»);
Serial2.print(«bind_mode_off»);
Serial2.write(3);
}
void mrClearAll() {
Serial.println(«Clear all cell»);
Serial2.print(«clear_all_cell»);
Serial2.write(3);
}
// nooLite MR1132 print works
void mrPrintHeader() {
Serial.println();
}
void mrPrintDeviceType() {
Serial.print(«Device: „);
if (mrDeviceType == 1) {
Serial.println(“PT112»);
}
if (mrDeviceType == 2) {
Serial.println(«PT111»);
}
}
void mrPrintBindState() {
if (mrBindState == 1) {
Serial.print(«Bind State: „);
Serial.println(“ON»);
}
}
void mrPrintBatteryState() {
if (mrBatteryState == 1) {
Serial.print(«Battery State: „);
Serial.println(“LOW!»);
}
}
void mrPrintChannel() {
Serial.print(«Channel: „);
Serial.println(mrChannel);
}
void mrPrintTemperature() {
Serial.print(“Temp: „);
Serial.println(mrTemp);
}
void mrPrintHumidity() {
Serial.print(“Humidity: „);
Serial.println(mrHumidity);
}
// nooLite MR1132 data works
void mrClearData() {
mrTogl = -1;
mrBindState = -1;
mrReceiveBit = -1;
mrChannel = -1;
mrCommand = -1;
mrFormat = -1;
mrData0 = -1;
mrData1 = -1;
mrData2 = -1;
mrData3 = -1;
mrDeviceType = -1;
mrBatteryState = -1;
mrHumidity = -1;
mrBrightness = -1;
mrTemp = -1.0;
}
void mrSetTogl() {
byte b0 = bitRead(mrBuf[0], 0);
byte b1 = bitRead(mrBuf[0], 1);
byte b2 = bitRead(mrBuf[0], 2);
byte b3 = bitRead(mrBuf[0], 3);
byte b4 = bitRead(mrBuf[0], 4);
byte b5 = bitRead(mrBuf[0], 5);
mrTogl = 32*b5 + 16*b4 + 8*b3 + 4*b2 + 2*b1 + b0;
}
void mrSetBindState() {
mrBindState = bitRead(mrBuf[0], 6);
}
void mrSetReceiveBit() {
mrReceiveBit = bitRead(mrBuf[0], 7);
}
void mrSetChannel() {
mrChannel = mrBuf[1];
}
void mrSetCommand() {
mrCommand = mrBuf[2];
}
void mrSetFormat() {
mrFormat = mrBuf[3];
}
void mrSetDeviceType() {
byte tp1 = bitRead(mrBuf[5], 4);
byte tp2 = bitRead(mrBuf[5], 5);
byte tp3 = bitRead(mrBuf[5], 6);
mrDeviceType = 4*tp3 + 2*tp2 + tp1;
}
void mrSetDatas() {
mrData0 = mrBuf[4];
mrData1 = mrBuf[5];
mrData2 = mrBuf[6];
mrData3 = mrBuf[7];
}
void mrSetTemperature() {
byte t8 = bitRead(mrData1, 0);
byte t9 = bitRead(mrData1, 1);
byte t10= bitRead(mrData1, 2);
int temp2 = 1024*t10 + 512*t9 + 256*t8;
int temp = mrData0 + temp2;
byte t11 = bitRead(mrData1, 3);
if (t11 == 1) {
temp = (4096 — temp) * -1;
}
mrTemp = (float)temp / 10.0;
}
void mrSetBatteryState() {
mrBatteryState = bitRead(mrBuf[5], 7);
}
void mrSetHumidity() {
mrHumidity = mrData2;
}
void mrSetBrightness() {
mrBrightness = mrData3;
}
void mrNewData() {
mrClearData();
mrPrintHeader();
mrSetBindState();
mrPrintBindState();
mrSetChannel();
mrPrintChannel();
mrSetCommand();
mrSetDatas();
switch (mrCommand) {
case 0:
Serial.print(“PIR command: „); Serial.println(“OFF»);
break;
case 2:
Serial.print(«PIR command: „); Serial.println(“ON»);
break;
case 21:
mrSetDeviceType();
mrPrintDeviceType();
if (mrDeviceType == 1) {
mrSetTemperature();
mrPrintTemperature();
}
if (mrDeviceType == 2) {
mrSetTemperature();
mrPrintTemperature();
mrSetHumidity();
mrPrintHumidity();
}
break;
default:
;
} // switch
mrSetBatteryState();
} // newData()
void mrCheck() {
if (Serial2.available() == 8) {
mrBuf[0] = Serial2.read();
mrBuf[1] = Serial2.read();
mrBuf[2] = Serial2.read();
mrBuf[3] = Serial2.read();
if (mrBuf[0] == 79 && mrBuf[1] == 75 && mrBuf[2] == 13 && mrBuf[3] == 10) {
Serial.println(«OK»);
} else {
mrBuf[4] = Serial2.read();
mrBuf[5] = Serial2.read();
mrBuf[6] = Serial2.read();
mrBuf[7] = Serial2.read();
mrNewData();
}
}
}
void setup() {
Serial.begin(9600);
Serial2.begin(9600);
Serial.println("*** Start sketch ***");
mrBind(0);
//mrUnbind(0);
}
void loop() {
mrCheck();
} // loop()
الخلاصة
هذا ، في الواقع ، كل ما تحتاجه لبدء العمل مع وحدة MR1132 واستخدامها في رسوماتك ومشاريعك. يمكن أيضًا استخدام هذه الوحدة للتحكم في الإشارات من وحدات تحكم محمولة على الحائط nooLite ويمكن لنظامك الآن معرفة مكان وحدة التحكم التي تعمل وأي أمر يتم إرسالها إلى وحدات الطاقة.قريبًا ، سيتم إصدار إصدار 0.15 جديد من نظام Arduino Mega Server الشهير وفي هذا الإصدار سيكون هناك دعم مدمج لوحدات MR1132 والإدارة المريحة مباشرة من صفحة الويب والمزيد.