# **Tutorial for temperature and humidity monitoring by Rasp Pi Pico W using DHT11 sensor**
*by Anna Safonova, as228ek*
# Introduction
Like if you notice from the rubric my IoT project speaks about the usage of a humidity and temperature sensor, the connection it to Raspberry pi pico w, and also the control it with Blynk so it reveals changes of temperature and humidity. The realization of the project will take a few hours. It could be used for example in a room, basement or in greenhouse to supervise the temperature and humidity.
# Objective
The objective of this IoT project is actually to simplify peoples lives in different spheres of live like for example job, agriculture, science and also just for a better environment for the people and the planet.
# Materials
| components | used for |
| ---------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| M2M jumper wires x3 | Allows us to connect components our with each other |
| Raspberry Pi Pico W (board) x1 | Microcontroller with WiFi access to enable wireless communication and also the "brain" of our comunication system |
| micro USB (Cable) x1 | allows us to connect rpi pi w (microcontroller) to our computer (microsoft, MAC,...) |
| DHT11 (Humidity & temperature sensor) x1 |Sensor to gather data about the temperature and humidity (temperature in celcius, Humidity in procent %) |
| breadboard x1 | Allows components to easily be removed and replaced, and also it allows us to connect everything together on one board. It makes also really easy to understand the circuit
 DHT11 temperature & humidity sensor
 RPI PI PICO W board
The material was bought at [elektrokit.com](https://)
# Computer set-up
The chosen IDE for this project was Thonny because it supports MicroPython, has a simple, one step installation that provides both the interpreter and runtime and an IDE configured to use it. In addition, the Thonny has debugger. So firstly you need to download thonny and wait before it would be done. After the download your next step should be to download the micropython firmware from thonny IDE for connecting your microcontroller. After, when uf2 file has been downloaded, it can be uploaded to the microcontroller by connecting our micro USB cable from the host computer to the microcontroller. Before connecting the computer and microcontroller you should hold down the BOOTSEL key on the microcontroller and then connect it to the computer. After you have connected the microcontroller to the computer, a new drive should open on your computer containing the microcontrollers files where the uf2 file can be uploaded to. For visualizing and control the collected data the Blynk could be used as an low code IoT solution.
# Circuit
To connect a DHT11 sensor to a Raspberry Pi Pico, you need to wire the sensor’s VCC pin to the Pico’s 3.3V pin, the sensor’s GND pin to the Pico’s GND pin, and the sensor’s DATA pin to any of the Pico’s GPIO pin. In my case for this project I chose and used the GPIO 28 "DATA" pin. GPIO (General Purpose Input Output) is a set of pins in the microcontroller, which functions by passing data into and out of the board. They serve as a bidirectional pin. When serving as input, it brings information into the board from an input device to the processor on the micro-controller board. When serving as an output pin, the data from the board is transferred to an output device from the processor.
Here is a diagram showing the pins of the DHT11 sensor:

and this is a simplified circuit diagram of how we need to wire the components:

This setup/circuit allows analog data to be sent from the DHT11 to the microcontroller, as well sending electricity to the DHT11 sensor through the microcontroller.
So, after you have wired the circuit correctly then it would become something like this:

# Platform
The platform that I would like to suggest to use is Blynk. I also tried Adafruit and Ubidots but I found them quite complicated. Blynk allows to build own apps to control any devices over the Internet. This tool permit to initiate actions and notifications in response to the data, and facilitates its visualization. This platform is free to download. Simple projects for individuals are also free of charge but building a relatively complicated app with many widgets will cost a little money.
To get started with Blynk it is necessary to download the Blynk iOS or Android app, install a Blynk library, generate an Authentication Token from Blynk app to connect Raspberry pi pico w, and then it is possible to get started building the app and to add widgets (buttons, sliders etc.).
# The Code
```
#define BLYNK_TEMPLATE_ID "TMPL4PVr6UwbC"
#define BLYNK_TEMPLATE_NAME "DHT11"
#define BLYNK_AUTH_TOKEN "1YJckdxKZEmxOpgm8pmMF_xRvgXSsBBM"
from machine import Pin, I2C #importing relevant modules & classes
import time
import utime as time
from dht11 import DHT11 , InvalidChecksum
import BlynkLib
import network
# i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000) #initializing the I2C method
led=machine.Pin('LED', machine.Pin.OUT)
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("Pro","1234567890") #SSID: Pro , PASS: 1234567890
BLYNK_AUTH = '1YJckdxKZEmxOpgm8pmMF_xRvgXSsBBM'
# connect the network
wait = 30
while wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
wait -= 1
print('waiting for connection...')
time.sleep(1)
# Handle connection error
if wlan.status() != 3:
#raise RuntimeError('network connection failed')
led.value(0) #turn the led off
else:
print('connected')
ip=wlan.ifconfig()[0]
print('IP: ', ip)
led.value(1) #turn the led on
# Initialize Blynk
Blynk = BlynkLib.Blynk(BLYNK_AUTH)
while True:
time.sleep(5)
pin = Pin(28, Pin.OUT, Pin.PULL_DOWN)
sensor = DHT11(pin)
t = (sensor.temperature)
h = (sensor.humidity)
print("Temperature: {}".format(sensor.temperature))
print("Humidity: {}".format(sensor.humidity))
# Print sensor data to console
print('Temperature: {:.1f} C'.format(sensor.temperature))
print('Humidity: {:.1f} %'.format(sensor.humidity))
# Send sensor data to Blynk
Blynk.virtual_write(0, t/1) # virtual pin 0 for temperature
Blynk.virtual_write(1, h/1) # virtual pin 1 for humidity
# Run Blynk
blynk.run()
# Delay for 10 seconds
time.sleep(10)
```
you can call it as dht11.py (such as i call it), and save it on your RPI PICO W board.
but do not forget that we need the library for blynkLib.py so it could connect to blynk safely.
so, here is the code:
```
import struct
import time
import sys
import os
try:
import machine
gettime = lambda: time.ticks_ms()
SOCK_TIMEOUT = 0
except ImportError:
const = lambda x: x
gettime = lambda: int(time.time() * 1000)
SOCK_TIMEOUT = 0.05
def dummy(*args):
pass
MSG_RSP = const(0)
MSG_LOGIN = const(2)
MSG_PING = const(6)
MSG_TWEET = const(12)
MSG_NOTIFY = const(14)
MSG_BRIDGE = const(15)
MSG_HW_SYNC = const(16)
MSG_INTERNAL = const(17)
MSG_PROPERTY = const(19)
MSG_HW = const(20)
MSG_HW_LOGIN = const(29)
MSG_EVENT_LOG = const(64)
MSG_REDIRECT = const(41) # TODO: not implemented
MSG_DBG_PRINT = const(55) # TODO: not implemented
STA_SUCCESS = const(200)
STA_INVALID_TOKEN = const(9)
DISCONNECTED = const(0)
CONNECTING = const(1)
CONNECTED = const(2)
print("""
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \\/ '_/
/____/_/\\_, /_//_/_/\\_\\
/___/ for Python v""" + __version__ + " (" + sys.platform + ")\n")
class EventEmitter:
def __init__(self):
self._cbks = {}
def on(self, evt, f=None):
if f:
self._cbks[evt] = f
else:
def D(f):
self._cbks[evt] = f
return f
return D
def emit(self, evt, *a, **kv):
if evt in self._cbks:
self._cbks[evt](*a, **kv)
class BlynkProtocol(EventEmitter):
def __init__(self, auth, tmpl_id=None, fw_ver=None, heartbeat=50, buffin=1024, log=None):
EventEmitter.__init__(self)
self.heartbeat = heartbeat*1000
self.buffin = buffin
self.log = log or dummy
self.auth = auth
self.tmpl_id = tmpl_id
self.fw_ver = fw_ver
self.state = DISCONNECTED
self.connect()
def virtual_write(self, pin, *val):
self._send(MSG_HW, 'vw', pin, *val)
def send_internal(self, pin, *val):
self._send(MSG_INTERNAL, pin, *val)
def set_property(self, pin, prop, *val):
self._send(MSG_PROPERTY, pin, prop, *val)
def sync_virtual(self, *pins):
self._send(MSG_HW_SYNC, 'vr', *pins)
def log_event(self, *val):
self._send(MSG_EVENT_LOG, *val)
def _send(self, cmd, *args, **kwargs):
if 'id' in kwargs:
id = kwargs.get('id')
else:
id = self.msg_id
self.msg_id += 1
if self.msg_id > 0xFFFF:
self.msg_id = 1
if cmd == MSG_RSP:
data = b''
dlen = args[0]
else:
data = ('\0'.join(map(str, args))).encode('utf8')
dlen = len(data)
self.log('<', cmd, id, '|', *args)
msg = struct.pack("!BHH", cmd, id, dlen) + data
self.lastSend = gettime()
self._write(msg)
def connect(self):
if self.state != DISCONNECTED: return
self.msg_id = 1
(self.lastRecv, self.lastSend, self.lastPing) = (gettime(), 0, 0)
self.bin = b""
self.state = CONNECTING
self._send(MSG_HW_LOGIN, self.auth)
def disconnect(self):
if self.state == DISCONNECTED: return
self.bin = b""
self.state = DISCONNECTED
self.emit('disconnected')
def process(self, data=None):
if not (self.state == CONNECTING or self.state == CONNECTED): return
now = gettime()
if now - self.lastRecv > self.heartbeat+(self.heartbeat//2):
return self.disconnect()
if (now - self.lastPing > self.heartbeat//10 and
(now - self.lastSend > self.heartbeat or
now - self.lastRecv > self.heartbeat)):
self._send(MSG_PING)
self.lastPing = now
if data != None and len(data):
self.bin += data
while True:
if len(self.bin) < 5:
break
cmd, i, dlen = struct.unpack("!BHH", self.bin[:5])
if i == 0: return self.disconnect()
self.lastRecv = now
if cmd == MSG_RSP:
self.bin = self.bin[5:]
self.log('>', cmd, i, '|', dlen)
if self.state == CONNECTING and i == 1:
if dlen == STA_SUCCESS:
self.state = CONNECTED
dt = now - self.lastSend
info = ['ver', __version__, 'h-beat', self.heartbeat//1000, 'buff-in', self.buffin, 'dev', sys.platform+'-py']
if self.tmpl_id:
info.extend(['tmpl', self.tmpl_id])
info.extend(['fw-type', self.tmpl_id])
if self.fw_ver:
info.extend(['fw', self.fw_ver])
self._send(MSG_INTERNAL, *info)
try:
self.emit('connected', ping=dt)
except TypeError:
self.emit('connected')
else:
if dlen == STA_INVALID_TOKEN:
self.emit("invalid_auth")
print("Invalid auth token")
return self.disconnect()
else:
if dlen >= self.buffin:
print("Cmd too big: ", dlen)
return self.disconnect()
if len(self.bin) < 5+dlen:
break
data = self.bin[5:5+dlen]
self.bin = self.bin[5+dlen:]
args = list(map(lambda x: x.decode('utf8'), data.split(b'\0')))
self.log('>', cmd, i, '|', ','.join(args))
if cmd == MSG_PING:
self._send(MSG_RSP, STA_SUCCESS, id=i)
elif cmd == MSG_HW or cmd == MSG_BRIDGE:
if args[0] == 'vw':
self.emit("V"+args[1], args[2:])
self.emit("V*", args[1], args[2:])
elif cmd == MSG_INTERNAL:
self.emit("internal:"+args[0], args[1:])
elif cmd == MSG_REDIRECT:
self.emit("redirect", args[0], int(args[1]))
else:
print("Unexpected command: ", cmd)
return self.disconnect()
import socket
class Blynk(BlynkProtocol):
def __init__(self, auth, **kwargs):
self.insecure = kwargs.pop('insecure', False)
self.server = kwargs.pop('server', 'blynk.cloud')
self.port = kwargs.pop('port', 80 if self.insecure else 443)
BlynkProtocol.__init__(self, auth, **kwargs)
self.on('redirect', self.redirect)
def redirect(self, server, port):
self.server = server
self.port = port
self.disconnect()
self.connect()
def connect(self):
print('Connecting to %s:%d...' % (self.server, self.port))
s = socket.socket()
s.connect(socket.getaddrinfo(self.server, self.port)[0][-1])
try:
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
except:
pass
if self.insecure:
self.conn = s
else:
try:
import ussl
ssl_context = ussl
except ImportError:
import ssl
ssl_context = ssl.create_default_context()
self.conn = ssl_context.wrap_socket(s, server_hostname=self.server)
try:
self.conn.settimeout(SOCK_TIMEOUT)
except:
s.settimeout(SOCK_TIMEOUT)
BlynkProtocol.connect(self)
def _write(self, data):
#print('<', data)
self.conn.write(data)
# TODO: handle disconnect
def run(self):
data = b''
try:
data = self.conn.read(self.buffin)
#print('>', data)
except KeyboardInterrupt:
raise
except socket.timeout:
# No data received, call process to send ping messages when needed
pass
except: # TODO: handle disconnect
return
self.process(data)
```
So, now we have all the codes that we need.
# Connectivity
The data is sent every 10 seconds, but can be adjusted in the code to fit different use-cases where on might want to gather the data more often or less often. The wireless protocol used is Wi-Fi, by connecting the microcontroller to a Wi-fi source (generally a router) via HTTPS to send requests to blynk and also send data to the gauche so it could show us the valor of temperature and humidity.
# Running the code
Now after that we have typed the code we need to run it, and also do not forget that when you run the code it needs to be smooth and fast, then you know that you made everything correct.
The results in the shell should be like this:

# Presenting the data
So when you have install Blynk then make a template and inserted some gadgets so you could see all the data about temperature and humidity, but only if you typed the code correctly.
The results in the app could be like this:

After that we could finalize the design. It could be done on the computer and also in the phone.
