The from XBee to Mirror

May 24th, 2014 7 min read

Github

The source code or files in this post are available on GitHub.

Series

This post is part of the Annoying Dishwasher series. Check out the other posts here:

    Tags

    Ads via Carbon

    So, The Annoying Dishwasher™ finally lost it’s vocal cords of hell and got connected an XBee using some optocouplers. It is time to jump into geek mode (as if we weren’t there yet …), and start the software part.

    But, before we do, let’s take a look at the setup: 

    image
    • I’m using a Raspberry Pi as server to handle all the information.
    • An USB to TTL (old school serial communication) cable connects the Raspberry to …
    • A XBee Module configured as Coordinator. This XBee is in charge of all other XBee modules.
    • An other XBee is wirelessly connected to the the coordinator and wired to the dishwasher using my own pcb.

    Configuring the XBee modules

    Configuring an XBee module is done using XCTU. It appeared to be Windows only, but after some searching around, I finally found the Mac version. Thank you Digi! :)

    The process of configuring a XBee isn’t all that complicated, but it takes some time to figure out what settings need to be adjusted. There are some pretty clear tutorials on Youtube on how to configure them.

    In my case a few specific setting were necessary.

    • Configure XBee 1 as Coordinator and put it in API mode.
    • Configure XBee 2 as Endpoint and leave it in AT mode.
    • Set the 16 bit address of XBee 2 to 0001. This way I can distinguish the endpoint XBee modules if I add more in the future. (Assuming I use a unique address for every XBee.
    • Set the DIO0 pin to digital input.
    • Set the Sample Rate to 1000 milliseconds. Which is HEX value: 3E8.

    After setting above settings and connecting the XBee 2 to the dishwasher’s PCB, it connected to the XBee Coordinator and started emitting DIO0’s pin status every second. It works! Or as a famous engineer once said:

    It’s alive, ALIVE!

    image

    Using XCTU’s Serial monitor i saw the raw data coming in every second:

    7E 00 13 97 55 00 13 A2 00 40 52 2B AA 7D 84 53 4C 00 40 52 2B AA F0
    

    Now, I don’t know about you … but raw data like this really doesn’t get me excited. So the next part of the job was making this a bit more useful. Luckily some genius named Jan Kolkmeier has developed a Node.js module to handle this raw data. So Node.js, here we come!

    Developing the Node.js application: XBee Monitor

    Before I started the development of the Xbee Monitor application, I installed Node.js on my Raspberry Pi. After this was done I additionally needed to install some Node.js modules, including the just mentioned Xbee Node.js module. Installing these modules can be done usingnpm:

    npm install xbee-api        # Install the XBee Node.js Module
    npm install serialport      # Install the module to use the serial port.
    npm install express         # Install the express module to use the app as webserver.
    npm install socket.io       # Install the Socket.io module to use web sockets.
    

    As you can see I am using Socket.io. This is because I want realtime communication to other devices like my Magic Mirror. Those devices can connect using web sockets and will be informed as soon as the dishwasher is ready. Not only does this enable perfect two way communication between a server (node application) and a client (website), but it also allows server to server communication. Which. Is. AWSOME! … for future projects.

    That being said, it’s time to do some programming and show you how we can use Node.js to read out the status of my dishwasher. All of this programming is done in one simple file: xbeeread.js.

    First of let’s set up the socket server on port 8080 so we can let the Magic Mirror connect to this node app:

    var express = require('express');
    var app = express();
    var io = require('socket.io').listen(app.listen(8080));
    

    Next, we need to create an XBeeAPI parser and connect it to the XBee module using the serial port. The right path of the serial port can be found by looking in the /dev folder. Be aware of the fact that this path can change if you unplug and plug the USB to TTL cable.

    //set up xbee system
    var xbee = require('xbee-api');
    var xbeeAPI = new xbee.XBeeAPI({
        api_mode: 1
    });
    
    //open serial port
    var SerialPort = require('serialport').SerialPort;
    var serialport = new SerialPort("/dev/ttyUSB0", {
        baudrate: 9600,
        parser: xbeeAPI.rawParser()
    });
    

    Additionally, some helper variable will come in handy:

    var dishwasherDone = false;
    var changeCount = 0;
    

    Now we have our communication to the XBee up and running, so it’s time to start listening for data. Something the XBee API modules calls frame_objects.

    xbeeAPI.on("frame_object", function(frame) {
        //handle the frame here.
    }
    

    We handle the frame by checking the 16 bit address. If this is 0001 we know it’s the dishwasher:

    if (frame.remote16 == '0001') {
        //It's the dishwasher!
        //Let's check the status.
    }
    

    Checking the status is achieved by reading out the frame’s data object. If the fourth element of this array is equal to 0, the dishwasher is done. Otherwise it’s still doing it’s job as my personal worker. I compare the new status with the earlier known status to check if it has changed.

    If the status is changed, I increase the change count. If the change count hits 5, I’m absolutely sure the status has changed. I use this counting mechanism to prevent unwanted status changes (for example by a problem with the pull down resistor). As soon as the status change is confirmed, the we store the new status and emit the new status to all socket connected clients.

    var done = (frame.data[4] === 0) ? true : false;
    
    if (done != dishwasherDone) {
        //status changed
        //increase the change count
    
        changeCount++;
    
        if (changeCount >= 5) {
                dishwasherDone = done;
    
                console.log(Date.now() + ' - Dishwasher done: ' + dishwasherDone);
    
                //broadcast new state to socket clients
                io.sockets.emit('dishwasher', dishwasherDone);
        }
    
    } else {
        //still the same status.
        //reset the change count.
    
        changeCount = 0;
    }
    

    An that’s all there is to create this server. Running it is as simple as typing: node xbeeread.js.

    Connecting to the XBee Monitor Server.

    Now, running this server without connecting isn’t very useful. Therefor I’m gonne use this server to display the dishwasher’s info on myMagic Mirror. To do this, we need to include the socket.io javascript library in the HTML. Since I don’t want to rely on my Raspberry Pi for this, I use a Content Delivery Network:

    <script src="http://cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js"></script>
    

    Additionally, I add a div in the body of the HTML displaying ’Vaatwasser is klaar!’ which is dutch for ’Dishwasher is ready!’:

    <div class="center-ver center-hor"><div class="dishwasher light">Vaatwasser is klaar!</div></div>
    

    And use CSS to type this div:

    .dishwasher {
        background-color: white;
        color: black;
        margin: 0 200px;
        font-size: 60px;
        border-radius: 1000px;
        border-radius: 1200px;
        display: none;
    }
    

    Last but not least some javascript code in main.js will do all the magic work. If the dishwasher is done it will fade in the notification and hide the compliment. As soon as the dishwasher is reset, the opposite will happen.

    //connect do Xbee monitor
    var socket = io.connect('http://rpi-development.local:8080');
    socket.on('dishwasher', function (dishwasherReady) {
        if (dishwasherReady) {
            $('.dishwasher').fadeIn(2000);
            $('.lower-third').fadeOut(2000);
        } else {
            $('.dishwasher').fadeOut(2000);
            $('.lower-third').fadeIn(2000);
        }
    });
    

    That, ladies and gentlemen, is all there is. In my opinion less work than doing the dishes. ;)

    All code is available on GitHub. But be aware. Some of it might already be changed a bit due to future projects:

    Built your first Node.js server yourself? And want it to keep running? You might want to check out Forever.

    Now, what more can I connect to my XBee server? Suggestions are more than welcome in the comments.

    Loading comments …
    ©2021 - MichaelTeeuw.nl