1. Trang chủ
  2. » Công Nghệ Thông Tin

IUH | BÁO CÁO THỰC HÀNH CHUYÊN ĐỀ IOT | LẬP TRÌNH TRAO ĐỔI DỮ LIỆU QUA GIAO THỨC TCP/UDP

15 0 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 15
Dung lượng 1,06 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Yêu cầu 1: Bố cục trình bày nội dung bài báo cáo, tỉ lệ đóng góp hoàn thiện báo cáo của từng thành viên. Yêu cầu 2: Sơ đồ nguyên lý chi tiết của hệ thống Yêu cầu 3: Lưu đồ giải thuật Yêu cầu 4: Mã nguồn của chương trình Yêu cầu 5: Minh chứng kết quả thực nghiệm (ảnh chụp dữ liệu đo đạc, trạng thái mô hình khi đang vận hành). • Hình ảnh minh chứng kết nối dây giữa mô-đun Raspberry với các mô-đun ngoại vi. • Hình ảnh minh chứng kết quả đo đạc bằng các thiết bị đo (Logic Analyzer, Oscillator,…). • Hình ảnh minh chứng kết quả hiển thị trên cửa sổ Terminal, màn hình LCD 16x2,…

Trang 1

BỘ CÔNG THƯƠNG TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP THÀNH PHỐ HỒ CHÍ MINH

KHOA: CÔNG NGHỆ ĐIỆN TỬ

BÁO CÁO THỰC HÀNH CHUYÊN ĐỀ IOT BUỔI 7: LẬP TRÌNH TRAO ĐỔI DỮ LIỆU QUA

GIAO THỨC TCP/UDP Giảng viên hướng dẫn: ThS Phạm Quang Trí Nhóm: 5

Nguyễn Phước Hòa 22633931

Thành phố Hồ Chí Minh, ngày 24 tháng 9 năm 2025

Trang 2

YÊU CẦU BÀI BÁO CÁO

Yêu cầu 1: Bố cục trình bày nội dung bài báo cáo, tỉ lệ đóng góp hoàn thiện báo

cáo của từng thành viên

Yêu cầu 2: Sơ đồ nguyên lý chi tiết của hệ thống

Yêu cầu 3: Lưu đồ giải thuật

Yêu cầu 4: Mã nguồn của chương trình

Yêu cầu 5: Minh chứng kết quả thực nghiệm (ảnh chụp dữ liệu đo đạc, trạng thái

mô hình khi đang vận hành)

 Hình ảnh minh chứng kết nối dây giữa mô-đun Raspberry với các mô-đun ngoại vi

 Hình ảnh minh chứng kết quả đo đạc bằng các thiết bị đo (Logic

Analyzer, Oscillator,…)

 Hình ảnh minh chứng kết quả hiển thị trên cửa sổ Terminal, màn hình LCD 16x2,…

Trang 3

Bài tập mức độ 3 (10 điểm):

Hệ thống IoT bao gồm 2 thành phần: mô-đun Raspberry “Master” (có thể thay thế bằng máy tính) và mô-đun Raspberry “Slave”

Master: Hiển thị giá trị nhiệt độ, độ ẩm nhận được từ Slave ra cửa sổ Terminal Thu thập và xác định giá trị trung bình của nhiệt độ, độ ẩm trong mỗi 20 giây Đồng thời gửi các dữ liệu trung bình này lên Server của ThingSpeak sau mỗi 20 giây cho một gói tin Việc gửi các gói tin lên Server phải được thực hiện liên tục trong ít nhất là 30 phút Ngoài ra, sau mỗi 1 giây sẽ gửi tín hiệu điều khiển 3 LED sáng đuổi liên tục (Đỏ  Vàng  Xanh)

Slave: Đọc giá trị nhiệt độ, độ ẩm của môi trường và hiển thị các giá trị này lên màn hình LCD 16x2 sau mỗi 1 giây Đồng thời gửi dữ liệu nhiệt độ, độ ẩm này đến Master sau mỗi 1 giây Nhận tín hiệu điều khiển từ Master để thay đổi trạng thái hoạt động của 3 LED

Bắt buộc phải tự xây dựng được Frame truyền dữ liệu đáp ứng yêu cầu trên Frame truyền phải được thiết kế có tính logic, bao quát được tất cả các trường hợp Giải thích chi tiết ý nghĩa các thông tin trong Frame truyền vào báo cáo Trong Frame truyền dữ liệu phải có CRC

Bắt buộc nhóm 1, 3, 5, 7, 9 và 11 sử dụng giao thức UDP; nhóm 2, 4, 6, 8, 10 và

12 sử dụng giao thức TCP/IP để trao đổi dữ liệu

Trang 4

Yêu cầu 1: Bố cục trình bày nội dung bài báo cáo, tỉ lệ đóng góp hoàn thiện

báo cáo của từng thành viên.

- Viết code

- Hình ảnh minh chứng

- Viết code

- Hình ảnh minh chứng

- Viết code

- Hình ảnh minh chứng

Yêu cầu 2: Sơ đồ nguyên lý chi tiết của hệ thống

Hình 1: Sơ đồ nguyên lý của hệ thống

Trang 5

Yêu cầu 3: Lưu đồ giải thuật

Trang 7

Yêu cầu 4: Mã nguồn của chương trình

CLIENT

import socket,struct

from urllib import request, parse

from time import sleep, time

import paho.mqtt.client as mqtt

from datetime import datetime

# ================== CẤU HÌNH THINGSPEAK

==================

# CH_ID_HTTP = 3050174x

# K_API_HTTP = "PVD9JHVMFWIMNC6S"

# HTTP_UPDATE_URL = "http://api.thingspeak.com/update"

CH_ID_MQTT = 3050167

username = "HQYdMBYqIAgiJSEiJiUnKhQ"

client_ID = "HQYdMBYqIAgiJSEiJiUnKhQ"

password = "Qa02xaIRFt5b9uLAen1Lwq2Y"

MQTT_HOST = "mqtt3.thingspeak.com"

MQTT_PORT = 1883

MQTT_TOPIC = f"channels/{CH_ID_MQTT}/publish"

#

========================================================= mqtt_client = mqtt.Client(client_ID)

mqtt_client.username_pw_set(username=username, password=password)

def mqtt_connect_if_needed():

try:

if not getattr(mqtt_client, "_is_connected", False):

mqtt_client.connect(MQTT_HOST, MQTT_PORT, 60)

mqtt_client.loop_start()

mqtt_client._is_connected = True

Trang 8

print("[MQTT] Connected")

except Exception as e:

mqtt_client._is_connected = False

print(f"[MQTT] Connect error: {e}")

def guidl_tsp_mqtt(ndtb, datb):

mqtt_connect_if_needed()

payload = f"field1={ndtb:.2f}&field2={datb:.2f}&status=OK"

try:

mqtt_client.publish(MQTT_TOPIC, payload, qos=0, retain=False)

print("[MQTT] da gui ->", payload)

except Exception as e:

print(f"[MQTT] error: {e}")

#======================================================== def tao_frame_ctrl(id_byte, cmd_byte, data_bytes):

Start_byte = 0xAA

Stop_byte = 0x55

length = len(data_bytes)

header = struct.pack('!BBBB', Start_byte, id_byte, cmd_byte, length)

crc = crc8(header[1:] + data_bytes)

frame = header + data_bytes + struct.pack('!B', crc) + struct.pack('!B',

Stop_byte)

return frame

def crc8(data: bytes):

crc = 0

for b in data:

crc ^= b

for _ in range(8):

if crc & 0x80:

crc = (crc << 1) ^ 0x07

Trang 9

else:

crc <<= 1

crc &= 0xFF

return crc

dl_nhietdo, dl_doam = [], []

GIẢI THÍCH VỀ FRAME TRUYỀN

| Start (0xAA) | ID | CMD | Length | Data[ ] | CRC | Stop (0x55) | Start byte (0xAA): Ký hiệu bắt đầu frame.

ID byte: Xác định thiết bị đích hoặc nguồn gửi.

CMD byte (lệnh): Quy định loại lệnh hoặc loại dữ liệu.

Length (số byte dữ liệu): Số byte trong trường Data[ ].

Data[ ] (payload): Nội dung chính của gói tin.

CRC (1 byte): Giá trị kiểm tra lỗi.

Stop byte (0x55): Ký hiệu kết thúc frame.

WINDOW_SEC = 20 # tính trung bình 20 giây

window_start = time()

ServerAddressPort = ("10.187.24.222",8000)

bufferSize = 1024

msgToServer = "Hello UDP Server"

bytesToSend = str.encode(msgToServer)

UDP_Client = socket.socket(family=socket.AF_INET,

type=socket.SOCK_DGRAM)

UDP_Client.sendto(bytesToSend, ServerAddressPort)

last_send = time()

while True:

ServerMsg = UDP_Client.recvfrom(bufferSize)

frame_bytes= ServerMsg[0]

ServerMsg_address = ServerMsg[1]

Trang 10

if len(frame_bytes) >= 7 and frame_bytes[0] == 0xAA and frame_bytes[-1] == 0x55:

id_byte = frame_bytes[1]

cmd_byte = frame_bytes[2]

length = frame_bytes[3]

data_bytes = frame_bytes[4:4+length]

crc_received = frame_bytes[4+length]

crc_calculated = crc8(frame_bytes[1:4+length])

if crc_received == crc_calculated:

print(f"ID={id_byte}, CMD={cmd_byte}, Length={length} (CRC OK)")

if length == 8:

t, h = struct.unpack('!ff', data_bytes)

print(f"Nhiệt độ: {t:.1f}°C Độ ẩm: {h:.1f}%")

dl_nhietdo.append(t)

dl_doam.append(h)

else:

print(f"CRC lỗi! Nhận={crc_received}, Tính={crc_calculated}")

if time() - window_start >= WINDOW_SEC:

if dl_nhietdo and dl_doam:

ndtb = round((sum(dl_nhietdo)/len(dl_nhietdo)),2)

datb = round((sum(dl_doam)/len(dl_doam)),2)

print(f"[MQTT] Gửi dữ liệu: Nhiệt độ={ndtb}, Độ ẩm={datb}")

guidl_tsp_mqtt(ndtb, datb)

dl_nhietdo.clear()

dl_doam.clear()

window_start = time()

if time() - last_send >= 1:

led_ctrl = 1 # hoặc 0, theo logic bạn muốn

Trang 11

data_bytes = struct.pack('!B', led_ctrl) # 1 byte

frame_ctrl = tao_frame_ctrl(id_byte=2, cmd_byte=0x20,

data_bytes=data_bytes)

UDP_Client.sendto(frame_ctrl, ServerAddressPort)

print(f"[SEND] Frame điều khiển LED -> {led_ctrl} ({datetime.now()})") last_send = time()

# message= "Message from Server {}".format(ServerMsg_message)

# address = "Server IP + Port {}".format(ServerMsg_address)

# print(message)

# print(address)

SEVER

import socket,struct,time

from time import sleep, time

from seeed_dht import DHT

from gpiozero import LED

from grove.display.jhd1802 import JHD1802

import select

import math

# phần cứng

lcd = JHD1802()

ss=DHT('22',5)

led1 = LED(22) # LED đỏ

led2 = LED(24) # LED vàng

led3 = LED(26) # LED xanh

localIP = "0.0.0.0"

localPort = 8000

bufferSize = 1024

msgToClient = "Hello LOC"

bytesToSend = str.encode(msgToClient)

Trang 12

Stop_byte=0x55

# Create a datagram socket

UDP_Server = socket.socket(family=socket.AF_INET,

type=socket.SOCK_DGRAM)

# Bind to address and ip

UDP_Server.bind((localIP, localPort))

print("UDP server up and listening")

# Listen for incoming

def crc8(data: bytes):

crc = 0

for b in data:

crc ^= b

for _ in range(8):

if crc & 0x80:

crc = (crc << 1) ^ 0x07

else:

crc <<= 1

crc &= 0xFF

return crc

def tao_frame(id_byte, cmd_byte, data_bytes):

length = len(data_bytes)

header = struct.pack('!BBBB', Start_byte, id_byte, cmd_byte, length)

crc = crc8(header[1:] + data_bytes) # tính CRC cho ID|CMD|Length|Data frame = header + data_bytes + struct.pack('!B', crc) + struct.pack('!B',

Stop_byte)

return frame

def hop_le_nhietdo(x):

return isinstance(x, (int, float)) and not (isinstance(x, float) and math.isnan(x)) and (-20 <= x <= 80)

Trang 13

def hop_le_doam(x):

return isinstance(x, (int, float)) and not (isinstance(x, float) and math.isnan(x)) and (0 <= x <= 100)

UDP_Server.setblocking(False) # socket non-blocking

last_send = time()

last_client_address = None # lưu client gần nhất

while(True):

# Kiểm tra xem có dữ liệu từ client không

ready = select.select([UDP_Server], [], [], 0.1)[0]

if ready:

ClientMsg=UDP_Server.recvfrom(bufferSize)

ClientMsg_message = ClientMsg[0]

ClientMsg_address = ClientMsg[1]

last_client_address = ClientMsg_address

if len(ClientMsg_message) >= 7 and ClientMsg_message[0] == 0xAA and ClientMsg_message[-1] == 0x55:

id_byte = ClientMsg_message[1]

cmd_byte = ClientMsg_message[2]

length = ClientMsg_message[3]

data_bytes = ClientMsg_message[4:4+length]

crc_received = ClientMsg_message[4+length]

crc_calculated = crc8(ClientMsg_message[1:4+length])

if crc_received == crc_calculated:

if id_byte == 2 and cmd_byte == 0x20 and length == 1:

led_ctrl = data_bytes[0]

if led_ctrl:

led1.on(); sleep(0.1); led1.off()

led2.on(); sleep(0.1); led2.off()

led3.on(); sleep(0.1); led3.off()

Trang 14

else:

led1.off(); led2.off(); led3.off()

print(f"[LED] LED set to {led_ctrl}")

# print message and IP address

# message = "Message from Client:{}".format(ClientMsg_message)

# address = "Client IP + Port:{}".format(ClientMsg_address)

# print(message)

# print(address)

# đọc cảm biến

if time() - last_send >= 1 and last_client_address is not None:

h,t=ss.read()

if hop_le_nhietdo(t) and hop_le_doam(h):

print("Nhiệt độ: {:.1f}*C Độ ẩm: {:.1f}%".format(t,h))

lcd.setCursor(0,0)

lcd.write("Nhiet do:{:>5.1f}C".format(t)) # format độ dài cố định để che chữ cũ

lcd.setCursor(1,0)

lcd.write("Do am:{:>6.1f}%".format(h))

data_bytes = struct.pack('!ff', t, h) # ! = big endian, 2 số float

frame_bytes = tao_frame(id_byte=1, cmd_byte=0x10,

data_bytes=data_bytes)

# Sending a message to client

UDP_Server.sendto(frame_bytes, last_client_address)

else:

print("Loi cam bien")

lcd.clear()

lcd.setCursor(0, 0)

lcd.write("Loi cam bien")

last_send = time()

Trang 15

Yêu cầu 5: Minh chứng kết quả thực nghiệm (ảnh chụp dữ liệu đo đạc,

trạng thái mô hình khi đang vận hành).

Minh chứng dữ liệu kênh sever( sever chanel):

Nhom5_Bai7

Channel ID: 3050167

 Author: mwa0000038323954

 Access: Public

Thời điểm đầu và cuối của các dữ liệu nhiệt độ, độ ẩm, điện áp:

Ngày đăng: 25/09/2025, 18:52

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w