Enter Moteino

Having played few days with Arduino Mini and the NRF24L01+ transceiver I came into conclusion that I wanted something more compact with lower power consumption. After some hours of coffee-powered research two top contesters surfaced: Jeenode and Moteino. Also there’s an upcoming ultra-low power arduino clone ULPNode which uses few quite interesting power saving techniques, that makes it possible to reach nanoampere scale basal power consumption when in deep sleep. Unfortunately prototypes are not yet available for purchasing but I will for sure try those out in the future!

Also one thing to consider is that these levels of ultra-low consumption can be implemented on a real-life sensor only when the sensor part itself can be put to sleep (for example with periodical temperature measurements). Since most of my sensor devices in planning will use at least one active sensor (PIR motion sensor mainly), it is irrelevant whether the board uses few microamps vs few dozen nanoamps when the PIR sensor itself uses 50 microamps in standby-mode.

Both Moteino and Jeenode use the low quiescent current MCP1703 voltage regulator and don’t include any kind of LED to indicate power on status (unnecessary power hogs), so low current consumption and long battery life could be obtained even without modifying the hardware.

In the end, I voted for Moteino for following reasons:

  • Compact and quite nice looking
  • RFM69W wireless chip (vs older RFM12B in Jeenode with no HW level encryption)
  • active user base and forum
  • few euros cheaper than JeeNode (not really a deciding factor, but nice to know if you are planning to spread your house full of these sensors..)

Testing

Testing Moteino on breadboard with FT232 USB adapter

Testing Moteino on breadboard with FT232 USB adapter

Here’s Moteinos sleep mode consumption after some testing:

  • 23 microamps (16 Mhz, BOD off, 5.0V to Vin)
  • 1.3 milliamps (16 Mhz, BOD off, 3.3V bypassing MCP1703).
    Wow, The regulator sure doesn’t like to be left idle 🙂
  • 22 microamps (16 Mhz, BOD off, 3.3V in, MCP1703 desoldered)
  • 20 microamps (8 Mhz, BOD off, 3.3V in, MCP1703 desoldered)

Note that also the RFM69 needs to be put to sleep (with the transmitter awake but idle I measured 1 milliamp higher values).

Whan transmitting packets the consumption jumps to few dozen milliamps, but this is inconsequential, since the transmitter and CPU will be in deep sleep 99% of the time, awakened only by interrupts from the sensor or hardware watchdog.

So, the setup and assumed current consumption is as follows (values for sensors are from datasheets, I didn’t test sensors separately):
* Moteino @ 16 Mhz: 23 uamps (I didn’t bother with 8 Mhz since at this stage the 2 microamp difference in consumption is negligible)
* 4xAA batteries (calculated later)
* DHT22 temperature and humidity sensor (40-50 uamps)
* PIR sensor (50 uamps)
* Voltage divider setup with a capacitor to measure 4-6V battery voltage (few microamps with 1 Mohm resistor)
* Motion detected LED (0 uamps off)

First prototype

I tossed the parts into left-over junction box. Better looking enclosure would have been nice, but unfortunately I don’t currently have tools nor working area in my current apartment to process suitable materials.

First prototype of bathroom motion sensor. This isn't going to win any beauty contests, but it works :)

First prototype of bathroom motion sensor. This isn’t going to win any beauty contests, but it works :)

Note that the 433 Mhz version of RFM69W seen here needs (or better said, is recommended to have) 17.2 cm antenna and is actually shipped with a 16,5 cm one since the PCB traces make up for the remainder. Now, in my tests I found out that I don’t need that long wire sticking out vertically, but can just route it inside around the edges of the enclosure. Even this gives it plenty of signal strength to transmit through 2 thick walls two rooms across. Good enough.

IMG_0053[1]

I measured the current consumption to be 104 microamps @ 5V, which is quite in the ballpark expected! With ideal situation (0% monthly battery discharge) this sensor would last for 4*2000 mAh / 0.104 = 76923 hours = 8.78 years 🙂 Of course now the self-discharge of NiMH batteries start to matter considerably: Cheap NiMH batteries have as high as 20-30% discharge rate, whereas better Sanyo Eneloops (3rd gen) are specified to hold 70% charge after 5 years! Now this would be an almost set-and-forget situation. Actually I just recently ordered a pack of Eneloops, so I think this is going to end up being a field-test lasting for few years 😀

Pairing with Openhab

Now, let’s concentrate on software a bit. Since MySensors supports only the NRF24L01+ and it’s libraries seem to be quite tightly coupled with it’s hardware functionality, I had to find a replacement. After some digging I came across this nicely done pack of libraries for MQTT Gateway and Sensor made by Computourist. With just a few tweaks I was able to fire up (not literally) the sensors and get them to communicate with Openhab. Unlike MySensors MQTT gateway, this one isn’t MQTT server but just normal client so no MQTT server bridging was necessary. Just configure the MQTT server IP address:port in the sketch and Moteino gateway connects automatically and will also keep on trying should it lose the connection to the MQTT server.

MQTT Gatewey will send and receive messages in a fixed notation such like these:

pi@raspberrypi:/opt/openhab# mosquitto_sub -v -t '#'
home/rfm_gw/nb/node02/dev02 -61
home/rfm_gw/nb/node02/dev04 5.2
home/rfm_gw/nb/node02/dev48 24.38

Here nb=northbound (messages from nodes/sensors to the server), sb=southbound (messages from server/openhab to nodes). Devices (items residing inside a node) will be defined per-node basis and could be anything from sensors, actuators to node setting containers. For example commands

pi@raspberrypi:/opt/openhab# mosquitto_pub -t home/rfm_gw/sb/node03/dev00 -m "READ"
pi@raspberrypi:/opt/openhab# mosquitto_pub -t home/rfm_gw/sb/node03/dev04 -m "READ"

could be used to read uptime and battery voltage of node #3.

pi@raspberrypi:/opt/openhab# mosquitto_pub -t home/rfm_gw/sb/node03/dev01 -m 60

Could be used to set periodic transmission interval to 60 seconds. Actual implementation depends on sensor, but these libraries give quite nice framework to work upon.

To accept messages from MQTT Gatewey we just define new items in the Openhab .items file to match the new sensors:

Contact Bathroom_Motion_Sensor {mqtt="<[mosquitto:home/rfm_gw/nb/node03/dev40:state:MAP(switchFromMqtt.map)]"}
Number Bathroom_Temperature  "Bathroom temperature [%.1f C]"   <temperature> {mqtt="<[mosquitto:home/rfm_gw/nb/node03/dev48:state:default]"}
Number Bathroom_Humidity  "Bathroom humidity [%.1f %%]" {mqtt="<[mosquitto:home/rfm_gw/nb/node03/dev49:state:default]"}
Number Bathroom_Sensor_Voltage  "Bathroom sensor voltage [%.1f V]"  {mqtt="<[mosquitto:home/rfm_gw/nb/node03/dev04:state:default]"}

We also need to map the state of the motion sensor (ON/OFF) to a state shat the "Contact" item understands (CLOSED/OPEN). That is done in switchFromMqtt.map (referenced above with MAP(switchFromMqtt.map):

ON=CLOSED
OFF=OPEN

PIR sensor and light rules

Then some timer magic is created to turn on the bathroom light when motion is detected:

import org.openhab.core.library.types.*
import org.openhab.core.library.items.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*

var Timer BathRoomTimer = null
var Integer timeOut = 120

rule "Bathroom Motion Sensor Trip"
        when
        Item Bathroom_Motion_Sensor received update
        then
        {
        logInfo("Bathroom motion Sensor", "sensor changed state")
        if (BathRoomTimer == null ) 
            logDebug("Bathroom Motion Sensor","timer==null")
        else                        
            logDebug("Bathroom Motion Sensor","timer!=null")
        if(Bathroom_Motion_Sensor.state == CLOSED)
            {
            if (BathRoomTimer == null ) 
                {                       
                // create timer
                logInfo("Bathroom Motion Sensor", "creating timer: " + timeOut + " sec")
                BathRoomTimer = createTimer( now.plusSeconds(timeOut) )
                    [ 
                        logInfo("Bathroom Motion Sensor", "timer expired, switching off ")
                        sendCommand(Bathroom_Light_Toggle,OFF)      
                        BathRoomTimer=null
                    ]               
                sendCommand(Bathroom_Light_Toggle, ON)
                sendCommand(Bathroom_Light_CT_Dimm, Light_Temperature.state as DecimalType)
                } 
            else
                {
                logInfo("Bathroom Motion Sensor", " rescheduling timer:" + timeOut + " sec" )
                BathRoomTimer.reschedule(now.plusSeconds(timeOut))
                }
            }
        }
    end

Everything seemed to work just fine, but when I took a shower in the morning, PIR sensor couldn't obviously detect any movement behind shower curtain and eventually the light was turned off again, me still in the shower 🙂 Hmm.. Either I could extend that delay period to few minutes (lazy option), OR I could use humidity sensor to detect rise in humidity above a certain threshold (when shower is being used) and extend the delay only then. I chose the latter, more elegant option:

var Integer timeOutWithShower = 300

rule "Bathroom Motion Sensor Humidity"
    when
        Item Bathroom_Humidity received update
    then
    {
        logInfo("Bathroom Humidity Sensor", "bathroom humidity changed")
        if( ( BathRoomTimer != null) && (Bathroom_Humidity.state > 60) )
        {
            logInfo("Bathroom Humidity Sensor", " shower on - rescheduling timer for bathroom in " + timeOutWithShower + "sec" )
            BathRoomTimer.reschedule(now.plusSeconds(timeOutWithShower))
        }
    }
    end             

This required also changes sensor-side, since in normal mode humidity would be measured only every few minutes. I implemented a "perceptive mode" to start measuring temperature and humidity every few seconds after motion is detected. Mode is then switched back to normal after 1 minute. This gives enough time for humidity sensors to react (in fact humidity goes over 50-60% in just 20 seconds after shower is turned on.)

Next coming: Dash of Z-Wave sorcery!

Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *