Laurent Modules and Smart Home (Part 2). Arduino and AMS

    This is the second article in a series on integrating KernelChip’s Laurent modules into home automation systems, and in this part we will focus on integrating these modules with the Arduino ecosystem. In the first part of the series, we talked about integration with MajorDoMo, a popular home automation system, and in the third part you will learn how to manage these modules from sketches in the Processing programming language, right from your computer’s desktop.

    image

    Arduino is our everything


    Where without Arduino? I’m not going to describe the advantages of this platform for a long time, its popularity speaks for itself, so let's immediately get down to the technical details of the interaction between Arduino and Laurent modules. And along the way, we will not forget the Arduino Mega Server system , as a very interesting derivative of the Arduino ecosystem.

    Iron


    For controlling modules over the network, for example, the common Arduino Uno board or the equally popular Arduino Mega board complete with an Ethernet Shield network interface card assembled on the basis of the W5100 chip are suitable. All examples in this article are given for such a combination and have been tested in practice. Everything works reliably and without any problems.

    image
    Ethernet Shield based on the W5100 chip

    That is, you just have to take the sketch and upload it to your Uno or Mega board, after changing it a little for your tasks.

    Manage Sketch Modules


    In the first part of the series, I already talked about the principles of managing Laurent modules over the network, for those who have not read the first part, I will briefly repeat the theory here.

    Information is exchanged with the modules over the network and to start working with them you need to establish a TCP / IP connection on port 2424. Once the connection is established, you can send text commands (so-called KE commands) which control the module. The KernelChip website has detailed documentation, including an accessible description of KE commands.

    Now let's try to translate this theoretical “terms of reference” into the plain language of Arduino's sketches.

    Sketch


    I will not explain here how to install and configure the Arduino programming environment, it is assumed that you have already done this and are able to write simple sketches. So, for starters, we need to connect the necessary libraries SPI.h and Ethernet.h to control the bus and the Ethernet module itself.

    #include 
    #include 

    Then you need to set the network settings for the Ethernet module and Laurent module, which we will manage. Note that MAC addresses and IP addresses must be unique, and LAURENT_PORT must be set to 2424 and no other.

    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;
    

    We still need a buffer for storing network commands, it is selected with a size of 200 bytes with some margin, if you have problems with a lack of RAM, then you can reduce it, for example, to 100 bytes or even less.

    char buf[200];
    

    And the final touch is the Ethernet client for the Laurent module. Now we will carry out all operations with the module using the lclient object.

    EthernetClient lclient;
    

    That's it, now let's look at a function that sends commands to the Laurent module.

    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");
        }
    }
    

    If a connection is established with the Laurent module on port 2424, the contents of the buffer are sent to the module and duplicated in Serial for visual inspection. Then 100 milliseconds are expected and the module response is received. After this, a pause again and communication with the module is broken. If for some reason the connection to the module could not be established, an error message is displayed.

    Now let's analyze the initialization. Ethernet initialization is a simple function

    void ethernetInit() {
      Ethernet.begin(SELF_MAC, SELF_IP);
    }
    

    And the Laurent module is initialized by the laurentInit () function, the operation of which we will now analyze in detail. It is quite large and you need to understand it well because it is on the basis of the code of this function that you can build your own requests to Laurent modules.

    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");
    }
    

    Initially, an initialization message is displayed and an attempt is made to connect to the Laurent module. If this fails, an error message is displayed, and if the connection to the module is successful, a self-diagnosis command is sent, to which the healthy module should respond with “#OK”.

    Next, a command is sent to enter the password (in this case, this is the default password). And 500 milliseconds is expected.

    Next, two additional commands are entered - one of them stops the data output by the module (if it goes), and the second turns off relay No. 2, which we use in our experiments. In other words, these commands bring the module to some initial state.

    Here is a printout of the initialization process on which all commands and all module responses are visible:

    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
    

    Now the code for the standard setup () function. All subsystems are initialized, including a serial port at a standard 9600 baud rate.

    void setup() {  
      Serial.begin(9600);  
      ethernetInit();
      laurentInit();
    }
    

    So, we initialized the module and can manage it in the way we need: send commands, read answers, build control logic taking into account the data issued by the Laurent module.

    Consider, for example, the simplest task - to turn on and off at regular intervals the light of a lamp connected to the second relay of the Laurent module.

    void loop() {
      // включаем реле
      sprintf(buf, "$KE,REL,2,1");
      sendLaurentRequest();
      delay(3000);
      // выключаем реле
      sprintf(buf, "$KE,REL,2,0");
      sendLaurentRequest();
      delay(3000);
    }
    

    The loop () function is an endless cycle and the lamp, obeying our commands, will continuously light up and go out every 3 seconds. This, of course, is just an example, in fact, the logic of work can be any and everything depends on your needs. And of course, you can send not only commands to enable or disable loads, but also any others supported by the module. You can find the complete list of commands and their description in the documentation for Laurent modules.

    You can take this sketch and integrate it into your own projects, thus adding support for managing Laurent modules to them. Or vice versa, take this sketch as a basis and gradually increase its functionality. There is no limit to perfection. Here is the full sketch.

    Full sketch code
    #include
    #include

    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);

    // stop issuing DATA
    sprintf (buf, "$ KE, DAT, OFF");
    sendLaurentRequest ();
    delay (100);

    // turn off the relay
    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 () {
    // enable the relay
    sprintf (buf, "$ KE, REL, 2.1");
    sendLaurentRequest ();
    delay (3000);

    // turn off the relay
    sprintf (buf, "$ KE, REL, 2.0");
    sendLaurentRequest ();
    delay (3000);
    }


    Arduino Mega Server


    image

    Arduino Mega Server (AMS) is a powerful system for Arduino Mega (now also for Arduino DUE and, soon, for other 32-bit platforms M0 (Zero) and Genuino 101), which contains the code “for all occasions” and plus built-in server and user-friendly web interface. AMS supports Laurent modules right out of the box and you do not need to add anything other than user logic.

    AMS has a modular structure and switching modules on and off is done by simply commenting out a line in a sketch, for example,

    #define LAURENT_FEATURE
    

    or

    //#define LAURENT_FEATURE
    

    If the line is commented out, then the module does not compile and does not participate in the work, as can be seen on the indicators of the modules in the header of the site. Or vice versa, a compiled and working module is indicated in blue. In this case, the LRT control module LRT does not work.

    image
    Module Operation Indicators

    Working with Laurent module responses


    Now let's add the ability to not only show module responses, but also work with them, for example, analyze them or display them on Arduino Mega Server web pages. To do this, we need a new string variable and a constant that determines the length of the string that we assign to the answers of Laurent modules. In the test example, it is equal to 25 characters, but you can increase it if the answers do not fit into this value. You only need to remember that the microcontroller's RAM is a valuable resource and you need to save it. Add the following lines to the standard laurent.ino module from the AMS package:

    byte MAX_LEN_LREQUEST = 25;
    String lrequest = String(MAX_LEN_LREQUEST);
    

    We also need to change the code of the function that makes the requests (the added changes are highlighted by arrows).

    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");
        }
    }
    

    Thus, we learned how to get Laurent answers in the lrequest variable and now we can do whatever we see fit with it. Next, I will show how to display the results of queries directly in the dash panel in the header of the AMS site.

    A small note. This example uses the Serialprint function instead of the standard Serial.print because it saves more RAM. And it can be easily transformed into a standard one, simply by putting an end to two words.

    Outputting the module response to the site header


    And the last example. Let's display the answers of the Laurent modules in the header of the Arduino Mega Server site. To do this, we need to add the request to the main loop () loop of the AMS sketch. Open the arduino_mega_server.ino file and enter the following code before the cyclosInSecWork () function:

        #ifdef LAURENT_FEATURE
          if (cycle30s) {
            sprintf(buf, "$KE");   
            sendLaurentRequest();
          }
        #endif
    

    This code will request the health status of the Laurent module every thirty seconds. Naturally, this is just an example, at this place there can be any request and any code. Thus, in the variable lrequest we have an answer about the state of the module and can now display it in the header of the site. To do this, open the server_ajax.ino module and at the very end, in the responseDash function code (EthernetClient cl), before the line cl.println (""); add the following code:

        #ifdef LAURENT_FEATURE
          sendTagString("laurent", "", lrequest, cl);
        #endif
    

    This code, in fact, sends the module answers to the web page. It remains to do two things: the first is to add code in the JavaScript language that will “catch” our data and the second is the HTML code on the AMS page itself, where the module answers will be displayed.

    So, open the scripts.js file and in the getDashData () function before the closing bracket} // if (this.responseXML! = Null) enter the code that will accept our premises.

              // Laurent
              try {
                var laurent = this.responseXML.getElementsByTagName('laurent')[0].childNodes[0].nodeValue;
              } catch (err) {
                  laurent = "-";
                }
              document.getElementById("laurent").innerHTML = laurent; 
    

    It remains only to slightly correct the dash.htm file from the standard AMS delivery and add code to it that will display information on the screen. Immediately after the line containing class = "online-device" we enter our new line with the code:

    Laurent: ...


    That's all. We have displayed Laurent module responses in the header of the Arduino Mega Server site. And here is the result of our efforts. The status of the module is clearly visible in the AMS panel and it is updated every 30 seconds, so if something happens to the module, you will know about it after a maximum of 30 seconds.

    image

    Conclusion


    As you can see, there is nothing complicated in managing Laurent modules using Arduino and Arduino Mega Server, and if you already have such modules or are planning to add them to your Smart Home system, this article will help you to do this easily and simply.

    And in the next article from the series, you will learn how to manage Loranes directly from the screen of your computer and how to make the process of teaching children programming interactive and more interesting.

    Addition . A Youtube channel is open and here is a promo video of the Arduino Mega Server, which demonstrates how to work with a real system.

    Also popular now: