Made by as228db. ## Project Overview This is a tutorial of how to use a knock sensor with a Rasperry Pi Pico W and connect it to Adafruit IO. It takes an estimated time of eight hours (with no prior experince). ## Objective I chose to make this project since I work with people who are hearing impaired. Part of my job is to find solutions to everyday situations that impact those who do not have normal hearing. That's were the idea of getting some sort of notification when someone is knocking at your door came from. This is a very simple prototype, but I have hopes of refining it. ## Material | Hardware | For/Use | | -------- | -------- | | Raspberry Pi Pico W | Microcontroller with Wifi. https://www.electrokit.com/produkt/raspberry-pi-pico-wh/ Cost: 109 SEK| | Breadboard | To ease connecting the sensor to the microcontroller. https://www.electrokit.com/produkt/kopplingsdack-840-anslutningar/ Cost: 69 SEK| | Cables| For wiring/connecting the sensor to the microcontroller. https://www.electrokit.com/produkt/labbsladd-20-pin-15cm-hona-hane/ Cost: 29 SEK| | Knock sensor | https://www.electrokit.com/en/product/knock-sensor/ Cost: 39 SEK| | USB micro-cable | To connect the Rasberry Pi Pico to your computer https://www.electrokit.com/produkt/usb-kabel-a-hane-micro-b-5p-hane-1-8m/ Cost: 39 SEK| ## Computer setup I will explain my computer setup which is a Windows computer. If you have Mac or Linux the installations can be a bit different. * Thonny IDE, link to download: https://thonny.org/ ![](https://hackmd.io/_uploads/HyOXG4Mt3.png) Choose windows ![](https://hackmd.io/_uploads/BJlif4zY2.png) Choose the first installer (works for most) ![](https://hackmd.io/_uploads/HkwyXNMF3.png) Open downloaded files and choose thonny ![](https://hackmd.io/_uploads/r1uvNNGth.png) Follow the steps as shown in the installer In Thonny: Connect your Rasperry Pi Pico and click on the name in the right lower corner. The meny on the left might not be visible to you know, but it should be visible after the next step. ![](https://hackmd.io/_uploads/rkW62R8Y2.png) Click on it in this list ![](https://hackmd.io/_uploads/Hk0EpC8Yh.png) Open a new workspace here ![](https://hackmd.io/_uploads/B1ZXCALF3.png) To save a the code to your Rasperry Pi Pico ![](https://hackmd.io/_uploads/H1yskyDF2.png) And then choose Rasperry Pi Pico ![](https://hackmd.io/_uploads/B1e2JJwth.png) If you want to STOP and RUN your code manually, you click these signs. You see that there are two saved files to the Pico here - mqtt.py and main.py. *This is how your project should look later on.* ![](https://hackmd.io/_uploads/H1gJgJDFn.png) **Firmware Update** You have to update the firmware on your Rasperry Pi Pico in order to use it. Download from this link: https://micropython.org/download/rp2-pico-w/ You will find this instruction on the page, and you should download the **u2f** file. To ease the firmware update, you can save the file to your desktop. Connect the small connection of the USB-cable to the Raspberry Pi Pico. Hold down the BOOTSEL button on the Pi Pico - while you connect the USB-cable to your computer. You will se a new drive on your computer called "RPI-RP2". Drag or copy the **u2f** file to the "RPI-RP2". The drive ("RPI-RP2") should now disconnect itself from your computer. It will then reconnect itself to your computer again, you will not have to remove the USB-cable. ## Putting everything together ![](https://hackmd.io/_uploads/rJ13q4fF3.jpg) ![](https://hackmd.io/_uploads/BkWZAwwt3.jpg) This is a developtment setup. Three cables - red, green and brown are connected from the sensor to the breadboard which in turn is connected to the Pi Pico. Brown = Ground (-) Red = Power (+) Green = Output (S) **NOTE ABOUT THE BREADBOARD** - Each numbered row has the same potential on all 5 points, except for the long lines (+) and (-) which has the same potential along the long side. To the breadboard: **Brown** = To Pin 38 on the Pico which is Ground (GND). **Red** = To Pin 36 on the Pico which is 3.3 V OUT (it gives power to the sensor). **Green** = To Pin 27 which is an ADC (Analog to Digital Converter, it converts the analog data from the knock sensor to digital data for the computer). ## Platform I choose [Adafruit](https://io.adafruit.com/) as it was the platform used as an example for the course that I made this project for. There are alot of information on the web about Adafruit - and they also have a Discord server where you can ask question and get help with your IO projects. I did not consider any other platform due to limited time for the course. ## The code *I have not used any external libraries for this code, but you need to copy this [mqtt.py](https://github.com/iot-lnu/applied-iot/blob/master/Pycom%20Micropython%20(esp32)/network-examples/mqtt_ubidots/mqtt.py) and save it to your Rasperry Pi Pico W code in order to make a MQTT connection to Adafruit.* Save the the file as mqtt.py to your Rasperry Pi Pico as shown above in the "Computer Setup" segment. As saif before, the mqtt.py and the main.py files should both be saved separetly to your Rasperry Pi Pico in Thonny IDE. **Now, make a new workspace and insert the code that follows, this will be your main.py file.** The code snippets are shown in order. This is the first part of the code which tells the program to **import pins** from the Rasperry Pi Pico W, imports **time functions** and tells your program how to **communicate** with Adafruit IO using MQTT protocol. It also tells the program how and to use Micropython as the language program. ``` import time # imports time function from mqtt import MQTTClient # For communication with Adafruit IO using MQTT protocol import ubinascii # converts binary data import machine # access to hardware functions import micropython # needed for the program to use micropython language from machine import Pin # tells the program to import hardware pins ``` This code makes Pin 27 an input for your Rasperry Pi Pico to collect data from the knock sensor. ``` pin_input = Pin(27, Pin.IN) # Pin 27 is set as INPUT for the Pico, which is connected to the OUTPUT on the sensor ``` This is the network configuration for the program, which tells it what network to connect to and how. **You need to put in your own wifi information here**. ``` # Wireless network WIFI_SSID = "Wifi-name" WIFI_PASS = "Wifi-password" ``` This part of the code connects you to your **Adafruit IO** account (more info about Adafruit and how you use it wil be explained later in the tutorial). ``` # Adafruit IO AIO_SERVER = "io.adafruit.com" # Server address for Adafruit IO AIO_PORT = 1883 # Port for the server AIO_USER = "USERNAME" # Your username at Adafruit IO AIO_KEY = "Adafruit_KEY" # Adafruit key (this is your own secret key) AIO_CLIENT_ID = ubinascii.hexlify(machine.unique_id()) # This could be namned whatever you like AIO_KNOCK_FEED = "Adafruit_FEED" # The MQTT link to your feed ``` This part of the code shows you if your connected to your network by printing your IP adress. ``` def do_connect(): import network from time import sleep import machine wlan = network.WLAN(network.STA_IF) if not wlan.isconnected(): print('connecting to network...') wlan.active(True) # set power mode to get WiFi power-saving off (if needed) wlan.config(pm=0xa11140) wlan.connect(WIFI_SSID, WIFI_PASS) print('Waiting for connection...', end='') while not wlan.isconnected() and wlan.status() >= 0: print('.', end='') sleep(1) ip = wlan.ifconfig()[0] print('\nConnected on {}'.format(ip)) return ip ``` This is a callback subroutine. ``` def sub_cb(topic, msg): print((topic, msg)) if msg == b"ON": led.on() elif msg == b"OFF": led.off() else: print("Unknown message") ``` This part of the code **reconnects if there is any loss of connection** to the MQTT server. Then it rests (time.sleep) for 10 seconds. ``` def restart_and_reconnect(): print('Failed to connect to MQTT server. Reconnecting...') time.sleep(10) machine.reset() ``` The code **do_connect** connects you to the internet. ``` try: ip = do_connect() except KeyboardInterrupt: print("Keyboard interrupt") ``` This code tells you that you are connected to your Adafruit feed. It connects by making a MQTT client using information like your username, what server to connect to, the server port for Adafruit IO and what feed you want your data to be connected to. The print line will print "Connected to io.adafruit.com and your chosen feed (in this case - knock)" if everything is working. ``` client = MQTTClient(AIO_CLIENT_ID, AIO_SERVER, AIO_PORT, AIO_USER, AIO_KEY) client.set_callback(sub_cb) client.connect() client.subscribe(AIO_KNOCK_FEED) print("Connected to %s, subscribed to %s topic" % (AIO_SERVER, AIO_KNOCK_FEED)) ``` This is a **loop** that checks if there is any data comming from the sensor. If there is no data (no one is knocking) the output from the sensor will be **0** (since the sensor is **not triggered**) and a message to Adafruit will say "Wait...". If someone is knocking the value **is no longer 0** and will go to the **else** segment of the code. This sends a message to Adafruit that someone is knocking and is "At the door!". When someone is knocking, the program will then rest for 30 seconds **(time.sleep(30)**. ``` while True: try: client.check_msg() value = pin_input.value() if value == 0: print("Wait...") else: print("At the door") client.publish(AIO_KNOCK_FEED, "At the door!") time.sleep(30) ``` If there was to be an error in the connection made by your hardware or operating system, this will disconnect you from Adafruit IO and print it out. The client is set to None to stop referencing the previous code. ``` except OSError as e: restart_and_reconnect() client.disconnect() client = None print("Disconnected from Adafruit IO.") ``` ## Transmitting the data / connectivity The data is sent using **WiFi** wireless protocol which the Rasperry Pi Pico W supports on the board. It sends the data to the internet. I choose to use WiFi since other wireless protocols (such as LoRaWAN wasn't supported near me, though I tried to use it). The program sends data any time the sensor senses a change (either if someone starts or stops knocking). If someone has knocked by the sensor, the program rests for 30 seconds using **time.sleep(30)** before checking in with the sensor again. Otherwise Adafruit blocked me for a short time. The data is sent to Adafruit IO using **MQTT** transport protocol to Adafruit MQTT Server. ## Presenting the data I used Adafruit to present the data. **Important** - you need to copy your key from Adafruit and put it in the code in order for it to work. You find the code by clicking on this key. ![](https://hackmd.io/_uploads/HkQg9yvK3.png) I first made an [Adafruit account](https://io.adafruit.com/). Then I made a Feed on Adafruit called "knock". ![](https://hackmd.io/_uploads/BJnr3J7F2.png) I then made a dashboard in the same way as a new feed, but this times under the "Dashboard" tab, and named that "knock" as well. Then I connected the "knock" feed to the "knock" dashboard in these steps: ![](https://hackmd.io/_uploads/r1umAyXKh.png) Klick on the "knock" dashboard and go to the settings in the right corner and choose "create new block" and choose **Stream.** ![](https://hackmd.io/_uploads/r1ioRk7Y3.png) Then connect the dashboard to the "knock" feed. ![](https://hackmd.io/_uploads/BJUWkgQKn.png) Name the block "knock" and if you want to view history of the data in the stream choose how many hours of history you want (I choose 36 hours). ![](https://hackmd.io/_uploads/B1avyx7tn.png) Then click on "create block". **This is how the Stream Dashboard looks after the code has been running and the sensor is triggered.** ![](https://hackmd.io/_uploads/Hk5vZlQYn.png) The data is saved **every 30 seconds** to Adafruit. ![](https://hackmd.io/_uploads/BJ_UGxXtn.png) **Important** - you will find all the links needed (besides your Adafruit key) to put in the code by going to **Feeds**, clicking on the feed you want to use, and then clicking on **Feed Info** listed to the right. ![](https://hackmd.io/_uploads/HyJKjJvYh.png) ## Finalizing the design Finally, I only have a prototype - I have not mounted my sensor to an actual door. I chose to be alerted if someone is at the door by recieving an email genereted from my Adafruit feed every 30 minutes. This isn't exactly ideal if there actually was someone knocking, but it still shows that you could get a notification from the feed if you want to. ![](https://hackmd.io/_uploads/SybKnWQY2.jpg) ## Final thoughts This was a project I made to learn what IoT was and how to implement it on an everyday situation, in order to make life easier. I have no prior knowledge about IoT and very little programming skills, so this was a fun learning experince. This is how the sensor looked after mounting it to a table using some double folded duct tape to test it: ![](https://hackmd.io/_uploads/SygCX1DF3.jpg) I would probably have wanted to make a box for it to be mounted to the door, so that people could knock on the box to be sure that the sensor would be triggered. Then I would have soldered the wires and not used the breadboard. But I did not have the time or material to do that before the course ended.