这是将KernelChip的 Laurent 模块集成到家庭自动化系统中的系列文章中的第二篇。在这一部分中,我们将重点介绍将这些模块与Arduino生态系统集成。在系列的第一部分中,我们讨论了与流行的MajorDoMo家庭自动化系统的集成,在第三部分中,您将学习如何从Processing编程语言中的草图直接在计算机的桌面上管理这些模块。
Arduino是我们的一切
没有Arduino的地方?我不会在很长一段时间内描述这个平台的优势,它的受欢迎程度是不言而喻的,所以让我们立即了解一下Arduino和Laurent模块之间交互的技术细节。在此过程中,我们不会忘记Arduino Mega Server系统,它是Arduino生态系统非常有趣的派生产品。铁
例如,对于通过网络控制模块,适合使用常见的Arduino Uno板或同样流行的Arduino Mega板,该板上配备了基于W5100芯片组装的Ethernet Shield网络接口卡。本文中的所有示例均针对此类组合给出,并已在实践中进行了测试。一切工作可靠,没有任何问题。
基于W5100芯片的Ethernet Shield,就是说,您只需要略做一些更改,就可以将其草图并上传到Uno或Mega板上。管理草图模块
在本系列的第一部分中,我已经讨论了通过网络管理Laurent模块的原理,对于那些没有阅读第一部分的人,我将在这里简单地重复一下理论。信息是通过网络与模块交换的,要开始使用它们,您需要在端口2424上建立TCP / IP连接。建立连接后,您可以发送控制模块的文本命令(所谓的KE命令)。该KernelChip网站有详细的文档,包括KE命令的访问描述。现在,让我们尝试将这种理论上的“参考术语”翻译成Arduino草图的简单语言。草图
我不会在这里解释如何安装和配置Arduino编程环境,前提是您已经完成了这一工作并且能够编写简单的草图。因此,对于初学者来说,我们需要连接必要的库SPI.h和Ethernet.h,以控制总线和以太网模块本身。#include <SPI.h>
#include <Ethernet.h>
然后,您需要设置我们将管理的以太网模块和Laurent模块的网络设置。请注意,MAC地址和IP地址必须唯一,并且LAURENT_PORT必须设置为2424,并且不能设置其他任何值。byte SELF_MAC[] = {0x00, 0x2A, 0xF5, 0x12, 0x67, 0xEE};
byte SELF_IP[] = {192, 168, 2, 20};
byte LAURENT_IP[] = {192, 168, 2, 19};
int LAURENT_PORT = 2424;
我们仍然需要一个用于存储网络命令的缓冲区,该缓冲区的大小选择为200字节,并留有一定余量,如果您遇到缺少RAM的问题,则可以将其减少到例如100字节甚至更少。char buf[200];
最后一点是Laurent模块的以太网客户端。现在,我们将使用lclient对象对模块执行所有操作。EthernetClient lclient;
就是这样,现在让我们看一下将命令发送到Laurent模块的函数。void sendLaurentRequest() {
if (lclient.connect(LAURENT_IP, LAURENT_PORT)) {
Serial.print("Command: ");
Serial.println(buf);
lclient.println(buf);
delay(100);
Serial.print("Answer: ");
while(lclient.available() != 0) {
char c = lclient.read();
Serial.print(c);
}
delay(500);
lclient.stop();
} else {
Serial.println("Error sending command");
}
}
如果在端口2424上与Laurent模块建立了连接,则缓冲区的内容将发送到模块并在Serial中复制以进行目测。然后,期望100毫秒并收到模块响应。之后,再次暂停并中断与模块的通信。如果由于某种原因无法建立与模块的连接,则会显示一条错误消息。现在让我们分析一下初始化。以太网初始化是一个简单的功能void ethernetInit() {
Ethernet.begin(SELF_MAC, SELF_IP);
}
Laurent模块由laurentInit()函数初始化,我们将详细分析其操作。它很大,您需要充分理解它,因为可以基于此函数的代码来建立对Laurent模块的自己的请求。void laurentInit() {
Serial.println("Start modul Laurent Init...");
Serial.print("Connect to Laurent... ");
if (lclient.connect(LAURENT_IP, LAURENT_PORT)) {
Serial.println("OK");
lclient.stop();
Serial.println("Selftest...");
sprintf(buf, "$KE");
sendLaurentRequest();
Serial.println("Set password...");
sprintf(buf, "$KE,PSW,SET,Laurent");
sendLaurentRequest();
} else {
Serial.println("failed");
}
delay(500);
sprintf(buf, "$KE,DAT,OFF");
sendLaurentRequest();
delay(100);
sprintf(buf, "$KE,REL,2,0");
sendLaurentRequest();
Serial.println("Modul Laurent Init done");
}
最初,显示初始化消息,并尝试连接到Laurent模块。如果失败,则会显示一条错误消息,并且如果成功连接到模块,则会发送自诊断命令,运行状况良好的模块应使用“ #OK”响应。接下来,发送命令以输入密码(在这种情况下,这是默认密码)。预期为500毫秒。接下来,引入了两个附加命令-其中一个命令停止模块输出的数据(如果有的话),第二个命令关闭我们在实验中使用的2号继电器。换句话说,这些命令将模块带入一些初始状态。这是初始化过程的打印输出,在该过程中所有命令和所有模块响应均可见:Start modul Laurent Init...
Connect to Laurent... OK
Selftest...
Command: $KE
Answer: #OK
Set password...
Command: $KE,PSW,SET,Laurent
Answer: #PSW,SET,OK
Command: $KE,DAT,OFF
Answer: #DAT,OK
Command: $KE,REL,2,0
Answer: #REL,OK
Modul Laurent Init done
现在,标准setup()函数的代码。所有子系统均已初始化,包括以标准9600波特率的串行端口。void setup() {
Serial.begin(9600);
ethernetInit();
laurentInit();
}
因此,我们初始化了模块,并可以按需要的方式对其进行管理:发送命令,读取答案,考虑Laurent模块发出的数据来构建控制逻辑。例如,考虑最简单的任务-定期打开和关闭连接到Laurent模块第二个继电器的灯的光。void loop() {
sprintf(buf, "$KE,REL,2,1");
sendLaurentRequest();
delay(3000);
sprintf(buf, "$KE,REL,2,0");
sendLaurentRequest();
delay(3000);
}
loop()函数是一个无限循环,按照我们的命令,指示灯将连续点亮并每3秒钟熄灭一次。当然,这只是一个例子,实际上,工作的逻辑可以是任何逻辑,而一切都取决于您的需求。当然,您不仅可以发送命令以启用或禁用负载,还可以发送模块支持的其他命令。您可以在Laurent模块的文档中找到命令及其说明的完整列表。您可以采用此草图并将其集成到您自己的项目中,从而增加对管理Laurent模块的支持。反之亦然,以此草图为基础并逐渐增加其功能。完美无止境。这是完整的草图。完整的草图代码#include <SPI.h>
#include <Ethernet.h>
byte SELF_MAC[] = {0x00, 0x2A, 0xF5, 0x12, 0x67, 0xEE};
byte SELF_IP[] = {192, 168, 2, 20};
byte LAURENT_IP[] = {192, 168, 2, 19};
int LAURENT_PORT = 2424;
char buf[200];
EthernetClient lclient;
void ethernetInit() {
Ethernet.begin(SELF_MAC, SELF_IP);
}
void laurentInit() {
Serial.println(«Start modul Laurent Init...»);
Serial.print(«Connect to Laurent… „);
if (lclient.connect(LAURENT_IP, LAURENT_PORT)) {
Serial.println(“OK»);
lclient.stop();
// Send test command
Serial.println(«Selftest...»);
sprintf(buf, "$KE");
sendLaurentRequest();
// Send password (default: «Laurent»)
Serial.println(«Set password...»);
sprintf(buf, "$KE,PSW,SET,Laurent");
sendLaurentRequest();
} else {
Serial.println(«failed»);
}
delay(500);
// DATA
sprintf(buf, "$KE,DAT,OFF");
sendLaurentRequest();
delay(100);
//
sprintf(buf, "$KE,REL,2,0");
sendLaurentRequest();
Serial.println(«Modul Laurent Init done»);
} // laurentInit
void sendLaurentRequest() {
if (lclient.connect(LAURENT_IP, LAURENT_PORT)) {
Serial.print(«Command: „);
Serial.println(buf);
lclient.println(buf);
delay(100);
Serial.print(“Answer: „);
while(lclient.available() != 0) {
char c = lclient.read();
Serial.print©;
}
delay(500);
lclient.stop();
} else {
Serial.println(“Error sending command»);
}
} // sendLaurentRequest
void setup() {
Serial.begin(9600);
ethernetInit();
laurentInit();
}
void loop() {
//
sprintf(buf, "$KE,REL,2,1");
sendLaurentRequest();
delay(3000);
//
sprintf(buf, "$KE,REL,2,0");
sendLaurentRequest();
delay(3000);
}
Arduino Mega服务器
Arduino Mega Server(AMS)是一个功能强大的系统,适用于Arduino Mega(现在也适用于Arduino DUE,不久之后适用于其他32位平台M0(零)和Genuino 101),其中包含代码“适用于所有场合”以及更多其他功能内置服务器和用户友好的Web界面。AMS开箱即用地支持Laurent模块,您无需添加用户逻辑即可。AMS具有模块化结构,打开和关闭模块的操作只需在草图中注释掉一条线即可,例如,#define LAURENT_FEATURE
要么
如果该行被注释掉,则该模块将无法编译,也不会参与工作,如在站点标题中的模块指示符上所示。反之亦然,已编译且工作正常的模块以蓝色表示。在这种情况下,LRT控制模块LRT不起作用。
模块操作指示灯使用Laurent模块响应
现在,让我们添加功能,不仅可以显示模块响应,还可以与它们一起使用,例如分析它们或在Arduino Mega Server网页上显示。为此,我们需要一个新的字符串变量和一个常量,该常量确定分配给Laurent模块答案的字符串的长度。在测试示例中,它等于25个字符,但是如果答案不适合该值,则可以增加它。您只需要记住微控制器的RAM是宝贵的资源,就需要保存它。将以下行从AMS软件包添加到标准laurent.ino模块中:byte MAX_LEN_LREQUEST = 25;
String lrequest = String(MAX_LEN_LREQUEST);
我们还需要更改发出请求的函数的代码(添加的更改用箭头突出显示)。void sendLaurentRequest() {
if (lclient.connect(LAURENT_IP, LAURENT_PORT)) {
Serialprint("Command: ");
Serial.println(buf);
lclient.println(buf);
delay(100);
Serialprint("Answer: ");
lrequest = "";
while(lclient.available() != 0) {
char c = lclient.read();
Serial.print(c);
if (lrequest.length() < MAX_LEN_LREQUEST) {
lrequest += (c);
}
}
delay(500);
lclient.stop();
} else {
Serialprint("Error sending command\n");
}
}
因此,我们学习了如何在lrequest变量中获得Laurent答案,现在我们可以做我们认为适合的任何事情。接下来,我将展示如何直接在AMS网站标题的仪表板上显示查询结果。一个小笔记。本示例使用Serialprint函数而不是标准Serial.print,因为它节省了更多RAM。只需将两个单词的结尾简单地转换为标准的即可。将模块响应输出到站点头
还有最后一个例子。让我们在Arduino Mega Server站点的标题中显示Laurent模块的答案。为此,我们需要将请求添加到AMS草图的main loop()循环中。打开arduino_mega_server.ino文件,并在cyclosInSecWork()函数之前输入以下代码: #ifdef LAURENT_FEATURE
if (cycle30s) {
sprintf(buf, "$KE");
sendLaurentRequest();
}
#endif
此代码将每隔三十秒查询Laurent模块的运行状况。自然,这只是一个例子,在这个地方可以有任何请求和任何代码。因此,在变量lrequest中,我们可以获得有关模块状态的答案,并且现在可以将其显示在站点的标题中。为此,请打开server_ajax.ino模块,最后在cl.println(“”)行之前,在responseDash函数代码(EthernetClient cl)中;添加以下代码: #ifdef LAURENT_FEATURE
sendTagString("laurent", "", lrequest, cl);
#endif
实际上,此代码将模块响应发送到网页。剩下要做的两件事:第一是添加将“捕获”我们的数据的JavaScript代码,第二是AMS页面本身上的HTML代码,其中将显示模块答案。因此,请打开scripts.js文件,并在右括号前的getDashData()函数中// //如果(this.responseXML!= Null)输入将接受我们前提的代码。
try {
var laurent = this.responseXML.getElementsByTagName('laurent')[0].childNodes[0].nodeValue;
} catch (err) {
laurent = "-";
}
document.getElementById("laurent").innerHTML = laurent;
只需稍微校正标准AMS交付中的dash.htm文件并向其添加代码即可在屏幕上显示信息。在包含class =“ online-device”的行之后,立即输入带有代码的新行:<p>Laurent: <span class="value" id="laurent">...</span></p>
就这样。我们已经在Arduino Mega Server站点的标题中显示了Laurent模块的响应。这是我们努力的结果。模块的状态在AMS面板中清晰可见,并且每30秒更新一次,因此,如果模块发生故障,您最多需要30秒才能知道。
结论
如您所见,使用Arduino和Arduino Mega Server管理Laurent模块并不复杂,并且如果您已经有这样的模块或计划将它们添加到Smart Home系统中,那么本文将帮助您轻松而轻松地完成此操作。在下一个周期的下一篇文章中,您将学习如何直接在计算机屏幕上管理劳兰斯,以及如何使教孩子编程的过程更具交互性和趣味性。加法。一个Youtube频道已打开,这是Arduino Mega Server 的促销视频,演示了如何在实际系统上工作。