{"id":40877,"date":"2021-02-23T10:59:50","date_gmt":"2021-02-23T02:59:50","guid":{"rendered":"\/blog\/?p=40877"},"modified":"2024-02-18T07:25:29","modified_gmt":"2024-02-18T07:25:29","slug":"build-a-tinyml-smart-weather-station-with-wio-terminal","status":"publish","type":"post","link":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/","title":{"rendered":"Build a TinyML Smart Weather Station with Wio Terminal"},"content":{"rendered":"\n<p><strong>Updated on Feb 28th, 2024<\/strong><\/p>\n\n\n\n<p>In today\u2019s tutorial, learn to create your own Wio Terminal Smart Weather Station with TinyML powered prediction capabilities! This article is a complete step-by-step guide to get this project up and running with your Wio Terminal, all the way from data acquisition to training, and finally deploying our smart weather station with Arduino code.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1030\" height=\"687\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/02\/Banner-1030x687.jpeg\" alt=\"\" class=\"wp-image-40897\" srcset=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-1030x687.jpeg 1030w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-300x200.jpeg 300w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-768x512.jpeg 768w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-1536x1024.jpeg 1536w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-2048x1365.jpeg 2048w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-1024x683.jpeg 1024w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-675x450.jpeg 675w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Smart Weather Station: Project Overview<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Typically, a weather station project would involve connecting the sensor to our microcontroller platform and reading out this data in real time, either on an LCD display or over an internet connection to an online database.<\/p>\n\n\n\n<p>Today, I want to share the smart version of this weather station project that I created by adding the capability for our Wio Terminal to predict the current weather conditions. With an onboard TensorFlow Lite model, the Wio Terminal becomes able to use real time temperature and relative humidity data for making half-hourly weather predictions!<\/p>\n\n\n\n<p>Let\u2019s first take a look at the completed project with the video below.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"800\" height=\"450\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/02\/ezgif.com-optimize.gif\" alt=\"\" class=\"wp-image-40880\"\/><\/figure><\/div>\n\n\n<div style=\"height:11px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Project Requirements<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To follow along with this project, the following materials are recommended.<\/p>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.seeedstudio.com\/Wio-Terminal-p-4509.html\">Wio Terminal<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.seeedstudio.com\/Grove-Temperature-Humidity-Sensor-DHT11.html\">DHT11 Grove Temperature and Humidity Sensor<\/a><\/li>\n<\/ul>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Apart from the <a href=\"https:\/\/www.arduino.cc\/en\/software\/\">Arduino IDE<\/a> to program the Wio Terminal, you\u2019ll also need a computer with <a href=\"https:\/\/www.python.org\/downloads\/\">Python 3<\/a>. We will be working with both Python scripts (.py files) and Python notebooks (.ipynb files). If you are new to Python, my code editor of choice is Microsoft\u2019s Visual Studio Code. It can open both the types of files we need for this project, and has a set up guide that you can follow <a href=\"https:\/\/code.visualstudio.com\/docs\/python\/python-tutorial\">here<\/a>.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is TinyML: TensorFlow Lite<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Machine learning has become a real buzzword in the recent decade, giving us amazing functionality like predictions, image recognition and anomaly detection. Traditionally, you might think of machine learning as a computationally intensive task &#8211; which is true! Modern deep neural networks used for advanced machine learning tasks are trained on powerful GPUs and ASICs customised for deep learning training, with massive amounts of data.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/b8w4MnKoSqxRu5cl8garTMMcHXlM6WYSlEVXaMKF_IIh_g-_yqeJs5UC2Qqrm-VLoRtnrLBWo8T27XkXvYZiXhR1Si47gx2xbCKVcRDR29DJZCkuNHUYudsleIP4yeE4xA9NyeSl\" alt=\"\" width=\"800\"\/><figcaption class=\"wp-element-caption\">Neural Network for Image Classification, Source: Carnegie Mellon University<\/figcaption><\/figure><\/div>\n\n\n<p>However, a new concept in machine learning aims to bring these very applications to less powerful, but compact and convenient edge computing devices like MCUs (microcontroller units). This is TinyML.<\/p>\n\n\n\n<p>In broad terms, TinyML seeks to optimise machine learning models to take up less space and require less computational power to use. Most notably, <a href=\"https:\/\/www.edgeimpulse.com\/\">Edge Impulse<\/a> is a user friendly platform that allows you to build your own datasets, train your own optimised TinyML models that can then be easily deployed.<\/p>\n\n\n\n<p>For today\u2019s project, however, we will be using the <a href=\"https:\/\/www.tensorflow.org\/lite\">TensorFlow Lite<\/a> library. TensorFlow is an open source machine learning platform maintained by Google, with its Lite version targeted at the optimisation of models for TinyML.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/ebehDeSyup5LNlStqr4si5eoZpvDJ1x4t_wMD5SXGi1eu_AYXHQCXOkO53SAfVbpzc1GyDU2tc772sxH7P6-R3l3W-PVo6Y17MiY_VWU9vq5d8aI_jR5KhbNikh-A9zd9-OPQdu-\" alt=\"\" width=\"800\"\/><figcaption class=\"wp-element-caption\">TensorFlow Lite Overview, Source: TensorFlow<\/figcaption><\/figure><\/div>\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Getting Temperature &amp; Humidity Data: 3 Ways<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The first part of this tutorial involves getting the historical data for your area or city. Believe it or not, it\u2019s actually quite hard to find accessible historical data even for simple temperature and relative humidity measurements.<\/p>\n\n\n\n<p>In summary, there are three primary ways that you can get this data.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1.  <strong>Measure and Collect the Data Yourself<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/uSXO1VZviA7z3IPzYCQw-i_KuekpdudZF5OPgcN1bh9f7x9gPyQwwQnQq0c5_y5zkc7Z6WWSbu0OlcnUbzCwLvQj-3NlirzqmQKbhrHaPZXldLGw2jaE5gLybRT95W6FZxzem1wi\" alt=\"\" width=\"300\"\/><\/figure><\/div>\n\n\n<p>If you\u2019re planning on making a weather station, chances are that you already have a microcontroller and temperature\/humidity sensor. If so, you can use a simple Arduino program to pull environmental data at set intervals to build your own dataset over time.<\/p>\n\n\n\n<p>While this seems easy and convenient, the time it would take to pull sufficient data (at least a few hundred) to train any kind of machine learning model would take ages! Even with one reading every hour, and considering cyclical weather patterns throughout the day, even one week\u2019s worth of readings would yield only 7 unique sets of data points. Not to mention, you\u2019ll have to label the data yourself.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">2.  <strong>Look for a Free Dataset or API<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>There are numerous APIs (or application programming interfaces) that are available for pulling weather data. However, most of them require a paid subscription to access the historical data which we need.<\/p>\n\n\n\n<p>Depending on where you live, your local agency or weather station might offer this data at no cost. For example, the National Environmental Agency in Singapore offers an <a href=\"https:\/\/data.gov.sg\/dataset\/realtime-weather-readings\">API for Weather Data<\/a> that is free for programmatically querying historical weather data. You can follow the documentation for the API you intend to use for how to get started.<\/p>\n\n\n\n<p>Otherwise, if you\u2019re in the US, the <a href=\"https:\/\/www.ncdc.noaa.gov\/cdo-web\/datasets\">National Centers for Environmental Information<\/a> also provides up-to-date hourly data that can be requested for in CSV format on their website. Otherwise, you can follow <a href=\"https:\/\/towardsdatascience.com\/getting-weather-data-in-3-easy-steps-8dc10cc5c859\">this article<\/a> to pull that data programmatically as well.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">3.  <strong>Scrape the Data with a Python Script<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/SDsQYkJZIzMLgTWrYWKDoF010bwSvTp6PI2WcMYYWkvsiC7hulALcaj5Nij_afz12Csqla-332cwqoSgaKDWajSGzZ4AGvBYQ4xM-I50BVBdmFRxlm-TUDcWrbrt09eL6Mlcq9x2\" alt=\"\" width=\"600\"\/><figcaption class=\"wp-element-caption\">Singapore\u2019s Historical Weather Data, Source: Wunderground<\/figcaption><\/figure><\/div>\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Many websites such as <a href=\"https:\/\/www.wunderground.com\/\">Wunderground<\/a> provide detailed historical weather data for referencing at no cost, but they often aren\u2019t in an easily processable format like CSV that we need for machine learning. We can circumvent this problem by using a program (often Python is used) to open the web pages and copy this data down for us. This is known as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Web_scraping\">Web Scraping<\/a>, and is the method I\u2019ve used for today\u2019s project.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Web Scraping Weather Data with Python<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>To make things easier for everyone following along with the article today, I\u2019ve referenced <a href=\"https:\/\/medium.com\/swlh\/web-scraping-weather-data-with-selenium-webdriver-69a7b501fac\">this article by Angel R.<\/a> as well as <a href=\"https:\/\/stackoverflow.com\/questions\/55306320\/scraping-wunderground-without-api-using-python\">this post on StackOverflow<\/a> to create a Python script for this purpose. This script will automatically pull data from Wunderground\u2019s historical daily weather data, then produce the data in a beautiful CSV file.<\/p>\n\n\n\n<p>Before we get to the code, visit wunderground.com and navigate to More &gt; Historical Weather as shown below.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/02\/Wunderground-1-1030x688.png\" alt=\"\" class=\"wp-image-40887\" width=\"800\" srcset=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Wunderground-1-1030x688.png 1030w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Wunderground-1-300x200.png 300w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Wunderground-1-768x513.png 768w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Wunderground-1-1024x684.png 1024w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Wunderground-1-675x450.png 675w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Wunderground-1.png 1328w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure><\/div>\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>You\u2019ll want to enter your location so that you can obtain data for and train your weather station to interpret weather conditions that are in your area. You can also enter the date that you want to start getting weather data from &#8211; I\u2019ve chosen 1 Jan 2020.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/n1tMLJehfk79NzNjunqHuAt28OmKceNj-oB-2rfV_sZMk20Vo5osACsAOvePfPkepIkT8EjXKpDFIngu9E-2kIab_NCJEE8DwKbbByvtpVs3Anws1lodo6pVx78ruiTBYx9Ly8yK\" alt=\"\" width=\"800\"\/><\/figure><\/div>\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>After clicking view, a new web page should load. You can take a look around to see what we\u2019re working with, but what we really want to get is the URL of this page. Ideally, it\u2019ll have the same format where we have the last section as the date of the weather data that\u2019s being shown. Note this URL down.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/4S_RuYdUaSqnvlZc6pRyfSE5tUgw_rVrW--U9FyvU8rrLP4GNncodqK35fES4xx1X8eIsttL62eEzq6JuIsS_Y3Wto3vBDYN9d9HyFcoAmT4tEU4fJ8rFmJRWtvk4joDuBBXr0k3\" alt=\"\"\/><\/figure><\/div>\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now we can get started with the web scraping. Download the code for this project as a ZIP file from the following <a href=\"https:\/\/github.com\/supperted825\/WioTerminal_TinyMLWeatherStation\">link<\/a>. Then, open the GetWeatherData.py file with your code editor of choice.<\/p>\n\n\n\n<p>Before you can run the script, you will need to install the following Python packages with the command in your computer\u2019s command line or terminal. These packages will help us parse web page data without us having to actually open it, and handle the recorded data later on.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>pip3 install numpy pandas beautifulsoup4 selenium<\/code><\/pre>\n\n\n\n<p>The first part of the code that you will need to replace is the lookup_URL. This is where you\u2019ll want to place the link that you found in the previous section. Take note, however, that we are replacing the date numbers with \u201c{}\u201d.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>lookup_URL = 'https:\/\/www.wunderground.com\/history\/daily\/WSSS\/date\/{}-{}-{}.html'<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Then, you can define the start date and how many days\u2019 weather data you\u2019d like to collect. I\u2019ve chosen around 400 so that we can help our model get a good grasp of weather patterns all year-round.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>start_date = datetime(2020, 1, 1)\nend_date = start_date + pd.Timedelta(days=400)<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The next thing you need to check is the webdriver. By default, the code will use a chrome webdriver MacOS executable based on the Google Chrome browser to load the web page data. If you are on Windows or want to use another web driver, you can visit <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/WebDriver\">here<\/a> for Firefox and <a href=\"https:\/\/chromedriver.chromium.org\/downloads\">here<\/a> for Chrome.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>driver = webdriver.Chrome(executable_path='chromedriver', options=options)<\/code><\/pre>\n\n\n\n<p>Note: If you get path errors stating that your chromedriver is not found, replace \u2018chromedriver\u2019 in the command with the absolute path to your web driver executable file.<\/p>\n\n\n\n<p>We can finally execute the Python file and begin web scraping! Sit back and relax as our program opens each page one by one and harvests its weather data. At this time, you might see something similar to below in your program output.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>Gathering data from:  2020-01-01 00:00:00\nOpened URL\nGathering data from:  2020-01-02 00:00:00\nOpened URL\nGathering data from:  2020-01-03 00:00:00\nOpened URL\nGathering data from:  2020-01-04 00:00:00\nOpened URL\n...<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Finally, we get a CSV file with all the historical weather data we need, ready for building our machine learning model!<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/4R0rfAz6ilS6-Lj8i0Z7ZPJ6pPuj9POmJ3NLGLgxwfbqBW8XbxIKlBqfXG8_UJEGNo61udb_40OfwzjVlP3kD7atqwDij9uCNSLD0q3BrV93Y8NGV5t9w2mJwXTretweP-AhspXM\" alt=\"\" width=\"800\"\/><\/figure><\/div>\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Training our TensorFlow Lite Model<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This next section of our project will utilise the BuildTFLiteModel.ipynb file. Python notebooks are a type of Python file that is popular for data science and machine learning. They allow Python code to be run in chunks, which means that we can work through our project progressively and easily reference the outputs from previous parts.<\/p>\n\n\n\n<p>Note: While the chunks can be run individually, it&#8217;s important to run this notebook in order. Otherwise, the code will not work as intended.<\/p>\n\n\n\n<p>Once again, you\u2019ll have to install the following libraries before we begin. Scikit-learn is another popular machine learning library. It also has some useful data processing functions that we will utilise for this project.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>pip install tensorflow scikit-learn<\/code><\/pre>\n\n\n\n<p>Our primary objective is to utilise real time temperature and humidity data to predict the present weather conditions. Hence we\u2019ll drop the other columns that aren\u2019t necessary. We\u2019re also parsing the temperature and humidity values from strings into integer values while converting the temperature units to Kelvin (K).<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/TA0eyjrRM8qhH-JJj0muSkFx4wRhuYFUH-Awrah6I6ycrySXjuCkQpY8YMfxDWAGwxDyZGxr5dm25eo2pY_TeLCrkvLLOOM54JxfhHjRqgJOqCDwmBEmSd13Ed_6yNPbqS4g6QoD\" alt=\"\"\/><\/figure>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This next step is important and has to be done by you. In the previous chunk, we displayed the unique labels for our weather conditions. Because there are so many possible outputs for our model that only fundamentally takes two inputs, we will have to convert these labels into three primary categories.<\/p>\n\n\n\n<p>In the next chunk, you\u2019ll see three lists that group these labels into \u201cNo Rain\u201d, \u201cMight Rain\u201d and \u201cRain\u201d. The values are then <a href=\"https:\/\/machinelearningmastery.com\/why-one-hot-encode-data-in-machine-learning\/\">one-hot encoded<\/a> to represent our categories numerically. You can eventually adjust these labels to be more useful for the climate where you live.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>norain = &#91;'Mostly Cloudy', 'Fair', ... , 'Partly Cloudy \/ Windy']\nmightrain = &#91;'Showers in the Vicinity', 'Thunder in the Vicinity', 'Thunder']\nrain = &#91;'Rain Shower', 'Light Rain Shower', 'Light Rain', ... , 'Light Rain \/ Windy']<\/code><\/pre>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Next, to better make use of our available input data, we will only perform predictions once for a given 7 input window. Each entry from Wunderground represents a reading taken at half an hour intervals. We will follow this and make half-hourly predictions with our implementation with the current + 6 previous half-hourly readings.<\/p>\n\n\n\n<p>This allows us to provide more features for our model to recognise the patterns between the input and outputs, which should improve classification performance. Check that the lengths of the x and y array are the same to ensure that this step has been completed successfully.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>y = processed_data&#91;&#91;\"NoRain\", \"MightRain\", \"Rain\"]].to_numpy()&#91;7:]\nrawx = processed_data.drop(columns = &#91;\"NoRain\", \"MightRain\", \"Rain\"]).to_numpy()\n \nx = &#91;]\ntemp = np.array(0)\nfor i in range(len(rawx)-7):\n    temp = rawx&#91;i:i+6].flatten()\n    x.append(temp)\nx = np.array(x)\nx.shape, y.shape<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The next chunk splits the data into training and testing data.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>xtrain, xtest, ytrain, ytest = train_test_split(x, y, test_size = 0.20, random_state = 33)<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Then, we will proceed to define our model before compiling it and fitting it to our data. If you are new to Keras machine learning models and would like to learn more, you can visit this <a href=\"https:\/\/machinelearningknowledge.ai\/keras-dense-layer-explained-for-beginners\/\">short read for beginners<\/a> by Palash Sharma.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>model = tf.keras.Sequential()\nmodel.add(Dense(14, activation='relu'))\nmodel.add(Dense(8, activation='relu'))\nmodel.add(Dense(3, activation='softmax'))\n \nmodel.compile(loss = 'categorical_crossentropy',\n              optimizer = tf.optimizers.Adam(),\n              metrics=&#91;'accuracy'])\n \nmodel.fit(xtrain, ytrain, epochs=10, validation_split=0.1)<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The last two chunks are arguably the most important &#8211; we have to use the TF Lite converter to transform our keras model into a TF Lite model that is small enough and in a format that we can use for inferences on our Wio Terminal.<\/p>\n\n\n\n<p>Once you have run the final chunk, a model.h file should have been written to the folder. This header file is how we will bring our trained TF Lite model to Arduino! For the final step in this section, use this file to <strong>replace the model.h file<\/strong> in the WioTerminal_SmartWeatherStation folder where the Arduino code resides.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Implementing Machine Learning on the Wio Terminal<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>It\u2019s finally time to move on to implementing our model on our Wio Terminal.<\/p>\n\n\n\n<div style=\"height:5px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Hardware Setup<\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Plug your DHT11 temperature and humidity sensor into your Wio Terminal as shown below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/02\/Copy-of-Clean-7-1030x601.png\" alt=\"\" class=\"wp-image-40901\" width=\"800\" srcset=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Copy-of-Clean-7-1030x601.png 1030w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Copy-of-Clean-7-300x175.png 300w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Copy-of-Clean-7-768x448.png 768w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Copy-of-Clean-7-1536x896.png 1536w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Copy-of-Clean-7-2048x1195.png 2048w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Copy-of-Clean-7-1024x597.png 1024w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\"><strong>Install the Wio Terminal Libraries<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First of all, if this is your first time working with the Wio Terminal, it\u2019s highly recommended to first get started <a href=\"https:\/\/wiki.seeedstudio.com\/Wio-Terminal-Getting-Started\/\">here<\/a>.<\/li>\n\n\n\n<li>Download and install the <a href=\"https:\/\/github.com\/Seeed-Studio\/Grove_Temperature_And_Humidity_Sensor\">Seeed DHT Library<\/a>. If you are new to installing Arduino libraries via ZIP files, you can follow <a href=\"https:\/\/wiki.seeedstudio.com\/How_to_install_Arduino_Library\/\">these instructions<\/a>.<\/li>\n\n\n\n<li>Finally, install the Arduino TensorFlowLite library through the Tools &gt; Manage Libraries. I will recommend installing Version 2.1.0 since that is the library that I\u2019ve had success with. However, others have reported issues with precompiled libraries, so your mileage may vary.<\/li>\n<\/ul>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/Grs1oEfca-owNNhb8QKYKcvyqd8ITSF55IZqXC9c6SofkGJ2yN5KvhZdtzbX04vOiYMGc3e0gNa2WVUAd_W8a38J8JVh-k4pbA3goohevzItEQe9z7uGntb1fDqq9DmDMyydiFcw\" alt=\"\" width=\"700\"\/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Prepare the Arduino Code<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>There\u2019s only one thing that you\u2019ll have to take note of before flashing the code to your Wio Terminal. If you changed the labels on your model\u2019s outputs, you\u2019ll want to edit the following parameters accordingly.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>const char* OUTPUTS&#91;] = {\n    \"No Rain\",\n    \"Might Rain\",\n    \"Rain\"\n};\nint NUM_OUTPUTS = 3;<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Arduino Code Highlights<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The more \u2018challenging\u2019 implementation of this Arduino code involves how we will build a FIFO (first-in-first-out) structure to manage our 7-reading window. Take a look at the truncated code below:<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>if (array_count == 0 | millis() - dataMarker &gt; 30 * 60000) {\n      dataMarker = millis();\n\n      for (int i=0; i&lt;12; i++) {\n        temp_hum_val&#91;i] = temp_hum_val&#91;i+2];\n      }\n\n      temp_hum_val&#91;12] = reading&#91;1] + 273.15;\n      temp_hum_val&#91;13] = reading&#91;0];\n      array_count ++;\n\n      if (array_count &gt; 7) array_count = 7;\n      if (array_count == 7) {\n        \n        \/\/ Copy array into tensor inputs\n        for (int i=0; i&lt;14; i++) {\n          tflInputTensor-&gt;data.f&#91;i] = temp_hum_val&#91;i];\n        }\n        \n        \/\/ Run inference on data (not shown)\n        \/\/ Get and display output (not shown)\n      }\n}<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>When we first start the Wio Terminal, we will have array_count at its initialised value of 0. We will use this variable to record the total number of readings that we have taken to ensure that we have at least 7 readings for machine learning model\u2019s prediction.<\/p>\n\n\n\n<p>The for loop shifts all values\u2019 indices forward by 2, essentially deleting the earliest temperature and humidity readings. Then, we will assign the latest sensor readings to the back of the queue and increment the array_count value.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code>for (int i=0; i&lt;12; i++) {\n        temp_hum_val&#91;i] = temp_hum_val&#91;i+2];\n}<\/code><\/pre>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Every half an hour after this, we will run this code again to sample the data until we have built up an array of 14 values (ie. array_count == 7). Once the array_count value reaches 7, we will copy the stored temp_hum_val array values to the model input pointers and begin invoking the TF Lite interpreter for predictions.<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Managing Memory on the Wio Terminal<\/strong><\/h3>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>When you make edits to the Arduino sketch, it\u2019s important to remember that the amount of memory we have on our Wio Terminal is a mere 192 kilobytes. I\u2019ve had my Wio Terminal freeze up numerous times when it called the AllocateTensors() function, which I highly suspect is due to a lack of available memory.<\/p>\n\n\n\n<p>Hence, it\u2019s best to keep things in this sketch lightweight, especially with regard to the variables that you declare prior to your TF Lite interpreter being successfully initialised!<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>The Final Product<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Our TinyML smart weather station is now ready for action! The image below demonstrates what you should see once 7 half-hourly readings have been accumulated. The prediction will continue to be updated half-hourly with the new data that comes in! In your testing, you can reduce the interval between new readings being put into the model input array to check that your interpreter is working as intended.<\/p>\n\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/blog.seeedstudio.com\/wp-content\/uploads\/2021\/02\/IMG_0087-1030x687.jpg\" alt=\"\" class=\"wp-image-40898\" width=\"700\" srcset=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/IMG_0087-1030x687.jpg 1030w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/IMG_0087-300x200.jpg 300w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/IMG_0087-768x512.jpg 768w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/IMG_0087-1536x1024.jpg 1536w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/IMG_0087-2048x1365.jpg 2048w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/IMG_0087-1024x683.jpg 1024w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/IMG_0087-675x450.jpg 675w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure><\/div>\n\n\n<div style=\"height:15px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Summary<\/strong><\/h2>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>I hope that this tutorial has been helpful for those of you who are looking to build a smart weather station! It\u2019s also a very basic introduction to enabling TinyML with TensorFlow Lite on a microcontroller like the Wio Terminal.<\/p>\n\n\n\n<p>Since you\u2019ll be working with your own data, there is a non-negligible chance that some of the code that I\u2019ve provided will not work directly out of the box. Nonetheless, I hope that you will enjoy the learning process and own the satisfaction of completing your very own project!<\/p>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>For more TinyML on Wio Terminal projects, please visit:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/01\/19\/tiny-ml-with-wio-terminal-1-intro\/\">Learn TinyML using Wio Terminal and Arduino IDE #1 Intro<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/03\/learn-tinyml-using-wio-terminal-and-arduino-ide-2-audio-scene-recognition-and-mobile-notifications\/\">Learn TinyML using Wio Terminal and Arduino IDE #2 Audio Scene Recognition and Mobile Notifications<\/a><\/li>\n<\/ul>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>For some of my other Wio Terminal projects, you can also visit:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/08\/wio-terminal-arduino-smart-doorbell-with-code\/\">Wio Terminal: Arduino Smart Doorbell (with Code!)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/04\/wio-terminal-arduino-customisable-timer-with-code\/\">Wio Terminal: Arduino Customisable Timer (with Code!)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/19\/build-an-mqtt-intercom-with-wio-terminal-with-code\/\">Build an MQTT Intercom with Wio Terminal (with Code!)<\/a><\/li>\n<\/ul>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Choose the best tool for your TinyML project<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong><a href=\"https:\/\/www.seeedstudio.com\/Grove-Vision-AI-V2-Kit-p-5852.html\">Grove \u2013 Vision AI Module V2<\/a><\/strong><\/h3>\n\n\n\n<p>It\u2019s an MCU-based vision AI module powered by Himax WiseEye2 HX6538 processor, featuring rm Cortex-M55 and Ethos-U55. It integrates Arm Helium technology, which is finely optimized for&nbsp;<strong>vector data processing<\/strong>, enables:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Award-winning low power consumption<\/li>\n\n\n\n<li>Significant uplift in DSP and ML capabilities<\/li>\n\n\n\n<li>Designed for battery-powered endpoint AI applications<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img decoding=\"async\" src=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/5-101021112-Grove-Vision-AI-Module-V2-feature-1030x773.jpg\" alt=\"\" class=\"wp-image-91983\" width=\"463\" height=\"347\" srcset=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/5-101021112-Grove-Vision-AI-Module-V2-feature-1030x773.jpg 1030w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/5-101021112-Grove-Vision-AI-Module-V2-feature-300x225.jpg 300w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/5-101021112-Grove-Vision-AI-Module-V2-feature-768x576.jpg 768w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/5-101021112-Grove-Vision-AI-Module-V2-feature-1024x768.jpg 1024w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/5-101021112-Grove-Vision-AI-Module-V2-feature.jpg 1400w\" sizes=\"(max-width: 463px) 100vw, 463px\" \/><\/figure><\/div>\n\n\n<p>With support for\u00a0<strong>Tensorflow\u00a0<\/strong>and\u00a0<strong>Pytorch\u00a0<\/strong>frameworks, it allows users to deploy both off-the-shelf and custom AI models from Seeed Studio\u00a0<a href=\"https:\/\/sensecraft.seeed.cc\/ai\/#\/model\">SenseCraft AI<\/a>. Additionally, the module features a range of interfaces, including IIC, UART, SPI, and Type-C, allowing easy integration with popular products like Seeed Studio XIAO, Grove, Raspberry Pi, BeagleBoard, and ESP-based products for further development.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong><a href=\"https:\/\/www.seeedstudio.com\/XIAO-ESP32S3-Sense-p-5639.html\">Seeed Studio XIAO ESP32S3 Sense<\/a><\/strong>&nbsp;&amp;&nbsp;<strong><a href=\"https:\/\/www.seeedstudio.com\/Seeed-XIAO-BLE-Sense-nRF52840-p-5253.html\">Seeed Studio XIAO nRF52840 Sense<\/a><\/strong><\/h3>\n\n\n\n<p>Seeed Studio XIAO Series are diminutive development boards, sharing a similar hardware structure, where the size is literally thumb-sized. The code name \u201cXIAO\u201d here represents its half feature \u201cTiny\u201d, and the other half will be \u201cPuissant\u201d.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1030\" height=\"773\" data-id=\"91985\" src=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072058195881-1030x773.png\" alt=\"\" class=\"wp-image-91985\" srcset=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072058195881-1030x773.png 1030w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072058195881-300x225.png 300w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072058195881-768x576.png 768w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072058195881-1024x768.png 1024w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072058195881.png 1400w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1030\" height=\"773\" data-id=\"91984\" src=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072046576630-1030x773.png\" alt=\"\" class=\"wp-image-91984\" srcset=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072046576630-1030x773.png 1030w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072046576630-300x225.png 300w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072046576630-768x576.png 768w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072046576630-1024x768.png 1024w, https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2024\/02\/\u4f01\u4e1a\u5fae\u4fe1\u622a\u56fe_17072046576630.png 1400w\" sizes=\"(max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n<\/figure>\n\n\n\n<p>Seeed Studio XIAO ESP32S3 Sense integrates an OV2640 camera sensor, digital microphone, and SD card support. Combining embedded ML computing power and photography capability, this development board can be your great tool to get started with intelligent voice and vision AI.<\/p>\n\n\n\n<p>Seeed Studio XIAO nRF52840 Sense is carrying Bluetooth 5.0 wireless capability and is able to operate with low power consumption. Featuring onboard IMU and PDM, it can be your best tool for embedded Machine Learning projects.<\/p>\n\n\n\n<p><a href=\"https:\/\/www.seeedstudio.com\/catalogsearch\/result\/?q=XIAO+\">Click here<\/a>\u00a0to learn more about the\u00a0<a href=\"https:\/\/www.seeedstudio.com\/xiao-series-page\">XIAO family<\/a>!<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>SenseCraft AI<\/strong><\/h3>\n\n\n\n<p><a href=\"https:\/\/sensecraft.seeed.cc\/ai\/#\/model\" target=\"_blank\" rel=\"noreferrer noopener\">SenseCraft AI<\/a>&nbsp;is a platform that enables easy AI model training and deployment with no-code\/low-code. It supports Seeed products natively, ensuring complete adaptability of the trained models to Seeed products. Moreover, deploying models through this platform offers immediate visualization of identification results on the website, enabling prompt assessment of model performance.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/06\/%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_17072049675606-1030x637.png\" alt=\"\" class=\"wp-image-91977\" width=\"573\" height=\"354\"\/><\/figure><\/div>\n\n\n<p>Ideal for tinyML applications, it allows you to effortlessly deploy off-the-shelf or custom AI models by connecting the device, selecting a model, and viewing identification results.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Updated on Feb 28th, 2024 In today\u2019s tutorial, learn to create your own Wio Terminal<\/p>\n","protected":false},"author":3537,"featured_media":40897,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_tribe_ticket_capacity":"0","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"iawp_total_views":0,"footnotes":""},"categories":[1],"tags":[3100,1284,1771,3171,3411,3003,3678],"class_list":["post-40877","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","tag-dht11-sensor","tag-tensorflow","tag-tensorflow-lite","tag-tinyml","tag-weather-station","tag-wio-terminal","tag-wio-terminal-project"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Build a TinyML Smart Weather Station with Wio Terminal - Latest News from Seeed Studio<\/title>\n<meta name=\"description\" content=\"Follow this step-by-step tutorial to build your very own smart weather station with the Wio Terminal, powered by TensorFlow Lite machine learning!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build a TinyML Smart Weather Station with Wio Terminal - Latest News from Seeed Studio\" \/>\n<meta property=\"og:description\" content=\"Follow this step-by-step tutorial to build your very own smart weather station with the Wio Terminal, powered by TensorFlow Lite machine learning!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/\" \/>\n<meta property=\"og:site_name\" content=\"Latest News from Seeed Studio\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-23T02:59:50+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-18T07:25:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jonathan Tan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jonathan Tan\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/\",\"url\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/\",\"name\":\"Build a TinyML Smart Weather Station with Wio Terminal - Latest News from Seeed Studio\",\"isPartOf\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg\",\"datePublished\":\"2021-02-23T02:59:50+00:00\",\"dateModified\":\"2024-02-18T07:25:29+00:00\",\"author\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/61e29862da8741ee517eacd92f4cd094\"},\"description\":\"Follow this step-by-step tutorial to build your very own smart weather station with the Wio Terminal, powered by TensorFlow Lite machine learning!\",\"breadcrumb\":{\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#primaryimage\",\"url\":\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg\",\"contentUrl\":\"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg\",\"width\":2560,\"height\":1707},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.seeedstudio.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build a TinyML Smart Weather Station with Wio Terminal\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#website\",\"url\":\"https:\/\/www.seeedstudio.com\/blog\/\",\"name\":\"Latest News from Seeed Studio\",\"description\":\"Emerging IoT, AI and Autonomous Applications on the Edge\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.seeedstudio.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/61e29862da8741ee517eacd92f4cd094\",\"name\":\"Jonathan Tan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d8dd1a4a7882386e8818e110c9322897?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d8dd1a4a7882386e8818e110c9322897?s=96&r=g\",\"caption\":\"Jonathan Tan\"},\"url\":\"https:\/\/www.seeedstudio.com\/blog\/author\/jonathan-tan\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Build a TinyML Smart Weather Station with Wio Terminal - Latest News from Seeed Studio","description":"Follow this step-by-step tutorial to build your very own smart weather station with the Wio Terminal, powered by TensorFlow Lite machine learning!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/","og_locale":"en_US","og_type":"article","og_title":"Build a TinyML Smart Weather Station with Wio Terminal - Latest News from Seeed Studio","og_description":"Follow this step-by-step tutorial to build your very own smart weather station with the Wio Terminal, powered by TensorFlow Lite machine learning!","og_url":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/","og_site_name":"Latest News from Seeed Studio","article_published_time":"2021-02-23T02:59:50+00:00","article_modified_time":"2024-02-18T07:25:29+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg","type":"image\/jpeg"}],"author":"Jonathan Tan","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jonathan Tan","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/","url":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/","name":"Build a TinyML Smart Weather Station with Wio Terminal - Latest News from Seeed Studio","isPartOf":{"@id":"https:\/\/www.seeedstudio.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#primaryimage"},"image":{"@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#primaryimage"},"thumbnailUrl":"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg","datePublished":"2021-02-23T02:59:50+00:00","dateModified":"2024-02-18T07:25:29+00:00","author":{"@id":"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/61e29862da8741ee517eacd92f4cd094"},"description":"Follow this step-by-step tutorial to build your very own smart weather station with the Wio Terminal, powered by TensorFlow Lite machine learning!","breadcrumb":{"@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#primaryimage","url":"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg","contentUrl":"https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg","width":2560,"height":1707},{"@type":"BreadcrumbList","@id":"https:\/\/www.seeedstudio.com\/blog\/2021\/02\/23\/build-a-tinyml-smart-weather-station-with-wio-terminal\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.seeedstudio.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Build a TinyML Smart Weather Station with Wio Terminal"}]},{"@type":"WebSite","@id":"https:\/\/www.seeedstudio.com\/blog\/#website","url":"https:\/\/www.seeedstudio.com\/blog\/","name":"Latest News from Seeed Studio","description":"Emerging IoT, AI and Autonomous Applications on the Edge","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.seeedstudio.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/61e29862da8741ee517eacd92f4cd094","name":"Jonathan Tan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.seeedstudio.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d8dd1a4a7882386e8818e110c9322897?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d8dd1a4a7882386e8818e110c9322897?s=96&r=g","caption":"Jonathan Tan"},"url":"https:\/\/www.seeedstudio.com\/blog\/author\/jonathan-tan\/"}]}},"modified_by":"Sue Guan","views":8841,"featured_image_urls":{"full":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg",2560,1707,false],"thumbnail":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-80x80.jpeg",80,80,true],"medium":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-300x200.jpeg",300,200,true],"medium_large":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-768x512.jpeg",640,427,true],"large":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-1030x687.jpeg",640,427,true],"1536x1536":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-1536x1024.jpeg",1536,1024,true],"2048x2048":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-2048x1365.jpeg",2048,1365,true],"visody_icon":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-scaled.jpeg",32,21,false],"magazine-7-slider-full":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-1536x1020.jpeg",1536,1020,true],"magazine-7-slider-center":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-936x897.jpeg",936,897,true],"magazine-7-featured":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-1024x683.jpeg",1024,683,true],"magazine-7-medium":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-720x380.jpeg",720,380,true],"magazine-7-medium-square":["https:\/\/www.seeedstudio.com\/blog\/wp-content\/uploads\/2021\/02\/Banner-675x450.jpeg",675,450,true]},"author_info":{"display_name":"Jonathan Tan","author_link":"https:\/\/www.seeedstudio.com\/blog\/author\/jonathan-tan\/"},"category_info":"<a href=\"https:\/\/www.seeedstudio.com\/blog\/category\/news\/\" rel=\"category tag\">News<\/a>","tag_info":"News","comment_count":"0","_links":{"self":[{"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/posts\/40877","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/users\/3537"}],"replies":[{"embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/comments?post=40877"}],"version-history":[{"count":30,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/posts\/40877\/revisions"}],"predecessor-version":[{"id":92236,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/posts\/40877\/revisions\/92236"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/media\/40897"}],"wp:attachment":[{"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/media?parent=40877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/categories?post=40877"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.seeedstudio.com\/blog\/wp-json\/wp\/v2\/tags?post=40877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}