OskarAlmqvist
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    ### Oskar Almqvist - oa222my ###### oa222my # (VibSense) - How to build yourself a third hand by creating a IOT assistant capable of sensing vibrations and impacts with ultra high sensitivity. :::warning This project showcases how to build an IOT device/assistant capable of combining the output of multiple vibration sensors to achieve a "ultra sensitive" way to detect impacts, shocks and vibrations using two simple, inexpensive, commodity sensors. Data is stored in a .JSON database for further analysis and sent to a dashboard for "live monitoring" ::: **Project cost:** 100 $ **Time to replicate:** Using this tutorial and the code from the Github repo it should be possible to replicate this project in 2-4 hours depending on prior experience and background. --- ## Objective ![Overview image](https://i.imgur.com/gOK2lQ8.jpg) I've been toying with the idea of moving out the country for years and spent quite a few years now looking at prospects. Many of these places completely lack the things we in cities take for granted. Such as running water, electricty and of course internet connectivity. The good news is that while the lack of these amendenties historically has been a great pain in the ass, technology - has caught up. Electricity? Solar panels. Water? Purification or drilling. Internet? 4G, LoRa, SigFox and satellites! ### However.. One problem remain! **There is no people!!** So how do we solve issues like theft or watching over a dog? How do make sure a tree or a storm isn't causing our entire house to tremble? ![image](https://i.imgur.com/tVRmiwK.jpg) # We build ourselves a third hand! VibSense is just that. A third hand! By combining the power of multiple, cheap vibration sensors with internet connectivity we create a device capable of assisting us in all kinds of scenarios. * Worried about theft? * Place VibSense in your boat or car and get an alert when something is happening * Worried about your dog? * Place VibSense in your dogs resting place to get frequent updates about his movements * When the heck is the mailman arriving? * You guessed it, place VibSense inside your mailbox! VibSense senses duration of vibrations as well as the impact of shocks and can be calibrated for all kinds of uses. It's basically your third hand! --- ## Material ![Material](https://i.imgur.com/HfT4RKG.jpeg) At first I purchased only the low sensitivity vibration sensor (41015724) and my plan was to combine that sensor with some other type of sensor for the hand. However, as I tested out that sensor I realized that while it's somewhat capable of detecting the actual impact of the shock it's not very capable at detecting the duration of the shock. The problem with this is that while a "dangerous vibration" for a procelain vase obviously is the actual force of the impact the "dangerous vibration" for a bowl of fish is something difference. Minor shakes but where the shaking continue for longer periods of time might be just as dangerous, if not more dangerous to a living thing even if the actual force of impact is small. Since I wanted a device capable of being useful in both scenarios I decided to combine this sensor with the high sensitivity vibration sensor 41015741. | Item | Bought At | Price € | |:---------------------------------- |:-------------- | -------:| | LoPy4 | pycom.io | 39 | | Pycom Expansion Board 3.0 | pycom.io | 18 | | Vibration sensor (low) - 41015724 | electrokit.com | 3 | | Vibration sensor (high) (41015741) | electrokit.com | 4 | | Portable battery pack | electrokit.com | 3 | | Breadboard | electrokit.com | ? | | Wires | electrokit.com | ? | | Micro USB cable | electrokit.com | ? | | | | 67 € | # Material ![LoPy!](https://pycom.io/wp-content/uploads/2018/08/lopySide-1.png =360x) **Fig 1. LoPy4** A small development board capable of being programmed with MicroPython. This board is able to connect to various networks such as WiFi, Blueooth, LoRa and Sigfox. ![Expansion board 3.1](https://i.imgur.com/YKgBENP.png =400x) **Fig 2. Expansion Board** Provides an easy way to connect things like sensors and battery to the LoPy4. Also has an USB-port which makes interfacing with, and powering the LoPy4 significantly easier. ![Power bank](https://i.imgur.com/c83anqb.jpg =400x) **Fig 3. Portable battery pack** Enables the device to run without being connected to an outlet. Easy to charge and most people have them available for free at home. ![Low sens vib sensor](https://i.imgur.com/17JecV4.jpg =400x) **Fig 4. Vibration Shake Sensor 41015724** The switch primarily consists of a terminal that forms a center post and a second terminal that is a spring that surrounds the center post. When a sufficient force is transferred to the switch, the terminal consisting of the spring moves and shorts both terminals together. ![High sens vib sensor](https://i.imgur.com/tWrNu0u.jpg =400x) **Fig 5. High sensitivity Vibration Shake Sensor 41015741** The switch primarily consists of a terminal that forms a center post and a second terminal that is a spring that surrounds the center post. When a sufficient force is transferred to the switch, the terminal consisting of the spring moves and shorts both terminals together. * This sensor has significantly higher sensitivity than 41015724 **Fig 6. Wires and breadboard** Wires and breadboards are used to connect the sensors to the LoPy. It is possible to make the project without the breadboard. ![wires](https://i.imgur.com/DXHbOao.jpg =400x) --- ## Computer & hardware setup To communicate with the devices you need to install some software to your computer. In this tutorial I've used VSCode for writing all the code. But this can also be done using the Atom IDE. If you're using a new Pycom device to execute this tutorial than it's highly recommended that you update the firmware of the expansion board and the device itself to get access to all new features and make sure that any bugs are corrected. There is very good documentation about how to achieve this on the Pycom website accessible here: https://docs.pycom.io/updatefirmware/ To install the IDE used in this tutorial you can download Visual Studio Code here: https://code.visualstudio.com/docs/setup/windows In addition you need the PyMakr plugin which can be installed here: https://marketplace.visualstudio.com/items?itemName=pycom.Pymakr PyMakr allows us to communicate with the LoPy and is used to run code on the board and to upload files to the board. --- ## Putting everything together ![Wiring](https://i.imgur.com/WTwBg1S.jpeg) ![IRL-wiring](https://i.imgur.com/HfT4RKG.jpeg) **Breadboard** the breadboard is connected with black to GND on the LoPy and - on the BreadBoard. It is also connected with red to 3V3 on the LoPy and + on the breadboard to power the sensors. **Vibration Shake Sensor 41015724** is attached to the breadboard and connected to power and ground via the breadboard and to PIN16 on the LoPy via the breaboard. :::info The reason the vibration shake sensor is not attached directly to the breadboard is that after testing it for a hundred+ times I saw that the readings got significantly worse when directly attached to the breadboard. Probably because the breadboard itself then absorbs some of the vibrations. The high sensitivity sensor does not have this problem. ::: **High sensitivity Vibration Shake Sensor 41015741** is not attached to the breadboard but connected to power and ground via the breadboard and to PIN13 on the LoPy via the breadboard. :::danger The official image is WRONG and the sensor has been reworked. There is now three pins. From up to down - VCC (power), GND (ground) and DO (signal). ::: **Portable battery pack** is connected to the MicroUSB-port on the expansion board to provide power. **Case** To make a simple case I used an old lunchbox wrapped with bubblewrap to hold all the components together. This could actually be somewhat waterproof but there is a drawback in that the components aren't properly fixed and could fall out in case of a extreme shock causing incorrect readings. This can be improved upon. :::info The case has been wrapped in bubblewrap to protect the LoPy from vibrations. This is recommended :) ::: ### Battery calculations According to the Chinese manufacturer the USB power bank has a capacity of 13000 mAh. Once testing the device we will see that this actually isn't the case. The power bank is slightly dated and in addition the batteries inside probably isn't of the highest quality. For the sake of this tutorial we're going to calculate what would happen if we actually got 13000 mAh out of the power bank. Looking at previous IOT projects posted and through the Pycom forums it's estimated that the device draws about 200 mA while awake transmitting through WiFi with the expansion board connected and multiple sensors. To calculate the battery life we can make a very simple calculation Battery life in hours = (battery capacity mAh)/current in mA If we then use a 13000 mAh power bank and the average current is 200 ma we get x/y = h, 13000/200 = 65 = 65 hours of run time for the portable power bank. :::warning This can be extended by playing around with deep sleep and other connectivity methods that draws less power. ::: :::danger These calculations is a rought estimation and might deviate in actual usage. ::: --- ## Platform ![Network](https://pycom.io/wp-content/uploads/2020/02/PyBytes-logo.png) PyBytes is the cloud-based device management platform offered for free for all PyCom devices. PyBytes gives us the ability to track our device (is it online, etc) and to visualize data in dashboards. It has a ton of other features except for this like webhooks, firmware upgrades etc. I know that previous students of this course decided against using [Pybytes](https://pybytes.pycom.io/) mainly because the platform only retains your data for 30 days. However, that is plenty for this project as the IOT device we're building provides instant feedback and historical data is of less importance. As I am familiar with web development getting a webhook from PyBytes to my server and then coding that data myself in a web language to suit my needs is preferable to setting everything up on a more complicated platform. In addition, all the data collected by the device is saved to a local .JSON file on the device which means that we can at any point in time retreive the device, download the data and perform any kind of analysis on the data. --- ## The code [The full code is published on GitHub](https://github.com/MrSvenson/IOTLinneusKurs). I've separated the code into several files and included heavy commentary in the code to make it easier to follow. The algorithm is contained in algorithm.py and can be modified freely depending on how you're using the device. In addition I've used try/except blocks where needed to make the device less sensitive to unexpeected errors. ### boot[]().py Here we initialize everything and make sure to disable bluetooth to save power. ```python= import pycom from network import Bluetooth, LTE from machine import UART import machine import os uart = UART(0, baudrate=115200) os.dupterm(uart) # Disable bluetooth to save power bluetooth = Bluetooth() bluetooth.deinit() machine.main('main.py') ``` ### main[]().py Magic. Here we get data from all the sensors, compare it and send it to PyBytes if it matches our criteria. ```python= ## Data is sent to Pybytes. Needs to flashed with Pybyte firmware from machine import Pin from machine import ADC import time # import library called time import pycom # import library called pycom import json # import json import ssl # import ssl import functions # import our functions file import sensors # import sensors file import algorithm # import the algorithm # Making sure the "connection" to pybytes is activated pycom.pybytes_on_boot(True) # Set time using NTP server rtc = functions.set_time() VibSensorPin = 'P16' # Knock sensor connected to P16. Valid pins are P13 to P20. VibSensorPinHigh = 'P13' # Vibration sensor connected to P13. Valid pins are P13 to P20. Pin(VibSensorPin, mode=Pin.IN) # set up pin mode to input Pin(VibSensorPinHigh, mode=Pin.IN) # set up pin mode to input # create an ADC object bits=10 means range 0-705 the lower value the more vibration detected adc = ADC(bits=10) # create analog pins on P16 and P13; # attn=ADC.ATTN_11DB measures voltage from 0.1 to 3.3v apin = adc.channel(attn=ADC.ATTN_11DB, pin=VibSensorPin) # Low sensitivity sensor apin_high = adc.channel(attn=ADC.ATTN_11DB, pin=VibSensorPinHigh) # High sensitivity sensor if __name__ == '__main__': # Loop forever while True: try: # Do one initial reading. If we don't detect anything here then we continue waiting for something to happen low_sensitivity_sensor = apin() # analog value, low sensitivity sensor high_sensitivity_sensor = apin_high() # analog value, high sensitivity sensor # Everything above 600 is too little to care about. Ignoring that. # Everything below 20 (high sensitivty) is also too little/nothing. We ignore that as well. if low_sensitivity_sensor < 650 or high_sensitivity_sensor > 20: print("Detected a shock! Running application") # Get data from the high sensititivty sensor data = sensors.detect_duration_of_shake(apin_high) high_sensitivity_duration = data[0] # Duration in MS of the vibration shake_readings = data[1] # How many times during the function did we get a value above 0 indicating vibration is occuring. # Get data from the low sensitivity sensor low_sensitivity_sensor = sensors.detect_shock_value(apin) # Get a calibrated value using the two sensors calibrated_data = algorithm.vibration_formula( low_sensitivity_sensor, shake_readings) # Store data, read data. For testing mainly functions.store_file_json_new( low_sensitivity_sensor, high_sensitivity_duration, calibrated_data['calibrated_value']) # functions.read_json() if calibrated_data['calibrated_value'] > 600: pretty_status = "SICK" signal = 1 elif calibrated_data['calibrated_value'] > 500: pretty_status = "BIG" signal = 2 elif calibrated_data['calibrated_value'] > 300: pretty_status = "Medium" signal = 3 else: pretty_status = "Light" signal = 4 # Console printing print("-------------------------", pretty_status," shock!-------------------------") print("Raw value (knock): ", low_sensitivity_sensor) print("Duration of shake: ",high_sensitivity_duration) print("Low sensor score: ",calibrated_data['low_sensor_score']) print("High sensor score: ",calibrated_data['high_sensor_score']) print("Calibrated score: ",calibrated_data['calibrated_score']) #C = Calibrated value, using the formula above and combining the readings of the two sensors. This is defined in algorithm.py #C = Right now more emphasis is put on the low sensivity sensors which mean that we increase how much we care about the shock of the impact and less about the impact duration #R = Raw data from the knock sensor, this detects how hard the impact is. Did we drop it from 10 cm height or from 2 meter height? #D = Duration from the vibration sensor, for how long did the impact last? Did it rattle around? # Pybytes send pybytes.send_signal( signal, ""+pretty_status+": C: "+str(sensors_calibrated_value)+"/R: "+str(low_sensitivity_sensor)+"/D: "+str(round(high_sensitivity_duration))+"ms") # Sleep after a impact to give the machine time to reset. time.sleep(1) except Exception as e: print(str(e)) ``` ### algorithm[]().py The formula used in this file has been calibrated by basically throwing stuff around in my apartment :) Here is some math behind it: ### Low sensitivty sensor Low sensitivity sensor gives 720 when it hasn't detected anything. The score then for that in idle is 720-720 = 0 ### High sensitivty sensor The high sensitivty sensor gives 0 when it hasn't detected anything. If it detects something then it calculates for how long the shake is happening. This is recorded in milliseconds. The shake_duration parameter is 100 milliseconds. I.E shake_duration = 4 = 400ms. # Math # A small impact would give us # 720-600 = 120 (low sensor) # 1 (100ms)*200 = 200 (high sensor) # A small impact == 300 # A big impact? # 720-200 = 520 (low sensor) # 2*200 = 400 (high sensor) # A really big impact would therefore be 520+400 = 920. ```python= def vibration_formula(low_sensitivity_sensor, shake_duration): # The knock sensor returns a low_sensitivity_sensorue from 700 (nothing detected), down to 0 (big impact detected). This is less accurate low_sensor_score = 720-int(low_sensitivity_sensor) low_sensor_score = low_sensor_score*4 # Increase importance of knock by a factor of 4. # The vibration sensor returns a low_sensitivity_sensor from 0 (nothing detected) up to 1024 (vibration detected) # By taking the vibration time into account, we can consider how extreme the impact is. # This is more accurate sensor, so we place more emphasis on this low_sensitivity_sensor # So if we detected a shake for 4'isch second this would give us 4*100 = 400 high_sensor_score = shake_duration*100 calibrated_score = int(round(low_sensor_score)+int(high_sensor_score)) data = { "low_sensor_score": low_sensor_score, "high_sensor_score": high_sensor_score, "calibrated_score": calibrated_score } return data ``` In main.py we use the data like this. Of course both this and the calculation in algorithm.py can be changed depending on if you want to put more emphasis on the force of the impact or the duration of the shake. I calibrated this by throwing stuff around in my apartment and so far this is the best calibration values I could come up with. ```python= if calibrated_data['calibrated_score'] > 600: pretty_status = "SICK" signal = 1 elif calibrated_data['calibrated_score'] > 500: pretty_status = "BIG" signal = 2 elif calibrated_data['calibrated_score'] > 300: pretty_status = "Medium" signal = 3 else: pretty_status = "Light" signal = 4 ``` ### sensors[]().py ```python= import functions import time from machine import Timer def detect_duration_of_shake(apin_high): # Small shake = 800ms # Two small shakes = 1200ms # Three smalle shakes = 1600ms try: # print("Detecting shake duration") chrono = Timer.Chrono() chrono.start() # Start a timer to record how long it's been shaking for. shake_readings = 0 while True: value = 0 # Read the data 400 times over 1 second to detect if it stopped shaking or not. for i in range(400): value = value+apin_high() time.sleep(0.001) if value == 0: # If we don't detect any shaking over 1 second then we assume shaking stopped and break out of loop break else: shake_readings += 1 # Otherwise continue reading the sensor. chrono.stop() total_ms = chrono.read()*1000 return [total_ms, shake_readings] #Return the execution time of the function in ms, and the shake readings 1 == 100ms. except Exception as e: print(str(e)) # Read the shock_value 100 times and get an average reading. # We do this in case there is any problems with the readings due to interference from the high sensitivity sensor. def detect_shock_value(apin): value = 0 for i in range(100): value = value+apin() time.sleep(0.001) return int(value)/100 ``` ### functions[]().py Many functions for storing/reading data, setting RTC-time etc. The main function in this file is the ability to store the data we collect in a .JSON file. This is great for analysis/investigation at a later point without having to send all the data to the cloud. ```python= from machine import RTC import time # import library called time import json # Store data in a .JSON file. # This is great since we later have the option to analyze and use all the data for calculations. def store_file_json_new(low_sensitivity_sensor, high_sensitivity_duration, cal): try: FILENAME = 'data.json' new = False try: f = open(FILENAME, "r") HAS_FILE = True f.close() except: # open failed HAS_FILE = False if not HAS_FILE: new = True my_list = [] else: with open(FILENAME, 'r+') as file: my_list = json.loads(file.read()) with open(FILENAME, 'w+') as file: entry = { 'pretty_status': pretty_status, # Pretty status 'low_sensitivity_value': low_sensitivity_sensor, # Raw value from the low sensor 'high_sensitivity_duration': high_sensitivity_duration, # Raw duration value 'shake_readings': shake_readings, # Same as duration, 1 == 100ms 'low_sensor_score': calibrated_data['low_sensor_score'], # Calibrated score of the low sensor 'high_sensor_score': calibrated_data['high_sensor_score'], # Calibrated score of the high sensor 'calibrated_score': calibrated_data['calibrated_score'], # Low+high sensor calibrated together. 'time': str(time.localtime()) } my_list.append(entry) jsonString = json.dumps(my_list) file.write(jsonString) except Exception as e: print(e) ``` --- ## Transmitting the data / connectivity ![Network](https://i.imgur.com/xgTeAbf.png) [WiFi](https://en.wikipedia.org/wiki/Wi-Fi) is a family of wireless network protocols, based on the IEEE 802.11 family of standards, which are commonly used for local area networking of devices and Internet access, allowing nearby digital devices to exchange data by radio waves. This project transfers data to Pybytes using WiFi. A 4G bridge (mobile hotspot) is adviced, there is of course also the opportunity to easily implement LoRa. The problem with WiFi is the lack of range and the increased battery usage. However, the range is easily corrected by using a 3G/4G bridge (cellular hotspot). Data is transferred to Pybytes via the MQTT protocol every time a impact is detected by the device. --- ## Presenting the data ![PyBytes](https://i.imgur.com/yEc38Bd.png) Pybytes is a good way to get an overview of the VibSense. Despite being a simple platform we're able to get a ton of useful data displayed. First we have a pretty printed status (SICK, BIG, Medium Light) giving us an easy overview of how severe the latest impact was, as well as when it happened. We can also see the calibrated value (C) (the combined value of both sensors from the algorithm), the raw value (R) from the low sensitivity sensor which represents the force of the last impact (the force of the impact) as well as the duration of the impact (D) from the high sensitivity sensor. Of course, we also have all the data available in a .JSON file on the device which can be downloaded at any time for further analysis. ```json= [ { "pretty_status":"Light", "calibrated_score":140, "high_sensitivity_duration":800.6931, "time":"(2021, 7, 22, 10, 21, 25, 3, 203)", "shake_readings":1, "high_sensor_score":100, "low_sensitivity_value":710.69, "low_sensor_score":40 }, { "pretty_status":"Medium", "high_sensitivity_duration":1200.734, "shake_readings":2, "calibrated_score":352, "time":"(2021, 7, 22, 10, 21, 37, 3, 203)", "high_sensor_score":200, "low_sensitivity_value":682.99, "low_sensor_score":152 }, { "pretty_status":"BIG", "high_sensitivity_duration":800.9038, "shake_readings":1, "low_sensor_score":504, "calibrated_score":604, "high_sensor_score":100, "time":"(2021, 7, 22, 10, 21, 41, 3, 203)", "low_sensitivity_value":594.08 } ] ``` ### Webhook and notifications PyBytes allows us to [set a webook](https://docs.pycom.io/pybytes/integrations/webhooks/) to forward all incoming data to another server. ![Webhook](https://i.imgur.com/Zlgxm2n.png) I decided to integrate this with the application [Pushover](/pushover.net/apps/a9uc6ybiy925xfaz5wyxwkpzgrvynb) which is a smartphone app that enables you to send pushnotifications to your phone using WEB-requests. To do that I created a new application in the Pushover dashboard ![Pushover Image](https://i.imgur.com/MZFlCJ0.png) I then made a simple PHP-script and placed it on a webserver ```php= <?php curl_setopt_array($ch = curl_init(), array( CURLOPT_URL => "https://api.pushover.net/1/messages.json", CURLOPT_POSTFIELDS => array( "token" => "XXXX", "user" => "YYYY", "title" => "Shock detected!", "message" => $_POST['payload'] ), CURLOPT_SAFE_UPLOAD => true, CURLOPT_RETURNTRANSFER => true, )); curl_exec($ch); curl_close($ch); ?> ``` To summarize this architecture * VibSense sends data to PyBytes * PyBytes receives the data, sends it to a PHP-script on a webserver * The PHP-script takes the data, sends it to Pushover * We get a push notification on our phones ## Pushover result ![Pushover result](https://i.imgur.com/J3FsoYy.jpeg) It doesn't get more awesome than that! --- ## Insights I think the most important insights i've gained throughout this project is: * How cheap IOT sensors is. For a dollar or two you can get a vibration, temperature or light sensor that is quite capable. * How big of a difference it makes to take TWO sensors, combine the input/output and make conclusions from that. Running the project with only one sensor connected highlights the difference. We get significantly worse readings and suddenly the device is prone to all kinds of errors. For example the side of the box where the sensor is located might be hit extra hard, or extra soft giving us a inaccurate reading of the force of the impact. This is almost completely eliminated by using dual sensors. --- ## Final product ![Finalized project](https://i.imgur.com/Xf1ttwy.jpeg) {%youtube LALFXFXRjiQ %} There is room for improvements. LoRa can be implemented to support long-range activities without a cellular bridge. The code can be cleaned up and explained better. You could also include even more vibration sensors to get a even more accurate reading.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully