Raspberry Pi Pico DS18B20 Máy chủ Web (Trạm thời tiết)

Raspberry Pi Pico DS18B20 Máy chủ Web (Trạm thời tiết)

Giới thiệu DS18B20

Nó là một cảm biến nhiệt độ có thể lập trình một dây trong tự nhiên. Nó được sử dụng rộng rãi để đo nhiệt độ của các dung dịch hóa học và các chất có trong môi trường cứng. Một trong những lợi thế của việc sử dụng cảm biến này là chúng tôi chỉ yêu cầu một chân duy nhất của bảng Raspberry Pi Pico để truyền dữ liệu. Do đó, việc sử dụng với bộ điều khiển vi mô là vô cùng thuận tiện vì chúng ta có thể đo nhiều nhiệt độ bằng cách sử dụng số lượng chân ít nhất trên bảng phát triển của mình.

Bảng dưới đây cho thấy một số đặc điểm chính của cảm biến ds18b120.

Tính năng

Giá trị

Điện áp hoạt động

3V-5V ·

Phạm vi nhiệt độ

-55 °C đến + 125 °C

Chính xác

±0,5 °C

Độ phân giải đầu ra

9bit đến 12bit

 

Sơ đồ sơ đồ chân

Một phiên bản chống nước của cảm biến này cũng có sẵn trên thị trường. Các số liệu sau đây cho thấy sơ đồ chân của các cảm biến DS18B20.

Sơ đồ sơ đồ sơ đồ chân chống thấm nước DS18B20

Sơ đồ sau đây cho thấy sơ đồ chân của cảm biến nhiệt độ DS18B20 bình thường.

Sơ đồ sơ đồ chân DS18B20

Bảng dưới đây liệt kê các cấu hình ghim:

Ghim

Mô tả:__________

VCC

Đây là chân cấp nguồn cho cảm biến. 3.3V cho bảng Raspberry Pi Pico

Dữ liệu

Chân này cho giá trị nhiệt độ

Mặt đất

Chân này được kết nối với mặt đất

Chi tiết cấu hình pin DS18B20

Cảm biến nhiệt độ này cũng đi kèm trong một mô-đun gói duy nhất có chứa cảm biến và điện trở kéo lên. Nếu bạn đang sử dụng mô-đun, bạn không cần kết nối điện trở ohm 4.7K bên ngoài. Bởi vì mô-đun đã có một điện trở kéo lên trên tàu.

Mô-đun DS18B20

DS18B20 Ký sinh trùng so với chế độ bình thường

Cảm biến DS18B20 có thể được cấp nguồn ở hai chế độ khác nhau.

Chế độ bình thường: Cảm biến được cấp nguồn thông qua nguồn bên ngoài thông qua chân VDD và điện trở kéo lên 4.7K ohm.

Chế độ ký sinh trùng: Cảm biến thu được nguồn điện từ đường dữ liệu của chính nó. Do đó, không cần nguồn điện bên ngoài.

Giao diện Raspberry Pi Pico với DS18B20 và ESP-01

Raspberry Pi Pico với ds18b20 và ESP-01

Phần này hướng dẫn cách kết nối Raspberry Pi Pico với cảm biến DS18B20 và ESP-01.

Chúng tôi sẽ yêu cầu các thành phần sau:

  • Raspberry Pi Pico

  • Cảm biến DS18B20

  • Điện trở 4.7k ohm

  • Mô-đun ESP-01

  • Dây kết nối

  • Breadboard

Raspberry Pi Pico với DS18B20

Chúng tôi sẽ cấp nguồn cho cảm biến DS10B20 ở chế độ bình thường. Do đó, chân VCC của nó sẽ được kết nối với chân 3.3V của bảng Raspberry Pi Pico thông qua điện trở 4.7k ohm.

Cảm biến DS18B20 có ba thiết bị đầu cuối mà chúng ta đã thấy ở trên trong sơ đồ chân. Thiết bị đầu cuối đầu tiên được nối đất với bảng Raspberry Pi Pico. Đường dữ liệu của cảm biến, là cực giữa, được kết nối thông qua GP16 thông qua điện trở kéo lên 4.7k-ohm. Chúng tôi cũng có thể chọn bất kỳ chân GPIO nào khác. Thiết bị đầu cuối thứ ba được cung cấp bởi 3.3V từ Raspberry Pi Pico.

Raspberry Pi Pico

DS18B20 ·

GND ·

GND ·

GP16 ·

Dữ liệu

3.3V

VCC

Raspberry Pi Pico với ESP-01

Mô-đun ESP-01 bao gồm 8 chân. Tuy nhiên, chúng tôi sẽ sử dụng 5 chân để kết nối với bảng Pi Pico. Chúng bao gồm các chân VCC, EN, GND, RX và TX. Các chân RX và TX của mô-đun sẽ được kết nối với các chân UART của bảng Pi Pico. Trước tiên chúng ta hãy xem xét các Chân Raspberry Pi Pi UART.

Chân Raspberry Pi Pico UART

Raspberry Pi Pico chứa hai thiết bị ngoại vi UART giống hệt nhau với các FIFOs 32×8 Tx và 32×12 Rx riêng biệt.

Bảng sau liệt kê các chân GPIO cho cả hai thiết bị ngoại vi UART được tiếp xúc trên sơ đồ chân của bảng phát triển Raspberry Pi Pico.

Chân UART

Chân GPIO

UART0-TX

GP0 / GP12 / GP16

UART0-RX

GP1 / GP13 / GP17

UART1-TX

GP4/GP8

UART1-RX

GP5/GP9

Đối với hướng dẫn này, chúng tôi sẽ sử dụng chân UART0-TX và RX.

Làm theo sơ đồ kết nối bên dưới để kết nối hai thiết bị.

 

Raspberry Pi Pico

ESP-01 ·

3.3V

VCC

3.3V

EN

GND ·

GND ·

GP1 (UART0 RX)

TX

GP0 (UART0 TX)

RX

Sơ đồ kết nối Raspberry Pi Pico với DS18B20 và ESP-01

Chúng tôi đã sử dụng các kết nối tương tự như được đưa ra trong hai bảng trên. Cả ba thiết bị sẽ được nối đất chung và sẽ được cấp nguồn bằng cùng một chân 3.3V của Raspberry Pi Pico.

Sơ đồ dưới đây cho thấy sơ đồ kết nối của Raspberry Pi Pico với DS18B20 và ESP-01.

Raspberry Pi Pico với sơ đồ kết nối ds18b20 và ESP-01

Cài đặt thư viện DS18B20

Đối với dự án này, chúng tôi sẽ yêu cầu hai thư viện: ds18x20.py và onewire.py. Sao chép cả hai thư viện này và lưu chúng trong Raspberry Pi Pico của bạn với các tên tệp tương ứng. Mở một tệp mới trong Thonny. Sao chép các thư viện được cung cấp dưới đây. Lưu chúng vào Raspberry Pi Pico với tên ds18x20.py và onewire.py trong thư mục lib.

ds18x20.py

# DS18x20 temperature sensor driver for MicroPython.

# MIT license; Copyright (c) 2016 Damien P. George

 

from micropython import const

 

_CONVERT = const(0x44)

_RD_SCRATCH = const(0xBE)

_WR_SCRATCH = const(0x4E)

 

 

class DS18X20:

    def __init__(self, onewire):

        self.ow = onewire

        self.buf = bytearray(9)

 

    def scan(self):

        return [rom for rom in self.ow.scan() if rom[0] in (0x10, 0x22, 0x28)]

 

    def convert_temp(self):

        self.ow.reset(True)

        self.ow.writebyte(self.ow.SKIP_ROM)

        self.ow.writebyte(_CONVERT)

 

    def read_scratch(self, rom):

        self.ow.reset(True)

        self.ow.select_rom(rom)

        self.ow.writebyte(_RD_SCRATCH)

        self.ow.readinto(self.buf)

        if self.ow.crc8(self.buf):

            raise Exception("CRC error")

        return self.buf

 

    def write_scratch(self, rom, buf):

        self.ow.reset(True)

        self.ow.select_rom(rom)

        self.ow.writebyte(_WR_SCRATCH)

        self.ow.write(buf)

 

    def read_temp(self, rom):

        buf = self.read_scratch(rom)

        if rom[0] == 0x10:

            if buf[1]:

                t = buf[0] >> 1 | 0x80

                t = -((~t + 1) & 0xFF)

            else:

                t = buf[0] >> 1

            return t - 0.25 + (buf[7] - buf[6]) / buf[7]

        else:

            t = buf[1] << 8 | buf[0]

            if t & 0x8000:  # sign bit set

                t = -((t ^ 0xFFFF) + 1)

            return t / 16

onewire.py

# 1-Wire driver for MicroPython

# MIT license; Copyright (c) 2016 Damien P. George

 

import _onewire as _ow

 

 

class OneWireError(Exception):

    pass

 

 

class OneWire:

    SEARCH_ROM = 0xF0

    MATCH_ROM = 0x55

    SKIP_ROM = 0xCC

 

    def __init__(self, pin):

        self.pin = pin

        self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP)

 

    def reset(self, required=False):

        reset = _ow.reset(self.pin)

        if required and not reset:

            raise OneWireError

        return reset

 

    def readbit(self):

        return _ow.readbit(self.pin)

 

    def readbyte(self):

        return _ow.readbyte(self.pin)

 

    def readinto(self, buf):

        for i in range(len(buf)):

            buf[i] = _ow.readbyte(self.pin)

 

    def writebit(self, value):

        return _ow.writebit(self.pin, value)

 

    def writebyte(self, value):

        return _ow.writebyte(self.pin, value)

 

    def write(self, buf):

        for b in buf:

            _ow.writebyte(self.pin, b)

 

    def select_rom(self, rom):

        self.reset()

        self.writebyte(self.MATCH_ROM)

        self.write(rom)

 

    def scan(self):

        devices = []

        diff = 65

        rom = False

        for i in range(0xFF):

            rom, diff = self._search_rom(rom, diff)

            if rom:

                devices += [rom]

            if diff == 0:

                break

        return devices

 

    def _search_rom(self, l_rom, diff):

        if not self.reset():

            return None, 0

        self.writebyte(self.SEARCH_ROM)

        if not l_rom:

            l_rom = bytearray(8)

        rom = bytearray(8)

        next_diff = 0

        i = 64

        for byte in range(8):

            r_b = 0

            for bit in range(8):

                b = self.readbit()

                if self.readbit():

                    if b:  # there are no devices or there is an error on the bus

                        return None, 0

                else:

                    if not b:  # collision, two devices with different bit meaning

                        if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i):

                            b = 1

                            next_diff = i

                self.writebit(b)

                if b:

                    r_b |= 1 << bit

                i -= 1

            rom[byte] = r_b

        return rom, next_diff

 

    def crc8(self, data):

        return _ow.crc8(data)

MicroPython Script Raspberry Pi Pico DS18B20 Máy chủ web với ESP-01 (Trạm thời tiết)

import uos

import utime

import machine, onewire, ds18x20

 

recv_buf="" # receive buffer global variable

 

print()

print("Machine: \t" + uos.uname()[4])

print("MicroPython: \t" + uos.uname()[3])

 

ds_pin = machine.Pin(16)

ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

roms = ds_sensor.scan()

 

uart0 = machine.UART(0, baudrate=115200)

print(uart0)

 

def Rx_ESP_Data():

    recv=bytes()

    while uart0.any()>0:

        recv+=uart0.read(1)

    res=recv.decode('utf-8')

    return res

def Connect_WiFi(cmd, uart=uart0, timeout=3000):

    print("CMD: " + cmd)

    uart.write(cmd)

    utime.sleep(7.0)

    Wait_ESP_Rsp(uart, timeout)

    print()

 

def Send_AT_Cmd(cmd, uart=uart0, timeout=3000):

    print("CMD: " + cmd)

    uart.write(cmd)

    Wait_ESP_Rsp(uart, timeout)

    print()

    

def Wait_ESP_Rsp(uart=uart0, timeout=3000):

    prvMills = utime.ticks_ms()

    resp = b""

    while (utime.ticks_ms()-prvMills)<timeout:

        if uart.any():

            resp = b"".join([resp, uart.read(1)])

    print("resp:")

    try:

        print(resp.decode())

    except UnicodeError:

        print(resp)

    

Send_AT_Cmd('AT\r\n')          #Test AT startup

Send_AT_Cmd('AT+GMR\r\n')      #Check version information

Send_AT_Cmd('AT+CIPSERVER=0\r\n')      #Check version information

Send_AT_Cmd('AT+RST\r\n')      #Check version information

Send_AT_Cmd('AT+RESTORE\r\n')  #Restore Factory Default Settings

Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the Wi-Fi mode

Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the Wi-Fi mode = Station mode

Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the Wi-Fi mode again

Connect_WiFi('AT+CWJAP="A1601","123456789104"\r\n', timeout=5000) #Connect to AP

Send_AT_Cmd('AT+CIFSR\r\n',timeout=5000)    #Obtain the Local IP Address

Send_AT_Cmd('AT+CIPMUX=1\r\n')    #Obtain the Local IP Address

utime.sleep(1.0)

Send_AT_Cmd('AT+CIPSERVER=1,80\r\n')    #Obtain the Local IP Address

utime.sleep(1.0)

print ('Starting connection to ESP8266...')

while True:

    res =""

    res=Rx_ESP_Data()

    utime.sleep(2.0)

    if '+IPD' in res: # if the buffer contains IPD(a connection), then respond with HTML handshake

        print('Found DS devices')

        print('Temperature')

        ds_sensor.convert_temp()

        utime.sleep(1)

        for rom in roms:

          temperature_Celsius = round(ds_sensor.read_temp(rom), 2)

          temperature_Fahrenheit = round((ds_sensor.read_temp(rom)*(9/5) + 32.0), 2)

          print(temperature_Celsius) 

          print( temperature_Fahrenheit)

          print('__________________')

        utime.sleep(3)

        id_index = res.find('+IPD')

        print("resp:")

        print(res)

        connection_id =  res[id_index+5]

        print("connectionId:" + connection_id)

        print ('! Incoming connection - sending webpage')

        uart0.write('AT+CIPSEND='+connection_id+',1569'+'\r\n')  #Send a HTTP response then a webpage as bytes the 108 is the amount of bytes you are sending, change this if you change the data sent below

        utime.sleep(1.0)

        uart0.write('HTTP/1.1 200 OK'+'\r\n')

        uart0.write('Content-Type: text/html'+'\r\n')

        uart0.write('Connection: close'+'\r\n')

        uart0.write(''+'\r\n')

        uart0.write('<!DOCTYPE HTML>'+'\r\n')

        html ='<html> <head> <meta http-equiv=\"refresh\" content=\"10\"> <title>Raspberry Pi Pico Web Server</title> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.7.2/css/all.css\" integrity=\"sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr\" crossorigin=\"anonymous\"> <link rel=\"icon\" href=\"data:,\"> <style> html {font-family: Arial; display: inline-block; text-align: center;} p { font-size: 1.2rem;} body { margin: 0;} .top_nav { overflow: hidden; background-color: #da0a0a; color: white; font-size: 1rem; } .content { padding: 30px; } .card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); } .cards { max-width: 800px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } .value { font-size: 3rem; } .symbol { font-size: 2rem; } </style> </head> <body> <div class=\"top_nav\"> <h1>Raspberry Pi Pico DS18B20 Web Server</h1> </div> <div class=\"content\"> <div class=\"cards\"> <div class=\"card\"> <p><i class=\"fas fa-thermometer-half fa-3x\" style=\"color:#da0a0a;\"></i><span class=\"symbol\">Temperature</span></p><p><span class=\"value\"><span id=\"temperature_Celsius\">' + str(temperature_Celsius) + '</span> &deg;C</span></p> </div> <div class=\"card\"> <p><i class=\"fas fa-thermometer-half fa-3x\" style=\"color:#da0a0a;\"></i> <span class=\"symbol\">Temperature</span></p><p><span class=\"value\"><span id=\"temperature_Fahrenheit\">' + str(temperature_Fahrenheit)+ '</span> &deg;F</span></p> </div> </div> </div> </body> </html>'

        uart0.write(html +'\r\n')

        utime.sleep(4.0)

        Send_AT_Cmd('AT+CIPCLOSE='+ connection_id+'\r\n') # once file sent, close connection

        utime.sleep(4.0)

        res="" #reset buffer

        print ('Waiting For connection...')

Mã hoạt động như thế nào?

Chúng tôi sẽ bắt đầu bằng cách nhập mô-đun máy và mô-đun uos. Chúng tôi cũng nhập mô-đun utime để chúng tôi có thể thêm độ trễ 10 giây giữa các lần đọc của chúng tôi. Ngoài ra, nhập một dây và thư viện ds18x20 mà chúng tôi vừa tải lên bảng của mình.

import uos

import utime

import machine, onewire, ds18x20

Sau đó, chúng tôi sẽ in thông tin về hệ điều hành hiện tại của chúng tôi trong thiết bị đầu cuối Thonny shell. Chúng tôi sẽ uos.uname() và in phiên bản hệ điều hành và phát hành.

print()

print("Machine: \t" + uos.uname()[4])

print("MicroPython: \t" + uos.uname()[3])

Tiếp theo, chúng ta sẽ tạo một đối tượng của lớp Pin với tên đối tượng là ds_pin và thiết lập GP16 làm chân dòng dữ liệu DS18B20.

ds_pin = machine.Pin(16)

ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin))

Phương pháp quét() quét tất cả các cảm biến DS18B20 được kết nối với chân ds_sensor và lưu địa chỉ 64 bit của mỗi cảm biến trong một biến danh sách là "roms". Sau đó, chúng tôi sẽ sử dụng các địa chỉ này để đọc nhiệt độ từ cảm biến.

roms = ds_sensor.scan()

Khởi tạo giao tiếp UART

Sau đó, chúng ta sẽ tạo một đối tượng uart bằng cách sử dụng UART() và chỉ định kênh UART làm tham số đầu tiên và tốc độ truyền làm tham số thứ hai. Chúng tôi đang sử dụng UART0 trong trường hợp này với tốc độ truyền 115200 cho giao tiếp uart. ESP8266 có tốc độ truyền mặc định là 115200, do đó chúng tôi sẽ sử dụng cùng một tốc độ truyền ở đây cho giao tiếp Raspberry Pi Pico UART để tạo đồng bộ hóa. Hơn nữa, chúng tôi cũng sẽ in các chi tiết UART trong thiết bị đầu cuối vỏ.

uart0 = machine.UART(0, baudrate=115200)

print(uart0)

Hàm Connect_WiFi() này được sử dụng để kết nối ESP8266 với WiFi.

def Connect_WiFi(cmd, uart=uart0, timeout=3000):

    print("CMD: " + cmd)

    uart.write(cmd)

    utime.sleep(7.0)

    Wait_ESP_Rsp(uart, timeout)

    print()

Tiếp theo, chúng ta sẽ định nghĩa ba hàm. Cái đầu tiên là Rx_ESP_Data(). Điều này đọc dữ liệu nối tiếp đang được nhận. Dữ liệu này được giải mã từ định dạng UTF-8 và được trả về.

def Rx_ESP_Data():

    recv=bytes()

    while uart0.any()>0:

        recv+=uart0.read(1)

    res=recv.decode('utf-8')

    return res

Hàm thứ hai là Send_AT_Cmd(cmd, uart=uart0, timeout=3000). Nó có ba tham số, lệnh AT, kênh UART và thời gian phản hồi. Chức năng này sẽ được sử dụng để nó gửi lệnh AT đến ESP8266 thông qua uart0. Thời gian phản hồi được đặt thành 3 giây.

 

def Send_AT_Cmd(cmd, uart=uart0, timeout=3000):

    print("CMD: " + cmd)

    uart.write(cmd)

    Wait_ESP_Rsp(uart, timeout)

    print()

    

Hàm Wait_ESP_Rsp(uart=uart0, timeout=3000) đợi 3 giây để nhận được phản hồi từ ESP8266. Sau khi nhận được dữ liệu từ ESP8266, nó nối các byte nhận được và in chúng trên thiết bị đầu cuối shell.

def Wait_ESP_Rsp(uart=uart0, timeout=3000):

    prvMills = utime.ticks_ms()

    resp = b""

    while (utime.ticks_ms()-prvMills)<timeout:

        if uart.any():

            resp = b"".join([resp, uart.read(1)])

    print("resp:")

    try:

        print(resp.decode())

    except UnicodeError:

        print(resp)

Lệnh AT

Bây giờ chúng ta hãy xem xét loạt lệnh AT mà chúng ta sẽ gửi qua UART0 đến ESP8266.

Send_AT_Cmd('AT\r\n')          #Test AT startup

Send_AT_Cmd('AT+GMR\r\n')      #Check version information

Send_AT_Cmd('AT+CIPSERVER=0\r\n')      #Check version information

Send_AT_Cmd('AT+RST\r\n')      #Check version information

Send_AT_Cmd('AT+RESTORE\r\n')  #Restore Factory Default Settings

Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the Wi-Fi mode

Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the Wi-Fi mode = Station mode

Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the Wi-Fi mode again

Connect_WiFi('AT+CWJAP="YOUR_SSID","YOUR_PASSWORD"\r\n', timeout=5000) #Connect to AP

Send_AT_Cmd('AT+CIFSR\r\n',timeout=5000)    #Obtain the Local IP Address

Send_AT_Cmd('AT+CIPMUX=1\r\n')    #Obtain the Local IP Address

utime.sleep(1.0)

Send_AT_Cmd('AT+CIPSERVER=1,80\r\n')    #Obtain the Local IP Address

utime.sleep(1.0)

AT: Loại lệnh này được sử dụng để kiểm tra chức năng khởi động của mô-đun WiFi. Phản hồi sẽ ổn, chống lại lệnh này nếu mọi thứ đều ổn.

Send_AT_Cmd('AT\r\n')          #Test AT startup

AT + GMR : Loại lệnh AT này được sử dụng để kiểm tra phiên bản lệnh AT và chúng tôi đã sử dụng phiên bản SDK của lệnh AT trong loại mô-đun WIFI này.

Send_AT_Cmd('AT+GMR\r\n')      #Check version information

AT + CIPSERVER = 0: Điều này cấu hình ESP8266 làm máy chủ và đặt chế độ là 0, có nghĩa là xóa máy chủ (cần phải làm theo bằng cách khởi động lại)

Send_AT_Cmd('AT+CIPSERVER=0\r\n')     

AT + RST: Loại lệnh này được sử dụng để đặt lại mô-đun WiFi khi nó ở trong tình trạng hoạt động. Phản hồi sẽ ổn, khi đặt lại mô-đun.

Send_AT_Cmd('AT+RST\r\n')   

AT + RESTORE: Loại lệnh này được sử dụng để khôi phục cài đặt gốc có nghĩa là, khi lệnh này được nhập thì tất cả các tham số sẽ tự động được đặt lại về mặc định của một người.

Send_AT_Cmd('AT+RESTORE\r\n')  #Restore Factory Default Settings

AT + CWMODE? : Loại lệnh này được sử dụng để truy vấn chế độ WiFi của ESP8266.

Send_AT_Cmd('AT+CWMODE?\r\n')  #Query the WiFi mode

AT + CWMODE = 1: Điều này đặt chế độ WiFi của ESP8266 trong trường hợp này ở chế độ trạm.

Send_AT_Cmd('AT+CWMODE=1\r\n') #Set the WiFi mode = Station mode

AT + CWJAP = "SSID", "PASSWORD"\r\n', timeout=TIME_ms : Điều này kết nối ESP8266 với một AP có SSID và mật khẩu được cung cấp, Thời gian chờ ở đây là thời gian kết nối lại.

Connect_WiFi('AT+CWJAP="YOUR_SSID","YOUR_PASSWORD"\r\n', timeout=5000) #Connect to AP

AT + CIFSR: Lệnh này lấy địa chỉ IP cục bộ.

Send_AT_Cmd('AT+CIFSR\r\n')

AT + CIPMUX = 1: Lệnh này được sử dụng để kích hoạt nhiều kết nối (tối đa 4)

Send_AT_Cmd('AT+CIPMUX=1\r\n')

AT + CIPSERVER = 1: Lệnh này cấu hình ESP8266 làm máy chủ.

Send_AT_Cmd('AT+CIPSERVER=1,80\r\n')

trong khi vòng lặp

Bên trong vòng lặp while, trước tiên chúng ta sẽ gọi Rx_ESP_Data() trả về dữ liệu mà ESP8266 nhận được. Điều này được lưu trong biến 'res.'

Thêm độ trễ 2 giây trước khi tiếp tục.

res =""

res=Rx_ESP_Data()

utime.sleep(2.0)

Tiếp theo, chúng tôi sẽ kiểm tra xem bộ đệm có chứa kết nối IPD hay không. Nếu có, hãy trả lời bằng một cái bắt tay HTML.

Để có được số đọc cảm biến, chúng ta sẽ gọi (ds_sensor) đối tượng trên phương pháp convert_temp() trước khi đọc nhiệt độ từ cảm biến bằng địa chỉ duy nhất của nó. Để đọc nhiệt độ tính bằng độ C, chúng tôi sử dụng quy trình read_temp() trên đối tượng ds_sensor và truyền một địa chỉ được lưu trữ trong danh sách roms. Cảm biến nhiệt độ DS18B20 cung cấp đầu ra dữ liệu ở dạng dữ liệu nổi. Chúng tôi sẽ làm tròn số đọc đến 2 chữ số thập phân và lưu trữ nó dưới dạng một chuỗi. Hơn nữa, chúng tôi sẽ thực hiện một số tính toán để chuyển đổi chỉ số Celsius sang độ F. Cả hai số đọc nhiệt độ được lưu trong các biến tương ứng của chúng.

Các chỉ số cảm biến DS18B20 này cùng với phản hồi sẽ được in trong thiết bị đầu cuối vỏ. Ngoài ra, chúng tôi lấy ID kết nối và in nó.

    if '+IPD' in res: # if the buffer contains IPD(a connection), then respond with HTML handshake

        print('Found DS devices')

        print('Temperature')

        ds_sensor.convert_temp()

        utime.sleep(1)

        for rom in roms:

          temperature_Celsius = round(ds_sensor.read_temp(rom), 2)

          temperature_Fahrenheit = round((ds_sensor.read_temp(rom)*(9/5) + 32.0), 2)

          print(temperature_Celsius) 

          print( temperature_Fahrenheit)

          print('__________________')

        utime.sleep(3)

        id_index = res.find('+IPD')

        print("resp:")

        print(res)

        connection_id =  res[id_index+5]

        print("connectionId:" + connection_id)

Sau đó, bằng cách sử dụng đối tượng uart trên phương thức write(), chúng ta sẽ gửi các byte đến UART. Đầu tiên, chúng tôi đang viết lệnh AT: AT + CIPSEND = 'ID', 'LENGTH' Điều này sẽ đặt độ dài của dữ liệu sẽ được gửi. Tiếp theo sau độ trễ 1 giây, chúng tôi sẽ viết tập lệnh HTML sẽ xây dựng trang web vào cổng nối tiếp. Sau đó, chúng tôi sẽ đóng nhiều kết nối khi chúng tôi đang gửi lệnh AT: AT + CIPCLOSE = 'ID'. Sau đó, chúng tôi sẽ đặt lại bộ đệm và chờ kết nối.

print ('! Incoming connection - sending webpage')

        uart0.write('AT+CIPSEND='+connection_id+',1569'+'\r\n')  #Send a HTTP response then a webpage as bytes the 108 is the amount of bytes you are sending, change this if you change the data sent below

        utime.sleep(1.0)

        uart0.write('HTTP/1.1 200 OK'+'\r\n')

        uart0.write('Content-Type: text/html'+'\r\n')

        uart0.write('Connection: close'+'\r\n')

        uart0.write(''+'\r\n')

        uart0.write('<!DOCTYPE HTML>'+'\r\n')

        html ='<html> <head> <meta http-equiv=\"refresh\" content=\"10\"> <title>Raspberry Pi Pico Web Server</title> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.7.2/css/all.css\" integrity=\"sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr\" crossorigin=\"anonymous\"> <link rel=\"icon\" href=\"data:,\"> <style> html {font-family: Arial; display: inline-block; text-align: center;} p { font-size: 1.2rem;} body { margin: 0;} .top_nav { overflow: hidden; background-color: #da0a0a; color: white; font-size: 1rem; } .content { padding: 30px; } .card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); } .cards { max-width: 800px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } .value { font-size: 3rem; } .symbol { font-size: 2rem; } </style> </head> <body> <div class=\"top_nav\"> <h1>Raspberry Pi Pico DS18B20 Web Server</h1> </div> <div class=\"content\"> <div class=\"cards\"> <div class=\"card\"> <p><i class=\"fas fa-thermometer-half fa-3x\" style=\"color:#da0a0a;\"></i><span class=\"symbol\">Temperature</span></p><p><span class=\"value\"><span id=\"temperature_Celsius\">' + str(temperature_Celsius) + '</span> &deg;C</span></p> </div> <div class=\"card\"> <p><i class=\"fas fa-thermometer-half fa-3x\" style=\"color:#da0a0a;\"></i> <span class=\"symbol\">Temperature</span></p><p><span class=\"value\"><span id=\"temperature_Fahrenheit\">' + str(temperature_Fahrenheit)+ '</span> &deg;F</span></p> </div> </div> </div> </body> </html>'

        uart0.write(html +'\r\n')

        utime.sleep(4.0)

        Send_AT_Cmd('AT+CIPCLOSE='+ connection_id+'\r\n') # once file sent, close connection

        utime.sleep(4.0)

        res="" #reset buffer

        print ('Waiting For connection...')

Tạo trang Web (HTML+CSS)

Để xây dựng trang web, chúng tôi sẽ thêm mã HTML và để tạo kiểu, chúng tôi sẽ thêm tập lệnh CSS.

Bây giờ chúng ta hãy đi qua từng dòng mã HTML để hiểu cách nó xây dựng trang web.

Trong tài liệu HTML này, chúng tôi sử dụng thẻ, đoạn văn, tiêu đề, biểu tượng và thẻ tiêu đề để tạo một trang web. Trang web này hiển thị chỉ số nhiệt độ của cảm biến DS18B20 ở cả độ C và độ F.

HTML là một ngôn ngữ đánh dấu siêu văn bản được sử dụng để xây dựng các trang web. Tất cả các trình duyệt web đều hiểu ngôn ngữ này và có thể đọc các trang web dựa trên ngôn ngữ HTML.

Trong HTML, chúng tôi đặt tất cả nội dung của một trang web giữa các thẻ <html> và </html>. Thẻ <html> hiển thị phần đầu của một trang web và </html> cho biết sự kết thúc của một trang web.

Mã HTML chủ yếu bao gồm hai phần như đầu và thân. Phần đầu chứa CSS, tập lệnh, thẻ meta, liên kết của các tài nguyên bên ngoài và mã tạo kiểu. Nó được đặt giữa các thẻ <head> và </head>.

'<html> <head> <meta http-equiv=\"refresh\" content=\"10\"> <title>Raspberry Pi Pico Web Server</title> <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.7.2/css/all.css\" integrity=\"sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr\" crossorigin=\"anonymous\"> <link rel=\"icon\" href=\"data:,\"> <style> html {font-family: Arial; display: inline-block; text-align: center;} p { font-size: 1.2rem;} body { margin: 0;} .top_nav { overflow: hidden; background-color: #da0a0a; color: white; font-size: 1rem; } .content { padding: 30px; } .card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); } .cards { max-width: 800px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } .value { font-size: 3rem; } .symbol { font-size: 2rem; } </style> </head>

Tiêu đề, Biểu tượng và tiêu đề HTTP

Chúng tôi sẽ bắt đầu với tiêu đề của trang web. Thẻ <title> sẽ cho biết phần đầu của tiêu đề và thẻ </title> sẽ cho biết kết thúc. Ở giữa các thẻ này, chúng tôi sẽ chỉ định "Raspberry Pi Pico Web Server" sẽ được hiển thị trên thanh tiêu đề của trình duyệt.

<title>Raspberry Pi Pico Web Server</title> 

Thẻ meta http-equiv này cung cấp các thuộc tính cho tiêu đề HTTP. Thuộc tính http-equiv lấy nhiều giá trị hoặc thông tin để mô phỏng phản hồi tiêu đề. Trong ví dụ này, chúng tôi sử dụng thuộc tính http-equiv để làm mới nội dung của trang web sau mỗi khoảng thời gian được chỉ định. Người dùng không bắt buộc phải làm mới trang web để nhận các giá trị cảm biến được cập nhật. Dòng này buộc trang HTML tự làm mới sau mỗi 10 giây. Hơn nữa, thẻ meta này sẽ đảm bảo máy chủ web của chúng tôi có sẵn cho tất cả các trình duyệt, ví dụ: điện thoại thông minh, máy tính xách tay, máy tính, v.v.

<meta http-equiv=\"refresh\" content=\"10\">

<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> 

Trong trang web của chúng tôi, chúng tôi cũng sẽ hiển thị một biểu tượng của nhiệt kế. Thẻ liên kết này tải các biểu tượng được sử dụng trong trang web

<link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.7.2/css/all.css\" integrity=\"sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr\" crossorigin=\"anonymous\">

Tạo kiểu trang web với CSS

CSS được sử dụng để cung cấp các kiểu cho một trang web. Để thêm các tệp CSS vào thẻ head, chúng tôi sử dụng các thẻ <style></style>. Mã CSS này tạo kiểu cho các thẻ và trang web bằng cách chỉ định màu sắc, phông chữ, kích thước phông chữ, v.v.

Mã CSS này đặt căn chỉnh văn bản, đệm, lề và chiều rộng của các thẻ nội dung của tài liệu HTML cùng với kích thước phông chữ, màu sắc của thẻ, v.v. Chúng tôi sử dụng thẻ để hiển thị các chỉ số giá trị nhiệt độ từ DS18B20 theo đơn vị độ C và Fahrenheit. Trong HTML, thẻ là một hộp có viền có các tính năng như đệm. Nội dung. Đầu trang, chân trang và màu sắc, v.v.

<style> html {font-family: Arial; display: inline-block; text-align: center;} p { font-size: 1.2rem;} body { margin: 0;} .top_nav { overflow: hidden; background-color: #da0a0a; color: white; font-size: 1rem; } .content { padding: 30px; } .card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); } .cards { max-width: 800px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } .value { font-size: 3rem; } .symbol { font-size: 2rem; } </style>

Nội dung trang web HTML

Phần quan trọng thứ hai của tài liệu HTML là phần nội dung đi vào bên trong các thẻ <body> và < / body >. Phần nội dung bao gồm nội dung chính của trang web như tiêu đề, hình ảnh, nút, biểu tượng, bảng, biểu đồ, v.v. Ví dụ: trong máy chủ web dựa trên Raspberry Pi Pico DS18B20 MicroPython này, phần cơ thể bao gồm tiêu đề và hai thẻ để hiển thị số đọc nhiệt độ.

<body> <div class=\"top_nav\"> <h1>Raspberry Pi Pico DS18B20 Web Server</h1> </div> <div class=\"content\"> <div class=\"cards\"> <div class=\"card\"> <p><i class=\"fas fa-thermometer-half fa-3x\" style=\"color:#da0a0a;\"></i><span class=\"symbol\">Temperature</span></p><p><span class=\"value\"><span id=\"temperature_Celsius\">' + str(temperature_Celsius) + '</span> &deg;C</span></p> </div> <div class=\"card\"> <p><i class=\"fas fa-thermometer-half fa-3x\" style=\"color:#da0a0a;\"></i> <span class=\"symbol\">Temperature</span></p><p><span class=\"value\"><span id=\"temperature_Fahrenheit\">' + str(temperature_Fahrenheit)+ '</span> &deg;F</span></p> </div> </div> </div> </body> </html>'

Chúng tôi sẽ bao gồm tiêu đề của trang web của chúng tôi bên trong các thẻ <h1>< / h1> và nó sẽ là "Raspberry Pi Pico DS18B20 Web Server".

<h1>Raspberry Pi Pico DS18B20 Web Server</h1>

Tiếp theo, chúng tôi sẽ bao gồm các dòng mã sau để hiển thị văn bản và thẻ về nhiệt độ, số đọc ở cả độ C và độ F cùng với các biểu tượng.

</div> <div class=\"content\"> <div class=\"cards\"> <div class=\"card\"> <p><i class=\"fas fa-thermometer-half fa-3x\" style=\"color:#da0a0a;\"></i><span class=\"symbol\">Temperature</span></p><p><span class=\"value\"><span id=\"temperature_Celsius\">' + str(temperature_Celsius) + '</span> &deg;C</span></p> </div> <div class=\"card\"> <p><i class=\"fas fa-thermometer-half fa-3x\" style=\"color:#da0a0a;\"></i> <span class=\"symbol\">Temperature</span></p><p><span class=\"value\"><span id=\"temperature_Fahrenheit\">' + str(temperature_Fahrenheit)+ '</span> &deg;F</span></p> </div> </div> </div>

 

Bài viết cùng chuyên mục

NHANH

NHANH

Vì Đổi mới liên tục nên Nhanh hơn

ĐÚNG

ĐÚNG

Coi trọng và ưu tiên việc làm Đúng

ĐỦ

ĐỦ

Tìm và mua Đủ Đơn hàng hơn

KỊP THỜI

KỊP THỜI

Hiệu suất tối ưu bởi Kịp Thời hơn