Building a cat detection system using HFS-DC06 microwave sensor with data logging and notifications

Project by: Mohammad Qasem (mq222bp)

This project aims to create a baseline or a little more than a POC (Proof Of Concept) for how to create a wireless movement detection unit that can detect the change of speed of any electrically conductive object including animals and humans, as well as a home unit consisting of a microcontroller with an that with the help of wireless module can communicate with the microcontroller inside the detection unit.

In it's current state this project is not optimized for power saving but it can easily be modified to accomplish that (recommended).

Time approximation: 3 hours

Objective

As an outside-cat 😸 owner I always had the problem of having to check the balcony to see if my cat is back home or not. I manly have to do that because my cat never tries to grab attention when he is back but rather decides to just sleep on the chair outside drawing the sympathy of everyone passing by. I therefor came up with the idea of a waterproof enclosure with a sensor and a microcontroller inside that would send a signal to another microcontroller placed inside the house that would notify the family whenever the cat is back.

This project should be able to give you a bit of idea on how to read data from sensors as well as how to communicate wirelessly between 2 microcontrollers.

Material

Detection Unit:

📃Name 💲Price 🔗Link 🔨Usage 💬Comments
1x HFS-DC06 ~7.22$ Link Used to detect the cat when it walks into the balcony. There are cheaper sensors out there but what makes this one stand out is the easily adjustable sensitivity and delay as well as the 180 degree detection area contrary to the 360° on most other sensor.
1x DHT22 ~4.29$ Link Used to measure temperature and humidity inside the enclosure. Not really necessary.
1x DC-DC Boost Converter (Step Up) ~2.82$ Link Used to smooth the voltage going to the HFS-DC06 sensor, Can be replaced with any smoothing circuit. It is not used to boost the 5v input at all. 5v in ➡ 5v out.
1x Arduino Pro mini 3.3v ~7.83$ Link Reads data from DHT22 and HFS and decides when the data should be sent to the home unit. The brain of the detection unit. Can be replaced with any similar board or any other board if you account for the differences.
1x FT232RL FTDI USB To TTL Serial Converter Adapter ~3$ Link Used to program the Arduino pro mini IMPORTANT Make sure to move the jumper to the 3.3v position to match your Arduino board voltage otherwise you will fry your Arduino board.
1x USB breakout board <1$ Link Used as a main input port to power the detection unit . Optional, but can make life easier.
1x NRF24l01+ or non-plus ~2$ Link Used to communicate with the home unit. You might also need a 10uF capacitor or even better ➡ Link, Also you can ditch that entirely and use a ESP board but you will have to optimize the power usage.
1x Waterproof ABS Plastic Electronic Box ~9$ Link Used to house the electronics and protect them from humidity, water, rain and snow. I got the 200x120x75mm one but it's dependent on your components, especially the battery.
1x Omni Plus Metal Powerbank 20.000 mAh ~75$ Link Used as the main power source for the detection unit Not recommended. I bought along time ago when there was a great discount on it. You can get power banks with much bigger capacity for a lower price or you can use a lipo/lion battery with a charge and protection circuit if you want to cut down on space.
1x Strong Velcro tape ~10$ Link Used to stick the power bank to the lid of the enclosure. I really recommend this one since it has super strong Velcro with good adhesive side.

Home Unit:

📃Name 💲Price 🔗Link 🔨 Usage 💬 Comments
1x LILYGO TTGO LORA32 868Mhz ~17.13$ Link Used as the brain of the main unit. Has 2 buttons to control the unit and send commands. Again any other similar microcontroller works, you can also use an external SPI OLED Screen
2x 6mm push button <1$ Link Used as the direct input to the TTGO board Didn't buy it since I already had it
1x Passive Buzzer <1$ Link Used as an acoustic indicator of either cat or high temperature Didn't buy it since I already had it
1x NRF24l01+ or non-plus ~2$ Link Used to communicate with the detection unit. You might also need a 10uF capacitor or even better ➡ Link. Also you might want to use the amplified version but make sure you got a good power source.

Other:

📃Name 💲Price 🔗Link 💬 Comments
Raspberry pi 4 ~46$ Link Used as a backend server and MQTT broker (optional if you want to ditch datalogging and telegram notifications)
Dupont header kit ~4$ Link Recommended. Can be very useful and it makes for a solid enough connection without any permanent bonds
Jumper Cable DuPont Wire Rainbow Flat Wire ~9$ Link Not Recommended. Or at least not from this seller. The one I got had a very strong paint smell. The wires are aluminum with copper colored coating so solder NEVER sticks to them. A better alternative would be ➡ Link

Notes and recommendations:

The choice of the microwave sensor is specific to my use case. I wanted a sensor that:

  1. Could sense my cat without annoying it, so no ultra sound (has been tested and it really disturbs MY cat, your cat might not react in the same way)
  2. Can be placed outside without being effected by the sun (PIR Out)
  3. Don't want to drill a hole in the enclosure and have to re-seal it

with all that in mind the doppler effect sensors were the way to go. The reason I settled on the more expensive HFS-DC06 is because it's easily adjustable as not to be so sensitive and detect the neighbors going into the building or walking past the balcony, and also for having a 180 degrees filed of sense instead of the more common 360 degrees found on other sensors.

If you decide to follow this tutorial and use the NRF24l01 then I really recommend using the base module and applying a stable 5v instead of applying direct 3.3v from the microcontroller like I did since it will lead to more stability. Also I would recommend ditching the TTGO LORA32 board for a different board with ESP8266 and running circuitpython instead of micropython since it has a much better library for the NRF24l01 module.

The Project consists of 3 Parts or main units:

  1. The detection unit.
  2. The home unit.
  3. The Raspberry pi backend unit.

Every one of those 3 stages has some kind of improvement or adaptation that can be done. I can never say for sure which modification is best since it is very case specific but one thing I can say for sure is that you will need to do some kind of modification either in the software or hardware to get the best out of this project. You don't need a home unit and a phone notification is enough? Replace the Arduino pro mini with an ESP board with deep sleep and you're good to go. You don't care for datalogging and just need a simple acoustic indication? ditch the raspberry pi. *** You want a simple, cheap, easy, and power efficient setup?** Train you cat to ring a bell and voila!!

One thing that I am considering is to ditch the NRF24l01 and the Arduino pro mini in favor of a cheap ESP module and using MQTT to communicate with the Raspberry PI backend and the home unit. Although that would probably work nicely I still prefer to have a setup that would work even without the raspberry PI broker.

Computer setup

The detection Unit:

For the detection unit I used Arduino IDE and connected the Arduino board to the FTDI module which I connected to my computer through USB. To upload the code to the Arduino board all I had to do was:

  1. Choose the board type: "Arduino Pro or Pro mini".
  2. Choose the processor type: "Atmega328p (3.3v 8Mhz)"
  3. Choose the correct serial port (for example COM4).
  4. Click on the upload button

The home unit:

I used VSCode since I am fairly familiar with it and already am using it for a multitude of other things. The only thing needed to proceed was to install Pymakr VSCode Extension following this tutorial. I also installed micropy-cli in order to get Intellisense support for micropython libraries by following this tutorial.

Uploading code to the device was very easy:

  1. Make sure all the files that I need are in the src folder and all the libraries that I want to upload are in the lib folder.
  2. Make sure that I am connected to the device and that the device is plugged in.
  3. Click the upload button.

The devices then resets on it's own but if that's not the case you can manually reset the device using the RST button.

The Raspberry Pi MQTT broker and backend:

Now all that was left to do is to install Mosquitto MQTT broker by following this tutorial. Then I installed NodeRed by following this tutorial, and to be able to store data and visualize it I set up Grafana along side InfluxDB by following this tutorial.

Before proceeding we are also going to add a few pallets to NodeRed:

📃 Name 🔨 Usage 🔗 Link
node-red-contrib-influxdb 0.4.1 Used to store data to the local influxDB Link
node-red-contrib-binary 0.1.3 Used to parse the binary struct that will be sent from the detection unit through the main unit Link
node-red-contrib-telegrambot 8.1.0 To be able to send and receive messages and commands from a telegram bot Link

Putting everything together

Home

The detection Unit:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

In the schematics above you won't need R1 resistor if you use the DHT22 breakout board listed in the material list above since it already comes installed. However if you use the sensor on it's own without the breakout board then you will need to place a 1k Ω resistor between VCC and DATA.

The "PowerBank Button +" is connected to the high lead of the on button of my power bank. This isn't necessarily the same for you and probably is not the same. More on that later.

The boost converter might be needed since some reported having an issue with just supplying 5V to the sensor and needed to boost it to 6V or more. However I solved my issues by using a boost converter without actually boosting the voltage. The reason boost converters solve the problem is probably because it soothes it out not because it is boosting it and therefore you can just use a regular 5V power source and just use a circuit to smooth it out.

The 1k Ω and 2k Ω between GND and OUT of the HFS-DC06 sensor are a simple voltage divider. Since the OUT pin of the sensor is 5V HIGH when it detects movement we need to reduce the voltage to 3.3V so we don't fry the Arduino. This also means that you won't need to do that if you have a 5V board or if you power the board with 3.3V which I don't recommend. I also didn't check the voltage level when the sensor is supplied with a voltage higher than 5V since it can actually withstand higher voltages than 5V.

The resistors values were calculated using the formula:

Vout=VsR2R1+R2
Where Vout is the voltage we want at the end of the division which in our case is 3.3V
And Vs is the source voltage we are getting from the OUT pin on the sensor which in our case is 5V

I choose R1* to be 1k Ω and if we substitute all the values we get:


3.3=5R21000+R2
If we solve for R2 we get 1.941 and the closest resistor value we have to that is 2K Ω. As you might have noticed we can use other resistor values if we use the same ratio between R1 and R2 but that's only in theory. In practice we have to account for current and power that will be running through the resistor so it doesn't overheat and burn.

To wire everything up I used multi-core copper wires and crimped DuPont terminals to the end so that I can easily connect them to the Arduino board and the sensors without worrying about having a permanent connection. The HFS-DC06 sensor however was soldered to the boost convert out. I also created a 3D printed holder and a little bit of electrical tape to keep everything in place. After everything was wired up it looked something like this:

In the picture you can also see that I have added a 10uF between VCC and GND of the NRF24l01 module. This has been confirmed by many to lead to better performance and more stability. I still however recommend using a base module and supplying 5V to the base module from a good power source aka not the Arduino :P .

You might have noticed that the power bank is missing and that there is no more space for it. The power bank I got is quit big and heavy and would not fit into the enclosure if placed on it's edge and it will take more than 75% of the space if placed facing down. My solution was to use the empty space above the components by sticking some Velcro to the enclosure lid and to one side of the power bank as such:

Power bank auto shut-off:

Most power banks if not all have a feature that prevents battery drain by shutting down that battery after a specific amount of time if not enough current is being drawn. The current draw of the current setup is around 50mA. The power bank seems to require more than 100mA. I also measured the time between the absence of current and the power shut-off and found that it was exactly 30 seconds . Some power banks do have a so called "always on mode" which can be accessed in different ways such as holding a button for a set amount of time. I tried multiple different ways but with no success and never got an answer from the manufacturer regarding the feature. After looking on the internet I found that some people add a dummy load which increases current rate or create a circuit that draws high current for a short amount of time every now and then to reset the battery timer. My solution was based on the fact that the power bank button resets the timer if clicked during the 30 seconds delay (holding the button has no effect). So knowing that I opened the power bank and checked the button with my multimeter do discover that it was normally closed with 3.1V. That meant I could just pull that signal to ground by connecting it to a GPIO pin set as OUTPUT LOW on my Arduino. So I soldered a wire to the buttons + and 3D printed a new button for the power bank with a hole in the middle for the wire to pass through. I then crimped it and added a female DuPont connector to the end and now it was ready to be connected to my Arduino. I tested it with a minimal testing sketch and it was working perfectly!

⚠️Disclaimer⚠️

I do NOT recommend that you follow the previously mentioned steps if you decide to do that procced at your own risk. Remember that battery cells are sensitive to high heat and might explode if poked 🔥. Also it's very possible that you short ⚡ something which also could cause an explosion. Power banks come with short circuit protection but that is for what comes after the USB port so you can't rely on it since you might short something that is connected behind the short circuit protection. You also need to understand that this is very specific to this power bank and this revision. Even if you have the same exact power bank it's not guaranteed that you will have the exact same PCB inside so do your own research and proceed at your own risk.

The home unit:

Do note that the board in the picture is the heltec lora 32 v2 while the one used in this project is LILYGO TTGO LORA32 868Mhz v1. However the only fritzing board design I found for the TTGO V1 used in this project had wrong pin order where GPIO PIN 5 and GPIO PIN 15 were swapped. The GPIO pins of both boards is exactly the same so you can follow the wiring as shown above when it comes to the GPIO numbering without a problem. What you need to be aware of however is the fact that the Heltec board has GND-3v3-3v3 on one side and GND-5V on the other. Whereas the TTGO v1 board has GND-5v-3v3 on both sides.

Platform

The Detection unit:

For the detection unit I went with Arduino since I am using an Arduino pro mini.

This unit communicates with the home unit through the NRF24 module. It pings the home unit with a 6 bytes payload that describes the temperature reading from the DHT22 sensor, the current state of the detection, and if any movement has been detected (Alarm).

The state of the detection can be one of 3 values. It's either Enabled, Disabled or Waiting. Waiting means that the microcontroller has been instructed to enable detection after a predetermined delay. This is the default behavior for the enable button on the home unit. When I enable the detection I don't want it to detect my cat going out but rather wait for a while so that my cat is out of the balcony before the detection unit starts to detect movement. If the detection unit is in the Disabled or Waiting state the signals from the HFS-DC06 are ignored. However if the sensor is in the Enabled state then it will try to immediately send a packet with alarm set to true. If it fails then it will keep the value set to true and that value will be sent along with every ping until the ping is received by the home unit. This ensures that even if the packet with the alarm indicator was lost then the alarm will indicated until it's received.

The Home unit:

For the Home unit I had the option of using either Arduino or Micropython. Unfortunately due to the board being based on the ESP32 chip I didn't have the option of installing CircuitPython -which is a fork of Micropython by Adafruit- since it has better libraries for interacting with the NRF24l01.

I settled on Micropython since it would allow me to take benefit of the advanced features that the Python language has which will come in handy when it comes to stuff like connecting to WIFI, exception handling and MQTT. Also it is much easier to debug code running Micropython due to the way Micropython works.

The Home unit tries to connect to WIFI on boot. When the main program is run it will try to connect to the MQTT broker and if that succeeded it will indicate that by showing a WIFI icon on the OLED display. If the connection was not successful then it won't try to connect again and will only show a different icon indicating that failure. The user then can press and hold the red button to retry. The home unit checks for packages from the detection unit and if so it will check the temperature and the alarm indicator. High temperature and alarm cause an alarm state which will invert the color of the screen, show a message and start the buzzer. If the temperature is high and movement has been detected then the high temperature message is prioritized. If the temperature is too low or if the no packets has been received in while a warning sign ⚠️ will be shown to alert the user of the problem, however there will be no sound warning as not to annoy the user every time the connection is lost or the temperature is too low.

The home unit also passes the data from the detection unit as is to the MQTT broker if it's connected to it. This allows the home unit to function with the detection unit without the need of a MQTT broker but also it can work with the MQTT broker without a problem if it's up and running.

To interact with the home unit 2 colored buttons are installed. Both support single clicks, double clicks and hold. The double clicks are disable since there are not needed currently and are not as easy to accomplish as single clicks and holding.

If the green button is clicked then it will send a command to put the detection unit in Waiting state. If the the button is held down it will send a command to put the detection unit in the Enabled state. If the command was successfully sent the screen will blink. Unfortunately due to how the NRF24l01 driver works it's possible that the command will be received by the NRF module but not read by the microcontroller. It seems to happen mostly when a command is sent after a package is received but that wasn't consistent and more research is needed.

The red button is used to dismiss the alarm if it has been triggered by single clicking the button. If the alarm has not been triggered then single clicking the button will send a command to the detection unit to put it in the Disabled state. If the button is held down it will try to connect to the MQTT broker if the connection is not already in place.

The Raspberry Pi Backend:

The original plan was to use my own Nodejs or ASP Core implementation to manage and visualize data as well as an SQLite database to store the data. I already had a working version but after seeing how well NodeRed, InfluxDB and Grafana work together, how easy it is to integrate them, as well as how feature rich they are I decided to ditch my own website implementation. The biggest advantage of this approach is how flexible it is, I can very easily change how I want to handle the data, how I want to store it and finally how I want to represent it in a few minutes.

Since I am using my raspberry pi and running it on my local network I didn't have to worry much about the rate of sending or how often I was sending the data which is the biggest reason for the unnecessarily huge data rate of 6 bytes every 5 seconds.

The data sent to the raspberry pi is mostly discarded unless it indicates high temp, low temp, or indicates an alarm. In that case it will be stored to the influx database which uses a retention policy of 4 weeks, and also a message will be sent from my Bot on telegram to my telegram account.

The Telegram bot:

In order to receive notifications on my phone I decided to create a telegram bot that will be used by NodeRed to send me messages every time my cat is detected in the balcony. There are many options to get notifications ranging from custom apps that can be programmed by placing blocks to already made solutions just for that purpose. They also range from totally free to expensive. I already use IFTTT webhooks to get a notification every time my printer finishes a print but I can't say that I am satisfied with how long it takes before I get a message. I also remember that the procedure to setup the webhooks was a bit tedious to the point I didn't want to touch them ever again. Can't remember what exactly made the experience the bad for me but one thing is for sureTelegram bot solves my problem. It's so easy to create a bot. The only hard thing is to find a name not already taken, but other than that it's pretty straight forward. You send commands as messages but you already have a button to display all commands. You can with a few messages add new commands, change the picture, nickname and much more. I also get a notification as soon as a movement is detect since I set it up to use the polling mode in NodeRed.

The code

Since the code is a bit long to be included in this tutorial I decided to upload it to my Github. Feel free to submit pull request as well as forking the project. I will go a little bit through some part of the code that might need to be explained other than you should be able to understand the code since it's not that complicated.

I used Adafruits SSD1306 library for micropython but I had to modify it a bit by defining the function fill_rect() that already exists in the underlying framebuf class but is not exposed by the library as well as overload the pixel() function to also expose the full potential that is provided by the framebuf class.

    def fill_rect(self,x,y,w,h,c):
        self.framebuf.fill_rect(x,y,w,h,c)

    def pixel(self, x, y, col = None):
        if(col == None):
            return self.framebuf.pixel(x, y)
        else:
            self.framebuf.pixel(x, y, col)

The detection unit:

The detection unit has a main loop which checks if the variable commandToExcute has a value different than NOCOMMAND which is equal to 0. If that's the case then it will begin executing the code that matches the command value. the HFSTrigger() function is an interrupt callback function that is called whenever the signal from the HFS-DC06 sensor goes from LOW to HIGH. The function checks if the state is set to enabled and if it's it will change the variable isHfsTriggered to true which in return will cause the main loop to execute the appropriate code.

The NRFTrigger() function is also an interrupt function that is called whenever the NRF24l01 module receives a packet. The function maskIRQ() function is used to decide the behavior of the interrupt pin so it is possible to mask or ignore the interrupts that happen when sending or on failure.

When a new packet is received the microcontroller will read the data from the chip equal to the size of the predetermined payload size. Then it will empty the buffer after reading since that is commented out for some reason in the NRF24l01 library used. The main loop also constantly checks if the buffer is full and empties it, which might cause packet loss but it could otherwise lead to the microcontroller crashing. I still didn't figure out what exactly is causing the problem but will continue to research the behavior if I feel it is happening too often.

void HFSTrigger() { if (currentHFSState == SensorEnabled && !isHfsTriggered) { isHfsTriggered = true; } } void NRFTrigger() { commandType commandReceived = NOCOMMAND; // set the command to be no command if (radio.available()) // check if there is a packet { byte payload[payloadSize]; radio.read(&payload, sizeof(payloadSize)); // read the command and store it in the variable created radio.flush_rx(); commandReceived = (commandType)payload[0]; } commandToExcute = commandReceived; // set the global command variable to the command received }

The home unit:

The home unit runs micropython which isn't really my specialty and I was learning as I go so there is a big chance that some parts of the code don't follow the best practices of the python language. Also due to the lack of time on my part I had to take a few shortcuts here and there in exchange of code reusability.

This is the main loop of the home unit:

while True:
    # check how the red button is pressed
    red_b = checkButton(red_button)
    if red_b == 1:
        red_click_event()
    if red_b == 2:
        red_double_click_event()
    if red_b == 3:
        red_hold_event()

    # check how the green button is pressed
    green_b = checkButton(green_button)
    if green_b == 1:
        green_click_event()
    if green_b == 2:
        green_double_click_event()
    if green_b == 3:
        green_hold_event()

    if not alarm_state:
        if(beeper.duty() != 0):
            beeper.duty(0)  # turn it off then
        draw_status_screen(oled)
        oled.show()
    else:  # alarm is on
        if(time.ticks_diff(time.ticks_ms(), alarm_sound_time) > 1000):  # has it been a second?
            beeper.duty(512)  # turn it on
        if(time.ticks_diff(time.ticks_ms(), alarm_sound_time) > 2000):
            beeper.duty(0)  # turn it on
            alarm_sound_time = time.ticks_ms()

    # check for nrf24 packages
    if radio.any():  # check if package is recieved
        radio_timeout_time = time.ticks_ms()
        radio_timedout = False
        # bool and char in arduino are represented as unsighned char with python type int for some reason, hence the usage of the two b's in the format
        payload = radio.recv()
        data = struct.unpack(struct_format, payload)
        info = list(data)  # but the data into a list
        print(info)
        # convert the numeric value of the state to the char value
        char = chr(info[2])
        info[1] = float("{:.2f}".format(info[1]))
        # info[2] = float("{:.2f}".format(info[2]))
        if(client is not None):
            try:
                client.publish(topic_pub, payload)
            except OSError as e:
                print("failed to send MQTT message")
        # convert the value from a char to a string representing the state
        if char == 'D':
            info[2] = "Disabled"
        elif char == 'E':
            info[2] = "Enabled"
        elif char == 'W':
            info[2] = "Waiting"
        else:
            info[2] = "UNKNOWN"
        latest_values = info[1:]  # get the values that need presentation
        if info[1] > 35 or info[0] == 1:  # temp too high or alarm
            alarm_state = True
            if info[1] > 35:  # temp too high
                text = "!!TOO HOT:{}C!!".format(info[1])
                draw_alarm_screen(oled, text, warning)
            else:  # alarm
                text = "!!CAT DETECTED!!"
                draw_alarm_screen(oled, text, cat)
        oled.show()  # show the buffer on the oled screen

    # check for mqtt messages
    if(client is not None):
        try:
            client.check_msg()
        except Exception:
            client = None

    # check for timeout
    if time.ticks_diff(time.ticks_ms(), radio_timeout_time) > (radio_timeout_delay * 1000):
        radio_timedout = True
        latest_values = [None, None]
    else:
        radio_timedout = False

The loop first runs the function checkButton() which is taken and translated from an Arduino sketch (4-Way Button By Jeff Saltzman). I converted the sketch to python and also removed the long hold function as well as converted the button logic to work with a button class called AdvancedButton so that I can assign use it with multiple buttons more easily.

The button then checks if the alarm has been triggered which is indicated by the alarm_state variable and if true will draw the appropriate text and graphics on the OLED screen as well as sound the buzzer.

After that it will be time to check if any new packets are in the NRF24l01 buffer and if so read them and send them as is to the MQTT broker if there is an active connection to it. The data is then checked and handled accordingly. The last 2 steps in the loop are to check if any message has come from the MQTT broker and to check if the time since the last packet from the detection unit has exceeded the timeout value and if so change the radio_timedout value to true which will be handled in the next loop cycle.

Transmitting the data / connectivity

Since I am running everything locally and I am mainly testing stuff I had the opportunity to test sending data at quite high rate of 6 bytes every 5 seconds. The data is send from the detection unit to the home unit over 2.4GHz band through the NRF24l01 module which uses the "Enhanced ShockBurst Protocol". The data rate used for the module is 250KB per second. Do note that the data rate, channel and CRC has to be the same on both modules in order for them to communicate with each others. From the home unit the data is display on the OLED screen but also passed as is to the MQTT broker Mosquitto that is running on my raspberry pi if the home unit is connected to it. The data is then received by NodeRed that is running on the same raspberry pi and is checked in order to determine if it should be discarded or not. If not it will be stored and sent to me on telegram through my telegram bot.

Transmission protocol:

2.4GHz

WIFI

Local

Local

Internet

Detection unit

Home unit

Raspberry pi

NodeRed

influxDB

telegram

Transport protocol:

Enhanced ShockBurst Protocol

MQTT

MQTT

InfluxQL

Polling

Detection unit

Home unit

Raspberry pi

NodeRed

influxDB

telegram

Due to the usage of the normal NRF24l01module and not the amplified version, sending data that often doesn't seem to cause big battery drain. However it is very unnecessary to send data that often and instead it's a better approach for the final product to just put the Arduino board to sleep and wake it up when it has to send a packet or when the HFS sensor or the NRF24l01 send an interrupt signal. It can also be extended further and stop sending packets all together and instead only respond to pings coming from the home unit and therefor is in sleep until it either senses movement or responds to a packet. That also makes it much easier to re-configure how often the data is send just by changing how often the home unit pings the detection unit. One reason to have a short ping time is to immediately detect temperatures which is the reason I configured it as such in the first place so that I could test and see if the temperature would be too high to have a 20000mAh power bank in a shut enclosure in outside weather. Also low temperatures can severely affect the performance of batteries leading to much shorter battery time.

The data is sent as a 6 bytes buffer consisting of 2 bytes and a float. One of the 2 bytes is for the current state and the other is to indicate if the alarm is triggered. The remaining 4 bytes store the temperature reading from the sensor. The payload can be further reduced in size to 5 bytes by representing the alarm and the state value in the same byte. Currently the state byte stores the numeric ASCII value of the first letter the represent the state so: E,D, and W. This means that I still have place for an extra number at the hundreds place so if I send 68 that means the state is Disabled and the alarm is not triggered but if I receive 168 that means the alarm is triggered and the state is Disabled

Presenting the data

Currently the data is stored in an InfluxDB database which seems like a very obvious choice when it comes to IOT application. Features like retention policy and how easy it is to configure makes it a really great choice. More importantly being a time series database means that I don't have to worry about time when storing data. The data that is stored currently is the temperature when the alarm was triggered or when it went over or under a set limit. I could reduce the retention police from 4 weeks to 1 week or less and have it register all the temperature values but temperature doesn't fluctuate that much especially in closed enclosure, which also is another reason do discard the data since it doesn't serve any other purpose since it does not accurately represent the actual temperature of the outside. One more thing I like about InfluxDB is how easy it integrates with NodeRed and Grafana.

Speaking of Grafana. I created a new test dashboard that shows every time the alarm has been triggered and the temperature at that time and used points to represent the data. This way I can monitor when my cat arrives home and also can look to see if there are any patterns for when he comes back.

The dashboard look rather empty currently but it gave me the Idea of moving the temperature senor when I am done testing from the detection unit to the home unit. This way I can have a dashboard for the Cat alarm and another for the temperature in the living room in one system.

dashboard

Finalizing the design

To summarize the project was fun and quite straight forward. Having the right tools for the job made it a lot easier and also having a 3D printer allowed me to test some ideas that I probably would have totally ignored (such as the power bank reset button). The home unit still needs a case which I will be working on soon enough and I will also be modifying the code a bit to change it from one used to test the idea to one that is actually usable and deployable. I encourage you to try it out on your own and add your own touch, modify it and make it better. Good luck! :happy:

final setup