mj224pb
    • 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
    # Remote temperature log with local alarm Mikael Johannesson, mj224pb This document is submitted as a project report in the course 'Introduction to Applied Internet of Things', 1DT305, S21 at LNU. {%youtube 8txhGYXtOMk %} *My presentation is now available at [YouTube https://youtu.be/8txhGYXtOMk](https://youtu.be/8txhGYXtOMk)* *00:00 Presentation part 1, finding a problem, defining a solution, device, Pybytes* *05:08 Azure for IoT* *10:10 Presentation part 2, challenges, limitations and lessons learned* On estimated time consumption - supposing that all parts are well known and in working order, like verified libraries, no name conflicts, well known platforms etc., a project like this is suggested to be planned for 30.5 h in total (see below). ## Objective The goal of this IoT project is to build a node that measures temperature. This node will have local alarms set that will indicate too high and too low temperature. Read data will be transported to a remote IoT server for storage and presentation. This project has been chosen for the pure reason of learning IoT systems in practice. I chose to measure temperature and humidity as they are easy to manipulate and also, one of the sensors I happen to have available. Insights I had hoped to get from this project was mainly practical knowledge in how different IoT parts can be put together and a better understanding of all parts and alternatives in a chain from sensors to big data. A suprising insight is that public LoRa nets are now available almost anywhere in bigger cities! ## Material The task has been built up mainly by development boards and discrete components as a mockup for a future more permanent implementation in case approved by anyone wanting such a system for a production environment. ### Lab equipment used * A DC power supply unit, HQ 1503SB (for power supply) * A DMM, Agilent U3401A (for current consumption measurements) * A soldering station * An anti-static mat * An USB cable * A battery cassette ### Development cards and components * Pycon Expansion board * Pycon lopy4 development board * Breadboards * 1 LED, blue * 1 LED, red * 2 BC547 NPN transistors * 2 R 33 * 2 R 1k * 1 R 4k7 * HW-061 I2C to parallel development board * 1602 LCD display development board * DHT11 temperature and humidity development board * An antenna tuned to 868 MHz * Dupond wires * Coaxial wire (for lopy4 - antenna) ### Development costs #### Laboratory As always with development kits, components etc., you need an assortment in your lab. As an estimate, a total of 5000 kr has been spent building up a lab with assorted discrete components like leds, transistors, capacitors, voltage regulators as well as different development cards with sensors, communication or microcomputers. Approximately 10000 kr to buy lab equipment like DMMs, cables and power supplies. As always when buying components, prices consist of handling costs and component costs, thus ordering 100 or 1000 items will render a considerably less unit price than while ordering 1 item. Being able to trace a component to a specific batch and producer will typically also render higher prices. Components, sensors and development cards have been collected over time from numerous delivers - Mouser, Elfa Distrelect, Wish, Amazon, Ebay, Electrokit, Digi-Key, Kjell & Co et.c. Costs of components, sensors and development cards actually used on this project is shown below. Prices are for low volume orders: * Pycoms development kit LoPy4 incl antenna, 849 kr * DHT11 temperature sensor, 45 kr * LCD-display kit, 80 kr * Discrete components, 5 kr * Dupond wires, 10 kr * Wireboard, 50 kr In total, 1039 kr + freight for components and development cards needed to build this project! #### Licenses IoT platforms need to be paid. For test- , learning and evaluation most platforms seem to be free for a limited time of usage. An Azure account has been set up for this project. For evaluation and learning, no costs so far! #### Time consumption (and cost) Setting up a new development environment, learning how to use it, learning all features and how to use a never before used development kit (pycom) and to that, finding micro python libraries that actually works with pycom, setting up accounts and learning to use a couple of IoT platforms like Azure IoT as building and installing a new computer will render hours equivalent to several weeks of work. However, when all MicroPython libraries are evaluated, development environment and IoT platforms have been set up properly and all interfaces for all desired design choices are well known, hours can be calculated: * Communicating with customer / group, 4 h * Design phase (decisions, choices, sketches, models), 8 h * Hardware - ordering, handling, finding and mounting, 4 h * LoPy4 firmware update, 0.5 h * Writing and testing LoPy4's Python code, 4 h * Setting up and testing communication, 2 h * Setting up storage, PyAzures IoT environment, 8 h In total, 30.5 h Labor cost? Suggesting a monthly salary of 40 kkr, 65% overhead costs and 169 h/month, an hourly cost excl vat of 390 kr/h over 30.5 h = 11900 kr. ## Computer setup The plan was to use my Windows 10 Workstation but due to name- and library conflicts with earlier installed development tools, I had to abandon that idéa. An old Intel i3-based desktop workstation was found in parts in my basement storage and together with a small SSD disk and after quite a bit of boot order and usb port identification problems, I finally managed to install Ubuntu 20.04 LTS Desktop on this hardware. No sound card so Discord discussions and Youtube films need to be handled using my Windows 10 Workstation. Setting my Ubuntu 20.04 LTS up for remote desktop from my Windows 10 Workstation I finally had a computer to use for Pycoms development environment! ![](https://i.imgur.com/nX4yrH9.png) ![Ubuntu RDP connection](https://i.imgur.com/nUAVq8Q.png) I chose to go with Visual Studio Code for my development environment. Plugins needed for Visual Studio Code to communicate with Pycoms development boards were installed: * NodeJS * Pymakr VSCode Extension A few other programmes were installed as well * Discord (without sound card) * Emacs (for editing, no fan of vim) ### Pycom Firmware Installer Getting Pycom's firmware update software to run properly after installation on a Ubuntu 20.04 LTS turned out to be hard and I finally abandoned that idea. It turned out that I was able to install and run Pycom's firmware updater on my Windows 10 Workstation without any conflicts so by that, my LoPy4 firmware could be properly updated using my Windows machine! ### Where files are stored (when not on my LoPy4) For some reason, pycom projects are stored in the hidden folder .config on a standard Ubuntu installation, thus making the files a bit harder than necessary to find. ~/.config/Code/User/{project} A github account has been set up for version control of my ~/.config/Code/User/{project} folder. ![github](https://i.imgur.com/fQ6ai6I.png) ### Timeout when uploading main.py Getting timeout when trying to upload code to my development board is quite time consuming. Several hours of trying to understand why! I still do not know why this happens and restarting my development board obviously won't solve the problem as a new time out will occur when making a new try. ![pymakr cannot upload](https://i.imgur.com/arVKgAz.png) .. alternatively the code failed to read pybytes_config.json ![](https://i.imgur.com/v8hFZB8.png) I hope that these problems were for me only and not common for all of you using Pycoms development environment. I spent most of my time programming my LoPy4 on blockers like the ones above! ### Pymakr Console to upload code Pymakr is a plugin available for Visual Studio Code, it provides a way to send data between Visual Studio Code and any Pycom device using a USB connection. ## Putting everything together ### A development setup This is obviosly a development setup. ### LED drivers Recommended output current on a LoPy4 GPIO pin is 6 mA and as I wanted to show some warning signals using LEDs (typically 20 mA) a driver unit is needed. #### Design Using a transistor as a switch, the plan is that my LoPy4 GPIO pin should only be loaded with the base current of the transistor, thus well within the 6 mA (12 mA max) LoPy4 current limit. Based on my assortment I chose to go with a small signal NPN transistor, 2BC547. ![bild kretsschema transitor som switch](https://i.imgur.com/SHcskUN.png) Circuit diagram showing switched led for 2 mA GPIO current, calculations see below! #### Electrical calculations 2BC547 is a small signal transistor that can be used as a switch. $U_{ce}$ sat is 0.6V, 2.1V over my LED and $V_{cc}$ = 3.3V, thus 0.5V left for the current limiting resistor $R_c$. Choosing $I_c$ to 20 mA, $R_c = U_{Rc} / I_c = 0.6 / 20m = 30 \Omega$. From E12 we choose $33 \Omega$ rending a slightly lower LED-current. Between the GPIO pin and transistor base, we add a 1k resistor as a voltage divider and current limiter between 3.3V 'on' and U_be sat 0.2V. Building this on a breadboard and measuring power consumption, the load on the GPIO pin is now typically 2 mA which is well within margin. ![bild strömförbrukning led](https://i.imgur.com/Fnu5YLY.png) ### DHT11 A simple sensor that uses serial (digital) data for communication with a microcontroller (LoPy4). It measures temperature and humidity. More in [DHT11 temperature sensor](https://https://components101.com/sensors/dht11-temperature-sensor) Needs a pull-up resistor for data communication, thus adding a 4k7 resistor from E12 to serial data pin. ### I2C bus The idea was to locally present current reading using a back-lit lcd display. Still working on finding a micro python library that actually supports 16x2 lcd displays over I2C for Pycom devices, no luck so far! ### Physical stand Lacking a 3D printer and a prefabricated Pycom box I decided to go with a traditional mockup solution with the main goal to be able to mount my antenna in a secure way. ![bild trä och bygel](https://i.imgur.com/g2eLUiC.png) A wooden plate, a self made bracket for the antenna and some wood screws later, I solved that problem for my mockup! ### My setup ![complete setup photo](https://i.imgur.com/jelblwf.png) A photo of my complete setup, now powered by a USB power bank and still sending temp and humidity every 20 seconds. Currently the alarm for too cold (blue led) is active! #### Circuit diagram ![circuit diagram](https://i.imgur.com/GG72Zk8.png) A circuit diagram of my complete setup. Everything is powered using a USB power bank. #### Power consumption Microcontrollers like ESP32 (what LoPy4 is based on) typically can be set in a deep sleep mode to be woken up by a timer when work is needed. Such code is reasonable to apply if low power consumption is needed. This project is not optimized for low power consumption. An intial estimate of power consumption is 100 mA over 5V (powered over USB, thus not 3.3V). ![](https://i.imgur.com/lP90hZM.png) ![](https://i.imgur.com/ryoUYVV.png) Connecting a DMM to a modified USB-cable to find out the actual power consumption of this setup, it turned out to be 125 mA, as expected more or less! Our 5 Ah USB power supply (the red unit) will thus be able to power this device in 5/0.125 h = 40 h. #### How to reduce power consumption How often do you need to measure temperature and humidity? Do you really need to activate the I2C bus? The main thing to add to this project is deep sleep mode between measuring and sending data. All together, considerable less power will be consumed using these steps and making the very same power supply power this device for 1000 h would probably be feasible after a low power optimization. Using LoPy optimized for low power consumption over WiFi will obviously also be a good choice. ## Platform ### My grounds for my choices There are a several different IoT platforms available out there so not an easy choice. Micrsoft do have big development resorces and in recent years, Azure have been a populare place to host servers. Learning how to use Azure in an IoT aspect will be valuable for me as I expect this will be a tool that many companies will be working with for IoT too very soon. ### Pybytes An account has been created on Pycoms platform making it possible to use Pybytes to collect data from my LoPy4 development board. The device was added and identified and signals were identified, numbered and labeled. In the process of adding Pycom development boards to Pybytes, a new firmware that keeps the communication with Pybytes is uploaded to connected development boards. ![](https://i.imgur.com/IW2bxIK.png) From pybytes, a MQTT rule to send everything forward to our Microsoft Azure IoT Hub MQTT broker has been set up ![](https://i.imgur.com/xHJJJ8i.png) ### Microsoft Azure For data storage, we will use Microsoft Azure and a SQL databse! Reasons are mainly due to that it is, in practice, an industry standard today and by that, tools I need to learn to work with. Three Microsoft Azure products are needed: * An IoT Hub - a MQTT Broaker more or less * A SQL database - for storage, shared server version * A Stream Analytics job - to move data from our MQTT broaker to our database #### IoT Hub A Azure IoT Hub has been set up that do recognize my Device. Pybytes has been set up to push data to Azure IoT using MQTT. ![](https://i.imgur.com/owsq1MM.png) #### Do Pybytes relay data to my Azure IoT Hub broker? ![](https://i.imgur.com/53CnqWg.png) Using the built in statistic tool, we can see that 481 MQTT packages has been received so far, thus data is recieved! #### A Stream Analytics job Using a Microsoft Stream Analytics Job to fetch data from our Microsoft IoT Hub and deliver it as sql questions to our SQL server! Setting up a Stream Anlytics job and feeding it with our IoT Device, we finally can se what our Azure IoT broker receives: ![](https://i.imgur.com/cLPOyTh.png) #### Database A Microsoft SQL RDBM has been set up in our Azure cloud for storage. Free for 30 days, 131 kr/month thereafter.. mtjattdb1.databse.windows.net In this, a database iotdatabase has been set up Further, using db console and SQL, our storage table can be created with, mostly, nvarchar fields: ![](https://i.imgur.com/6hM46iI.png) ```sql= create table data1 ( signal int null, payload nvarchar(200) null, EventProcessedUtcTime nvarchar(200) null, PartitionId int null, EventEnqueuedUtcTime nvarchar(200) null, IoTHub nvarchar(200) null ) ``` By default, my resorces in Azure cannot access my database in Azure, a firewall rule needs to be set to allow this! When setting up a SQL Database, default is not to allow this. Several hours later, this setting was found! Do set it to [Yes]! ![](https://i.imgur.com/Ch76CUo.png) #### Using three Azure objects - data will now be stored! By that, our Stream Analytics Job can now send data recieved by Azure IoT Hub broaker to our Azure Database. A simple SQL question for results from signal 2 renders the table below ```sql= select payload as temperature, EventProcessedUtcTime as received from data1 where signal = 2 ``` ![](https://i.imgur.com/qGZZ3B6.png) ## The code (for our LoPy4) ### Connecting to the world Using Pybytes as a platform and thus selecting Pybytes 1.6.1 as my LoPy4 firmware plugin, all connections to the world will be made through the settings in my pybytes account for this connected development board. Thus, while Pybytes 1.6.1 is active, you cannot also connect manually to LoRa or WiFi in boot.py or main.py, this will render conflicts! Setting up Pybytes as a platform and there registering my LoPy4 development board and when adding credentials for my local SSID of choice, I found that after this, my development card will access internet without me writing any code for wifi or lora in boot.py or main.py! Makes sense in a way I guess! #### The Things Network Looking at TTNs covering map, I found that a gateway is available approx 2 km away so I chose to go with this as a backup for WiFi. Using Pybytes, my device will be automatically created and connected to their TTN account. Reference [Pybytes LoRa](https://docs.pycom.io/pybytes/networks/lora/) ![](https://i.imgur.com/B9jbqoe.png) The Things Network covering map, yellow = the location of my LoPy4 device! #### pybytes_config.json Using pybytes, my project configuration file will look s below: ```json { "networks": [ "wifi", "lora" ], "wifi": { "ssid": "Intranet", "password": "****" }, "loraType": "loRa OTAA", "loraServer": "TTN Server" } ``` ### Included libraries (github links) A big problem turned out to be finding micro python libraries that actually works with a LoPy4 card. It seems there is no official Pycom code validation plan for libraries with code for different third party development cards, a bit of a drawback! #### DHT11 temperature and humidity sensor A working library written by Zoltan Szarvas for this development card works great with LoPy4 and is available at the repository below: * https://github.com/JurassicPork/DHT_PyCom #### LCD 16x2-display I2C driver Several trials to find a working library for this set of development boards connected to Pycom have failed. While writing this, my best choice is to write my own driver but that will be a couple of days so maybe for the final presentation? Still not working but I hope to write my own class later on! ### main py Below the main.py file that runs on my LoPy4 development board. Obviously a bigger span than 2 degrees between T_MIN and T_MAX would be set in a real situation, for testing in 27 degrees, it's perfect though! Data is sent to Pycoms platform using, first choice WiFi and second choice LoRa as json packages. The protocol is MQTT. ```python # Mikael Johannesson, mj224pb # 2021-08-01 # Remote temperature log with local alarm # Introduction to Applied Internet of Things, 1DT305, LNU import pycom import time import machine from dth import DTH # constants T_MAX = 28 # high temperature alarm T_MIN = 26 # low temperature alarm # led test and initiation p_too_cold = machine.Pin('P8', mode=machine.Pin.OUT) p_too_warm = machine.Pin('P4', mode=machine.Pin.OUT) p_too_warm.value(1) p_too_cold.value(1) #i2c bus test i2c = machine.I2C(0, pins=('P9','P10')) # P9=SDA, P10=SCL i2c.init(machine.I2C.MASTER, baudrate=100000) i2c.scan() #sensor hct-11 initiation th = DTH(machine.Pin('P23', mode=machine.Pin.OPEN_DRAIN),0) #2 s to validate that leds will light up as expected! time.sleep(2) # main loop 20s while True: result = th.read() if result.is_valid(): temperature = result.temperature if temperature >= T_MAX: p_too_warm.value(1) else: p_too_warm.value(0) if temperature <= T_MIN: p_too_cold.value(1) else: p_too_cold.value(0) pybytes.send_signal(2, temperature) pybytes.send_signal(3, result.humidity) else: pybytes.send_signal(1, "DHT11 error") time.sleep(20) ``` ## Transmitting data / connectivity ![](https://i.imgur.com/hKdXSO2.png) Data will flow according to the diagram above. Protocols for communication are written on the arrows. Note that only one communication layer has been written for each arrow! My Pybytes IoT Broker above could have been avoided and data sent directly from my LoPy4 to my Azure IoT Hub. I did include it as I wanted to understand what it could do but also for convenience as it was easier to have it in between due to nice interfaces. By chosing both Wifi and LoRa over TTN for my LoPy4, the range is good and I will be able to move my device within any densely populated area and still expect it to be able to communicate with my IoT Broaker. Obviously, LoRa has been designed for low power consumption and my MQTT packages are quite small so LoRa will be the choice over WiFi if power consumption is to be reduced. Setting a LoPy4 in deep sleep between readings (and transmittings) will also have dramatical effects on power consumption. ### Sensor -> Pycom A physical one-wire bus with serial data on. ### Pycom -> Pybytes MQTT over either WiFi or LoRaWAN (over LoRa). WiFi is prioritized ### Pybytes -> Azure IoT Hub MQTT over Ethernet and Internet ### Azure IoT Hub -> Azure SQL DB SQL over Internet set up as Azure Job ## Presenting data ### Pybytes I set my Lopy4 development board to send data to my Pybytes account, showing it as line charts. One can argue that the vertical scale is a bit rough thus needs more work to be easily readable! Data is sent every 20s. For a production environment less frequent samples are probably a better choice but for this test, it's also valuable to see that data actually is received thus waiting several minutes is impractical! Pybytes store received data for 30 days. For a test, this is sufficient. For real data, we probably want to store data for longer periods. #### Received temperatures, line chart ![](https://i.imgur.com/f7TLT3T.png) #### Received humidity, line chart ![](https://i.imgur.com/iJzcuHl.png) ### Azure Azure is chosen for storage. An SQL database has been set up and do now recieve and store data pushed from our Pycom device. As a bonus, Azure IoT Hub do provide us with statistics of how our data collection works: ![](https://i.imgur.com/8x5guYp.png) ### Choice of database A Microsoft SQL Database has been set up in my Azure cloud for long time storage and data collection from my sensor. Using a Microsoft SQL Database was the easyest way for me to solve the problem of making my Stream Job talk to the database. Other RDBMs would have been possible but would have been more time consuming! ### Automation/triggers of data Triggers are coded in my LoPy4 device for too low and too high temperatures. They affect pin P4 and pin P8 respectively. ## Finalizing design The task so far has been to set up a mockup using development cards and breadboards. To finalize this design in a hardware perspective a printed circuit board and housing is needed. Pycom do offer OEM modules for PCB-mounting, their L04 OEM Module seems to be the best choice here! * https://pycom.io/product/l04-oem-module/ For the front end, work needs to be put towards security to ensure that only authorized people are are able to see the collected data. Maybe data needs to be integrated into an existing customer interface? Microsoft do have a tool for presentation that seems interesting, Microsoft Power BI. Deep Sleep mode needs to be implemented on the L04 board if low power consumption is an issue. Azure solutions can be kept as they are set up although licences and server plans needs to be evaluated and optimized. ### Final results I managed to get sensor data from my sensor to my database, as the plan was! Working with Azures IoT tools turned out to be a bit tricky in two ways, security settings and that they have a big variety of apps to choose from. ![](https://i.imgur.com/YFZrTUT.jpg) ![](https://i.imgur.com/YkYQQJe.png) I would have loved finding time to write my own LCD I2C class or finding the 'error' in the existing one and then printing temperature and humidity data locally to this. Due to my problem with my instable computer - LoPy4 connection, this was however not an option as one single upload can take hours of trials. ### Pictures My breadboard (except LCD driver and display) ![](https://i.imgur.com/hbxXzZH.png) My physical mockup battery powered sending data (currently) over WiFi ![](https://i.imgur.com/tBeCby1.png)

    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