适用于Arduino的新nooLite MR1132接收器模块

图片

本文将讨论用于Arduino和微控制器的新型nooLite信号接收器模块。这个模块有什么特别之处?到目前为止,还没有办法从传感器接收信息并控制微控制器和Arduino上nooLite系统的遥控器的信号传输,这种可能性仅存在于使用特殊USB适配器的计算机上。

现在,随着MR1132模块的发布,已经可以从Arduino草图中的nooLite系统的无线传感器接收有关温度,湿度,照明和房间中有人的数据,能够通过遥控开关跟踪发给电源单元nooLite的命令的功能。以前不可用。

在本文中,我将向您介绍该模块的操作并给出工作原理图,您可以在此基础上轻松地在MR1132上创建设备。在随后的文章中,我将讨论该模块与流行的Arduino Mega Server系统的集成,以及与该集成相关的精彩功能。

模组


MR1132模块与它的兄弟MT1132模块非常相似(关于该模块,Gimetays 上已经有很多文章了)。区别在于MT1132模块是发送器,而MR1132模块是接收器,当它们一起使用时,可以获得最大的效果。

另一个重要的一点是,MT1132发射器具有通用性,可以在3.3 V和5 V的电压下工作(这意味着它可以与3.3V控制器和5V电压一起工作)以及接收器仅从5 V开始。设计设备时必须考虑到这一点,并在必要时使用逻辑电平协调器。

图片

连接就像MT1132模块一样简单-电源,接地和两个触点RX和TX。可以将RTS上拉至电源电压,但是即使不连接此输出,一切都对我有用。

工作时间


该模块通过串行接口以9600的速度运行。该模块接收来自控制器的命令,然后发布从空中(从传感器和nooLite遥控器)接收的数据。

让我们仔细看看这一点,以便您清楚地了解此模块的工作方式。

控制器可通过串行接口发送给模块的所有命令都与“绑定”或“取消” nooLite设备有关,模块将从中接收数据。不再有该模块的控制命令。例如,您将nooLite PT112温度传感器绑在零通道(总共32个通道,反映在模块名称上)上,然后模块将开始从该传感器接收数据并将其输出到串行接口(我们的任务是“捕获”它并将其用于我们的)目标)。

如果我们不再需要从任何传感器接收数据,则可以发送解耦命令(在这种情况下,在通道零),并且接收器将不再从该传感器提供信息给控制器。

至于MR1132模块从nooLite设备接收的信息,有一个单独的文档描述了所有可能命令的格式。在这种叙述的背景下,我们将从大量的清单中对温度,湿度和运动传感器团队感兴趣。这些命令将在下面以草图为例进行详细讨论。

感测器


在我们的实验中,将使用三个传感器。

图片

温度传感器PT112和温湿度传感器PT111。它们看起来相同并且工作方式完全相同,不同之处在于PT112仅提供有关温度的信息,而PT111提供有关温度和湿度的信息。这些传感器既可以在简单的传感器模式下工作,也可以在恒温器和恒湿器模式下工作,但是我们将对简单的传感器模式感兴趣。

图片

第三个传感器是PM111。这是一种可以直接控制nooLite动力单元的运动传感器,但我们只是对我们感兴趣,因为它是有关房间中人员移动和存在的信息源。

控制者



Arduino Mega 2560将用作控制控制器,其两个串行接口-串行(用于视觉信息控制)Serial2(用于与接收器模块进行通信)。Serial1为MT1132发送器模块保留。

图片

草绘


在setup()部分中,将启动两个接口,显示有关草图起点的信息消息,并发出命令以在零通道上绑定nooLite设备。这是一个测试命令,您可以将其注释掉或将其替换为另一个命令(例如,在另一个通道上的绑定或取消绑定)。

void setup() {
  Serial.begin(9600);
  Serial2.begin(9600);
  Serial.println("*** Start sketch ***");
  mrBind(0);
  //mrUnbind(0);
}

与草图工作之前,你需要做一些初步的步骤,即,配合你的传感器模块,具体如下:

PT112 -零通道
PT111 -第一通道
PM111 -第二通道

要做到这一点,你需要三次启动草图,改变snap命令

mrBind(0);
mrBind(1);
mrBind(2);

并每次按相应传感器上的按钮。这仅需要执行一次,然后可以注释掉绑定命令。或者,而不是放开untie命令并解开任何连接的传感器。

在loop()部分中,只有一个mrCheck()函数,该函数负责“捕获”来自串行接口Serial2的MR1132模块的消息。

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]阵列,或将其传输到由MR1132模块发出的串行消息“ OK”。此外,根据nooLite系统命令的数据格式解析mrBuf [8]数组的内容,并且其中涉及相应的草图函数。

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: 
      ;
  } // switch
  mrSetBatteryState();
} // newData()

名称中包含单词Print的功能可将信息输出到串行接口以进行视觉控制。

以下函数根据nooLite系统命令的数据格式解密mrBuf数组[8]中的数据:

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壁挂式控制台的信号,您的系统现在可以知道在何处,哪个控制台工作以及将哪个命令发送到功率单元。

很快,将发布流行的Arduino Mega Server系统的新0.15版本,并且在该版本中将内置对MR1132模块的支持,并可以直接从网页等进行便捷的管理。

Source: https://habr.com/ru/post/zh-CN393185/


All Articles