129
- - 1 MỞ ĐẦU Một lĩnh vực nổi bật của mạng cảm nhận không dây (Wireless Sensor Network- WSN) là sự kết hợp việc cảm nhận, tính toán và truyền thông vào một thiết bị nhỏ. Thông qua mạng hình lưới (mesh networking protocols), những thiết bị này tạo ra một sự kết nối rộng lớn trong thế giới vật lý. Trong khi khả năng của từng thiết bị là rất nhỏ, sự kết hợp hàng trăm thiết bị như vậy yêu cầu là phải có công nghệ mới. Sức mạnh của WSN nằm ở chỗ khả năng triển khai một số lượng lớn các thiết bị nhỏ có thể tự thiết lập cẩu hình hệ thống. Sử dụng những thiết bị này để theo dõi theo thời gian thực, để giám sát điều kiện môi trường, để theo dõi cấu trúc hoặc tình trạng thiết bị. Hầu hết những ứng dụng của WSN là giám sát môi trường từ xa với tần số lấy dữ liệu thấp. Ví dụ, có thể dễ dàng được giám sát sự rò rỉ của một nhà máy hoá học bởi hàng trăm cảm biến tự động kết nối thành hệ thống mạng không dây để ngay lập tức phát hiện và báo cáo sự rò rỉ. Không giống những hệ thống có dây truyền thống, chi phí triển khai cho WSN được giảm thiểu. Thay vì hàng ngàn mét dây dẫn thông qua các ống dẫn bảo vệ, người lắp đặt chỉ việc đơn giản là đặt thiết bị nhỏ gọn vào nơi cần thiết. Mạng có thể được mở rộng chỉ bằng cách đơn giản là thêm các thiết bị, không cần các thao tác phức tạp. Hệ thống cũng có khả năng hoạt động trong vài năm chỉ với một nguồn pin duy nhất. Để giảm thiểu chi phí lắp đặt, WSN cần phải có khả năng thay đổi linh hoạt theo môi trường. Cơ chế thích nghi theo sự thay đổi mô hình mạng hay do mạng có sự thay đổi giữa các chế độ làm việc. Ví dụ cùng một hệ thống mạng giám sát sự rò rỉ trong một nhà máy hoá chất có thể được cấu hình lại thành một mạng được thiết kế từ trước để khoanh vùng nguồn rò rỉ và tìm ra đúng chỗ. Mạng cũng có thể hướng dẫn các công nhân đường đi an toàn nhất khi có sự cố khẩn cấp. Nhìn chung, khi con người nghĩ đến mạng không dây họ sẽ nghĩ đến các thiết bị di động, PDA hay laptop. Những thiết bị này có giá thành cao và theo một mục đích cho trước và dựa trên cơ sở hạ tầng đã có trước. Ngược lại, WSN sử dụng các

All_New(Luan Van Son)

Embed Size (px)

Citation preview

Page 1: All_New(Luan Van Son)

- -

1

MỞ ĐẦU

Một lĩnh vực nổi bật của mạng cảm nhận không dây (Wireless Sensor

Network- WSN) là sự kết hợp việc cảm nhận, tính toán và truyền thông vào một

thiết bị nhỏ. Thông qua mạng hình lưới (mesh networking protocols), những thiết bị

này tạo ra một sự kết nối rộng lớn trong thế giới vật lý. Trong khi khả năng của

từng thiết bị là rất nhỏ, sự kết hợp hàng trăm thiết bị như vậy yêu cầu là phải có

công nghệ mới.

Sức mạnh của WSN nằm ở chỗ khả năng triển khai một số lượng lớn các thiết

bị nhỏ có thể tự thiết lập cẩu hình hệ thống. Sử dụng những thiết bị này để theo dõi

theo thời gian thực, để giám sát điều kiện môi trường, để theo dõi cấu trúc hoặc tình

trạng thiết bị.

Hầu hết những ứng dụng của WSN là giám sát môi trường từ xa với tần số lấy

dữ liệu thấp. Ví dụ, có thể dễ dàng được giám sát sự rò rỉ của một nhà máy hoá học

bởi hàng trăm cảm biến tự động kết nối thành hệ thống mạng không dây để ngay lập

tức phát hiện và báo cáo sự rò rỉ. Không giống những hệ thống có dây truyền thống,

chi phí triển khai cho WSN được giảm thiểu. Thay vì hàng ngàn mét dây dẫn thông

qua các ống dẫn bảo vệ, người lắp đặt chỉ việc đơn giản là đặt thiết bị nhỏ gọn vào

nơi cần thiết. Mạng có thể được mở rộng chỉ bằng cách đơn giản là thêm các thiết

bị, không cần các thao tác phức tạp. Hệ thống cũng có khả năng hoạt động trong vài

năm chỉ với một nguồn pin duy nhất.

Để giảm thiểu chi phí lắp đặt, WSN cần phải có khả năng thay đổi linh hoạt

theo môi trường. Cơ chế thích nghi theo sự thay đổi mô hình mạng hay do mạng có

sự thay đổi giữa các chế độ làm việc. Ví dụ cùng một hệ thống mạng giám sát sự rò

rỉ trong một nhà máy hoá chất có thể được cấu hình lại thành một mạng được thiết

kế từ trước để khoanh vùng nguồn rò rỉ và tìm ra đúng chỗ. Mạng cũng có thể

hướng dẫn các công nhân đường đi an toàn nhất khi có sự cố khẩn cấp.

Nhìn chung, khi con người nghĩ đến mạng không dây họ sẽ nghĩ đến các thiết

bị di động, PDA hay laptop. Những thiết bị này có giá thành cao và theo một mục

đích cho trước và dựa trên cơ sở hạ tầng đã có trước. Ngược lại, WSN sử dụng các

Page 2: All_New(Luan Van Son)

- -

2

thiết bị nhúng nhỏ, giá thành thấp cho các ứng dụng đa dạng và không dựa trên bất

kỳ cơ sở hạ tầng đã có từ trước. Không giống các thiết bị không dây truyền thống,

các nút mạng WSN không cần truyền trực tiếp tới trạm gốc, mà chỉ cần truyền tới

trạm gần nó, rồi lần lượt truyền về trạm gốc theo dạng truyền thông multihop.

Một ví dụ về mạng được đưa ra trong hình 1. Nó minh hoạ một ứng dụng trong

nông nghiệp. Hàng trăm nút nằm rải rác trong cánh đồng liên kết với nhau, thiết lập

một mô hình định tuyến, và truyền dữ liệu cho một trung tâm. Ứng dụng đòi hỏi

phải thiết thực, uyển chuyển, chi phí thấp và dễ triển khai thành mạng WSN. Nếu

một trong các nút lỗi, một mô hình mạng mới được lựa chọn và toàn bộ mạng vẫn

tiếp tục truyền dữ liệu. Nếu có thêm nút mạng, chúng chỉ tạo nên nhiều cơ hội định

tuyến hơn.

Một thách thức cơ bản của WSN là đưa các ràng buộc khắt khe vào trong một

thiết bị đơn lẻ. Các hệ xử lý nhúng với bộ nhớ cỡ kilobytes phải thực hiện các giao

thức mạng phức tạp theo dạng adhoc. Rất nhiều ràng buộc đối với các thiết bị được

triển khai với số lượng lớn cần có kích thước nhỏ và giá thành thấp. Kích thước

giảm là điều chủ yếu dẫn đến giảm giá thành, cũng như khả năng cho phép các thiết

bị được sử dụng trong một dải rộng các ứng dụng.

Hình 1. Một ví dụ về ứng dụng của WSN trong nông nghiệp

Page 3: All_New(Luan Van Son)

- -

3

Một khó khăn lớn là năng lượng tiêu thụ. Khi kích thước vật lý giảm, cũng làm

giảm năng lượng tiêu thụ. Các ràng buộc về năng lượng sẽ tạo nên giới hạn về tính

toán và lưu trữ dẫn đến phải có kiến trúc mới. Nhiều thiết bị, như điện thoại di động

hay máy nhắn tin, giảm năng lượng tiêu thụ thông qua phần cứng truyền thông được

thiết kế đặc biệt. Một trạm WSN cần hỗ trợ cho một hệ các giao thức ứng dụng cụ

thể để làm giảm mạnh kích thước, chi phí và năng lượng tiêu thụ cho ứng dụng đó.

Bản luận văn “Thiết kế chế tạo, vận hành và đo thử nghiệm mạng cảm nhận

không dây (wireless sensor network) trên cơ sở sử dụng chip vi điều khiển có mật

độ tích hợp cao làm nút mạng và xây dựng phần mềm nhúng nạp trong các vi

điều khiển này” sẽ tổng quát hoá WSN, đưa ra các tiêu chí đánh giá đối với một

WSN cũng như tiêu chí đánh giá một nút mạng, đồng thời xây dựng một số thử

nghiệm mạng cảm nhận không dây dùng VĐK CC1010 của hãng Chipcon-Nauy.

Luận văn gồm 5 chương nội dung, phần mở đầu, phần kết luận, phần phụ lục

và tài liệu tham khảo.

Chương 1: Giới thiệu mạng cảm nhận không dây sẽ giới thiệu một cách tổng

quan về WSN, các dạng ứng dụng của WSN và đưa ra những tiêu chí đánh giá cho

WSN cũng như tiêu chí đánh giá một nút mạng cảm nhận.

Chương 2: Nút mạng sẽ đưa ra các tiêu chí đánh giá cho một nút mạng trong

WSN, đồng thời giới thiệu một vi điều khiển CC1010 để làm nút mạng.

Chương 3: Các phương pháp ghép nối CC1010 với các loại đầu đo và chương

trình thực hiện. Mục đích của chương này nêu các phương pháp ghép nối giữa vi

điều khiển CC1010 với các loại cảm biến bao gồm các loại cảm biến số nối tiếp và

cảm biến tương tự. Chương này cũng giới thiệu chi tiết về cách làm việc của

CC1010 với cảm biến áp suất MS5535 cũng là một dạng cảm biến số nối tiếp. Điều

này góp phần khẳng định khả năng ghép nối với nhiều loại cảm biến khác nhau của

CC1010.

Chương 4: Phần mềm nhúng. Mục đích của chương này giới thiệu các bước cơ

bản xây dựng một phần mềm nhúng và các phương pháp gỡ lỗi cho phần mềm

nhúng.

Page 4: All_New(Luan Van Son)

- -

4

Chương 5: Triển khai chức năng mạng và các thử nghiệm. Mục đích của

chương này là đưa ra một cách xây dựng một WSN dựa trên vi điều khiển CC1010.

Đa truy cập được xây dựng dưới dạng hỏi-đáp. Bảng định tuyến hình cây chứa

trong các nút mạng. Các thử nghiệm đã thực hiện theo các tiêu chí độ ổn định

truyền dữ liệu, khả năng tiết kiệm năng lượng của các nút mạng.

Phần kết luận tổng kết những công việc đã thực hiện và những kết quả đã đạt

được đồng thời cũng đề cập đến công việc và hướng nghiên cứu trong tương lai.

Tác giả luận văn này xin gửi lời cảm ơn sâu sắc nhất đến PGS TS. Vương Đạo

Vy, Khoa Điện tử viễn thông - Trường Đại học công nghệ - Đại học quốc gia Hà

nội, người đã hướng dẫn tận tình và giúp đỡ tôi rất nhiều trong quá trình thực hiện

luận văn này.

Tác giả

Nguyễn Thế Sơn

Page 5: All_New(Luan Van Son)

- -

5

CHƯƠNG I

GIỚI THIỆU MẠNG CẢM NHẬN KHÔNG DÂY

1.1 Mạng cảm nhận không dây

Khái niệm mạng cảm nhận không dây dựa trên công thức đơn giản sau:

Cảm nhận + CPU + Radio = WSN

Từ công thức đơn giản trên, rất nhiều ứng dụng xuất hiện. Tuy nhiên, việc kết

hợp các cảm biến, radios, và CPU vào một mạng cảm nhận không dây (wireless

sensor network-WSN) đòi hỏi hiểu biết chi tiết về khả năng và giới hạn của các

thành phần phần cứng, cũng như hiểu rõ các công nghệ mạng hiện đại, lý thuyết

phân bố hệ thống. Một thách thức là ánh xạ toàn bộ yêu cầu hệ thống vào một thiết

bị riêng lẻ. Để làm cho WSN trở nên thực tế, một kiến trúc cần được phát triển để

tổng hợp các ứng dụng dựa trên khả năng của phần cứng.

Để phát triển kiến trúc hệ thống cần đi từ yêu cầu ứng dụng mức cao xuống

các yêu cầu phần cứng mức thấp. Để giới hạn số các ứng dụng phải xem xét, cần

tập trung vào một tập các dạng ứng dụng được sử dụng nhiều trong thực tế. Sử dụng

các dạng ứng dụng này để tìm ra các yêu cầu mức hệ thống cho toàn bộ kiến trúc.

Từ các yêu cầu mức hệ thống này, có thể có các yêu cầu cho các nút mạng riêng lẻ.

1.1.1 Các dạng ứng dụng của mạng cảm nhận

Có ba dạng ứng dụng của mạng cảm nhận không dây: thu thập dữ liệu môi

trường, giám sát an ninh, và theo dõi đối tượng. Hầu hết các ứng dụng chủ yếu của

WSN đều thuộc ba dạng này.

1.1.1.1 Thu thập dữ liệu môi trường

Mạng cảm nhận không dây thu thập dữ liệu môi trường ra đời đáp ứng cho

nhu cầu thu thập thông tin về môi trường tại một tập hợp các điểm xác định trong

một khoảng thời gian nhất định nhằm phát hiện xu hướng hoặc quy luật vận động

của môi trường. Bài toán này được đặc trưng bởi một số lớn các nút mạng, thường

xuyên cung cấp thông số môi trường và gửi về một hoặc một tập trạm gốc (base

station) có kết nối với trung tâm xử lý (thường là hệ thống máy tính) phân tích, xử

Page 6: All_New(Luan Van Son)

- -

6

lý, đưa ra các phương án phù hợp hoặc cảnh báo hay đơn thuần chỉ là lưu trữ số

liệu. Yêu cầu đặt ra đối với các mạng kiểu này là thời gian sống phải dài hay nói

cách khác là các nút mạng phải tiêu thụ năng lượng ít. Mạng cho ứng dụng thu thập

dữ liệu môi trường thường sử dụng topology dạng cây, mỗi nút mạng có một nút

cha duy nhất. Trạm gốc sẽ là gốc của cây. Dữ liệu từ một nút bất kỳ sẽ được gửi đến

cho nút cha của nó, nút này lại tiếp tục chuyển đến cho nút cha tiếp theo (nút ông),

cứ như vậy, dữ liệu sẽ được chuyển về trạm gốc.

Những vấn đề nảy sinh với cấu hình mạng này là:

- Hiện tượng thắt cổ chai (bottleneck) khi số lượng nút mạng lớn.

- Một vài nút mạng, vì một số lý do nào đó, không hoạt động. Để mạng

tiếp tục hoạt động nó phải có khả năng tự cấu hình lại, nghĩa là phải phát hiện ra các

nút bị hỏng hoặc định kỳ thực hiện việc cấu hình lại mạng.

- Mạng phải có thời gian sống dài, từ vài tháng đến vài năm, cần giải

quyết vấn đề tiêu thụ năng lượng của các nút mạng tối ưu nhất.

- Phần mềm nhúng phải được thiết kế và lập trình sao cho phù hợp nhất

với bài toán truyền thông các thông số đo được như nhiệt độ, độ ẩm, ánh sáng...

Phần mềm phải tương thích với phần cứng để hệ có khả năng hoạt động ổn định

theo thời gian.

1.1.1.2 Giám sát an ninh

Một ứng dụng thứ hai của mạng cảm nhận là giám sát an ninh. Các mạng giám

sát an ninh được tạo bởi các nút đặt ở những vị trí cố định trong môi trường liên tục

theo dõi một hay nhiều cảm biến để nhận biết sự bất thường. Sự khác nhau chủ yếu

giữa giám sát an ninh và giám sát môi trường là các mạng an ninh không thu thập

bất kỳ dữ liệu nào. Điều này có tác động lớn đến việc tối ưu kiến trúc mạng. Mỗi

nút thường xuyên kiểm tra trạng thái các cảm biến của chúng nhưng chỉ truyền dữ

liệu khi có sự vi phạm an ninh. Việc truyền tức thời và tin cậy của thông điệp cảnh

báo là yêu cầu chính của hệ thống.

Page 7: All_New(Luan Van Son)

- -

7

Thêm vào đó, nó cần được xác nhận là mỗi nút vẫn hiện diện và hoạt động.

Nếu một nút bị lỗi, nó sẽ thể hiện một sự vi phạm an ninh cần được thông báo. Đối

với các ứng dụng giám sát an ninh, mạng cần được cấu hình sao cho các nút chịu

trách nhiệm xác nhận trạng thái các nút khác. Một cách tiếp cận là mỗi nút ngang

hàng sẽ thông báo nếu một nút không hoạt động. Mô hình tối ưu của một mạng

giám sát an ninh sẽ hoàn toàn khác với mạng thu thập dữ liệu.

Trong cây thu thập số liệu, mỗi nút phải truyền dữ liệu của tất cả con cháu. Do

đó, tối ưu là cây ngắn và rộng. Ngược lại, với mạng an ninh cấu hình tối ưu sẽ có

mô hình mạng tuyến tính. Công suất tiêu thụ của mỗi nút chỉ tỷ lệ với số các con

của nó. Trong mạng tuyến tính, mỗi nút chỉ có 1 con. Điều này phân phối đều năng

lượng tiêu thụ của mạng.

Sự tiêu thụ năng lượng chủ yếu trong mạng an ninh là gặp các yêu cầu báo

hiệu cảnh báo khi có sự vi phạm an ninh. Mỗi khi nhận thấy, một sự vi phạm an

ninh cần được truyền tới trạm gốc ngay lập tức. Độ trễ của việc truyền dữ liệu qua

mạng tới trạm gốc có ảnh hưởng nhất định tới hiệu quả của ứng dụng. Các nút mạng

cần có khả năng trả lời nhanh chóng với các yêu cầu của các nút láng giềng để

chuyển tiếp dữ liệu.

Trong các mạng an ninh việc giảm thời gian trễ của việc truyền cảnh báo quan

trọng hơn việc giảm chi phí năng lượng khi truyền. Điều này do các sự kiện cảnh

báo rất hiếm khi xảy ra. Trong mạng phòng cháy các cảnh báo gần như không bao

giờ xảy ra. Đối với sự kiện xảy ra 1 lần năng lượng chủ yếu được dành cho việc

truyền. Giảm độ trễ truyền sẽ làm tăng năng lượng tiêu thụ vì các nút định tuyến

phải giám sát các kênh radio thường xuyên hơn.

Trong các mạng an ninh, phần lớn năng lượng tiêu thụ dành cho việc xác nhận

chức năng của các nút láng giềng và chuẩn bị chuyển tiếp thông báo cảnh báo. Việc

truyền dữ liệu hiện thời sẽ tốn một phần năng lượng của mạng.

1.1.1.3 Theo dõi đối tượng

Với các mạng cảm nhận không dây, các đối tượng có thể được theo dõi đơn

giản gắn chúng với một nút cảm biến nhỏ. Nút cảm biến này sẽ được theo dõi khi

Page 8: All_New(Luan Van Son)

- -

8

chúng đi qua một trường các nút cảm biến được triển khai tại những vị trí đã biết.

Thay vì cảm nhận dữ liệu môi trường, những nút này sẽ được triển khai để cảm

nhận các thông điệp RF của các nút gắn với các đối tượng. Những nút này có thể

được sử dụng như những thẻ để thông báo sự có mặt của một thiết bị. Một cơ sở dữ

liệu có thể được sử dụng để ghi lại vị trí tương đối của đối tượng với các nút mạng,

do đó có thể biết vị trí hiện thời của đối tượng.

Không như mạng cảm nhận hay mạng an ninh, các ứng dụng theo dõi sẽ liên

tục thay đổi topology khi các nút đi qua mạng. Trong khi sự kết nối giữa các nút tại

các vị trí cố định tương đối ổn định, sự kết nối tới các nút di động sẽ liên tục thay

đổi. Thêm vào đó tập hợp các nút bị theo dõi sẽ liên tục thay đổi khi các nút gia

nhập hay rời khỏi hệ thống. Điều chủ yếu là mạng có khả năng nhận biết một cách

hiệu quả sự có mặt của các nút mới đi vào mạng.

1.1.2 Các chỉ tiêu hệ thống

Sau đây là các chỉ tiêu để đánh giá một WSN. Các chỉ tiêu chủ yếu là thời gian

sống, độ bao phủ, chi phí và dễ triển khai, thời gian trả lời, độ chính xác thời gian,

bảo mật, và tốc độ lấy mẫu hiệu quả. Các chỉ tiêu này lại liên quan với nhau.

Thường thì khi tăng hiệu quả một tham số thì lại làm giảm hiệu quả của tham số

khác, ví dụ như tăng tốc độ lấy mẫu lại làm giảm thời gian sống. Mục đích ở phần

này hiểu rõ và cân bằng các chỉ tiêu với khả năng của hệ thống.

1.1.2.1 Thời gian sống

Có một giới hạn của mạng cảm nhận không dây đó là thời gian sống. Cả hai

ứng dụng giám sát môi trường và giám sát an ninh các nút đều được đặt ở ngoài môi

trường, không có người giám sát theo hàng tháng hay hàng năm.

Yếu tố chủ yếu giới hạn thời gian sống của mạng cảm nhận là năng lượng

cung cấp. Mỗi nút cần được thiết kế quản lý năng lượng cung cấp nội bộ để tối đa

thời gian sống của mạng. Trong trường hợp mạng an ninh, mỗi nút phải sống trong

nhiều năm. Một nút bị lỗi sẽ làm tổn thương hệ thống an ninh.

Trong vài tình huống có thể dùng nguồn năng lượng ngoài. Tuy nhiên, vì ưu

điểm chính của mạng không dây là tính linh hoạt dễ triển khai. Yêu cầu nguồn năng

Page 9: All_New(Luan Van Son)

- -

9

lượng ngoài cho tất cả các nút mạng lại mâu thuẫn với ưu điểm này. Một giải pháp

thoả hiệp là có một nhóm các nút đặc biệt được cấp nguồn ngoài.

Trong hầu hết các ứng dụng, đặc điểm chính của các nút là tự cấp nguồn.

Chúng sẽ có đủ năng lượng cho nhiều năm, hoặc có thể lấy năng lượng từ môi

trường thông qua thiết bị khác, như năng lượng mặt trời hay nguồn áp điện. Cả hai

sự lựa chọn đều yêu cầu năng lượng tiêu thụ trung bình của các nút càng ít càng tốt.

Yếu tố quan trọng quyết định thời gian sống là năng lượng tiêu thụ radio. Một

nút cảm nhận không dây khi truyền hoặc nhận tín hiệu radio sẽ tiêu thụ năng lượng

lớn. Năng lượng tiêu thụ này có thể giảm được bằng cách giảm năng lượng truyền,

tức là giảm chu trình làm việc của radio.

1.1.2.2 Độ bao phủ

Bên cạnh thời gian sống, độ bao phủ là cũng là tham số đánh giá cho mạng

không dây. Nó có thuận lợi là khả năng triển khai một mạng trên một vùng rộng

lớn. Điều này làm tăng giá trị hệ thống đối với người dùng cuối. Điều quan trọng là

độ bao phủ của mạng không tương đương với khoảng cách kết nối không dây được

sử dụng. Kỹ thuật truyền multi-hop có thể mở rộng độ bao phủ của mạng. Về mặt lý

thuyết chúng có khả năng mở rộng vô hạn. Tuy nhiên, trong một khoảng cách

truyền xác định, giao thức mạng multi-hop làm tăng năng lượng tiêu thụ của các

nút, và sẽ làm giảm thời gian sống của mạng. Hơn nữa, chúng đòi hỏi một mật độ

tối thiểu, và sẽ làm tăng chi phí triển khai.

Ràng buộc khoảng cách dẫn đến việc mở rộng một số lượng lớn các nút. Giá

trị chủ yếu của mạng cảm nhận là khả năng mở rộng. Một người dùng có thể triển

khai một mạng nhỏ ban đầu và sau đó tiếp tục thêm các nút. Tăng số lượng các nút

trong hệ thống sẽ ảnh hưởng tới thời gian sống. Càng nhiều điểm cảm nhận thì càng

có nhiều dữ liệu được truyền và sẽ làm tăng năng lượng tiêu thụ của mạng.

1.1.2.3 Chi phí và dễ triển khai

Ưu điểm mấu chốt của mạng cảm nhận không dây là dễ triển khai. Người sử

dụng không cần phải hiểu về mạng và cơ chế truyền thông khi làm việc với WSN.

Page 10: All_New(Luan Van Son)

- -

10

Để triển khai hệ thống thành công, WSN cần phải tự cấu hình. Các nút được đặt vào

môi trường và có thể hoạt động ngay.

Lý tưởng là, hệ thống cần phải tự cấu hình đối với sự sắp đặt nút vật lý. Tuy

nhiên, các hệ thống thực cần đặt các ràng buộc vào một sự sắp đặt nút hiện thời –

các nút không thể có khoảng cách vô hạn. WSN cần có khả năng phản hồi khi

những sự ràng buộc bị vi phạm. Mạng cần phải có khả năng đánh giá chất lượng

của việc triển khai mạng và chỉ rõ các vấn đề tiềm ẩn. Điều đó nghĩa là các nút

mạng cần có khả năng tìm kết nối và xác định chất lượng kết nối.

Thêm vào đó, hệ thống cần thích nghi đối với sự thay đổi điều kiện môi

trường. Trong suốt thời gian sống, sẽ có thể thay đổi vị trí hay các đối tượng lớn có

thể gây nhiễu tới sự truyền thông giữa hai nút. Mạng cần có khả năng tự cấu hình lại

để khắc phục những điều này.

Việc triển khai và thiết lập cấu hình ban đầu chỉ là bước đầu tiên trong chu kỳ

sống của mạng. Trong thời gian dài, tổng chi phí của hệ thống có thêm chi phí bảo

dưỡng. Ứng dụng an ninh còn có yêu cầu hệ thống phải rất mạnh. Để mở rộng khả

năng kiểm tra trước khi triển khai, hệ cảm nhận cần được xây dựng để có thể thực

hiện việc tự bảo trì. Khi cần, nó có thể tạo ra các yêu cầu bảo trì ngoài.

Trong thực tế, một phần năng lượng được dành cho kiểm tra và bảo trì hệ

thống. Việc tạo ra thông tin chẩn đoán và tái cấu hình sẽ làm giảm thời gian sống

của mạng, đồng thời cũng làm giảm tốc độ lấy mẫu.

1.1.2.4 Thời gian đáp ứng

Trong các ứng dụng cảnh báo, thời gian đáp ứng hệ thống là một thông số

quan trọng để đánh giá hệ thống. Một cảnh báo cần được tạo ra ngay lập tức khi

nhận thấy có một sự vi phạm. Dù hoạt động năng lượng thấp, các nút cần có khả

năng truyền tức thời các thông điệp qua mạng càng nhanh càng tốt. Trong khi

những sự kiện như vậy là không thường xuyên, chúng có thể xảy ra tại bất cứ thời

điểm nào mà không được báo trước. Thời gian đáp ứng cũng quan trọng khi điều

khiển máy móc trong nhà máy. Những hệ thống này chỉ thành hiện thực nếu đảm

bảo được thời gian đáp ứng.

Page 11: All_New(Luan Van Son)

- -

11

Khả năng có thời gian đáp ứng ngắn xung đột với các kỹ thuật làm tăng thời

gian sống của mạng. Thời gian sống của mạng có thể tăng bằng cách để các nút chỉ

hoạt động radio trong thời gian ngắn. Nếu một nút chỉ bật radio một lần trong một

phút để truyền hay nhận dữ liệu, nó không thể đáp ứng được đối với các ứng dụng

cho hệ thống an ninh.

Thời gian đáp ứng có thể cải thiện bằng cách cấp nguồn cho một số nút trong

toàn bộ thời gian. Những nút này có thể nghe các thông điệp cảnh báo và chuyển

tiếp chúng theo đường khi cần. Tuy nhiên điều này sẽ làm giảm tính dễ triển khai hệ

thống.

1.1.2.5 Độ chính xác về thời gian

Trong ứng dụng theo dõi đối tượng và giám sát môi trường các mẫu từ nhiều

nút có liên quan theo thời gian để xác định các hiện tượng khác thường được theo

dõi. Tính chính xác của cơ chế tương quan phụ thuộc vào tốc độ lan truyền của hiện

tượng được đo. Trong trường hợp xác định nhiệt độ trung bình của một toà nhà, các

mẫu chỉ được liên quan với nhau trong vòng cỡ hàng giây. Tuy nhiên, để xác định

cách phản ứng của toà nhà đối với một trận động đất thì đòi hỏi độ chính xác cỡ

mili giây.

Để đạt được độ chính xác theo thời gian, một mạng cần xây dựng và duy trì

một thời gian cơ sở toàn cục có thể được sử dụng để sắp xếp các mẫu và các sự kiện

theo thời gian. Trong một hệ phân tán, năng lượng cần được mở rộng để duy trì và

phân phát đồng hồ. Thông tin đồng bộ thời gian cần liên tục được truyền giữa các

nút. Tần số các thông điệp đồng bộ phụ thuộc vào yêu cầu độ chính xác của đồng hồ

thời gian.

1.1.2.6 Bảo mật

Các thông tin về nhiệt độ đối với ứng dụng giám sát môi trường đường như vô

hại nhưng việc giữ bí mật thông tin là rất quan trọng. Các hoạt động của một toà

nhà có thể thu thập được dễ dàng bằng cách lấy thông tin về nhiệt độ và ánh sáng

của toà nhà đó. Những thông tin này có thể được sử dụng để sắp xếp một kế hoạch

Page 12: All_New(Luan Van Son)

- -

12

tấn công vào một công ty. Do đó, WSN cần có khả năng giữ bí mật các thông tin

thu thập được.

Trong các ứng dụng an ninh, dữ liệu bảo mật trở nên rất quan trọng. Không chỉ

duy trì tính bí mật, nó còn phải có khả năng xác thực dữ liệu truyền. Sự kết hợp tính

bí mật và xác thực là yêu cầu cần thiết của cả ba dạng ứng dụng.

Việc sử dụng mã hoá và giải mã sẽ làm tăng chi phí về năng lượng và băng

thông. Dữ liệu mã hoá và giải mã cần được truyền cùng với mỗi gói tin. Điều đó

ảnh hưởng tới hiệu suất ứng dụng do giảm số lượng dữ liệu lấy từ mạng và thời gian

sống mong đợi.

1.1.2.7 Tốc độ thu thập thông tin hiệu quả

Trong một mạng thu thập dữ liệu, tốc độ thu thập thông tin hiệu quả là tham số

đánh giá hiệu suất của hệ thống. Tốc độ thu thập thông tin hiệu quả là số mẫu lấy

được từ mỗi nút riêng lẻ và truyền về điểm thu thập trung tâm. Thông thường, các

ứng dụng thu thập dữ liệu chỉ có tốc độ lấy mẫu là 1-2 mẫu trong 1 phút.

Trong một cây thu thập dữ liệu, một nút cần điều khiển dữ liệu của tất cả các

con cháu. Nếu mỗi nút con truyền một dữ liệu và một nút có 60 nút con cháu, nó

phải truyền 60 lần. Thêm vào đó nó còn phải nhận 60 lần trong một chu kỳ lấy mẫu.

Tốc độ và kích thước mạng ảnh hưởng tới tốc độ lấy mẫu hiệu quả.

Một cơ chế để tăng tốc độ lấy thông tin là truyền dữ liệu thô và xử lý dữ liệu

nội mạng (innetwork processing). Các dạng nén không gian và thời gian có thể

được sử dụng để giảm yêu cầu về băng thông trong khi vẫn duy trì được tốc độ lấy

mẫu hiệu quả. Xử lý dữ liệu nội mạng có thể được sử dụng để xác định khi một sự

kiện quan tâm xảy ra và tự động lưu trữ dữ liệu. Dữ liệu sau đó được truyền qua

mạng multi-hop khi băng thông cho phép.

1.1.3 Các chỉ tiêu nút mạng

Sau đây là những chỉ tiêu để đánh giá một nút mạng trong WSN. Mục đích là

qua các chỉ tiêu đánh giá đó để có thể lựa chọn loại VĐK thích hợp và cũng để xây

dựng hệ thống hiệu quả.

Page 13: All_New(Luan Van Son)

- -

13

1.1.3.1 Năng lượng

Để đạt được yêu cầu duy trì năng lượng hoạt động trong nhiều năm thì các nút

mạng cần phải tiêu thụ năng lượng rất thấp. Việc tiêu thụ năng lượng thấp chỉ đạt

được bằng cách kết hợp các thành phần phần cứng năng lượng thấp và chu trình

hoạt động ngắn. Trong thời gian hoạt động, truyền thông radio sẽ tiêu thụ một phần

năng lượng đáng kể trong tổng mức tiêu thụ năng lượng của nút mạng. Các thuật

toán và các giao thức cần được phát triển để giảm hoạt động truyền nhận radio.

Điều này có thể đạt được bằng cách sử dụng sự tính toán cục bộ để giảm luồng dữ

liệu nhận được từ cảm biến. Ví dụ, các sự kiện từ nhiều nút cảm biến có thể được

kết hợp cùng nhau thành một nhóm các nút trước khi truyền một kết quả đơn lẻ qua

mạng cảm nhận.

1.1.3.2 Tính mềm dẻo

Các nút mạng phải có khả năng thích nghi cao để thích hợp với các ngữ cảnh

khác nhau. Mỗi một ứng dụng sẽ yêu cầu về thời gian sống, tốc độ lấy mẫu, thời

gian đáp ứng và xử lý nội mạng khác nhau. Một kiến trúc WSN cần phải đủ mềm

dẻo để cung cấp một dải rộng các ứng dụng. Thêm vào đó, vì lý do chi phí mỗi thiết

bị sẽ chỉ có phần cứng và phần mềm cho một ứng dụng cụ thể. Kiến trúc cần phải

đơn giản để kết hợp giữa phần cứng và phần mềm. Vì vậy, những thiết bị này đòi

hỏi một mức độ cao về tính modul của phần cứng và phần mềm trong khi vẫn giữ

được tính hiệu quả.

1.1.3.3 Sức mạnh

Để hỗ trợ cho các yêu cầu về thời gian sống, mỗi nút cần phải càng mạnh càng

tốt. Trong sự thực tế, hàng trăm nút mạng sẽ hoạt động trong nhiều năm. Để đạt

được điều này, hệ thống cần được xây dựng để vẫn có thể hoạt động khi một nút bị

lỗi. Modul hoá hệ thống là một công cụ mạnh để phát triển hệ thống. Bằng cách

chia chức năng hệ thống thành các thành phần con độc lập, mỗi chức năng có thể

được kiểm tra đầy đủ trước khi kết hợp chúng thành một ứng dụng hoàn chỉnh. Để

làm điều này, các thành phần hệ thống phải độc lập đến mức có thể và có giao tiếp

chặt chẽ, để ngăn chặn các tương tác không mong đợi. Để tăng sức mạnh hệ thống

Page 14: All_New(Luan Van Son)

- -

14

khi nút bị lỗi, một WSN cũng cần có khả năng đối phó với nhiễu ngoài. Các mạng

thường cùng tồn tại cùng với các hệ thống không dây khác, chúng cần có khả năng

để thích nghi theo các hành động khác nhau. Nó cũng phải có khả năng hoạt động

trong môi trường đã có các thiết bị không dây khác hoạt động với một hay nhiều tần

số. Khả năng tránh tắc nghẽn tần số là điều cốt yếu để đảm bảo một sự triển khai

thành công.

1.1.3.4 Bảo mật

Để đạt được mức độ bảo mật mà ứng dụng yêu cầu, các nút riêng lẻ cần có khả

năng thực hiện sự mã hoá phức tạp và thuật toán xác thực. Truyền dữ liệu không

dây rất dễ bị chặn. Chỉ có một cách bảo mật dữ liệu là mã hoá toàn bộ dữ liệu

truyền. CPU cần có khả năng tự thực hiện các thao tác mật mã. Để bảo mật toàn bộ

dữ liệu truyền, các nút cần tự bảo mật dữ liệu của chúng. Trong khi chúng không có

lượng lớn dữ liệu lưu bên trong, chúng sẽ phải lưu các khoá mã hoá được sử dụng

trên mạng. Nếu những khoá này bị lộ, tính bảo mật của mạng sẽ mất. Để có được

tính bảo mật tốt, cần phải rất khó để lấy được khoá mã hóa từ một nút.

1.1.3.5 Truyền thông

Một chỉ tiêu đánh giá cho bất kỳ WSN là tốc độ truyền, năng lượng tiêu thụ và

khoảng cách. Trong khi độ bao phủ của mạng không bị giới hạn bởi khoảng cách

truyền của các nút riêng biệt, khoảng cách truyền có một ảnh hưởng quan trọng tới

mật độ tối thiểu có thể chấp nhận được. Nếu các nút được đặt rất xa nó không thể

tạo được kết nối với mạng liên kết hoặc với một nút dự trữ để có được độ tin cậy

cao. Nếu khoảng cách truyền radio thoả mãn một mật độ nút cao, các nút thêm vào

sẽ làm tăng mật độ hệ thống tới một mức độ nào đó cho phép. Tốc độ truyền cũng

có ảnh hưởng lớn đến hiệu suất của nút mạng. Tốc độ truyền cao hơn làm cho khả

năng lấy mẫu hiệu quả hơn và năng lượng tiêu thụ của mạng ít hơn. Khi tốc độ tăng,

việc truyền mất ít thời gian hơn và do đó đòi hỏi ít năng lượng hơn. Tuy nhiên, khi

tăng tốc độ cũng thường làm tăng năng lượng tiêu thụ radio. Mọi thứ trở nên bằng

nhau, một tốc độ cao sẽ tăng hiệu suất hệ thống. Tuy nhiên, tăng tốc độ có ảnh

Page 15: All_New(Luan Van Son)

- -

15

hưởng lớn tới năng lượng tiêu thụ và yêu cầu tính toán của nút. Tổng thể, lợi ích của

việc tăng tốc độ có thể được bù lại bởi các yếu tố khác.

1.1.3.6 Tính toán

Hai việc tính toán cho nút mạng tập trung chủ yếu vào xử lý dữ liệu nội mạng

và quản lý các giao thức truyền thông không dây mức thấp. Có những yêu cầu giới

hạn về mặt thời gian thực đối với truyền thông và cảm biến. Khi dữ liệu tới trên

mạng, CPU cần điều khiển đồng thời radio và ghi lại/giải mã (record/decode) dữ

liệu tới. Tốc độ truyền cao hơn đòi hỏi tính toán nhanh hơn. Điều tương tự cũng

đúng đối với xử lý dữ liệu cảm biến. Các cảm biến tương tự có thể phát ra hàng

ngàn mẫu trong một giây. Các thao tác xử lý cảm biến nói chung bao gồm lọc số,

trung bình hoá, nhận biết ngưỡng, phân tích phổ… Để tăng khả năng xử lý cục bộ,

các nút láng giềng có thể kết hợp dữ liệu với nhau trước khi truyền đi trên mạng.

Các kết quả từ nhiều nút mạng có thể được tổng hợp cùng nhau. Xử lý nội mạng

này đòi hỏi thêm tài nguyên tính toán. Ngoài ra, ứng dụng xử lý dữ liệu có thể tiêu

thụ một lượng tính toán phụ thuộc vào các phép toán được thực hiện.

1.1.3.7 Đồng bộ thời gian

Để hỗ trợ sự tương quan thời gian đọc cảm biến và chu trình hoạt động ngắn

của ứng dụng thu thập dữ liệu, các nút cần duy trì đồng bộ thời gian chính xác với

các thành viên khác trong mạng. Các nút cần ngủ và thức dậy cùng nhau để chúng

có thể định kỳ truyền thông cho nhau. Các lỗi trong cơ chế tính thời gian sẽ tạo nên

sự không hiệu quả dẫn đến làm tăng chu trình làm việc. Trong các hệ phân tán, việc

trôi clocks theo thời gian là do cơ chế tính thời gian không chính xác. Phụ thuộc vào

nhiệt độ, điện áp, độ ẩm, thời gian dựa theo dao động sẽ không như nhau. Cần có cơ

chế đồng bộ hoá cao để bù lại những sự không chính xác như vậy.

1.1.3.8 Kích thước và chi phí

Kích thước vật lý và giá thành của mỗi nút riêng lẻ có ảnh hưởng tới sự dễ

dàng và chi phí khi triển khai. Tổng chi phí vật tư và chi phí triển khai ban đầu là

hai yếu tố chủ chốt dẫn đến việc chấp nhận các công nghệ WSN. Với một ngân sách

cố định, việc giảm giá thành trên mỗi nút sẽ làm cho có khả năng mua thêm nhiều

Page 16: All_New(Luan Van Son)

- -

16

nút, triển khai một mạng thu thập với mật độ cao hơn, và thu thập được nhiều dữ

liệu hơn. Kích thước vật lý cũng ảnh hưởng tới sự dễ dàng khi triển khai mạng. Các

nút nhỏ hơn có thể được đặt ở nhiều vị trí hơn và được sử dụng trong nhiều tình

huống hơn. Trong tình huống theo dõi nút đối tượng, các nút nhỏ hơn, rẻ hơn sẽ

tăng khả năng theo dõi nhiều đối tượng hơn.

1.2 Một số hướng phát triển trong lĩnh vực WSN

1.2.1 Hệ điều hành nhỏ TinyOS

TinyOS là hệ điều hành sử dụng trong WSN do Trường đại học Berkeley

nghiên cứu và phát triển. TinyOS sử dụng cơ chế đa truy cập S-MAC [18], sử dụng

ngôn ngữ nesC [8]. Truyền thông trong mạng sử dụng TinyOS là dạng multihop.

TinyOS có kích thước nhỏ, mã nguồn mở, dùng mô hình hướng sự kiện, với bộ lập

lịch đơn giản cho phép vi điều khiển xử lý nhiều tác vụ song song trong sự hạn chế

về tài nguyên tính toán và không gian nhớ. TinyOS sử dụng bộ lập lịch thao tác kiểu

FIFO kết nối mềm dẻo giữa phần cứng và các ứng dụng. TinyOS cung cấp giao

diện mạng tiện dụng, dùng mô hình truyền thông Active Message (AM), phổ biến

và hiệu quả trong tính toán song song hiệu năng cao. TinyOS do vậy, đã tạo ra khả

năng giao tiếp mạnh cho các nút mạng trong WSN.

Hình 1.1 Kiến trúc thành phần của TinyOS

Page 17: All_New(Luan Van Son)

- -

17

TinyOS tạo ra khả năng giao tiếp mạnh cho các nút mạng trong WSN. Hiện

tại TinyOS đang được nghiên cứu, chuyển đổi để làm việc với VĐK CC1010, là

loại VĐK sẽ được dùng để xây dựng các thử nghiệm trong khuôn khổ luận văn.

Dựa trên TinyOS và các đặc trưng của CC1010, kiến trúc phần mềm nhúng

cho WSN được đề xuất như biểu diễn ở hình 1.2. Tầng trung gian giữa TinyOS và

CC1010 là thư viện HAL (Hardware Abstraction Library), cho phép TinyOS tương

tác với phần cứng.

Tầng phía trên TinyOS là giao thức dẫn đường trong WSN. Nó vừa cho phép

truyền dữ liệu an toàn vừa hạn chế hiện tượng thắt cổ chai. Tầng trên cùng là các

ứng dụng đặc thù cho WSN bao gồm: module tự cấu hình mạng và tự cầu hình lại

mạng, module thực hiện việc đo các thông số môi trường và chuyển về cho trạm

gốc. Hai module này hoạt động theo chế độ định kỳ: sau một khoảng thời gian nhất

định, nó được bộ định thời của CC1010 đánh thức và chuyển sang hoạt động; thực

hiện xong nhiệm vụ, lại chuyển về nghỉ. Thời gian cấu hình lại hệ thống và đo dữ

liệu không giống nhau và phụ thuộc vào từng ứng dụng cụ thể.

Mô hình mạng sử dụng TinyOS là mạng hình cây có dạng sau:

Hình 1.2 Kiến trúc phần mềm nhúng sử dụng TinyOS và VĐK CC1010

Page 18: All_New(Luan Van Son)

- -

18

1.2.2 Zigbee

Zigbee là hiệp hội được sáng lập bởi các công ty: Chipcon, Ember, Freescale,

Honeywell, Mitsubishi, Motorola, Philips và Samsung. Chuẩn Zigbee ra đời nhằm

thiết lập một tiêu chuẩn mới cho mạng không dây với mục đích tiết kiệm năng

lượng cho nút mạng.

1.2.2.1 Ngăn xếp Zigbee

Zigbee phát triển lớp mạng và lớp ứng dụng trên cơ sở lớp MAC và lớp vật

lý của chuẩn IEEE 802.11.4. Lớp mạng hỗ trợ ba mô hình mạng: Mạng hình sao,

Mạng lưới và Mạng hình cây

Lớp Vật lý

Lớp Vật lý được thiết kế có sự tích hợp cao với chi phí thấp.

Hình 1.3 Mô hình mạng hình cây sử dụng TinyOS

Page 19: All_New(Luan Van Son)

- -

19

Lớp MAC

Lớp MAC được thiết kế để hoạt động với nhiều dạng topology. MAC cho

phép các thiết bị ít chức năng (reduced functionality device - RFD) không cần nhiều

ROM hay RAM. Lớp MAC được thiết kế để kiểm soát số lượng lớn các thiết bị.

Lớp mạng

Lớp mạng được thiết kế cho phép mở rộng không gian mạng mà không đòi hỏi

năng lượng truyền cao. Lớp mạng cũng có thể kiểm soát lượng lớn các nút mạng.

Các chức năng của nút mạng là:

• Khởi tạo mạng.

• Gia nhập hay rời khỏi mạng

• Cấu hình nút mạng mới

• Cấp địa chỉ: khả năng của bộ điều phối để gán địa chỉ nút mới gia nhập

• Đồng bộ hoá trong một mạng: khả năng đồng bộ hóa giữa các nút mạng thông

qua theo dõi thông tin dẫn đường beacons hay thăm dò (polling).

• Bảo mật

• Định tuyến: Sử dụng thuật toán định tuyến Adhoc On-demand Vector (AODV)

1.2.2.2 Các mô hình mạng của Zigbee:

Mạng hình sao

Mạng lưới

Page 20: All_New(Luan Van Son)

- -

20

Trong đó:

ZigBee Coordinator: luôn phải có một thiết bị này trong mạng Zigbee. Nhiệm

vụ chủ yếu là:

- Thiết lập mạng

- Quản lý các nút mạng

- Truyền beacon

- Lưu trữ thông tin nút mạng

- Thường hoạt động ở trạng thái nhận

- Không cần khả năng tiết kiệm năng lượng

ZigBee Router: thiết bị định tuyến trong mạng. Không cần khả năng tiết kiệm

năng lượng

ZigBee End Device: nút mạng

- Được thiết kế để dùng nguồn acquy, tiết kiệm năng lượng.

- Tìm một mạng có sẵn

- Truyền nhận dữ liệu

- Có thể ngủ trong một khoảng thời gian

ZigBee Coordinator

ZigBee Router

ZigBee End Device

Mạng hình cây

Page 21: All_New(Luan Van Son)

- -

21

1.3 Kết luận

Chương 1 khái quát các khái niệm và các dạng ứng dụng mạng cảm nhận

không dây. Có ba dạng ứng dụng của mạng cảm nhận không dây, đó là: Thu thập

dữ liệu môi trường, Giám sát an ninh và Theo dõi đối tượng. Hầu hết ứng dụng

mạng cảm nhận không dây đều rơi vào một trong ba dạng ứng dụng này. Mỗi dạng

ứng dụng đều có những mục đích và nguyên tắc làm việc khác nhau, qua đó đòi hỏi

phải có thiết kế hệ thống khác nhau. Tuy nhiên các dạng ứng dụng khác nhau đó

đều có các chỉ tiêu đánh giá hệ thống như đã nói ở trên, đó là: thời gian sống, độ

bao phủ, giá thành và tính dễ triển khai, thời gian đáp ứng, độ chính xác về thời

gian, bảo mật và tốc độ thu thập thông tin hiệu quả. Tuỳ từng ứng dụng cụ thể mà

các chỉ tiêu trên có các cách đánh giá khác nhau.

Page 22: All_New(Luan Van Son)

- -

22

CHƯƠNG 2

NÚT MẠNG

2.1 Giới thiệu một số VĐK có thể làm nút mạng cảm nhận

Vấn đề lựa chọn VĐK để xây dựng nút mạng là một vấn đề quan trọng. Việc

chọn VĐK hợp lý sẽ làm cho qúa trình xây dựng hệ thống được rút ngắn, hệ thống

hoạt động ổn định, tin cậy và đạt các chỉ tiêu đề ra.

Từ các chỉ tiêu nút mạng đã nói ở Chương 1, các tiêu chí quan trọng để chọn

VĐK như sau:

o Tiêu thụ năng lượng thấp.

o Tích hợp ADC để có thể ghép nối với cảm biến tương tự.

o Bộ nhớ chương trình cũng như bộ nhớ dữ liệu có kích thước hợp lý.

o Kích thước vật lý nhỏ.

o Có công cụ phát triển giúp người phát triển xây dựng hệ thống dễ

dàng và thuận tiện như: sử dụng ngôn ngữ cấp cao, có các thư viện hỗ

trợ cho việc cảm nhận cũng như truyền nhận không dây, hỗ trợ gỡ

lỗi…

o Giá thành rẻ.

Hiện giờ có 3 họ VĐK trên thị trường có thể thoả mãn các tiêu chí trên:

- Họ VĐK MSP430 của Texas.

- Họ VĐK ATMEGA của Atmel.

- VĐK CC1010 của hãng Chipcon.

Các VĐK nói trên đều thỏa mãn các tiêu chí đề ra. Tuy nhiên, hai họ VĐK đầu

tiên không có tích hợp truyền nhận không dây, vì thế nếu sử dụng những VĐK như

vậy sẽ phải có thêm mạch truyền nhận không dây bên ngoài, quá trình xây dựng hệ

thống sẽ phức tạp. VĐK CC1010 được lựa chọn nhờ có tích hợp truyền nhận không

dây, do đó việc chọn VĐK CC1010 làm nút mạng hợp lý hơn chọn các VĐK khác.

Page 23: All_New(Luan Van Son)

- -

23

2.2 Giới thiệu Vi điều khiển CC1010

2.2.1 Các đặc điểm chính:

- Thu phát không dây 300-1000 MHz.

- Dòng tiêu thụ rất thấp (9,1 mA trong chế độ nhận).

- Độ nhạy cao (-107 dBm).

- Có thể lập trình cho công suất đầu ra tới +10 dBm.

- Tốc độ truyền RF có thể đạt 76.8 kbit/s.

- Cần rất ít thành phần ngoài

- Đo được cường độ RF (RSSI)

- Tương thích họ VĐK 8051

- 32 kB Flash, 2048 + 128 Byte SRAM

- 3 kênh ADC 10 bit, 4 timers / 2PWMs, 2 UARTs, RTC, Watchdog, SPI, mã

hoá DES, 26 cổng I/O

- Có khả năng gỡ lỗi sử dụng chương trình dịch Keil μVision2 IDE qua cổng

nối tiếp

- Điện áp 2.7 - 3.6 V

- 64-lead TQFP (Thin Quad Flat Pack)

2.2.2 Cổng

Có 4 cổng I/O P0, P1, P2, P3 với 26 chân cổng. Mỗi cổng có 2 thanh ghi tương

ứng: thanh ghi cổng P0, P1, P2, P3 và thanh ghi hướng (P0DIR, P1DIR, P2DIR,

P3DIR). Mỗi bit trong thanh ghi Px có một bit hướng tương ứng trong thanh ghi

PxDIR.y. Đặt PxDIR.y = 1 sẽ làm cho Px.y là cổng nhận dữ liệu (input) và đặt

PxDIR.y = 1 sẽ làm cho Px.y là cổng xuất dữ liệu (output)

2.2.3 Ngắt

CC1010 có tổng cộng 15 nguồn ngắt, chia sẻ 12 đường ngắt. Mỗi ngắt có một

mức ưu tiên, vector ngắt, cờ cho phép ngắt và cờ báo ngắt.

Page 24: All_New(Luan Van Son)

- -

24

Bảng 1. Ngắt và các tham số

Ngắt Mức ưu

tiên tự

nhiên

Điều khiển

mức ưu

tiên

Vector

ngắt

Cờ cho phép

ngắt

Cờ ngắt

Ngắt Flash/debug 0 - 0x33 EICON.PDIE EICON.PDIF

Ngắt ngoài 0 1 IP.PX0 0x03 IE.EX0 TCON.IE0

Ngắt Timer 0 2 IP.PT0 0x0B IE.ET0 TCON.TF0

Ngắt ngoài 1 3 IP.PX1 0x13 IE.EX1 TCON.IE1

Ngắt Timer 1 4 IP.PT1 0x1B IE.ET1 TCON.TF1

Ngắt truyền nối tiếp 0 5

IP.PS0 0x23 IE.ES0 SCON0.TI 0

Ngắt nhận nối tiếp 0 SCON0.RI 0

Ngắt truyền nối tiếp 1 6

IP.PS1 0x3B IE.ES1 SCON1.TI 1

Ngắt nhận nối tiếp 1 SCON1.RI 1

Ngắt truyền/nhận RF 7 EIP.PRF 0x43 EIE.RFIE EXIF.RFIF

Ngắt Timer 2 8 EIP.PT2 0x4B EIE.ET2 EXIF.TF2

Ngắt ADC 9 EIP.PAD 0x53 EIE.ADIE

và ADCON2.

ADCIE

EXIF.ADIF

ADCON2.

ADCIF

Page 25: All_New(Luan Van Son)

- -

25

Ngắt mã hoá/giải mã

DES

EIE.ADIE

CRPCON.

CRPIE

EXIF.ADIF

CRPCON.

CRPIF

Ngắt Timer 3 10 EIP.PT3 0x5B EIE.ET3 EXIF.TF3

Ngắt thời gian thực 11 EIP.PRTC 0x63 EIE.RTCIE EICON.RTCIF

2.2.3.1 Mặt nạ ngắt

IE.EA là cờ cho phép ngắt toàn bộ các ngắt, ngoại trừ ngắt Flash/Debug. Khi

cờ IE.EA được thiết lập, mỗi ngắt bị che bởi cờ cho phép ngắt được liệt kê ở bảng

1. Khi cờ IE.EA bị xoá, tất cả các ngắt bị che, ngoại trừ ngắt Flash/Debug, có bit

che ngắt riêng, EICON.FDIE.

2.2.3.2 Xử lý ngắt

Khi một ngắt được cho phép xảy ra, CPU nhảy tới địa chỉ phục vụ ngắt tương

ứng với ngắt đó (ISR), như chỉ ra ở bảng 1. CC1010 thực hiện ISR để hoàn thành

trừ khi một ngắt khác có mức ưu tiên cao hơn xảy ra. Mỗi ISR kết thúc với lệnh

RETI. Sau khi thực hiện lệnh RETI, CC1010 quay trở lại lệnh tiếp theo sau lệnh đã

được thực hiện trước khi xảy ra ngắt. Nếu lệnh đang thực hiện là RETI, hay đang

ghi vào các thanh ghi IP, IE, EIP, EIE, CC1010 hoàn thành thêm một lệnh trước

khi phục vụ ngắt.

2.2.3.3 Thứ tự ưu tiên

Các ngắt có 2 giai đoạn ưu tiên: mức ngắt và mức tự nhiên. Mức ngắt được ưu

tiên trước mức tự nhiên.

Mức ngắt có 2 mức: thấp và cao. Ngắt có mức ưu tiên là cao sẽ có thể ngắt

ngang chương trình phục vụ ngắt có mức ưu tiên thấp hơn. Nếu các ngắt có cùng

Page 26: All_New(Luan Van Son)

- -

26

mức ưu tiên mà cùng xảy ra đồng thời, ngắt nào có mức ưu tiên tự nhiên thấp nhất

sẽ được phục vụ trước.

2.2.4 Biến đổi ADC

Bộ biến đổi ADC của CC1010 có độ phân dải 10 bit, được điều khiển bởi các

thanh ghi ADCON và ADCON2. Có ba kênh vào ADC, được chọn bởi

ADCON.ADADR. Thanh ghi này cũng được sử dụng để chọn chân AD1 như là

điện áp tham chiếu ngoài (khi sử dụng AD0). Khi chân AD1 được dùng như tham

chiếu ngoài, chỉ có hai lối vào ADC được sử dụng. Đầu ra ADC là đơn cực, nghĩa là

giá trị 0 tương ứng với 0V và 1023 tương ứng với điện áp tham chiếu (1.25 V hoặc

VDD phụ thuộc vào bit ADCREF). Điện áp tham chiếu analog được điều khiển bởi

ADCON.ADCREF. ADCON.AD_PD cần đặt bằng 1 khi không sử dụng ADC để

tiết kiệm năng lượng. Biến đổi ADC được bắt đầu sau 5µs sau khi xoá bit điều

khiển ADCON.ADCRUN khi sử dụng VDD hay nguồn tham chiếu ngoài, hoặc

100 µs khi sử dụng tham chiếu trong 1.25V.

2.2.5 Bộ định thời

CC1010 có 4 bộ định thời Timer 0, Timer 1, Timer 2, Timer 3 hoạt động như

là bộ định thời hay bộ đếm (Timer/Counter) trong đó Timer2 và Timer3 còn có thể

hoạt động như bộ điều chế độ rộng xung (PWM - Pulse Width Modulation).

2.2.5.1 Time 0/ Timer 1

Timer/Counter 0 và 1 có thể được lập trình và hoạt động độc lập theo 4 chế độ,

được điều khiển bởi các thanh ghi TMOD và TCON. Các chế độ có thể như sau:

- 13 bit Timer/Counter (Mode 0)

- 16 bit Timer/Counter (Mode 1)

- 8 bit Timer/Counter tự động nạp lại (Mode 2)

- 2 Timer 8 bit (chỉ dùng cho Timer 0, Mode 0)

Chi tiết về các chế độ, cách điều khiển sử dụng 2 thanh ghi TCON và TMOD

xin xem thêm phần Tài liệu tham khảo [6].

Page 27: All_New(Luan Van Son)

- -

27

2.2.5.2 Timer 2/ Timer 3

Ngoài tính năng như là bộ định thời, Timer 2 và 3 có thể được sử dụng như bộ

điều chế độ rộng xung PWM. Nếu xoá bit TCON2.M2/TCON2.M3 thì sẽ là bộ

định thời. Nếu thiết lập bit TCON2.M2/TCON2.M3 thì sẽ là PWM. Khi đó chân

P3.4 và chân P3.5 là chân phát xung đầu ra tương ứng cho Timer2/Timer3. Chu kỳ

TnPWM đối với Timer n như sau:

fsystem

TnPRETnP

)1.(255WM

+=

Trong đó thời gian ở trạng thái cao Tnh là:

fsystem

eTnTnTnhP

)1Pr.(WM

+=

Điều này có nghĩa là trong chế độ PWM, nếu Tn = 0 thì có mức thấp ở đầu ra và

nếu Tn = 255 thì có mức cao.

Trong đó giá trị các thanh ghi Tn và TnPRE được đặt từ trước.

2.2.6 Bộ thu phát không dây (RF Transceiver)

2.2.6.1 Miêu tả chung

Bộ thu phát CC1010 UHF RF được thiết kế cho những ứng dụng tiêu thụ năng

lượng thấp và điện áp thấp. Mạch thu phát được dành cho ISM (công nghiệp, khoa

học và y học) và SRD (Short Range Device) dải tần 315, 433, 868 và 915 MHz,

nhưng có thể dễ dàng lập trình để hoạt động trong dải tần 300-1000 MHz. Các

thông số chính của CC1010 có thể được lập trình thông qua các thanh ghi chức

năng đặc biệt (Special Function Registers - SFRs), làm cho CC1010 rất mềm dẻo và

Page 28: All_New(Luan Van Son)

- -

28

dễ sử dụng bộ thu phát vô tuyến. Rất ít các thành phần tích cực đòi hỏi cho hoạt

động của bộ thu phát RF.

Một sơ đồ khối được đơn giản hoá của bộ thu phát RF được thể hiện ở hình

2.1. Chỉ các chân tín hiệu analog được thể hiện cùng với bus dữ liệu SFR bên trong

để thiết lập giao tiếp RF và để truyền và nhận dữ liệu.

Trong chế độ nhận, tín hiệu vào RF được khuếch đại bởi bộ khuếch đại ồn

thấp (low-noise amplifier LNA) và được chuyển thành trung tần (intermediate

frequency - IF) bởi bộ trộn (MIXER). Trong giai đoạn trung tần (IF STAGE) tín

hiệu được khuếch đại và lọc trước khi đưa tới bộ giải điều chế (DEMOD). Như một

lựa chọn, một tín hiệu RSSI hay IF sau khi trộn được đưa vào AD2. Sau khi giải

điều chế, tín hiệu số được đưa tới thanh ghi RFBUF. Ngắt có thể được sinh ra theo

mỗi bit hay mỗi byte nhận được (EXIF.RFIF).

Trong chế độ truyền, dao động được điều khiển bởi điện áp (VCO) được đưa

trực tiếp tới khuếch đại công suất (PA). Đầu ra RF là khoá dịch chuyển tần số

(frequency shift keyed - FSK) bởi luồng bit được đưa tới thanh ghi RFBUF. Ngắt

có thể được sinh ra cho mỗi bit hay byte được truyền (EXIF.RFIF). Mạch chuyển

Hình 2.1. Sơ đồ khối của bộ thu phát RF

Page 29: All_New(Luan Van Son)

- -

29

bên trong T/R làm cho giao tiếp với antenna dễ dàng và sử dụng rất ít thành phần

ngoại vi.

Bộ tổ hợp tần số tạo ra dao động bên trong được đưa tới MIXER trong chế độ

nhận và PA trong chế độ truyền. Bộ tổ hợp tần số bao gồm một dao động thạch anh

(XOSC), bộ nhận biết pha (phase detector - PD), bơm nạp (CHARGE PUMP), bộ

lọc (internal loop filter - LPF), VCO, và các bộ chia tần (/R và /N). Một tinh thể

ngoài có thể được nối vào XOSC. VCO chỉ cần một cuộn cảm ngoài.

2.2.6.2 Mạch ứng dụng RF

Bộ thu phát RF đòi hỏi rất ít các ngoại vi. Một mạch ứng dụng điển hình được

thể hiện ở hình 2.2. Các giá trị của các thành phần này xin xem thêm phần Tài liệu

tham khảo [6].

Page 30: All_New(Luan Van Son)

- -

30

Tương ứng vào/ra

Cặp C31/L32 là đầu vào cho nơi nhận của bộ nhận, và nội trở của L32 có tác

dụng định thiên (bias) một chiều. C41, L41 và C42 được sử dụng để tương ứng với

bộ truyền có trở kháng 50 Ohm. Một bộ chuyển mạch trong T/R làm cho nó có khả

năng cùng nối với đầu vào và đầu ra và thích hợp với bộ thu phát 50Ω trong cả hai

chế độ RX và TX. VCO được tích hợp hoàn toàn trừ cuộn cảm L101.

Lọc

Hình 2.2. Một mạch ứng dụng CC1010 điển hình

Page 31: All_New(Luan Van Son)

- -

31

Các thành phần bên ngoài (ví dụ RF LC hay lọc răng cưa) có thể được sử dụng

để cải tiến hiệu năng cho các ứng dụng riêng biệt. Nếu lọc răng cưa được sử dụng,

nó chỉ có tác dụng cho RX (phải sử dụng chuyển mạch ngoài RX/TX).

Nguồn cung cấp

Các tụ tách và lọc nguồn cần được sử dụng (không chỉ ra trong mạch ứng

dụng). Các tụ này càng gần chân nguồn càng tốt. Vị trí và kích thước của tụ tách và

lọc nguồn là rất quan trọng để đạt được độ nhạy tốt nhất.

Chú ý rằng các giá trị hợp thành cho 868 và 915 MHz có thể là như nhau. Tuy

nhiên, rất quan trọng là cách bố trí được tối ưu hoá để lựa chọn cuộn cảm VCO để

làm cho tần số hoạt động được chính xác. Cuộn cảm VCO phải được đặt rất sát và

đối xứng với các chân tương ứng (L1 và L2). Chipcon cung cấp cách bố trí tham

khảo để đạt được hiệu năng cao nhất.

2.2.6.3 Điều khiển bộ thu phát RF và quản lý năng lượng

Thanh ghi RFMAIN điều khiển chế độ hoạt động (RX hay TX), sử dụng hai

thanh ghi tần số và các chế độ tiết kiệm năng lượng (power down). Theo cách này

CC1010 có được sự mềm dẻo để quản lý công suất RF để đạt được chính xác năng

lượng tiêu thụ đòi hỏi và các ứng dụng chỉ sử dụng pin. Các chế độ tiết kiệm năng

lượng khác nhau được điều khiển thông qua các bit riêng biệt trong thanh ghi

RFMAIN. Các bit này điều khiển phần RX, TX, bộ tổ hợp tần số và dao động thạch

anh. Sự điều khiển riêng biệt này có thể dùng để tối ưu hoá làm cho dòng tiêu thụ

thấp nhất có thể trong các ứng dụng nào đó. Một thứ tự bật nguồn điển hình để đạt

được dòng tiêu thụ thấp nhất được thể hiện ở hình 2.3. Hình vẽ giả thiết rằng tần số

A dùng cho RX và tần số B dùng cho TX. Nếu không gặp trường hợp này, đảo lại

thiết lập F_REG.

Page 32: All_New(Luan Van Son)

- -

32

2.2.6.4 Điều chế dữ liệu và các chế độ dữ liệu

Có bốn chế độ dữ liệu khác nhau được xác định cho truyền và nhận, có thể lập

trình được qua MODEM0.DATA_FORMAT. Các chế độ này khác nhau ở cách

mã hoá dữ liệu, cách dữ liệu đến và đi được và được chấp nhận, và liệu có sự đồng

bộ hoá luồng bit hay không. Định dạng dữ liệu cần được chọn trước khi bộ thu phát

RF hoạt động. Hai trong số các chế độ, chế độ đồng bộ NRZ và chế độ đồng bộ

Manchester, truyền hay nhận dữ liệu có tốc độ baud được thiết lập trong

MODEM0.BAUDRATE. Modem thực hiện việc đồng bộ hoá luồng bit trong suốt

quá trình nhận. Trong chế độ Manchester modem cũng thực hiện mã hoá và giải mã

Manchester. Các chế độ NRZ và Manchester chấp nhận và truyền dữ liệu theo cả

hai cách một bit hay một byte trong cùng một thời điểm, lập trình được qua

RFCON.BYTEMODE. Trong hầu hết các ứng dụng có hai chế độ được khuyên

RX hay TX

Bật RX: RFMAIN: RXTX=0, F_REG=0 RX_PD=0, FS_PD=0 CURRENT=”RX current” Chờ 250 µs

Bật TX: PA_POW=00h RFMAIN: RXTX=1, F_REG=1 TX_PD=0, FS_PD=0 CURRENT=”RX current” Chờ 250 µs

Chế độ RX Chế độ TX

Tắt RX: RFMAIN: RX_PD=1, FS_PD=1 Tắt TX:

RFMAIN: TX_PD=1, FS_PD=1 PA_POW=00h

Tắt RF

Tắt RF

Hình 2.3. Tuần tự bật thu phát RF

Page 33: All_New(Luan Van Son)

- -

33

dùng. Dữ liệu truyền đi hay nhận về được đặt trong thanh ghi RFBUF. Trong quá

trình truyền hay nhận cần biết có dữ liệu đến hay đi, từng bit hay từng byte phụ

thuộc vào RFCON.BYTEMODE, được báo hiệu bằng cách tạo ra (EXIF.RFIF.)

Phụ thuộc vào liệu ngắt RF được cho phép hay không (EIE.RFIE), việc truyền hay

nhận dữ liệu có thể được điều khiển bởi chương trình phục vụ ngắt hay có thể được

thực hiện bằng cách hỏi (polling). Trong quá trình nhận khi sử dụng chế độ NRZ

hay Manchester, nhận biết tín hiệu dẫn đường bằng phần cứng và nhận biết dấu

hiệu bắt đầu một frame có thể sử dụng các thanh ghi PDET và BSYNC. Hai chế độ

khác, Transparent mode và UART mode, chỉ đơn giản là truyền số liệu FSK modem

và thanh ghi RFBUF và UART0, cho phép lựa chọn tốc độ và mã hoá dữ liệu. Khi

sử dụng UART0 trong chế độ UART chân P3.1 không được sử dụng cho UART

output và có thể sử dụng như một cổng I/O. Chipcon khuyên rằng các chế độ đồng

bộ được sử dụng. Các chế độ dữ liệu khác bỏ qua mạch quyết định dữ liệu của bộ

thu phát RF và không hỗ trợ chế độ bytemode. Chế độ Transparent mode chỉ dùng

để kiểm thử.

Mã hoá Manchester

Trong chế độ Manchester data clock được truyền cùng với dữ liệu. '1' được mã

hoá bằng tần số cao f1 theo sau là tần số thấp hơn f0. '0' được mã hoá bằng tần số

thấp f0 theo sau là tần số cao hơn f1. Điều này được minh hoạ ở hình 2.4.

Hình 2.4 Mã hoá Manchester

Page 34: All_New(Luan Van Son)

- -

34

2.2.6.5 Tốc độ Baud

Tốc độ từ 0.6 kBaud tới 76.8 kBaud được thiết lập trong bit điều khiển

MODEM0.BAUDRATE. MODEM0.XOSC_FREQ cũng phải được thiết lập tuỳ

vào tinh thể thạch anh đang sử dụng. Tốc độ baud được tính theo công thức sau:

kbaudMHz

fxosc

FREQXOSCBAUDRATERF

BAUDRATE

6.0.6864.3

.1_

_ 2+

=

RF_BAUDRATE là tốc độ tính theo kBaud, BAUDRATE và XOSC_FREQ là các

bit điều khiển trong MODEM0. Sử dụng một trong các thạch anh chuẩn đặt trong

MODEM0.XOSC_FREQ sẽ tạo ra các tốc độ chuẩn 0.6, 1.2, 2.4, 4.8, 9.6, 19.2,

38.4 hay 76.8 kBaud. Các tần số thạch anh khác nhau sẽ xác định các tốc độ khác

nhau như miêu tả ở trên. Tốc độ baud tới 19.2 kBaud có thể được tạo ra cho bởi bất

kỳ tần số thạch anh nào. Tốc độ lớn hơn 19.2 kBaud cần có thêm các sự kết hợp

như bảng 2.

Bảng 2. Tốc độ baud theo tần số thạch anh

MODEM0.

BAUDRATE

/XOSC

fxosc (MHz)

RF_BAUDRATE

(kBaud)

3.6864

7.3728

11.0592

14.7456

18.4320

22.1184

0.6 0/0 0/1 0/2 0/3 0/4 0/5

1.2 1/0 1/1 1/2 1/3 1/4 1/5

2.4 2/0 2/1 2/2 2/3 2/4 2/5

4.8 3/0 3/1 3/2 3/3 3/4 3/5

9.6 4/0 4/1 4/2 4/3 4/4 4/5

Page 35: All_New(Luan Van Son)

- -

35

19.2 5/0 5/1 5/2 5/3 5/4 5/5

38.4 NA 5/0 NA 5/1 NA 5/2

76.8 NA NA NA 5/0 NA NA

2.2.6.6 Truyền và nhận dữ liệu

Trong chế độ Transparent hay UART dữ liệu đi hay đến được đưa trực tiếp tới

bộ điều chế trong chế độ truyền và được nhận trực tiếp trong chế độ nhận. Trong

các chế độ NRZ và Manchester, dữ liệu được lưu tại RFBUF như được minh hoạ ở

hình 2.5. Việc lưu như vậy có những ảnh hưởng cần được xem xét khi nhận hay

truyền dữ liệu, nhất là trong chế độ bytemode.

Quá trình truyền

Khi truyền dữ liệu theo bytemode (RFCON.BYTEMODE=1), một thanh ghi

8-bit sẽ dịch từng bit tới bộ điều chế, MSB (bit cao nhất) trước tiên, và chu kỳ phụ

thuộc vào tốc độ được lựa chọn. Khi thanh ghi dịch này rỗng sẽ nạp một byte mới

từ RFBUF tiếp tục dịch bit. Nội dung của thanh ghi RFBUF không đổi sau khi

thanh ghi dịch lấy dữ liệu từ nó. Một ngắt được tạo ra (EICON.RFI) và RFBUF có

Thanh ghi dịch 8 bit

RFBUF

Nhân 8051

Điều chế truyền không dây

Giải điều chế nhận không dây

LSB

Hình 2.5 Đệm dữ liệu RF. Đường gạch là chế độ bit

Page 36: All_New(Luan Van Son)

- -

36

thể được nạp với byte dữ liệu mới. Nếu một byte mới không được ghi vào trong chu

kỳ tám bit (chu kỳ tám bit trong chế độ NRZ và chu kỳ 16 baud trong chế độ

Manchester), thời điểm tiếp theo thanh ghi dịch rỗng sẽ lấy lại dữ liệu cũ từ

RFBUF. Chẳng hạn khi truyền một tín hiệu dẫn đường bao gồm '0' và '1' thay đổi,

nó chỉ cần ghi byte vào RFBUF một lần và chờ tới khi số các byte cần truyền tín

hiệu dẫn đường được truyền đi. Ở chế độ bitmode (RFCON.BYTEMODE=0),

cũng xảy ra tương tự, nhưng chỉ một bit tại một thời điểm. Theo đó, thanh ghi dịch

sẽ nạp bit mới từ RFBUF.0 sau khi truyền một bit đi, và ngắt RF được tạo ra để báo

có bit mới được nạp. Để có thể ghi bit tiếp theo vào RFBUF.0 trong một chu kỳ bit

ở tốc độ cao, nên sử dụng vòng quét nhanh (tight polling loop) thay vì thủ tục

truyền dựa trên ngắt. Để bắt đầu truyền dữ liệu ngay khi có thể, bit/byte đầu tiên

được truyền được ghi vào RFBUF trước khi bộ điều chế hoạt động

(RFMAIN.TX_PD=0). Nó sẽ ngay lập tức được nạp vào thanh ghi dịch và một yêu

cầu ngắt được tạo ra cho bit/byte thứ hai. Điều này đặc biệt quan trọng khi tính đến

việc lưu dữ liệu tại cuối một quá trình truyền. Khi byte cuối cùng của một frame hay

packet được nạp vào thanh ghi dịch nó vẫn không được truyền đi. Như vậy yêu cầu

ngắt được tạo ra tại cùng thời điểm không bị dừng đối với cả phần analog hay

digital của một quá trình truyền. Quá trình truyền không thể kết thúc được một cách

an toàn cho tới chu kỳ 9 bit cuối cùng trong chế độ bytemode và chu kỳ 2 bit trong

chế độ bitmode, khi bit cuối cùng được dịch và được truyền tới antenna. Một giải

pháp đơn giản là luôn luôn truyền hai byte mở rộng trong chế độ bytemode hay hai

bit mở rộng trong chế độ bitmode ở cuối quá trình truyền dữ liệu. Điều này không

gây ra vấn đề gì trong thực tế

Quá trình nhận

Khi nhận dữ liệu lược đồ đệm sẽ hoạt động ngược với quá trình truyền. Từng

bit từ bộ giải điều chế được dịch vào thanh ghi dịch 8-bit, MSB trước tiên: Khi

thanh ghi dịch đầy nó được nạp vào RFBUF và một yêu cầu ngắt được sinh ra

(EICON.RFIF). Byte cần được đọc trong chu kỳ một byte (chu kỳ 8 baud trong

chế độ NRZ và 16 baud trong chế độ Manchester). Nếu không, nó sẽ bị ghi đè bởi

byte nhận được tiếp theo và dữ liệu sẽ bị mất. Trong chế độ bitmode quá trình đệm

Page 37: All_New(Luan Van Son)

- -

37

cũng xảy ra tương tự, nhưng mỗi bit tại một thời điểm. Theo đó, khi một bit mới tới

từ bộ giải điều chế thanh ghi dịch sẽ lưu nó và lưu bit cuối cùng vào RFBUF.0, lần

lượt tạo ra các yêu cầu ngắt RF để có thể đọc các bit mới. Để có thể đọc bit tiếp

theo từ RFBUF.0 trong chu kỳ một bit ở tốc độ cao nên sử dụng vòng quét nhanh

thay vì dựa vào ngắt. Không có sự cân nhắc đặc biệt nào đối với thời điểm bắt đầu

hay kết thúc quá trình nhận.

2.2.7 Module CC1010EM

Để dễ dàng và thuận tiện cho việc phát triển các ứng dụng sử dụng CC1010,

hãng Chipcon cũng cung cấp module CC1010 EM (Evaluation module), trên đó có

tích hợp hầu hết các linh kiện cần cho việc xây dựng một nút mạng như:

- VĐK CC1010

- Dao động thạch anh

- Antena

- Một cảm biến nhiệt độ đưa vào chân AD1

- Các chân cổng

Việc xây dựng thử nghiệm trong khuôn khổ luận văn cũng dùng module

CC1010EM. Việc thử nghiệm sau này đã cho thấy rằng module này đã đáp ứng

Hình 2.6 Module CC1010EM

Page 38: All_New(Luan Van Son)

- -

38

được các chức năng cơ bản nút mạng đó là chức năng mạng và chức năng cảm

nhận. Tuy nhiên, giá thành module này còn đắt (khoảng 150USD) trong khi giá

thành VĐK CC1010 rất rẻ (khoảng 10USD) nên việc nghiên cứu chế tạo module

này ở Việt Nam để hạ giá thành là rất cần thiết.

2.3 Kết luận

Chương này đã giới thiệu các một số loại VĐK có thể được dùng làm nút

mạng trong WSN theo các tiêu chí: năng lượng tiêu thụ thấp, tính mềm dẻo, sức

mạnh của nút mạng, tính bảo mật, truyền thông, khả năng tính toán, kích thước của

nút mạng. Từ các chỉ tiêu đánh giá đó đã chọn được loại vi điều khiển CC1010 của

hãng Chipcon (Nauy) để làm nút mạng. Đây là loại vi điều khiển tương thích họ

8051 thông dụng, sử dụng ngôn ngữ lập trình C và chương trình dịch Keil

µVision2.0. Bên cạnh đó Chipcon cũng cung cấp các thư viện làm việc với CC1010

làm cho việc viết chương trình trở nên dễ dàng và thuận tiện.

Page 39: All_New(Luan Van Son)

- -

39

CHƯƠNG 3

CÁC PHƯƠNG PHÁP GHÉP NỐI VỚI CÁC LOẠI ĐẦU ĐO VÀ

CHƯƠNG TRÌNH THỰC HIỆN CHỨC NĂNG THU THẬP DỮ LIỆU

3.1 Giới thiệu cảm biến

3.1.1 Khái niệm

Trong các hệ thống đo lường điều khiển mọi quá trình đều được đặc trưng bởi

các trạng thái như nhiệt độ, áp suất, tốc độ, momen…Các biến trạng thái này

thường là các đại lượng không điện. Nhằm mục đích điều chỉnh, điều khiển các quá

trình ta cần thu thập thông tin, đo đạc, theo dõi sự biến thiên của các biến trạng thái

của quá trình. Các bộ cảm biến thực hiện chức năng này, chúng thu nhận, đáp ứng

với các tín hiệu và kích thích, là tai mắt của các hoạt động khoa học và công nghệ

của con người.

Các bộ cảm biến thường được định nghĩa theo nghĩa rộng là thiết bị cảm nhận

và đáp ứng với các tín hiệu và kích thích.

Trong mô hình mạch, ta có thể coi bộ cảm biến như một mạng hai cửa, trong

đó cửa vào là biến trạng thái cần đo x và cửa ra là đáp ứng y của bộ cảm biến với

kích thích đầu vào x.

Phương trình mô tả quan hệ giữa đáp ứng y và kích thích x của bộ cảm biến có

dạng:

y = f(x)

Trong các hệ thống đo lường - điều khiển hiện đại, quá trình thu thập và xử lý

tín hiệu thường do máy tính đảm nhiệm.

Bộ cảm biến x kích thích

y đáp ứng

Page 40: All_New(Luan Van Son)

- -

40

Trong sơ đồ hình 3.1, quá trình (đối tượng) được đặc trưng bằng các biến trạng

thái và được các bộ cảm biến thu nhận. Đầu ra của bộ vi xử lý được phối ghép với

cơ cấu chấp hành nhằm tác động lên quá trình (đối tượng). Đây là sơ đồ điều khiển

tự động (qúa trình), trong đó bộ cảm biến đóng vai trò cảm nhận, đo đạc và đánh giá

các thông số của hệ thống. Bộ vi xử lý làm nhiệm vụ xử lý thông tin và đưa ra tín

hiệu điều khiển quá trình.

3.1.2 Phân loại các bộ cảm biến

3.1.2.1 Theo nguyên lý chuyển đổi giữa đáp ứng và kích thích

Hiện tượng Chuyển đổi đáp ứng và kích thích

Vật lý Nhiệt điện

Quang điện

Quang từ

Điện từ

Quang đàn hồi

Từ điện

Nhiệt từ

Nhiệt quang

Hoá học Biến đổi hoá học

Quá trình (Các biến trạng thái)

Cơ cấu chấp hành

Bộ cảm biến

Chương trình

Bộ vi xử lý

Hình 3.1 Hệ thống tự động điều khiển qúa trình

Page 41: All_New(Luan Van Son)

- -

41

Biến đổi điện hoá

Phân tích phổ

Sinh học Biến đổi sinh hoá

Biến đổi vật lý

Hiệu ứng trên cơ thể sống

Phân tích phổ

3.1.2.2 Theo dạng kích thích

Kích thích Các đặc tính của kích thích

Âm thanh - Biên, pha, phân cực

- Phổ

- Tốc độ truyền sóng

Điện - Điện tích, dòng điện

- Điện thế, điện áp

- Điện trường

- Điện dẫn, hằng số điện môi

Từ - Từ trường (biên, pha, phân cực, phổ)

- Từ thông, cường độ từ trường

- Độ từ thẩm

Quang - Biên, pha, phân cực, phổ

- Tốc độ truyền

- Hệ số phát xạ, khúc xạ

Page 42: All_New(Luan Van Son)

- -

42

- Hệ số hấp thụ, hệ số bức xạ

Cơ - Vị trí

- Lực, áp suất

- Gia tốc, vận tốc

- Ứng suất, độ cứng

- Momen

- Khối lượng, tỷ trọng

- Vận tốc chất lưu, độ nhớt

Nhiệt - Nhiệt độ

- Thông lượng

- Nhiệt dung, tỷ nhiệt

Bức xạ - Kiểu

- Năng lượng

- Cường độ

3.1.2.3 Theo tính năng

- Độ nhạy

- Độ chính xác

- Độ phân giải

- Độ chọn lọc

- Độ tuyến tính

- Công suất tiêu thụ

- Dải tần

- Khả năng quá tải

- Tốc độ đáp ứng

- Độ ổn định

- Tuổi thọ

- Điều kiện môi trường

- Kích thước, trọng lượng

Page 43: All_New(Luan Van Son)

- -

43

- Độ trễ

3.1.2.4 Theo phạm vi sử dụng

- Công nghiệp

- Nghiên cứu khoa học

- Môi trường, khí tượng

- Thông tin, viễn thông

- Nông nghiệp

- Dân dụng

- Giao thông

- Vũ trụ

- Quân sự

3.1.2.5 Theo thông số mô hình mạch thay thế

Các bộ cảm biến có thể phân chia theo thông số:

- Cảm biến tích cực (có nguồn) đầu ra là nguồn áp hoặc nguồn dòng.

- Cảm biến thụ động (không nguồn) được đặc trưng bởi các thông số

R,L,C,M… tuyến tính hoặc phi tuyến.

3.1.2.6 Theo dạng tín hiệu đầu ra

- Cảm biến có đầu ra là tín hiệu tương tự

- Cảm biến đầu ra là tín hiệu số

3.1.3 Các đặc trưng cơ bản của bộ cảm biến

3.1.3.1 Hàm truyền

Quan hệ giữa đáp ứng và kích thích của bộ cảm biến có thể cho dưới dạng

bảng giá trị, đồ thị hoặc biếu thức toán học. Gọi x là kích thích, y là tín hiệu đáp

ứng, hàm truyền cho ta quan hệ giữa đáp ứng và kích thích. Hàm truyền có thể được

biểu diễn dưới dạng tuyến tính, phi tuyến, logarit, hàm luỹ thừa hoặc hàm mũ

Page 44: All_New(Luan Van Son)

- -

44

Quan hệ tuyến tính giữa đáp ứng và kích thích có dạng:

y = ax + b

Ở đây a là hằng số bằng tín hiệu ra khi tín hiệu vào bằng không, b là độ nhạy,

y là một trong các đặc trưng của tín hiệu ra, có thể là biên độ, tần số hoặc pha tuỳ

theo các tính chất của bộ cảm biến

Hàm truyền logarit có dạng:

y = 1 + blnx

Dạng mũ:

y = aekx

Dạng luỹ thừa:

y = ao + a1xk với k là hằng số

Các bộ cảm biến phi tuyến không thể được đặc trưng bằng các hàm truyền kể

trên, trong trường hợp này ta phải sử dụng các hàm gần đúng bậc cao.

Đối với hàm truyền phi tuyến hoặc hàm truyền ở chế độ động, độ nhạy b phải

được định nghĩa theo biểu thức:

dx

xodyb

)(=

Trong nhiều trường hợp ta có thể làm gần đúng hàm truyền phi tuyến bằng

phương pháp tuyến tính hoá từng đoạn

3.1.3.2 Độ lớn của tín hiệu vào

Là giá trị lớn nhất của tín hiệu đặt vào bộ cảm biến mà sai số không vượt quá

ngưỡng cho phép.

3.1.3.3 Sai số và độ chính xác

Các bộ cảm biến cũng như các dụng cụ đo lường khác, ngoài đại lượng cần đo

(cảm nhận) còn chịu tác động của nhiều đại lượng vật lý khác gây nên sai số giữa

Page 45: All_New(Luan Van Son)

- -

45

giá trị đo được và giá trị thực của đại lượng cần đo. Gọi ∆x là độ lệch tuyệt đối giữa

giá trị đo và giá trị thực x, sai số tương đối của bộ cảm biến được tính bằng:

Δ% = 100.x

x∆

Khi đánh giá sai số của cảm biến ta thường phân chúng thành hai loại: sai số

hệ thống và sai số ngấu nhiên.

Sai số hệ thống là sai số không phụ thuộc vào số lần đo, có giá trị không đổi

hoặc thay đổi chậm theo thời gian đo và thêm vào một độ lệch không đổi giữa giá

trị thực và giá trị đo được. Sai số hệ thống thường do sự thiếu hiểu biết về hệ đo, do

điều kiện sử dụng không tốt

Sai số ngẫu nhiên là sai số xuất hiện có độ lớn và chiều không xác định.

3.1.4 Cảm biến số nối tiếp và cách ghép nối

Nhìn chung cảm biến là một thiết bị được thiết kế thu thập thông tin về một

đối tượng và chuyển đổi thành tín hiệu điện. Một cảm biến cổ điển có thể chia làm 4

phần như hình 3.2. Khối đầu tiên là khối cảm nhận (ví dụ, điện trở, điện dung, bán

dẫn, vật liệu áp điện, photodiode, cầu điện trở, …). Tín hiệu từ phần cảm nhận

thường bị ảnh hưởng bởi nhiễu. Do đó, cần có các kỹ thuật xử lý tín hiệu như

khuếch đại, tuyến tính hoá, bù và lọc để giảm những tác động đó.

Nếu có nhiều thành phần cảm nhận được sử dụng trong cùng một chip, cần

phải có bộ hợp kênh. Trong trường hợp thu thập dữ liệu, tín hiệu từ cảm biến có

dạng nối tiếp hay song song. Chức năng này có thể nhận ra bởi bộ biến đổi tương

tự-số hay tần số-số. Khối cuối cùng là bus giao tiếp cảm biến. Một hệ thống thu

thập dữ liệu có thể có cấu hình dạng hình sao trong đó mỗi cảm biến được nối với

một bộ hợp kênh số. Khi sử dụng số lượng lớn các cảm biến, tổng độ dài cáp và số

Thành phần cảm nhận

Xử lý tín hiệu Chuyển đổi A/D

Bus giao tiếp Máy tính

Hình 3.2. Cảm biến tích hợp

Page 46: All_New(Luan Van Son)

- -

46

các kết nối tại bộ hợp kênh có thể rất lớn. Vì lý do đó cần có hệ thống tổ chức bus,

nối tất cả các dữ liệu nguồn với các nơi nhận. Hệ thống bus điều khiển tất cả các dữ

liệu truyền và được nối tới một giao tiếp phù hợp mà cảm biến có thể gửi dữ liệu tới

máy tính.

Sơ đồ giao tiếp của cảm biến số nối tiếp với vi điều khiển được thể hiện ở hình

3.3. Một vi điều khiển thường sử dụng xử lý tín hiệu số (ví dụ, lọc số), chuyển đổi

tương tự-số, tần số-mã, tính toán và các chức năng giao tiếp. Vi điều khiển có thể

kết hợp hay trang bị với các giao tiếp chuẩn. Nhiều vi điều khiển có cả bus giao tiếp

2 dây I2C, có thể truyền với khoảng cách ngắn (vài mét) hay giao diện nối tiếp RS-

232/485 cho truyền khoảng cách dài.

Cảm biến số nối tiếp khác cảm biến tương tự ở bus giao tiếp. Cảm biến tương

tự thường đưa tín hiệu tương tự dạng dòng điện hay điện áp về vi điều khiển, sau đó

vi điều khiển phải thực hiện việc chuyển đổi tương tự-số rồi mới đọc dữ liệu. Còn

trong cảm biến số nối tiếp, việc chuyển đổi tương tự-số được thực hiện ngay trong

cảm biến, giá trị chuyển đổi sau đó được đưa về vi điều khiển dưới dạng các xung

nối tiếp thể hiện giá trị của cảm biến. Điều này sẽ khắc phục được nhiễu tác động

lên bus giao tiếp.

Để gửi lệnh đọc dữ liệu cho cảm biến, vi điều khiển trước tiên phải xác lập

xung dữ liệu DATA, sau đó phát xung đồng bộ SCK. Việc gửi các xung dữ liệu

được thực hiện cho tới khi bit cuối cùng của DATA được gửi đi. Khi đọc dữ liệu từ

cảm biến thì vi điều khiển phải phát xung SCK trước, sau đó đọc giá trị xung dữ

Vi điều khiển Cảm biến

GND

Vcc

DATA

SCK

Hình 3.3. Sơ đồ giao tiếp điển hình giữa vi điều khiển và cảm biến số nối tiếp

Page 47: All_New(Luan Van Son)

- -

47

liệu dạng bit từ cảm biến. Các bit dữ liệu nhận được sau đó sẽ được kết hợp lại

thành dữ liệu dạng byte

Thông thường, để đọc dữ liệu từ cảm biến số nối tiếp theo các bước sau:

- Vi điều khiển gửi tín hiệu Start cho cảm biến để bắt đầu quá trình đọc dữ

liệu. Tín hiệu Start thường là một chuỗi xung có định dạng

- Khi cảm biến nhận được tín hiệu này sẽ khởi tạo lại các tham số. Sau khi

khởi tạo xong, cảm biến gửi lại thông báo ACK cho vi điều khiển.

- Vi điều khiển sau khi nhận được ACK từ cảm biến sẽ gửi lệnh đọc dữ liệu

cho cảm biến.

- Cảm biến khi nhận được lệnh đọc dữ liệu từ vi điều khiển sẽ thu thập dữ liệu,

biến đổi AD rồi truyền dữ liệu dạng số về cho vi điều khiển.

Các ưu điểm của cảm biến số nối tiếp:

- Năng lượng tiêu thụ thấp: năng lượng tiêu thụ của cảm biến chủ yếu xảy ra

lúc lấy thông tin và thực biến đổi A/D. Bằng việc cho phép/không cho phép

đọc dữ liệu sẽ kiểm soát được năng lượng tiêu thụ. Khi cảm biến không làm

việc thì năng lượng tiêu thụ là thấp nhất.

- Khả năng chống nhiễu lớn: cảm biến sử dụng đường truyền số, do vậy rất

khó bị ảnh hưởng bởi nhiễu lúc truyền số liệu.

- Độ chính xác cao: Việc tự chuẩn hoá cho phép giảm sai số hệ thống. Việc sử

dụng thuật toán thống kê và các thuật toán trung bình trọng số cho phép làm

giảm sai số ngẫu nhiên gây nên bởi nhiễu.

DATA

SCK

Hình 3.4. Quan hệ giữa xung đồng bộ SCK và xung dữ liệu DATA

Page 48: All_New(Luan Van Son)

- -

48

- Giao tiếp đơn giản, chỉ dùng ít dây: cảm biến số truyền nối tiếp nên chỉ dùng

ít dây để truyền dữ liệu. Thông thường, để giao tiếp dữ liệu với vi điều khiển

chỉ cần 2 đường tín hiệu, một đường là xung đồng bộ do vi điều khiển phát

ra, một đường là dữ liệu đọc về.

- Dải đo rộng.

- Kích thước nhỏ.

3.2 Ghép nối giữa CC1010 với các loại cảm biến:

3.2.1 Ghép nối với cảm biến áp suất MS5535:

Cảm biến áp suất MS5535 cũng là cảm biến số nối tiếp. Nó cũng có cùng

nguyên tắc làm việc như cảm biến số nối tiếp đã giới thiệu ở trên. Tuy nhiên nó

cũng có sự khác biệt. Đó là chân dữ liệu DATA có 2 chân là DIN và DOUT, đồng

thời có thêm 1 chân Master Clock (MCLK) để làm xung nhịp cho MS5535. Sơ đồ

giao tiếp giữa vi điều khiển CC1010 và MS5535 như sau:

Trong đó:

MCLK: Master Clock của MS5535

DIN: chân dữ liệu vào cho MS5535

DOUT: chân dữ liệu ra cho MS5535

MS-5535

MCLK

DIN

DOUT

SCLK

GND

VDD VDD

P3.4

GND

P1.1

P0.3

P1.0

CC1010EM

Hình 3.5. Sơ đồ giao tiếp giữa MS-5535 và CC1010

3.3 VDC

Page 49: All_New(Luan Van Son)

- -

49

SCLK: Serial Clock, đồng bộ quá trình đọc ghi dữ liệu cho MS5535

Trong sơ đồ trên hình 3.5, các cổng P0.3 được định nghĩa làm cổng vào dữ

liệu, P1.0, P1.1, và P3.4 làm cổng ra dữ liệu. Để xử lý tình huống này, sử dụng các

lệnh chương trình như sau:

clr P1DIR.0 ;for SCLK MS5535

clr P1DIR.0 ;for DIN MS5535

setb P0DIR.3 ;for DOUT MS5535

clr P2DIR.3 ;for MSCLK MS5535

Trong đó ghi mức “1” ra cổng P0.0 các lệnh được hiểu như sau:

clr P0DIR.0 ; đặt bit hướng là ghi ra

setb P0.0 ; xuất dữ liệu

Giá trị dữ liệu và tín hiệu trên các cổng vào ra này được xác định nhờ sử

dụng các bộ định thời/đếm và chế độ ngắt của vi mạch CC1010.

Các bộ định thời, các ngắt, tín hiệu SCLK, MCLK và đầu đo MS-5535.

CC1010 có 4 timer/counter trong đó có 2 timer/counter theo chuẩn 8051, 2

Timer còn lại là timer 3 và timer 4, hoạt động ở chế độ timer hoặc chế độ điều chế

độ rộng xung PWM (Pulse Width Modultion). Timer 2 /Timer 3 làm việc ở chế độ

PWM khi thiết lập bit TCON2.M2/TCON2.M3. Các cổng P3.4 / P3.5 lúc này là

các lối ra, thông qua việc lập các bit hướng P3DIR.4 / P3DIR.5. Chu kỳ PWM

TnPWM đối với timer n được tính là:

fsystem

eTnTnP

)1Pr.(255WM

+=

Trong đó thời gian ở trạng thái cao Tnh là:

fsystem

eTnTnTnhP

)1Pr.(WM

+=

Điều này có nghĩa là trong chế độ PWM, nếu Tn = 0 thì có mức thấp ở đầu ra

và nếu Tn = 255 thì có mức cao. Trong sơ đồ hình 3.6, Timer2 ở chế độ PWM tạo

Page 50: All_New(Luan Van Son)

- -

50

xung Master clock. cho MS-5535, tần số 29kHz. Tần số này phát trên cổng P3.4

bằng các lệnh:

orl TCON2,#0x01 ;đặt Timer 2 ở chế độ PWM

mov T2Pre,#1 ;đặt chu kỳ PWM bằng 29kHz

mov T2,#128 ;xung vuông đối xứng

setb TR2 ;bắt đầu phát xung

Làm tương tự như vậy cũng thu được chuỗi xung SCLK phát trên cổng P1.0.

Chương trình thực hiện

Chương trình làm việc với MS5535 theo các bước sau:

Bước 1: Khởi tạo MS5535.

- Đặt bit hướng P3.4, P1.1, P1.0 là hướng xuất dữ liệu ra (output) tương

ứng là các chân MCLK, DIN và SCLK của MS5535.

- Đặt bit hướng P0.3 là hướng đọc dữ liệu vào tương ứng (input) là chân

DOUT của MS5535.

- Phát xung tần số 29 kHz ra cổng P3.4 để làm Master Clock cho MS5535.

- Đọc các hệ số bù nhiệt của MS5535.

Bước 2: Đọc các tham số áp suất và nhiệt độ của MS5535.

- Reset MS5535.

- Phát lệnh cho MS5535. Lệnh ở đây có thể là đọc nhiệt độ hay áp suất.

- Đọc giá trị trả về từ MS5535.

Hình 3.6. Giản đồ chu kỳ xung của PWM

Page 51: All_New(Luan Van Son)

- -

51

- Dựa trên giá trị trả về và các hệ số đọc được ở bước 1, tính giá trị nhiệt

độ và áp suất tương ứng.

Chi tiết về làm việc với đầu đo áp suất MS5535 xin xem thêm phần tham khảo

[13] và chương trình ở phần phụ lục.

3.2.2 Ghép nối với cảm biến nhiệt độ dạng tương tự

ADCi: ADC0, ADC1, ADC2

Các lối vào AD0, AD1, AD2 của CC1010 có điện áp tham chiếu chọn là

1,25V hoặc VDD, sử dụng chung một ADC trên cơ sở hợp kênh lối vào. Thí dụ,

trong hệ thống nói trên, lối ra của đầu đo nhiệt độ được đưa tới AD0 và chương

trình khởi tạo qúa trình chuyển đổi tương tự số qua ADC phải tiến hành bằng lệnh:

mov ADCON,#0Ch

tức là chọn kênh AD0, điện áp tham chiếu 1,25V internal, bộ biến đổi ADC

ở chế độ hoạt động (active ADC). Lệnh bắt đầu chuyển đổi ADC:

setb ADCRUN

Khi ADC thực hiện xong việc chuyển đổi tương tự-số, bit ADCRUN được

xóa tự động. Thời gian đợi chuyển đổi thể hiện qua việc quét bit ADCRUN:

jb ADCRUN,$

Giá trị chuyển đổi đọc ở 2 thanh ghi ADDATL(7:0) và ADDATH(9:8). Giá

trị đọc được từ 0 đến 1023 tương ứng với điện áp lối vào từ 0 vôn đến 1,25 vôn.

Chương trình thực hiện

Chương trình đọc giá trị ADC thực hiện theo các bước sau:

Cảm biến CC1010

VDD VDD

GND GND

ADCi

Hình 3.7. Sơ đồ ghép nối giữa VĐK và cảm biến tương tự

Page 52: All_New(Luan Van Son)

- -

52

Bước 1: Khởi tạo ADC

- Đặt bộ biến đổi ADC về chế độ single.

- Đặt điện áp tham chiếu là 1,25V

Bước 2: Đọc giá trị ADC

- Chọn kênh ADC

- Ra lệnh đọc ADC

- Chờ cho ADC biến đổi xong

- Đọc giá trị chuyển đổi

3.3 Kết luận:

Chức năng cảm nhận là một trong những chức năng chính của một nút mạng

trong WSN. Do đó nút mạng cần phải có khả năng ghép nối được với nhiều loại

cảm biến khác nhau.

Chương III đã giới thiệu tổng quan về cảm biến nói chung và các bước cụ thể

để giao tiếp giữa vi điều khiển và cảm biến số nối tiếp. Đồng thời đã xây dựng được

cách làm việc cụ thể với cảm biến áp suất MS5535 cũng là loại cảm biến số nối

tiếp. Việc giao tiếp giữa cảm biến số nối tiếp được thực hiện qua các chân cổng của

CC1010. Còn việc giao tiếp giữa cảm biến tương tự với vi điều khiển được thực

hiện qua 3 lối vào tương tự của CC1010, đó là các chân AD0, AD1, AD2. Qua đó

cho thấy rằng CC1010 hoàn toàn có thể làm việc được với nhiều loại cảm biến khác

nhau, bao gồm cả cảm biến tương tự và cảm biến số.

Page 53: All_New(Luan Van Son)

- -

53

CHƯƠNG 4

PHẦN MỀM NHÚNG

4.1 Phần mềm nhúng

4.1.1 Tổng quan về phần mềm nhúng

Phần mềm nhúng đang có những bước đột phá mới, tạo ra những cuộc cách

mạng triệt để trong tương lai. Lý do của sự phát triển này xuất phát từ những nhu

cầu bức thiết của thực tế và những bước tiến mạnh mẽ trong công nghệ phần cứng.

Một phần mềm nhúng phải kết hợp chặt chẽ với môi trường của nó bao gồm phần

cứng và các hệ thống liên quan. Nó có những ràng buộc về tốc độ xử lý, dung lượng

bộ nhớ và mức tiêu thụ điện năng... Một phần mềm nhúng tốt là phần mềm phải

đảm bảo các yếu tố trên và đó cũng là hướng phát triển quan trọng của các phần

mềm nhúng. Điểm mấu chốt của các phần mềm nhúng ngày nay là việc lựa chọn

các phương pháp thực thi của một chức năng giống như một thành phần phần cứng

nhưng theo một cách riêng. Vì vậy mà không thể bỏ đi các tính năng “cứng” của

phần mềm như các phần mềm truyền thống khác. Một phần mềm nhúng ngày nay

được phát triển theo cách sau:

o Liên kết phần mềm nhúng từ dưới lên trên, từ các lớp trừu tượng đến các

chức năng hệ thống.

o Liên kết phần mềm nhúng với các nền lập trình được - các nền hỗ trợ nó

cung cấp các phương tiện cần thiết để đánh giá xem các ràng buộc đưa ra

có thỏa mãn hay không.

Để làm được như vậy thì thực chất cần phải phát triển các kỹ thuật hình thức ở

mức trừu tượng để có những đánh giá sớm cùng với các nhóm công cụ và phương

pháp đúng đắn. Mặt khác cũng cần phải xem xét phần mềm nhúng và kiến trúc phần

cứng của nó trong một tổng thể cân đối. Do phải thỏa mãn nhiều yếu tố khác nhau

về phần cứng, môi trường, giá thành, hiệu năng nên tồn tại nhiều thách thức trong

phát triển phần mềm nhúng ngày nay, như:

o Tăng cường việc tái sử dụng.

Page 54: All_New(Luan Van Son)

- -

54

o Đồng thiết kế phần cứng, phần mềm.

o Xây dựng mô hình các thuộc tính phi chức năng.

o Chuyển đổi các phần mềm thành các dịch vụ thông qua các thành phần

phần mềm.

o Kiến trúc hệ thống và kiến trúc phần mềm.

o Đánh giá và kiểm định mức hệ thống.

o Tương thích phần cứng và phần mềm nhờ các cấu trúc có thể định cấu

hình lại và các thành phần Plug and Play.

o Xây dựng các hệ thống có khả năng tổ hợp được nhờ các thành phần phần

mềm có thể tái sử dụng.

4.1.2 Các bước cơ bản xây dựng một phần mềm nhúng

Phần mềm nhúng viết cho các họ vi xử lý có thể sử dụng các ngôn ngữ khác

nhau như C/C++ hoặc Assembler. Tuỳ theo tiêu chí xây dựng hệ thống mà lựa chọn

ngôn ngữ thích hợp. Từ đó cũng chọn chương trình dịch thích hợp. Ngày nay, do

nhu cầu phát triển hệ thống nhanh, bảo trì dễ dàng nên ngôn ngữ được lựa chọn

thường là ngôn ngữ cấp cao như C/C++.

Quy trình xây dựng một phần mềm bất kỳ thường trải qua các bước sau:

- Tìm hiểu bài toán

- Phân tích

- Thiết kế

- Viết chương trình

- Kiểm thử

Việc xây dựng phần mềm nhúng cũng tuân theo trình tự các bước như trên.

Ngoài ra, phần mềm nhúng còn có đặc trưng là làm việc trực tiếp với phần cứng. Do

đó để kiểm soát quá trình làm việc với các thành phần chấp hành có đúng đắn hay

không là điều đặc biệt quan trọng.

Page 55: All_New(Luan Van Son)

- -

55

4.1.3 Phần mềm nhúng viết cho CC1010

Phần mềm nhúng viết cho CC1010 được viết bằng ngôn ngữ C, sử dụng các

thư viện cho CC1010 do hãng Chipcon cung cấp, chương trình biên dịch Keil

uVision 2.0

Chương trình dịch Keil uVision 2.0 do hãng Keil Elektronik GmbH xây dựng

là một môi trường phát triển tích hợp (IDE) dùng để xây dựng các chương trình cho

các họ VĐK tương thích 8051 của Intel. Đây là bộ chương trình dịch cho phép

người viết chương trình soạn thảo chương trình, dịch chương trình và gỡ lỗi trên

cùng một môi trường. Chương trình dịch hỗ trợ cho cả ngôn ngữ C và Assembly.

Hãng Chipcon cũng cung cấp bộ thư viện CC1010IDE hỗ trợ cho việc xây

dựng phần mềm cho VĐK CC1010. Đây là bộ thư viện giúp cho việc xây dựng

chương trình cho CC1010 được dễ dàng và nhanh chóng.

CC1010IDE dựa trên công cụ phát triển “uVision2” của hãng Keil ™

Elektronik GmbH. Công cụ này cung cấp một khung (framework) cho hầu hết các

đặc điểm của CC1010IDE và cũng hỗ trợ hầu hết cho các VĐK họ 8051. Trình soạn

thảo là một công cụ chủ yếu để soạn thảo các file nguồn và file hợp ngữ. Nó cũng

cung cấp các chức năng trợ giúp khác như giao diện đồ hoạ (Graphic User Interface

- GUI), cần cho mô phỏng/gỡ lỗi (mã lệnh dạng hợp ngữ, thanh ghi, bộ nhớ, các cửa

sổ theo dõi, bước lệnh, …). Thêm vào đó, IDE cũng cung cấp các giao diện với thư

viện liên kết động (Dynamic Linking Library – DLL) được sử dụng để mô phỏng và

gỡ lỗi trên mạch. Một điểm đặc biệt của bộ dịch là có thể chuyển các file nguồn

được viết bằng C sang dạng hợp ngữ, để sau đó có thể tối ưu hoá mã lệnh. Dạng

hợp ngữ sau đó được chuyển thành các file đối tượng (mã máy hoặc dữ liệu nhị

phân). Cuối cùng, bộ liên kết đưa ra dạng file thực thi dạng Intel HEX và có thể nạp

vào bộ nhớ Flash của VĐK.

Mô hình của một phần mềm nhúng viết cho CC1010 như sau:

Page 56: All_New(Luan Van Son)

- -

56

Các file định nghĩa phần cứng - Hardware Definition Files (HDF)

Các file định nghĩa phần cứng định nghĩa địa chỉ các thanh ghi, ánh xạ vectơ

ngắt và các hằng số phần cứng khác. Chúng cũng thường dùng các macro cho

CC1010EB, và các định nghĩa hỗ trợ hợp ngữ và ngôn ngữ C.

Thư viện phần cứng - Hardware Abstraction Library (HAL)

Để hỗ trợ việc phát triển chương trình nhanh chóng và dễ dàng, Chipcon

cung cấp thư viện các macro và các hàm truy cập phần cứng C1010 dễ dàng. Những

thư viện này nằm trong Thư Viện Phần Cứng (HAL) và thi hành một giao tiếp phần

cứng trừu tượng đối với chương trình người dùng. Nhờ đó chương trình người dùng

có thể truy cập ngoại vi của vi điều khiển, thông qua các lời gọi hàm/macro, mà

không cần hiểu chi tiết về phần cứng.

Thư viện HAL hỗ trợ các chức năng sau:

- Truyền nhận không dây

- Đo cường độ RSSI

- Truyền nhận RS232

- Làm việc với ADC

- Xử lý thời gian thực

- Mã hoá DES

- Thiết lập các bộ định thời

- Làm việc với các cổng

Chương trình ứng dụng

Các file định nghĩa phần cứng (Hardware definition file - HDF)

Thư viện phần cứng (Hardware abstraction library – HAL)

Thư viện tiện ích Chipcon (Chipcon utility library-CUL)

Thư viện C chuẩn

Page 57: All_New(Luan Van Son)

- -

57

Thư viện tiện ích Chipcon - Chipcon Utility Library (CUL)

Bên cạnh module HAL CC1010IDE cũng cung cấp một thư viện cho truyền

thông RF đặt trong Thư Viện Tiện Ích (CUL). Thư viện này thường dùng cho các

ứng dụng RF điển hình, và cung cấp một giao thức RF đầy đủ.

Thư viện CUL hỗ trợ các chức năng sau:

- Truyền nhận không dây

- Tính toán Mã dư vòng (CRC)

- Xử lý Thời gian thực (Realtime Clock)

Cả hai thư viện HAL và CUL đều hỗ trợ Truyền nhận không dây và xử lý thời

gian thực. Tuy nhiên, các hàm ở thư viện CUL làm việc ở mức cao hơn, người viết

chương trình cũng dễ dàng và tiện lợi hơn, nhưng bù lại cũng kém mềm dẻo hơn so

với sử dụng các hàm ở thư viện HAL. Do vậy, đối với những ứng dụng đòi hỏi sự

phức tạp thì thường dùng thư viện HAL.

Phần mềm WSN viết cho CC1010

Phần mềm viết cho nút mạng cho WSN cần thực hiện những chức năng cơ

bản sau:

o Cảm nhận

o Tính toán

o Truyền thông

Một thách thức là phải thực hiện tất cả những công việc trên vào một VĐK bị

ràng buộc về mặt tài nguyên. Điều đó đòi hỏi chương trình viết càng ngắn và càng

tốn ít bộ nhớ càng tốt, trong khi vẫn đảm bảo việc viết chương trình nhanh, bảo trì

và nâng cấp dễ dàng.

Việc thực hiện cảm nhận và tính toán đã được đề cập chi tiết tại chương III.

Còn thực hiện việc truyền thông, chương trình sử dụng các hàm trong bộ thư viện

HAL của Chipcon.

Chương trình truyền thông cho CC1010 thực hiện theo các bước sau:

Page 58: All_New(Luan Van Son)

- -

58

o Khởi tạo RF: thiết lập tần số RF, tốc độ truyền, cách điều chế tín

hiệu, công suất phát. Trong chương trình cụ thể, các thông số trên lần lượt có

giá trị là: 868MHz, 2.4kb/s, mã hoá Manchester, 4 dBm. Các khai báo này

được đặt trong một cấu trúc RF_SETTINGS được khai báo như sau:

RF_RXTXPAIR_SETTINGS code RF_SETTINGS =

0x4B, 0x2F, 0x15, // Modem 0, 1 and 2: Manchester, 2.4 kBaud

0x75, 0xA0, 0x00, // Freq A

0x58, 0x32, 0x8D, // Freq B

0x01, 0xAB, // FSEP 1 and 0

0x40, // PLL_RX

0x30, // PLL_TX

0x6C, // CURRENT_RX

0xF3, // CURRENT_TX

0x32, // FREND

0xFF, // PA_POW 4dBm

0x00, // MATCH

0x00, // PRESCALER

;

Việc khởi tạo RF theo các bước trình tự sau:

halRFCalib(&RF_SETTINGS, &RF_CALDATA); //chuẩn hoá RF

INT_GLOBAL_ENABLE (INT_OFF); //cấm ngắt toàn cục

INT_SETFLAG (INUM_RF, INT_CLR); //xoá ngắt RF

INT_PRIORITY (INUM_RF, INT_HIGH); //mức ưu tiên ngắt RF là cao

RF_SET_BYTEMODE(); //RF hoạt động ở chế độ byte

RF_SET_PREAMBLE_COUNT(PREAMBLE_BYTE_COUNT); //thiết lập số

//byte dẫn đường

Page 59: All_New(Luan Van Son)

- -

59

RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE);//thiết lập byte đồng bộ

MODEM1=(MODEM1&0x03)|0x24; //lọc trung bình

// Reset preamble detection

PDET &= ~0x80;

PDET |= 0x80;

INT_ENABLE (INUM_RF, INT_OFF); //cấm ngắt ngắt RF

INT_GLOBAL_ENABLE (INT_ON); //cho phép ngắt toàn cục

o Nhận dữ liệu RF: việc nhận dữ liệu RF thông qua ngắt. Mỗi khi nhận

được một byte, VĐK sinh ra một ngắt. Chương trình xử lý ngắt có nhiệm vụ

đưa byte này vào một bộ đệm. Khi toàn bộ gói tin đã nhận xong, ngắt này bị

cấm để chờ xử lý xong bộ đệm.

Quá trình nhận một byte từ bộ đệm RFBUF vào bộ đệm chương trình như sau:

//nhận một byte từ RFBUF vào bộ đệm rf_rx_buf tại vị trí rf_rx_index;

rf_rx_buf[rf_rx_index] = RF_RECEIVE_BYTE();

rf_rx_index++; //tăng chỉ số lên 1

Byte đầu tiên của bộ đệm chương trình rf_rx_buf[0] lưu độ dài gói tin.

Việc nhận dữ liệu kết thúc khi rf_rx_index bằng giá trị độ dài gói tin, nghĩa là:

rf_rx_index = rf_rx_buf[0];

Sau khi toàn bộ gói tin RF đã nhận được, chương trình sẽ phân tích gói

tin, lọc ra các dữ liệu cần thiết. Nếu là nút Master, nó sẽ truyền dữ liệu nhận

được về PC qua cổng RS232. Nếu là Slave, nó sẽ thực hiện việc cảm nhận,

tính toán rồi truyền dữ liệu về Master.

o Truyền dữ liệu RF: việc truyền dữ liệu RF được thực hiện bởi các

hàm/macro trong thư viện HAL của Chipcon như sau:

halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA);//turn on

TX

Page 60: All_New(Luan Van Son)

- -

60

RF_START_TX(); //bắt đầu truyền

halRFSendPacket(PREAMBLE_BYTE_COUNT,&txDataBuffer[0], 4);

//truyền dữ liệu tại txDataBuffer với độ dài là 4

halRFSetRxTxOff(RF_RX,&RF_SETTINGS,&RF_CALDATA);//turn on

//RX

RF_START_RX(); // bắt đầu chế độ nhận

INT_SETFLAG (INUM_RF, INT_CLR); //xoá cờ ngắt RF

INT_ENABLE (INUM_RF, INT_ON); //cho phép ngắt RF

4.1.4 Gỡ lỗi

4.1.4.1 Giới thiệu

Gỡ lỗi là một phần không thể thiếu khi phát triển phần mềm, đặc biệt là phần

mềm nhúng. Việc gỡ lỗi cẩn thận, chi tiết giúp cho phát hiện những lỗi chương trình

mà người viết nhiều khi không lường hết được, điều đó giúp cho chương trình có độ

ổn định và tin cậy cao. Ngoài việc kiểm tra tính đúng đắn của thuật toán hay các kết

quả nhận được sau khi xử lý dữ liệu nào đó, gỡ lỗi còn cho phép biết cụ thể sự làm

việc giữa chương trình với thành phần chấp hành tại từng tình huống cụ thể. Điều

đó cho phép người viết chương trình biết đoạn chương trình đó có đúng theo thiết

kế hay không.

Có ba dạng gỡ lỗi đang được dùng phổ biến, đó là:

- Giám sát ROM (ROM Monitor)

- Mô phỏng trên mạch (In-circuit Emulator)

- Gỡ lỗi trên chip (On-chip debug)

Trước khi xét từng trường hợp cụ thể trên, hãy xét các định nghĩa sau:

Code Dowload nạp chương trình từ PC xuống bộ nhớ hệ thống đích (RAM hoặc

flash ROM) với mục đích là thực thi chương trình

Go/Halt/Step Cho phép điều khiển thực thi của mã lệnh trong trình gỡ lỗi

Page 61: All_New(Luan Van Son)

- -

61

CodeBreakpoints Cho phép dừng chương trình thực thi khi lệnh đã chỉ ra được

thực hiện. Breakpoints thường hoạt động bằng cách chèn một lệnh đặc biệt tại vị trí

cần theo dõi (còn được gọi là Software breakpoints) hay giám sát các bus của vi

điều khiển sử dụng một bộ so sánh và dừng chương trình khi một lệnh cụ thể được

thực hiện (Hardware breakpoints)

Data Access Breakpoints. Cho phép dừng chương trình khi một vị trí bộ nhớ được

truy cập để đọc hay ghi.

Complex/Advanced Breakpoints. Cho phép mô tả breakpoints ví dụ một dải địa

chỉ được chỉ ra hay một mặt nạ được sử dụng cho phép thiết lập các điều kiện

“không quan tâm”. Hơn nữa, một breakpoint chỉ xuất hiện khi một chuỗi các sự

kiện đã định nghĩa trước xảy ra, ví dụ khi thực hiện một lệnh cho trước theo sau bởi

một thao tác ghi dữ liệu tại địa chỉ xác định thì sẽ xác nhận breakpoint (nghĩa là

dừng chương trình)

Memory/Register Access. Cho phép trình gỡ lỗi đọc thanh ghi hay bộ nhớ.

“On-the-fly” Access. Các chức năng gỡ lỗi vẫn được hoàn thành trong khi vi điều

khiển vẫn đang thực thi. Rất nhiều ứng dụng nhúng thực hiện điều khiển thời gian

thực như cánh tay máy... và gỡ lỗi những ứng dụng như vậy ở giai đoạn khởi

động/dừng là không thực tế khi dừng VĐK sẽ làm cho hệ thống khởi động lại (và

như vậy phần gỡ lỗi khởi động lại toàn bộ). “On-the-fly” áp dụng điều này cho phép

truy cập các biến mà không phải dừng chương trình.

Real-time Trace and Watchpoints. Cung cấp một cơ chế bắt (catch) luồng chương

trình (hoặc dữ liệu truy cập) theo thời gian thực. Thông thường, thông tin lần vết

được tạo ra từ VĐK, bắt và gắn tem thời gian và lưu bởi bộ mô phỏng. Watchpoints

hoạt động giống Breakpoints, tuy nhiên thay vì dừng VĐK chúng đơn giản là chỉ ra

điều kiện đặt trước đã xảy ra và có thể dùng bộ mô phỏng lọc hay bắt các thông tin

lần vết. Lần vết theo thời gian thực là điểm mạnh cho gỡ lỗi của các hệ thống

nhúng. Nếu một ứng dụng thường xuyên đổ vỡ khi ngắt do tràn ngăn xếp, sử dụng

lần vết thời gian thực có khả năng bắt được những gì ứng dụng thực hiện trước khi

Page 62: All_New(Luan Van Son)

- -

62

đổ vỡ và như vậy xác định được nguyên nhân của vấn đề (bằng cách xem lại chuỗi

lệnh ghi được trước khi đổ vỡ).

4.1.4.2 Các dạng gỡ lỗi

4.1.4.2.1 Giám sát ROM (ROM Monitor)

Một monitor là một đoạn mã chạy trong hệ thống đích sẽ được gỡ lỗi. Trình

gỡ lỗi, chạy trên PC giao tiếp với monitor thông qua cổng dành riêng trên hệ thống

đích (thường là cổng nối tiếp hay ethernet). Trình gỡ lỗi truyền các lệnh tới Monitor

và chờ trả lời. Một ví dụ điển hình là yêu cầu đọc bộ nhớ tại một vị trí xác định với

một độ dài nào đó. Monitor rất thông dụng và rẻ tiền, tuy nhiên chúng có những hạn

chế sau:

• Monitor nằm trong bộ nhớ đích, làm mất không gian của ứng dụng và phải nạp

vào bộ nhớ trước khi gỡ lỗi.

• Monitor đòi hỏi một cổng dành riêng trên thiết bị đích để truyền tới PC.

• Monitor chỉ có thể chạy nếu đích đã chạy, do đó gỡ lỗi một đích “chết” hay

không boot là không thể.

• Gỡ lỗi ở Flash hay ROM với một Monitor sẽ không thể ghi vào bộ nhớ hệ

thống đích khi đặt software breakpoints.

4.1.4.2.2 Mô phỏng trên mạch (In-Circuit Emulator)

Một hệ mô phỏng trên mạch (In-Circuit Emulator, ICE) hoạt động bằng cách

thay thế mạch VĐK và mô phỏng các chức năng của nó. ICE nối với PC và được

Hình 4.1 Gỡ lỗi dạng Giám sát ROM

Page 63: All_New(Luan Van Son)

- -

63

điều khiển bởi một trình gỡ lỗi. The ICE cung cấp cái nhìn vào bên trong sự hoạt

động bên trong của VĐK được mô phỏng. Mô phỏng một VĐK là nhiệm vụ rất

phức tạp và thường được thực hiện sử dụng các phiên bản đặc biệt của VĐK gọi là

thiết bị “bond-out” cung cấp chức năng cơ bản của ICE. Tuy nhiên, chi phí để sản

xuất Bond-outs rất đắt, vì lý do đó nên một số nhà cung cấp VĐK có sự thay đổi

bằng cách dùng Field Programmable Gate Arrays (FPGAs). FPGAs là một giải

pháp trong một vài trường hợp, tuy nhiên chúng không chạy nhanh bằng các thiết bị

bond-out hay các mạch mô phỏng tương tự (VD chuyển đổi số-tương tự) và như

vậy cần thêm mạch bên ngoài.

4.1.4.2.3 Gỡ lỗi On-Chip

Do vấn đề chi phí và giá thành của ICE, rất nhiều nhà cung cấp tích hợp mạch

gỡ lỗi vào trong chip. Motorola là nhà cung cấp đầu tiên và Chế độ gỡ lỗi nền tảng

(Background Debug Mode - BDM) là một trong các chuẩn gỡ lỗi on-chip được biết

đến rộng rãi. Mạch gỡ lỗi on-chip thường giao tiếp với thế giới bên ngoài thông qua

giao diện nối tiếp với JTAG ngày càng là chuẩn thông dụng. (JTAG - Joint Test

Action Group, tên của chuẩn IEEE 1149.1)

Máy tính giao tiếp với hệ thống thông qua một bộ mô phỏng JTAG, cung cấp

một giao diện JTAG và một kết nối USB/Ethernet tới PC. Tất cả các nhà cung cấp

sẽ chuẩn hoá bộ kết nối gỡ lỗi on-chip nối bộ mô phỏng tới hệ thống đích.

Hình 4.2 Gỡ lỗi dạng Mô phỏng trên mạch

Page 64: All_New(Luan Van Son)

- -

64

Hỗ trợ thiết kế Gỡ lỗi On-chip là một yêu cầu của VĐK vì nếu không có hỗ

trợ thiết kế sẽ không thể hay có giá rất cao để đưa ra công cụ gỡ lỗi. Các lý do chính

là:

• Sử dụng bộ nhớ Flash để lưu chương trình sẽ rất khó hay không thể đối với các

công cụ mở rộng để xác định câu lệnh hiện thời sẽ được thực hiện.

• Với các VĐK tốc độ cao thì ICE không thể dừng chương trình thực thi trước

khi nó thi hành lệnh cần thiết.

• Các kiến trúc RISC (Reduced instruction set computer) và on-chip rất khó để

xác định các lệnh đã được nạp (fetched) và các lệnh đã được thực hiện.

• Với các hệ hướng ứng dụng hay theo yêu cầu của khách hàng, Systems-On-a

Chip (SOCs) sẽ phải thiết kế lại một bộ mô phỏng vi xử lý cho từng thiết kế

SOC riêng lẻ.

Gỡ lỗi on-chip giải quyết tất cả những vấn đề trên và cũng có các chức năng

điều khiển thời gian thực như nạp chương trình, go/step/halt, truy cập bộ nhớ/thanh

ghi và breakpoints. Các hệ gỡ lỗi on-chip hiện nay cũng có chức năng lần vết thời

gian thực. Để tối thiểu hoá yêu cầu băng thông, thông tin lần vết được nén bởi giao

diện gỡ lỗi trước khi đưa ra ngoài (hay lưu trong chip). Bộ mô phỏng sau đó giải

nén thông tin nhận được và xây dựng lại luồng chương trình hiện thời để hiển thị

trong trình gỡ lỗi.

Hình 4.3 Gỡ lỗi On-Chip

Page 65: All_New(Luan Van Son)

- -

65

4.1.4.3 Tóm tắt về gỡ lỗi

Đặc điểm ROM Monitor ICE On-chip debug

Code Download Có Có Có

Go/Halt/Step Có Có Có

Code Breakpoints Có Có Có

Data Access

Breakpoints

Không Có Có

Complex/Advanced

Breakpoints

Không Có Có

Truy cập

Bộ nhớ/Thanh ghi

Có Có Có

Intrusive Có Không Không

Truy cập “On-the-

fly”

Không Có Có

Real-time Trace

and Watchpoints

Không Có Có

Giá thành Thấp Cao Trung bình

Kết nối Kết nối đơn giản

với PC

Cơ chế kết nối phức

tạp

Kết nối đơn giản

giữa đích và công

cụ gỡ lỗi

Ưu điểm Giá thành thấp Có đầy đủ các đặc

điểm, không giới

hạn hardware

breakpoints.

Có đầy đủ các đặc

điểm, giá thành

chấp nhận được. Hỗ

trợ nhiều loại VĐK,

Page 66: All_New(Luan Van Son)

- -

66

hỗ trợ tốc độ cao

Nhược điểm Bị giới hạn chức

năng. Đòi hỏi tài

nguyên hệ thống

Giá thành cao, khó

kết nối, thường chỉ

dùng cho những

VĐK chuyên dụng

Đòi hỏi thiết kế

riêng và các chân

mở rộng cho VĐK

4.1.4.4 Gỡ lỗi cho CC1010

CC1010 có hỗ trợ gỡ lỗi và dạng gỡ lỗi là dạng ROM Monitor. Bộ công cụ

phát triển cho CC1010 bao gồm phần cứng và phần mềm. Phần cứng là module

CC1010EB vừa làm nhiệm vụ điều khiển nạp chương trình vào module

CC1010EM, vừa làm nhiệm vụ hỗ trợ gỡ lỗi cho chương trình. Phần mềm là bộ thư

viện CC1010IDE đã giới thiệu ở trên, ngoài việc cung cấp các thư viện chương

trình còn cung cấp thư viện gỡ lỗi. Phần Monitor được nạp vào CC1010 phục vụ

quá trình gỡ lỗi có tên là BootLoader có kích thước 2322 byte. BootLoader phải

được nạp vào CC1010 trước khi thực hiện việc gỡ lỗi.

Hình 4.4 Module CC1010EB

Page 67: All_New(Luan Van Son)

- -

67

Ví dụ về gỡ lỗi cho CC1010: Code Breakpoints

Mục đích: Kiểm tra dạng xung Reset mà CC1010 phát tới cảm biến áp suất

MS5535 có đúng theo yêu cầu hay không.

Giả sử hàm làm việc này là: void resetMS5535(). Xung reset là 2 chuỗi

xung DIN và SCLK của MS5535 lệch pha nhau, mỗi chuỗi gồm 21 xung. Chương

trình dịch cụ thể là Keil uVision 2.0. Thiết bị kiểm tra là dao động ký số.

Trình tự các bước như sau:

- Nối cáp từ cổng Parallell của PC với cổng Parallell của CC1010EM. Đây

là cáp giao tiếp để nạp chương trình.

- Nối cáp từ cổng RS232 của PC với cổng Serial 1 của CC1010EB. Đây là

giao tiếp cho quá trình gỡ lỗi.

- Nạp chương trình Bootloader vào CC1010EM.

- Kẹp đầu đo kênh 1 của dao động ký vào chân DIN của MS5535.

- Kẹp đầu đo kênh 2 của dao động ký vào chân SCLK của MS5535.

- Đặt chế độ đo của dao động ký ở dạng trigger. Điều này giúp cho dao

động ký dừng lấy mẫu khi lấy được 1 chùm xung.

- Đặt Code BreakPoint tại lời gọi hàm resetMS5535()

- Chạy chương trình ở chế độ gỡ lỗi đến lời gọi hàm resetMS5535(), sau

đó chạy qua lời gọi này một bước rồi dừng lại (nhấn phím F10). Trên

màn hình dao động ký sẽ xuất hiện dạng xung mà chương trình vừa phát,

qua đó sẽ biết dạng xung đó có đúng với dạng xung cần thiết hay không.

Page 68: All_New(Luan Van Son)

- -

68

4.2 Kết luận

Chương 4 đã giới thiệu tổng quan về phần mềm nhúng, các bước xây dựng

cũng như các thách thức khi phát triển một phần mềm nhúng.

Gỡ lỗi là một phần không thể thiếu khi phát triển phần mềm nói chung và

phần mềm nhúng nói riêng. Nó sẽ góp phần xây dựng phần mềm nhúng đạt độ ổn

định và tin cậy cao. Ở đây đã giới thiệu ba dạng gỡ lỗi, đó là: Giám sát ROM, Mô

phỏng trên mạch, Gỡ lỗi On-chip, và phân tích ưu nhược điểm của từng dạng. Phần

cuối cùng minh hoạ các bước cụ thể khi gỡ lỗi cho chương trình viết cho CC1010

dùng để đọc giá trị áp suất MS5535.

Hình 4.5 Giao diện gỡ lỗi của Keil μVision

Page 69: All_New(Luan Van Son)

- -

69

CHƯƠNG 5

TRIỂN KHAI CHỨC NĂNG MẠNG VÀ

CÁC THỬ NGHIỆM

Việc thử nghiệm chức năng mạng đã thực hiện những công việc sau:

- Thử nghiệm mạng gồm hai nút mạng:

• Khảo sát quan hệ độ cao cột nước - áp suất

• Khảo sát độ ổn định của cảm biến áp suất theo nhiệt độ

• Khảo sát khí áp tại khu vực Hà nội trong 10 ngày từ 08/06/2005 đến

18/06/2005

• Kiểm tra làm việc dài ngày và mức tiêu thụ điện của hệ thống

- Thử nghiệm mạng gồm nhiều nút mạng:

• Xây dựng mạng gồm 3 nhiều nút mạng, truyền thông theo dạng

multihop

5.1 Thử nghiệm mạng gồm 2 nút mạng:

Sơ đồ tổ chức tổng quát của mạng này như sau:

Cảm biến VĐK có tích hợp thu phát RF (Slave)

VĐK có tích hợp thu phát RF (Master)

Máy tính RS232

Hình 5.1 Sơ đồ tổng quát của mạng có 2 nút mạng

Page 70: All_New(Luan Van Son)

- -

70

5.1.1 Khảo sát quan hệ độ cao cột nước – áp suất:

Module MS5535 được ghép với CC1010 và với phần mềm nhúng thích hợp sẽ

tạo thành một điểm đo độc lập, tự động đo giá trị áp suất, nhiệt độ, xử lý dữ liệu thu

được và truyền không dây định kỳ số liệu đo này về cho một CC1010 khác nối với

máy tính xách tay hoặc máy tính để bàn. Sơ đồ ghép nối cụ thể MS5535 và CC1010

thể hiện trong hình 3.5.

Như đã chỉ ra trong hình 3.5, nguồn nuôi dùng chung cho MS5535 và

CC1010, MCLK là tần số CC1010 cung cấp để MS5535 thực hiện biến đổi ADC,

SCLK là tần số nhịp đồng bộ quá trình truyền và nhận giữa hai vi mạch này, tín

hiệu DIN do CC1010 cung cấp, địa chỉ đến 6 hệ số bù nhiệt được nhà sản xuất chip

chuẩn hoá và nhớ trong chip, địa chỉ đến dữ liệu nhiệt độ và dữ liệu áp suất riêng

biệt. DOUT là lối ra các dữ liệu khác nhau của MS5535, tương ứng yêu cầu của

CC1010. Độ lớn giá trị tần số MCLK, SCLK, các giá trị địa chỉ dữ liệu, việc xử lý

CC1010EM CC1010EM

CC1010EB

RS232

Ống nước

Độ cao h

Sensor áp suất

MS5535 Không khí

Nước

H1

1

H2

Hình 5.2. Sơ đồ khảo sát thực nghiệm

Page 71: All_New(Luan Van Son)

- -

71

các loại dữ liệu đọc được đều do phần mềm nhúng trong CC1010 thực hiện. Phần

mềm này còn thực hiện chức năng truyền/nhận dữ liệu không dây giữa hai CC1010

và truyền về máy tính. Giải thuật của phần mềm này cho trên hình 5.3.

Ý nghĩa của các bước trong sơ đồ thuật toán:

Khởi tạo RF:

- Mã hoá dữ liệu: Manchester

- Tốc độ truyền dữ liệu: 2,4 kb/s

Khởi tạo ADC:

- Điện áp tham chiếu: 1,25 V internal

- 10 bit single.

Khởi tạo Timer:

Sử dụng Timer 2 ở chế độ điều chế độ rộng xung, tần số 29kHz, dạng xung

vuông đối xứng. Xung này dùng làm Master Clock (MCLK) cho cảm biến áp suất

MS5535.

Khởi tạo MS5535:

Khởi tạo các tham số: - Khởi tạo RF, ADC, TIMER - Khởi tạo MS5535

Đọc 3 kênh ADC

Đọc dữ liệu MS5535

Truyền dữ liệu không dây

Nhận dữ liệu không dây

Truyền thông tin về máy tính

Hình 5.3. Giải thuật phần mềm nhúng trong CC1010 của nút Master

Page 72: All_New(Luan Van Son)

- -

72

- Đưa các chân SCLK và DIN của MS5535 về trạng thái 0

- Đọc các hệ số lưu trong MS5535

Đọc 3 kênh ADC:

- Chọn kênh cần đọc

- Phát lệnh chuyển đổi ADC

- Chờ cho đến khi chuyển đổi ADC kết thúc

- Đọc giá trị ADC từ hai thanh ghi ADCDATH và ADCDATL

Đọc dữ liệu MS5535:

- Reset MS5535

- Gửi lệnh cho MS5535 để chọn tham số cần đọc: nhiệt độ hay áp suất.

- Đọc dữ liệu trả lời từ MS5535

Chờ nhận lệnh từ máy tính:

Nếu có lệnh yêu cầu gửi dữ liệu về trung tâm, Slave sẽ đọc các tham số nhiệt

độ áp suất rồi truyền về trung tâm.

Một thí nghiệm đơn giản như trình bày ở hình 5.2, những kết quả đo được cho

trong bảng 3, đồ thị tương ứng biểu diễn trên hình 5.4.

Bảng 3. Số liệu đo áp suất theo độ cao cột nước

Độ cao (cm)

(h=H1-H2)

Áp suất (mbar)

Lần 1 Lần 2 Lần 3 Lần 4 Lần 5 Trung bình

0 986 986 986 986 986 986

20 1012 1010 1010 1011 1011 1010.8

40 1031 1031 1031 1030 1030 1030.6

60 1054 1054 1052 1052 1052 1052.8

Page 73: All_New(Luan Van Son)

- -

73

80 1069 1070 1070 1070 1070 1069.8

100 1088 1088 1088 1088 1088 1088

120 1111 1111 1111 1111 1111 1111

140 1127 1127 1127 1127 1127 1127

160 1149 1149 1149 1149 1149 1149

233 1214 1214 1214 1215 1215 1214.4

313 1290 1290 1290 1290 1290 1290

5.1.2 Khảo sát độ ổn định của phép đo áp suất khi thay đổi nhiệt độ

Đầu đo được đặt trong môi trường nhiệt độ thay đổi từ 160C đến 420C và đo

giá trị khí áp tại một vị trí, trong khoảng thời gian ngắn. Số liệu đo được phản ánh

qua đồ thị tương ứng cho trên hình 5.5.

Đồ thị quan hệ Độ cao-áp suất

0

50

100

150

200

250

300

350

0 200 400 600 800 1000 1200 1400

áp suất (mbar)

độ

cao

(c

m)

Hình 5.4. Sự phụ thuộc của áp suất vào độ cao cột nước

Page 74: All_New(Luan Van Son)

- -

74

5.1.3 Kiểm tra làm việc dài ngày và mức tiêu thụ điện của hệ thống

Trong CC1010, CPU, biến đổi ADC, truyền nhận RF, v.v…không làm việc

đồng thời. Chu kỳ nghỉ và chu kỳ hoạt động có tần số nhịp khác nhau. Quản trị chặt

chẽ quá trình này sẽ tiết kiệm được năng lượng tiêu thụ bởi hệ thống. CC1010 có 3

chế độ làm việc:

+ Tích cực (Active Mode), chế độ 8051 chạy bình thường, xung Clock là tần số

dao động của tinh thể thạch anh chính. Dòng tiêu thụ phụ thuộc vào tần số đó;

+ Chế độ nghỉ (Idle Mode): 8051 không hoạt động, các ngoại vi vẫn hoạt động

bình thường. Thoát ra khỏi chế độ nghỉ bằng: Ngắt (Interrupt), thiết lập lại (Reset),

Tắt - bật nguồn;

+ Chế độ tắt nguồn (Power-Down Mode): 8051 và các ngoại vi không hoạt

động, chỉ clock cho ADC hoạt động. Nó là chế độ tiết kiệm năng lượng nhất, thoát

khỏi chế độ này bằng Reset hoặc Tắt - bật nguồn.

Thử nghiệm tiết kiệm năng lượng khi truyền giữa Master và Slave. Slave thu

thập dữ liệu nhiệt độ, áp suất truyền cho Master. Thời gian nghỉ giữa 2 lần truyền là

30 phút. Nuôi Slave là pin điện thoại di động loại 3.6V-580mAh. Slave ở chế độ

nghỉ, chỉ khi thu thập số liệu truyền cho Master, Slave mới ở chế độ tích cực, chu

trình hoạt động theo giải thuật sau:

Hình 5.5. Độ ổn định của áp suất theo nhiệt độ

900

950

1000

1050

1100

1150

1200

0 10 20 30 40 50

Page 75: All_New(Luan Van Son)

- -

75

Dòng tiêu thụ của Slave đo được như sau: không phát RF, chỉ thu thập số liệu,

dòng 17mA, mất khoảng 5 giây do lấy số liệu trung bình 4 lần liên tiếp. Khi phát

RF, không thu thập số liệu, dòng 35mA.

Với tốc độ truyền 2,4kb/s, mỗi gói tin dài 22 byte, thời gian truyền gói tin là:

22*8(bit)/2400 = 73ms.

Để Master nhận dữ liệu một cách tin cậy, Slave phát 5 gói tin cùng 1 nội dung,

tổng thời gian phát là:

73*5 = 365ms ≈ 0,4s.

Chế độ nghỉ, dòng 0,5mA. Thời gian của chế độ này (tính trong vòng 1 giờ) là:

3600 - 2*5(giây) – 2*0,4 = 3589.2 s.

Như vậy, dòng tiêu thụ trung bình trong 1 giờ là:

(17*5*2 + 35*0,3*2 + 0,5*3589)/3600 = 0,55 mA ≈ 0,6mA.

Thời gian hoạt động lý tưởng của Slave với tính toán như trên là:

580/0.6 = 967 giờ = 40 ngày (thực tế có thể đạt 50% giá trị này).

Khởi tạo: - Khởi tạo ADC, RF, các tham số khác - Về chế độ nghỉ

- Wake up C1010 - Thu thập số liệu - Phát số liệu cho Master - Trở về chế độ nghỉ

F

T

Đến thời điểm phát số liệu?

Hình 5.6. Thuật toán làm việc của khối Slave

Page 76: All_New(Luan Van Son)

- -

76

Với Master, việc tiết kiệm năng lượng không đặt thành vấn đề vì nó được đặt

cùng máy tính ở trung tâm, nơi có sẵn nguồn điện lưới. Sơ đồ hoạt động của Master

như sau:

5.1.4 Khảo sát số liệu khí áp tại Hà nội

Việc khảo sát số liệu khí áp tại Hà nội được thực hiện liên tục trong vòng 10

ngày từ 08/06/2005 đến 18/06/2005 nhằm mục đích phục vụ dự báo thời tiết. Sau

đây là kết quả khảo sát:

Bảng 4. Số liệu khí áp tại Hà Nội từ 08 đến 18/06/2005

Thời gian

(giờ)

Áp suất

(mBar)

Thời gian

(giờ)

Áp suất

(mBar)

Thời gian

(giờ)

Áp suất

(mBar)

6:00 991 72:00 991 144:00 994

12:00 990 78:00 993 150:00 992

18:00 989 84:00 992 156:00 995

24:00 988 90:00 990 162:00 994

Khởi tạo: - Khởi tạo RF - Khởi tạo UART - Khởi tạo các tham số khác

Chờ nhận dữ liệu từ Slave

Đã nhận xong

Truyền dữ liệu về máy tính

T

F

Hình 5.7. Thuật toán làm việc của khối Master

Page 77: All_New(Luan Van Son)

- -

77

30:00 992 96:00 989 168:00 995

36:00 993 102:00 988 174:00 994

42:00 991 108:00 991 180:00 995

48:00 993 114:00 999 186:00 994

54:00 999 120:00 991 192:00 995

57:00 1004 126:00 990 198:00 993

60:00 990 132:00 989 204:00 993

66:00 987 138:00 990 210:00 994

216:00 995

Khí áp là thông số cơ bản để dự báo sự thay đổi thời tiết, đặc biệt khi biết sự

thay đổi khí áp trong vòng một giờ dP/dt. Thông tin thay đổi khí áp liên quan đến

thay đổi thời tiết đã được tổng kết như sau:

dP/dt > 2,5mb/h: khí áp cao mức trung bình, không ổn định

0,5mb/h < dP/dt < 2,5mb/h: Khí áp cao trong thời gian dài, thời tiết rất ổn định

- 0,5mb/h < dP/dt < 0,5mb/h: Thời tiết ổn định

- 2,5mb/h < dP/dt < - 0,5mb/h: Khí áp thấp trong thời gian dài, trời mưa liên tục

dP/dt < -2,5mb/h: khí áp thấp trung bình, dông tố, không ổn định.

Như vậy, từ kết quả đo có thể dự báo rằng sẽ có mưa trong các ngày 10 và

12/06/ 2005.

Page 78: All_New(Luan Van Son)

- -

78

5.2 Thử nghiệm mạng gồm nhiều nút mạng

Mạng được tổ chức theo sơ đồ hình cây theo dạng sau:

1

2 1

4 5

9 10

1

3

6 7 8

11

Master

RS232

Hình 5.9. Mô hình mạng dạng cây

Sự thay đổi khí áp ở Hà nội từ 08 đến 18/06/2005

975

980

985

990

995

1000

1005

1010

Thời gi an ( g i ờ)

Series1

Hình 5.8. Sự thay đổi khí áp ở Hà nội từ 08 đến 18/06/2005

Page 79: All_New(Luan Van Son)

- -

79

Master và Slave đều là Vi điều khiển CC1010

Master giao tiếp với máy tính trung tâm qua đường RS232.

Các Slave giao tiếp với nhau hoặc với Master qua đường truyền không dây

Master và Slave đều phải chứa toàn bộ topology của mạng, qua đó mỗi nút sẽ biết

đường đi để truyền gói tin đến đích.

Topology của mạng được xây dựng ngay từ lúc viết chương trình.

Khi một nút nhận được lệnh truyền từ nút cha, nó sẽ xem địa chỉ đích:

- Nếu địa chỉ đích chính là nó, nó sẽ gửi dữ liệu về cho nút cha.

- Nếu không, nó sẽ tìm trong bảng địa chỉ:

o Nếu tồn tại một đường đi từ nó tới nút đích, nó sẽ chuyển tiếp gói tin tới

chặng tiếp theo. Chặng tiếp theo chính là nút con của nó có khả năng tới

đích.

o Nếu không tồn tại đường đi thì không làm gì cả.

5.2.1 Biểu diễn cây trong bộ nhớ

Biểu diễn cây bằng danh sách các con của mỗi đỉnh

Với mỗi đỉnh của cây, ta thành lập một danh sách các đỉnh con của nó theo thứ

tự từ trái sang phải. Ở đây ta sử dụng một mảng để lưu giữ các đỉnh của cây. Mỗi

thành phần của mảng là một tế bào chứa thông tin gắn với mỗi đỉnh và danh sách

các đỉnh con của nó. Danh sách các đỉnh con của một đỉnh có thể biểu diễn bởi

mảng hoặc bởi danh sách liên kết. Tuy nhiên, vì số con của mỗi đỉnh có thể thay đổi

nhiều nên ta sẽ sử dụng danh sách liên kết. Như vậy mỗi tế bào mô tả của cây là

một bản ghi gồm 2 trường: trường id là địa chỉ của nút mạng, trường next là con trỏ

trỏ tới danh sách các con của đỉnh đó. Giả sử các đỉnh của cây được đánh số từ 1

đến N. Với cách cài đặt này, ta có thể khai báo cấu trúc dữ liệu biểu diễn cây như

sau:

#define N 11

struct node

Page 80: All_New(Luan Van Son)

- -

80

int id;

node *next;

node tree[N];

Trong khai báo trên, Member biểu diễn các thành phần của danh sách các con,

còn Node biểu diễn các đỉnh của cây. Với cách cài đặt này, cấu trúc dữ liệu biểu

diễn cây trong hình trên được minh hoạ như sau:

1

2

3

4 .

5

6 .

7

8 .

9 .

10 .

11 .

2 3 .

4 5 .

6 7 .

9 10 .

11

id next id next

Hình 5.10. Cấu trúc dữ liệu biểu diễn cây trong bộ nhớ

Page 81: All_New(Luan Van Son)

- -

81

Ta có nhận xét rằng, trong cách cài đặt này, với mỗi đỉnh k ta xác định được

ngay con trưởng của nó. Chẳng hạn, với cây trong hình trên, con trưởng của đỉnh 3

là đỉnh 6, con trưởng của đỉnh 5 là đỉnh 9, còn đỉnh 6 không có con. Phép toán tìm

con trưởng EldestChild(k) có thể được mô tả như sau:

int EldestChild(int k, Tree T)

node *p;

if(T[k])

p = T[k].next;

return pàid;

else return -1; //không tìm thấy con

Tuy nhiên trong cách cài đặt này, việc tìm cha và em liền kề của mỗi đỉnh lại

không đơn giản. Chẳng hạn, để tìm cha của đỉnh k, ta phải duyệt các danh sách các

con của mỗi đỉnh. Nếu phát hiện ra trong danh sách các con của đỉnh m có chứa k

thì Parent(k) = m. Hàm Parent(k) được xác định như sau:

int Parent(int k, Tree T)

node *p;

int i;

BOOL found;

i = 0;

while(i<N)

Page 82: All_New(Luan Van Son)

- -

82

p = T[i].next;

while(p)

if(pàid = = k) return i

else p = pànext;

i++;

return -1; //không tìm thấy cha

Một cách tương tự (duyệt danh sách các con), ta cũng có thể tìm được em liền

kề của mỗi đỉnh. Hàm tìm em liền kề NextSibling(k) như sau:

int NextSibling(int k, Tree T)

node *p;

int i;

i = 0;

while(i < N)

p = T[i].next;

while(p)

if(pàid = = k)

Page 83: All_New(Luan Van Son)

- -

83

p = pànext;

if(p) return pàid;

else return -1; //không có em liền kề

else p = pànext;

i++;

return -1;

Khi Master muốn gửi thông tin cho một nút k nào đó, ta phải tìm đường đi từ

Master tới nút k. Muốn vậy, từ nút k trong topology của mạng lưu trong Master, ta

tìm nút cha của nó, sau đó cứ tìm ngược lên trên cho tới Master. Toàn bộ các nút

tìm được chính là đường đi từ Master tới nút k. Các nút tìm được này sẽ được lưu

trong một mảng để từ Master, thông qua mảng đó có thể tới được nút k. Mảng này

được khai báo như sau:

int RoutingTable[N];

Ví dụ trong sơ đồ hình cây trên, đường đi từ Master tới nút 11 được lưu trong bảng

như sau: [1, 3, 7, 11, -1, -1, -1, -1, -1, -1, -1]

Hàm xây dựng bảng định tuyến RoutingTable như sau:

//Hàm này tìm đường đi từ Master tới nút k, Master có địa chỉ là 1

void FindHops(int k, Tree T)

int par,i,j;

Page 84: All_New(Luan Van Son)

- -

84

for(i=0; i<N; i++) RoutingTable [i] = -1;

i = 0;

j = k;

do

par = Parent(j, T);

RoutingTable [i] = par;

j = par;

i++;

while ( par != 1)

5.2.2 Định dạng dữ liệu truyền

Truyền dữ liệu từ Master tới Endpoint:

Định dạng dữ liệu truyền từ Master qua các chặng trung gian cho Endpoint như sau:

Len + NextHop + DestAddress + Command + CRC

Truyền dữ liệu về Master:

Định dạng dữ liệu của Endpoint truyền về trung tâm như sau:

Len + ParentAddress + DestAddress + Command + ADC0 + ADC1 + ADC2 + P

+ CRC

Trong đó:

Endpoint: là nút mạng cuối cùng mà Master muốn gửi gói tin đến.

Len: độ dài gói tin, 1byte

DestAddress: Địa chỉ của Endpoint, 1 byte

Page 85: All_New(Luan Van Son)

- -

85

NextHop: Địa chỉ của nút kế tiếp có thể tới đích

ParentAddress: địa chỉ của nút cha của nút hiện thời, 1 byte.

Command: lệnh gửi cho Endpoint phải thi hành, 1 byte

ADC0, ADC1, ADC2: các giá trị nhiệt độ đọc từ 3 kênh này, 2 byte

P: giá trị áp suất đọc từ cảm biến áp suất MS5535, 2 byte

CRC: Mã dư vòng, 2 byte

5.3 Kết luận

Việc thử nghiệm được tiến hành từ xây dựng mạng gồm hai nút mạng đến xây

dựng mạng có nhiều nút mạng. Phần xây dựng mạng có 2 nút mạng đã tiến hành các

thử nghiệm như: khảo sát quan hệ độ cao cột nước - áp suất, khảo sát độ ổn định

của phép đo áp suất theo nhiệt độ, khảo sát khí áp tại Hà nội và kiểm tra vấn đề tiết

kiệm năng lượng. Kết quả thử nghiệm còn cho thấy độ chính xác và tính tuyến tính

của cảm biến áp suất MS5535. Một kết quả cũng rất quan trọng của việc thử nghiệm

là vi điều khiển CC1010 tiêu thụ năng lượng thấp, một tiêu chí quan trọng của

WSN.

Phần xây dựng mạng gồm nhiều nút mạng được tiến hành trên 3 nút mạng, 2

nút là Slave, 1 nút Master. Các nút mạng đều dùng vi điều khiển CC1010 của hãng

Chipcon. Mạng được xây dựng theo dạng adhoc, bảng định tuyến dạng cây được

nhớ cố định trong các nút mạng. Theo chu kỳ, cứ 2 giây nút Master lại gửi yêu cầu

lấy dữ liệu tại một nút mạng. Gói tin yêu cầu lấy dữ liệu từ nút Master tới nút Slave

sẽ đi qua các nút trung gian để tới nút cần gửi. Khi nút Slave nhận được yêu cầu từ

Master, nó sẽ thu thập thông tin môi trường như nhiệt độ, áp suất rồi gửi về Master

cũng theo đường đi vừa rồi. Việc thăm dò của Master được thực hiện vòng tròn cho

tới nút mạng cuối cùng.

Kết quả các thực nghiệm cho thấy việc truyền nhận dữ liệu ổn định và tin cậy,

không bị xung đột.

Page 86: All_New(Luan Van Son)

- -

86

KẾT LUẬN

Bản luận văn đã đưa ra kiến trúc tổng quát và chỉ ra các yêu cầu chủ yếu cần

đạt được khi xây dựng một WSN, đó là: năng lượng tiêu thụ, kích thước, tính mềm

dẻo, độ chính xác theo thời gian. Những đặc điểm này cần được thể hiện trong hệ

thống WSN. Hệ thống phải có khả năng mềm dẻo để thích hợp với dải rộng các yêu

cầu của ứng dụng. Các dạng ứng dụng chủ yếu của WSN là: thu thập dữ liệu môi

trường, mạng an ninh, và theo dõi đối tượng. Mỗi dạng ứng dụng có sự khác nhau

căn bản về truyền thông và các giao thức cần được hỗ trợ bởi kiến trúc phần cứng.

Yêu cầu quan trọng của một nút mạng là có kích thước bé, tiêu thụ năng lượng

thấp và có tích hợp truyền nhận không dây, từ đó đã chọn loại vi điều khiển

CC1010 do hãng Chipcon-NaUy chế tạo có độ tích hợp cao, truyền nhận RF, tiêu

thụ năng lượng thấp để làm nút mạng và xây dựng hệ thống thực nghiệm.

Bản luận văn cũng đã giới thiệu về phần mềm nhúng, các yêu cầu về phần

mềm nhúng cho các nút mạng và vấn đề gỡ lỗi cho phần mềm nhúng. Gỡ lỗi sẽ làm

cho phần mềm trở nên ổn định và tin cậy, dễ bảo trì. Trong lĩnh vực phần mềm

nhúng có ba phương pháp gỡ lỗi, đó là: Giám sát ROM, Mô phỏng trên mạch và Gỡ

lỗi Onchip.

Hai chức năng quan trọng nhất của một nút mạng trong WSN là chức năng

mạng và chức năng cảm nhận. Chức năng cảm nhận của nút mạng đòi hỏi một nút

mạng phải có khả năng ghép nối được với nhiều loại cảm biến. Điều đó cho phép

một nút mạng có thể thu thập được nhiều thông tin khác nhau theo nhiều cách khác

nhau. Một nút mạng như vậy có khả năng thích nghi cao với nhiều dạng ứng dụng.

Từ các nghiên cứu lý thuyết tổng quát về cảm biến, bản luận văn đã đưa ra các

phương pháp ghép nối VĐK với các loại cảm biến tương tự cũng như cảm biến số.

Phần thực nghiệm đã tiến hành các thử nghiệm ở mức hệ thống mạng WSN và

xây dựng phần mềm nhúng cho các nút mạng. Các thử nghiệm chức năng mạng đã

được thực hiện bao gồm:

Page 87: All_New(Luan Van Son)

- -

87

- Xây dựng được mạng không dây gồm 2 nút mạng sử dụng vi điều

khiển CC1010 nối với đầu đo áp suất MS5535. Kết quả thử nghiệm cho thấy

hệ thống làm việc chính xác, ổn định.

- Xây dựng mạng gồm 2 nút mạng để đánh giá khả năng tiết kiệm năng

lượng của nút mạng. Kết quả nút mạng hoạt động liên tục, có thể sống trong

nhiều ngày.

- Xây dựng mạng gồm nhiều nút mạng truyền theo dạng multihop.

Bảng định tuyến được tổ chức theo dạng cây, được nhớ trong tất cả các nút,

qua đó mỗi nút trung gian sẽ biết được nút tiếp theo của gói tin hiện thời để có

thể đến đích.

Từ các kết quả thực nghiệm trên cho thấy: Việc xây dựng một WSN bước đầu

đã đạt được một số kết quả mang tính cơ bản, cho phép tiếp tục phát triển và đi sâu

nghiên cứu theo hướng đã xác lập. Việc theo dõi các thông số môi trường trở nên dễ

dàng và tiện lợi, người sử dụng chỉ cần ngồi tại một chỗ cũng có thể giám sát các

thông số đó nhằm phục vụ các công việc của mình như: dự báo thời tiết, phòng

chống cháy rừng, các ứng dụng trong nông nghiệp… Các thử nghiệm dùng module

CC1010EM cho thấy rằng việc dùng vi điều khiển CC1010 cho WSN là hoàn toàn

khả thi.

Áp dụng các công nghệ cho WSN vào thực tế như: đa truy cập, định tuyến,

truyền thông multihop đã được tích hợp sẵn trong TinyOS là hướng nghiên cứu tiếp

theo của đề tài.

Page 88: All_New(Luan Van Son)

- -

88

TÀI LIỆU THAM KHẢO

Tài liệu Tiếng Việt

[1] Đinh Mạnh Tường (2002), “Cấu trúc dữ liệu và thuật toán”, Nhà xuất bản khoa

học và kỹ thuật.

[2] Vương Đạo Vy, Nguyễn Thế Sơn, Phùng Công Phi Khanh, Hòa Quang Dự,

“Xây dựng hệ tự động đo khí áp sử dụng cảm biến áp suất MEMS và các thí nghiệm

kiểm tra”, tóm tắt các báo cáo Hội thảo Quốc gia lần thứ VIII, Hải Phòng 25-

27/08/2005, Một số vấn đề chọn lọc của công nghệ thông tin và truyền thông, Chủ

đề Mã nguồn mở, tr. 79, Hải phòng 08/2005

[3] Vương Đạo Vy, Nguyễn Thế Sơn, “Hệ tự động đo thông số môi trường theo

thời gian thực, truyền dữ liệu không dây liên tục, dài ngày có kích thước nhỏ, giá

thành thấp, tiêu thụ năng lượng ít”, tóm tắt các báo cáo Hội nghị Vật lý toàn quốc

lần thứ VI, tr. 297, Hà nội 11/2005

[4] Vũ Duy Lợi (2002), “Mạng thông tin máy tính”, Nhà xuất bản Thế giới.

Tài liệu Tiếng Anh

[5] Alec Woo and David Culler, “A transmission control scheme for media access

in sensor networks,” in Proceedings of the ACM/IEEE International Conference on

Mobile Computing and Networking, Rome, Italy, July 2001, ACM.

[6] Chipcon, CC1010 DataSheet, www.chipcon.com

[7] Chipcon, CC1010 IDE Manual, www.chipcon.com

[8] David Gay, Philip Levis, Robert von Behren, “The nesC Language: A Holistic

Approach to Networked Embedded Systems”, University of California, Berkeley,

http://webs.cs.berkeley.edu

[9] E. Jason Riedy, Robert Szewczyk (2000), “Power and Control in Networked

Sensors”

[10] Hugh O’Keeffe, R&D Director, Ashling Microsystems Ltd (2006), “Embedded

Debugging”

Page 89: All_New(Luan Van Son)

- -

89

[11] Jason Hill (2000), “A Software Architecture Supporting Networked Sensors”,

University of California, Berkeley

[12] Jason Lester Hill (2000), “System Architecture for Wireless Sensor Networks”,

University of California, Berkeley

[13] MS5534 DataSheet, http://www.intersema.ch

[14] MS5535 DataSheet, http://www.intersema.ch

[15] Nikolay Kirianaki, Sergey Yurish, Nestor Shpak, Vadim Deynega (2001),

“Smart sensors for electrical and non-electrical, physical and chemical variables:

tendencies and perspectives”, John Wiley & Sons Ltd

[16] Patrick Kinney, Kinney Consulting LLC - Chair of IEEE 802.15.4 Task Group, Secretary of ZigBee BoD, Chair of ZigBee Building Automation Profile WG (2 october 2003), “ZigBee Technology: Wireless Control that Simply Works”

[17] Vuong Dao Vy, Nguyen The Son, Phung Cong Phi Khanh, College of

Technology VNU (December 2005), “The automatic measure system contains the

pieszoresistive pressure sensor in MEMS architecture and the experiment for

checking”, International conference on Mecha-Electronic, Malaixia

[18] Wei Ye, John Heidemann, Deborah Estrin (2002), “An Energy-Efficient MAC

Protocol for Wireless Sensor Networks”, University of California, Berkeley

[19] ZigBee Specification, www.zigbee.org

Page 90: All_New(Luan Van Son)

- -

90

PHỤ LỤC

Phụ lục 1: Chương trình khảo sát quan hệ độ cao cột nước-áp suất Phần mềm viết cho Master bao gồm các file: Common.h, Master.c Phần mềm viết cho Slave bao gồm các file: Common.h, Slave.c, Slave.h, MS5535.c, MS5535.h

1. Common.h #ifndef common_h #define common_h// Only include this header file once #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <chipcon/reg1010.h> #include <chipcon/cc1010eb.h> #include <chipcon/hal.h> #define CLKFREQ CC1010EB_CLKFREQ #define PREAMBLE_BYTE_COUNT 18 #define PREAMBLE_BITS_SENSE_INIT 81 #define PREAMBLE_BITS_SENSE 16 #define CMD_GET_PARAMS 1 void RFSetup(void); void setupTimer0(); void InitRF(void); void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS); void Wait1sec (void); void SelectClockMode(char iMode); #endif 2. MS5535.h #ifndef __MS5535_H__ #define __MS5535_H__ #include <chipcon/reg1010.h> #include <chipcon/hal.h> #include <chipcon/cc1010eb.h> sbit P_MSCLK = P2^3; sbit P_SCLK = P1^0; sbit P_DIN = P1^1; sbit P_DOUT = P0^3; #define CLKFREQ CC1010EB_CLKFREQ //18432 #define DUTY_CYCLE 128 //MS5535 #define MS5535_W1 0x0157 #define MS5535_W2 0x00d7 #define MS5535_W3 0x0137 #define MS5535_W4 0x00b7 #define MS5535_P 0x002f #define MS5535_T 0x004f #define SCLK_W 1 #define true 1 #define false 0

Page 91: All_New(Luan Van Son)

- -

91

void reset(); void SerialSendLsbFirst(char pattern, char nbr_clock); word SerialGet16(); word getW (word index); // 1 to 4 word getD1 (word *error_pt); word ConvertWtoC5535 (int ix, word W1, word W2, word W3, word W4); void WaitOnePulse(); void setSCLK(bit status); void setDIN(bit status); bit getDOUT(); word waitOnDoutFall(); void calcPT5535 (word *pressure, word *temperature, word d1_arg, word d2_arg); word readMS5535param1(word type); void readMS5535Values(word *p,word *t); void readMS5535Coefficients(); void InitMS5535(); void wait(word t_wait); //void setupTimer0(word timeout); void SetupCounter0(); word GetCounter(); #endif 3. MS5535.c #include "MS5535.h" word xdata w1,w2,w3,w4; word xdata c1,c2,c3,c4,c5,c6; void InitMS5535() PORTDIRBIT(1, 0, POUT); //for SCLK MS5535 PORTDIRBIT(1, 1, POUT); //for DIN MS5535 PORTDIRBIT(0, 3, PIN); //for DOUT MS5535 PORTDIRBIT(2, 3, POUT); //for MSCLK MS5535 // Setup PWM2 pin direction PORTDIRBIT(3, 4, POUT); P_SCLK = 0; P_DIN = 0; halWait (20, CLKFREQ); //delay 20ms // Configure timer 2 as a PWM timer, max timeout interval halConfigTimer23(TIMER2 | TIMER23_PWM, 0, CLKFREQ); PWM2_SET_PERIOD(1); PWM2_SET_DUTY_CYCLE(DUTY_CYCLE); TIMER2_RUN(FALSE); readMS5535Coefficients(); //reset sequence void resetMS5535() byte xdata i; P_SCLK = 0; P_DIN = 0; wait(2);

Page 92: All_New(Luan Van Son)

- -

92

for(i=0;i<21;i++) if(i<16) P_DIN = !P_DIN; P_SCLK = 0; wait(2); P_SCLK = 1; wait(2); P_SCLK = 0; halWait (SCLK_W, CLKFREQ); //delay 1ms halWait (SCLK_W, CLKFREQ); //delay 1ms return; word readMS5535param(word type) word xdata d; byte xdata i,n; if((type==MS5535_P) || (type==MS5535_T)) n=9; else n=11; resetMS5535(); P_SCLK = 0; wait(2); //setup for(i=0;i<=n;i++) P_DIN = type & 0x1; type = type >> 1; P_SCLK = 0; wait(2); P_SCLK = 1; wait(2); P_SCLK = 0; wait(2); P_SCLK = 1; wait(2); P_SCLK = 0; wait(2); P_SCLK = 1; wait(2); P_SCLK = 0; halWait (50, CLKFREQ); //delay 1ms //read data d = 0; for(i=0;i<16;i++) P_SCLK = 1; wait(2); P_SCLK = 0; d = (d<<1) | P_DOUT; wait(2);

Page 93: All_New(Luan Van Son)

- -

93

P_SCLK = 1; wait(2); P_SCLK = 0; wait(2); return d; void readMS5535Values(word *p,word *t) double xdata dt, off, sens, pressure1,temperature1; double xdata fd1, fd2, x; word xdata d1_arg, d2_arg; d1_arg = readMS5535param(MS5535_P); d2_arg = readMS5535param(MS5535_T); d1_arg = d1_arg & 0xFFFF; d2_arg = d2_arg & 0xFFFF; fd1 = (double) d1_arg; fd2 = (double) d2_arg; dt = -10000.0 + fd2 - (8.0 * c5); off = 10000.0 + c2 + ( ( ( c4-250.0) * dt ) / 4096.0); sens = 3000.0 + (c1 / 2.0) + ( ( ( c3+200.0) * dt ) / 8192.0); pressure1 = 1000.0 + (( sens * (fd1- off)) / 4096.0); temperature1 = ( 200 + (( dt * (c6+100.0) ) / 2048.0)); *p = (word)pressure1; *t = (word)temperature1; void readMS5535Coefficients() w1 = readMS5535param1(MS5535_W1); w2 = readMS5535param1(MS5535_W2); w3 = readMS5535param1(MS5535_W3); w4 = readMS5535param1(MS5535_W4); c1 = w1 >> 3; c2 = ((w1 & 0x7)<<10) | (w2>>6); c3 = w3 >> 6; c4 = w4 >>7; c5 = ((w2 & 0x3f) << 6) | (w3 & 0x3f); c6 = w4 & 0x7f; word readMS5535param1(word type) word xdata d; byte xdata i,n; n=11; resetMS5535(); wait(2); for(i=0;i<=n;i++) P_DIN = type & 0x1; type = type >> 1;

Page 94: All_New(Luan Van Son)

- -

94

P_SCLK = 0; wait(2); P_SCLK = 1; wait(2); P_SCLK = 0; wait(2); P_SCLK = 1; wait(2); P_SCLK = 0; wait(2); halWait (50, CLKFREQ); //delay 50ms //read data d = 0; for(i=0;i<16;i++) P_SCLK = 1; wait(2); P_SCLK = 0; d = (d<<1) | P_DOUT; wait(2); P_SCLK = 1; wait(2); P_SCLK = 0; wait(2); return d; void wait(word t_wait) word xdata i; i = 0; while(i<t_wait) i++; void SetupCounter0() TMOD = TMOD | 0x5; //16bit counter TH0 = TL0 = 0; TR0 = 1; word GetCounter() word xdata counter; TR0 = 0; counter = TH0; counter = (counter << 8)|TL0; TH0=TL0=0; TR0=1; return counter; 4. Master.c #include "..\common\common.h" // Temperature packet: #define TBC_NODE_ID_LENGTH 2 // word #define TBC_NODE_NAME_LENGTH 5 //20 #define TBC_TEMP_OFFSET (TBC_NODE_ID_LENGTH + TBC_NODE_NAME_LENGTH) #define TBC_TEMP_LENGTH 2 #define TBC_TEMP_OFFSET1 (TBC_NODE_ID_LENGTH + TBC_NODE_NAME_LENGTH + TBC_TEMP_LENGTH)

Page 95: All_New(Luan Van Son)

- -

95

#define TBC_TEMP_LENGTH1 2 #define TBC_TEMP_OFFSET2 (TBC_TEMP_OFFSET1 + TBC_TEMP_LENGTH1) #define TBC_TEMP_LENGTH2 2 #define TBC_TEMP_OFFSET3 (TBC_TEMP_OFFSET2 + TBC_TEMP_LENGTH2) #define TBC_TEMP_LENGTH3 2 #define TBC_TEMP_OFFSET4 (TBC_TEMP_OFFSET3 + TBC_TEMP_LENGTH3) #define TBC_TEMP_LENGTH4 2 #define TBC_TEMP_OFFSET5 (TBC_TEMP_OFFSET4 + TBC_TEMP_LENGTH4) #define TBC_TEMP_LENGTH5 2 #define TBC_DATA_LEN (TBC_TEMP_OFFSET5 + TBC_TEMP_LENGTH5) // Radio related: #define MY_ADDRESS 1 // Node registration #define INVALID_NODE_INDEX 255 #define UNUSED_NODE_ID 0x0000 #define MAJOR_PERIOD 600//360000 #define RF_RX_BUF_SIZE 50 #define TEST_STRING_LENGTH 10 // The temperature "table": #define MAX_NODE_COUNT 16 word xdata nodeIDs[MAX_NODE_COUNT]; byte xdata nodeNames[MAX_NODE_COUNT][TBC_NODE_NAME_LENGTH]; word xdata nodeTemps[MAX_NODE_COUNT]; word xdata nodeTemps1[MAX_NODE_COUNT]; word xdata nodeTemps2[MAX_NODE_COUNT]; word xdata nodeTemps3[MAX_NODE_COUNT]; word xdata nodeTemps4[MAX_NODE_COUNT]; word xdata nodeTemps5[MAX_NODE_COUNT]; word xdata nodeLastT[MAX_NODE_COUNT]; byte xdata rxDataBuffer[TBC_DATA_LEN]; byte xdata txDataBuffer[TBC_DATA_LEN]; // Function prototypes void Receive (void); void PrintTable (void); void CmdGetParams(void); void RFSetup(void); void setupTimer0(); void InitRF(void); void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS); void Wait1sec (void); bit bPolled; byte xdata rf_rx_buf[50]; byte xdata rf_rx_index; unsigned long xdata TMajorPeriod; bit bRF_RXdone; // X-tal frequency: 14.745600 MHz // RF frequency A: 868.277200 MHz Rx // RF frequency B: 868.277200 MHz Tx // RX Mode: Low side LO // Frequency separation: 64 kHz // Data rate: 2.4 kBaud

Page 96: All_New(Luan Van Son)

- -

96

// Data Format: Manchester // RF output power: 4 dBm // IF/RSSI: RSSI Enabled RF_RXTXPAIR_SETTINGS code RF_SETTINGS = 0x4B, 0x2F, 0x15, // Modem 0, 1 and 2: Manchester, 2.4 kBaud //0x43, 0x2F, 0x15, // Modem 0, 1 and 2: NRZ, 2.4 kBaud //0xA1, 0x2F, 0x29, // Modem 0, 1 and 2: NRZ, 38.4 kBaud //0xA0, 0x2F, 0x52, // Modem 0, 1 and 2: NRZ, 76.8 kBaud 0x75, 0xA0, 0x00, // Freq A 0x58, 0x32, 0x8D, // Freq B 0x01, 0xAB, // FSEP 1 and 0 0x40, // PLL_RX 0x30, // PLL_TX 0x6C, // CURRENT_RX 0xF3, // CURRENT_TX 0x32, // FREND 0xFF, // PA_POW 0x00, // MATCH 0x00, // PRESCALER ; RF_RXTXPAIR_CALDATA xdata RF_CALDATA; //---------------------------------------------------------------------------- // MAIN PROGRAM //---------------------------------------------------------------------------- void main (void) byte xdata n; // Initialize peripherals WDT_ENABLE(FALSE); RLED_OE(TRUE); YLED_OE(TRUE); GLED_OE(TRUE); BLED_OE(TRUE); RLED = LED_OFF; // Startup macros for speed and low power consumption MEM_NO_WAIT_STATES(); FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS); // Reset the node IDs for (n = 0; n < MAX_NODE_COUNT; n++) nodeIDs[n] = UNUSED_NODE_ID; // Reset our name buffer for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) nodeNames[0][n] = 0x00; // Setup UART0 for polled I/O UART0_SETUP(57600, CLKFREQ, UART_NO_PARITY | UART_RX_TX | UART_POLLED); nodeIDs[0] = MY_ADDRESS; setupTimer0(); RFSetup(); halRFCalib(&RF_SETTINGS, &RF_CALDATA); // Calibration halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA);// Turn on RF for RX RF_START_TX(); halRFReadRSSIlevel(RSSI_MODE_INIT); while (TRUE) if(bPolled)

Page 97: All_New(Luan Van Son)

- -

97

InitRF(); n=0; CmdGetParams(); PrepareRX(&RF_SETTINGS); n++; bPolled = 0; Receive(); // main void Receive (void) byte xdata n,i; byte xdata nodeIndex; word xdata nodeID; if(!bRF_RXdone) return; BLED = !BLED; if(rf_rx_buf[0]==RF_SUITABLE_SYNC_BYTE) for(i=0;i<TBC_DATA_LEN;i++) rxDataBuffer[i]= rf_rx_buf[i+2]; nodeID = (rxDataBuffer[0] << 8) + rxDataBuffer[1];// Get the node ID for (n = 0; n < MAX_NODE_COUNT; n++) if (nodeIDs[n] == nodeID) nodeIndex = n; break; else if (nodeIDs[n] == UNUSED_NODE_ID) nodeIndex = n; break; else nodeIndex = INVALID_NODE_INDEX; // Update the table if (nodeIndex != INVALID_NODE_INDEX) nodeIDs[nodeIndex] = nodeID; for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) nodeNames[nodeIndex][n] = rxDataBuffer[n + TBC_NODE_ID_LENGTH]; nodeTemps[nodeIndex] = (rxDataBuffer[TBC_TEMP_OFFSET] << 8) + rxDataBuffer[TBC_TEMP_OFFSET + 1]; nodeTemps1[nodeIndex] = (rxDataBuffer[TBC_TEMP_OFFSET1] << 8) + rxDataBuffer[TBC_TEMP_OFFSET1 + 1]; nodeTemps2[nodeIndex] = (rxDataBuffer[TBC_TEMP_OFFSET2] << 8) + rxDataBuffer[TBC_TEMP_OFFSET2 + 1]; nodeTemps3[nodeIndex] = (rxDataBuffer[TBC_TEMP_OFFSET3] << 8) + rxDataBuffer[TBC_TEMP_OFFSET3 + 1]; nodeTemps4[nodeIndex] = (rxDataBuffer[TBC_TEMP_OFFSET4] << 8) + rxDataBuffer[TBC_TEMP_OFFSET4 + 1]; nodeTemps5[nodeIndex] = (rxDataBuffer[TBC_TEMP_OFFSET5] << 8) + rxDataBuffer[TBC_TEMP_OFFSET5 + 1];

Page 98: All_New(Luan Van Son)

- -

98

nodeLastT[nodeIndex] = 0; PrintTable(); InitRF(); // Receive void PrintTable (void) int xdata n; float xdata fTemp; for (n = 0; n < MAX_NODE_COUNT; n++) if (nodeIDs[n] == UNUSED_NODE_ID) continue; printf("%d", nodeIDs[n]); printf(" %d", nodeTemps[n]); //ad0 fTemp = nodeTemps1[n]; //ad1 fTemp -= 492; fTemp /= 8.192; if(fTemp<0) fTemp=0; printf(" %.1f", fTemp); printf(" %d", nodeTemps2[n]); //ad2 printf(" %d", nodeTemps3[n]); //ms5535_p printf(" %d", nodeTemps4[n]); //ms5535_t printf(" %d", n); //level printf(" %d\n", n); // PrintTable // Flash interrupt handler (do nothing) // We need to handle the interrupt even though we do not do anything. // If not, the program will not run correctly except under the debugger, // which has its own Flash interrupt handler void FlashIntrHandler(void) interrupt INUM_FLASH INT_SETFLAG(INUM_FLASH, INT_CLR); return; // RF interrupt service routine: void RF_ISR (void) interrupt INUM_RF INT_SETFLAG (INUM_RF, INT_CLR); if(!bRF_RXdone) // Get RF receive data rf_rx_buf[rf_rx_index] = RF_RECEIVE_BYTE(); if(rf_rx_index==0) RF_LOCK_AVERAGE_FILTER(TRUE); if(rf_rx_buf[rf_rx_index] != RF_SUITABLE_SYNC_BYTE) RLED = LED_ON; rf_rx_index++; if(rf_rx_index > TBC_DATA_LEN + 3) rf_rx_index = 0;

Page 99: All_New(Luan Van Son)

- -

99

bRF_RXdone = 1; PDET &= ~0x80; PDET |= 0x80; INT_ENABLE(INUM_RF, INT_OFF); YLED = !YLED; return; //timer 10ms void TIMER0_ISR() interrupt INUM_TIMER0 TF0 = 0; TH0 = 0xd0; TL0 = 0; TR0 = 1; if(TMajorPeriod == 0) bPolled = 1; TMajorPeriod = MAJOR_PERIOD + 1; TMajorPeriod--; void CmdGetParams() INT_ENABLE (INUM_RF, INT_OFF); GLED = LED_ON; txDataBuffer[0]=0x02; //address txDataBuffer[1]=CMD_GET_PARAMS; //command txDataBuffer[2]=0; //reserve halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); RF_START_TX(); halRFSendPacket(PREAMBLE_BYTE_COUNT, &txDataBuffer[0], 3); GLED = LED_OFF; INT_SETFLAG (INUM_RF, INT_CLR); void setupTimer0() TMajorPeriod = 0; bPolled = 0; TH0 = 100; TL0 = 100; TMOD = TMOD | 0x1; //timer0 mode1-16 bit timer INT_ENABLE(INUM_TIMER0, INT_ON); INT_GLOBAL_ENABLE (INT_ON); CKCON = CKCON & 0xf7; TF0 = 1; // Setup RF void RFSetup(void) InitRF(); halRFCalib(&RF_SETTINGS, &RF_CALDATA);

Page 100: All_New(Luan Van Son)

- -

100

halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); INT_GLOBAL_ENABLE (INT_OFF);// Disable global interrupt // Setup RF interrupt INT_SETFLAG (INUM_RF, INT_CLR); INT_PRIORITY (INUM_RF, INT_HIGH); // Select RF bytemode RFCON |= 0x01; // Enable RF interrupt based on bytemode RF_SET_BYTEMODE(); // Setup preamble configuration RF_SET_PREAMBLE_COUNT(PREAMBLE_BYTE_COUNT); RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE); // Make sure avg filter is free-running + 22 baud settling time MODEM1=(MODEM1&0x03)|0x24; // Reset preamble detection PDET &= ~0x80; PDET |= 0x80; INT_ENABLE (INUM_RF, INT_OFF); // Enable global interrupt INT_GLOBAL_ENABLE (INT_ON); void InitRF(void) bRF_RXdone = 0; rf_rx_index = 0; void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS) halRFSetRxTxOff(RF_RX, RF_SETTINGS, &RF_CALDATA); RF_START_RX(); INT_ENABLE (INUM_RF, INT_ON); void Wait1sec (void) halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); // Wait1sec 5. Slave.c #include "ms5535.h" #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <chipcon/reg1010.h> #include <chipcon/cc1010eb.h> #include <chipcon/hal.h> #define CLKFREQ CC1010EB_CLKFREQ #define PREAMBLE_BYTE_COUNT 18 #define PREAMBLE_BITS_SENSE_INIT 81 #define PREAMBLE_BITS_SENSE 16

Page 101: All_New(Luan Van Son)

- -

101

#define CMD_GET_PARAMS 1 // Temperature packet: #define TBC_NODE_ID_LENGTH 2 // word #define TBC_NODE_NAME_LENGTH 5 //20 #define TBC_TEMP_OFFSET (TBC_NODE_ID_LENGTH + TBC_NODE_NAME_LENGTH) #define TBC_TEMP_LENGTH 2 #define TBC_TEMP_OFFSET1 (TBC_NODE_ID_LENGTH + TBC_NODE_NAME_LENGTH + TBC_TEMP_LENGTH) #define TBC_TEMP_LENGTH1 2 #define TBC_TEMP_OFFSET2 (TBC_TEMP_OFFSET1 + TBC_TEMP_LENGTH1) #define TBC_TEMP_LENGTH2 2 #define TBC_TEMP_OFFSET3 (TBC_TEMP_OFFSET2 + TBC_TEMP_LENGTH2) #define TBC_TEMP_LENGTH3 2 #define TBC_TEMP_OFFSET4 (TBC_TEMP_OFFSET3 + TBC_TEMP_LENGTH3) #define TBC_TEMP_LENGTH4 2 #define TBC_TEMP_OFFSET5 (TBC_TEMP_OFFSET4 + TBC_TEMP_LENGTH4) #define TBC_TEMP_LENGTH5 2 #define TBC_DATA_LEN (TBC_TEMP_OFFSET5 + TBC_TEMP_LENGTH5) // Radio related: #define TBC_MY_SPP_ADDRESS 2 #define TBC_RX_INTERVAL 50 // Node registration #define TBC_INVALID_NODE_INDEX 255 #define TBC_UNUSED_NODE_ID 0x0000 #define MAJOR_PERIOD 1500 #define MINOR_PERIOD 100 #define AVG_COUNT 10 // The temperature "table": #define TBC_MAX_NODE_COUNT 16 word xdata nodeIDs[TBC_MAX_NODE_COUNT]; byte xdata nodeNames[TBC_MAX_NODE_COUNT][TBC_NODE_NAME_LENGTH]; word xdata nodeLastT[TBC_MAX_NODE_COUNT]; bit initrunflag = 1; byte xdata rxDataBuffer[TBC_DATA_LEN]; byte xdata txDataBuffer[TBC_DATA_LEN]; bool xdata bSample; // Unit name, stored in Flash byte code flashUnitName[TBC_NODE_NAME_LENGTH]; // RAM buffer for Flash copy byte xdata ramBufNonAligned[128]; bit bPolled; byte xdata rf_rx_buf[50]; byte xdata rf_rx_index; unsigned long xdata TMajorPeriod; bit bRF_RXdone; // Function prototypes void tbcWait1sec (void); void GetParameters (void); void RFProc(); void RFSetupReceive (void); void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS);

Page 102: All_New(Luan Van Son)

- -

102

void InitRF(void); void RFSetup(void); // X-tal frequency: 14.745600 MHz // RF frequency A: 868.277200 MHz Rx // RF frequency B: 868.277200 MHz Tx // RX Mode: Low side LO // Frequency separation: 64 kHz // Data rate: 2.4 kBaud // Data Format: Manchester // RF output power: 4 dBm // IF/RSSI: RSSI Enabled RF_RXTXPAIR_SETTINGS code RF_SETTINGS = 0x4B, 0x2F, 0x15, // Modem 0, 1 and 2: Manchester, 2.4 kBaud //0x43, 0x2F, 0x15, // Modem 0, 1 and 2: NRZ, 2.4 kBaud //0xA1, 0x2F, 0x29, // Modem 0, 1 and 2: NRZ, 38.4 kBaud //0xA0, 0x2F, 0x52, // Modem 0, 1 and 2: NRZ, 76.8 kBaud 0x75, 0xA0, 0x00, // Freq A 0x58, 0x32, 0x8D, // Freq B 0x01, 0xAB, // FSEP 1 and 0 0x40, // PLL_RX 0x30, // PLL_TX 0x6C, // CURRENT_RX 0xF3, // CURRENT_TX 0x32, // FREND 0xFF, // PA_POW 0x00, // MATCH 0x00, // PRESCALER ; RF_RXTXPAIR_CALDATA xdata RF_CALDATA; //---------------------------------------------------------------------------- // MAIN PROGRAM //---------------------------------------------------------------------------- void main (void) byte xdata n; // Initialize peripherals WDT_ENABLE(FALSE); // Startup macros for speed and low power consumption MEM_NO_WAIT_STATES(); FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS); halRFCalib(&RF_SETTINGS, &RF_CALDATA);// Calibrate RLED_OE(TRUE); YLED_OE(TRUE); GLED_OE(TRUE); BLED_OE(TRUE); RLED = LED_OFF; YLED = LED_OFF; GLED = LED_OFF; BLED = LED_OFF; bRF_RXdone = 0; rf_rx_index = 0; halConfigADC(ADC_MODE_SINGLE | ADC_REFERENCE_INTERNAL_1_25, CLKFREQ, 0); // Reset the node IDs for (n = 0; n < TBC_MAX_NODE_COUNT; n++) nodeIDs[n] = TBC_UNUSED_NODE_ID; // Reset our name buffer

Page 103: All_New(Luan Van Son)

- -

103

for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) nodeNames[0][n] = 0x00; // Load name from Flash memcpy(&nodeNames[0][0],flashUnitName,TBC_NODE_NAME_LENGTH); nodeIDs[0] = TBC_MY_SPP_ADDRESS; // Prepare the id+name part of the packet txDataBuffer[0] = (nodeIDs[0] >> 8) & 0xFF; txDataBuffer[1] = nodeIDs[0] & 0xFF; for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) txDataBuffer[n + TBC_NODE_ID_LENGTH] = nodeNames[0][n]; InitMS5535(); RFSetupReceive (); // Loop forever while (TRUE) RFProc(); // main void tbcWait1sec (void) halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); // tbcWait1sec void GetParameters(void) word xdata temp; word xdata temp1; word xdata temp2; word xdata temp3; word xdata temp4; word xdata p; word xdata i; temp = 0; temp1 = 0; temp2 = 0; temp3 = 0; temp4 = 0; // Indicate transmission for(i=0;i<4;i++) TIMER2_RUN(TRUE); halWait (1, CLKFREQ); readMS5535Values(&temp3,&temp4); TIMER2_RUN(FALSE); if(i==0) p = temp3; else p = (p+temp3)/2;

Page 104: All_New(Luan Van Son)

- -

104

tbcWait1sec(); ADC_POWER(TRUE); // Power up the ADC and sample the temperature ADC_SELECT_INPUT(ADC_INPUT_AD0); ADC_SAMPLE_SINGLE(); temp = ADC_GET_SAMPLE_10BIT(); ADC_SELECT_INPUT(ADC_INPUT_AD1); ADC_SAMPLE_SINGLE(); temp1 = ADC_GET_SAMPLE_10BIT(); ADC_SELECT_INPUT(ADC_INPUT_AD2); ADC_SAMPLE_SINGLE(); temp2 = ADC_GET_SAMPLE_10BIT(); ADC_POWER(FALSE); // Update the TX buffer and the table with the new temperature txDataBuffer[TBC_TEMP_OFFSET] = (temp >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET + 1] = temp & 0xFF; txDataBuffer[TBC_TEMP_OFFSET1] = (temp1 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET1 + 1] = temp1 & 0xFF; txDataBuffer[TBC_TEMP_OFFSET2] = (temp2 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET2 + 1] = temp2 & 0xFF; txDataBuffer[TBC_TEMP_OFFSET3] = (temp3 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET3 + 1] = temp3 & 0xFF; txDataBuffer[TBC_TEMP_OFFSET4] = (temp4 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET4 + 1] = temp4 & 0xFF; txDataBuffer[TBC_TEMP_OFFSET5] = 0;//(temp5 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET5 + 1] = 0;//temp5 & 0xFF; // tbcTransmit // Flash interrupt handler (do nothing) // We need to handle the interrupt even though we do not do anything. // If not, the program will not run correctly except under the debugger, // which has its own Flash interrupt handler void FlashIntrHandler(void) interrupt INUM_FLASH INT_SETFLAG(INUM_FLASH, INT_CLR); return; //timer 10ms void TIMER0_ISR() interrupt INUM_TIMER0 TF0 = 0; TH0 = 0xd0; TL0 = 0; TR0 = 1; if(TMajorPeriod==0)

Page 105: All_New(Luan Van Son)

- -

105

bSample = 1; TMajorPeriod = MAJOR_PERIOD + 1; TMajorPeriod--; void RF_ISR (void) interrupt INUM_RF INT_ENABLE(INUM_RF, INT_OFF); INT_SETFLAG (INUM_RF, INT_CLR); if(!bRF_RXdone) // Get RF receive data rf_rx_buf[rf_rx_index] = RF_RECEIVE_BYTE(); if(rf_rx_index==0) RF_LOCK_AVERAGE_FILTER(TRUE); if(rf_rx_buf[rf_rx_index] != RF_SUITABLE_SYNC_BYTE) RLED = LED_ON; rf_rx_index++; if(rf_rx_index>/*rf_rx_buf[1]+1*/6) rf_rx_index = 0; bRF_RXdone = 1; PDET &= ~0x80; PDET |= 0x80; INT_ENABLE(INUM_RF, INT_ON); GLED = !GLED; return; void RFProc() if(!bRF_RXdone) return; if(rf_rx_buf[0]==RF_SUITABLE_SYNC_BYTE) INT_ENABLE(INUM_RF, INT_OFF); if(rf_rx_buf[3]==CMD_GET_PARAMS) GetParameters(); halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); RF_START_TX(); halRFSendPacket(PREAMBLE_BYTE_COUNT,&txDataBuffer[0],TBC_DATA

_LEN); PrepareRX(&RF_SETTINGS); InitRF(); void RFSetupReceive (void) // Disable global interrupt INT_GLOBAL_ENABLE (INT_OFF); // Setup RF interrupt INT_SETFLAG (INUM_RF, INT_CLR); INT_PRIORITY (INUM_RF, INT_HIGH);

Page 106: All_New(Luan Van Son)

- -

106

INT_ENABLE (INUM_RF, INT_ON); // Enable RF interrupt based on bytemode RF_SET_BYTEMODE(); // Setup preamble configuration RF_SET_PREAMBLE_COUNT(PREAMBLE_BYTE_COUNT); RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE); // Make sure avg filter is free-running + 22 baud settling time MODEM1=(MODEM1&0x03)|0x24; // Reset preamble detection PDET &= ~0x80; PDET |= 0x80; halRFSetRxTxOff(RF_RX, &RF_SETTINGS, &RF_CALDATA); // Start RX RF_START_RX(); // Enable global interrupt INT_GLOBAL_ENABLE (INT_ON); void InitRF(void) bRF_RXdone = 0; rf_rx_index = 0; void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS) halRFSetRxTxOff(RF_RX, RF_SETTINGS, &RF_CALDATA); RF_START_RX(); INT_ENABLE (INUM_RF, INT_ON); void Wait1sec (void) halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); // Wait1sec // Setup RF void RFSetup(void) InitRF(); halRFCalib(&RF_SETTINGS, &RF_CALDATA); halRFSetRxTxOff(RF_OFF, &RF_SETTINGS, &RF_CALDATA); // Disable global interrupt INT_GLOBAL_ENABLE (INT_OFF); // Setup RF interrupt INT_SETFLAG (INUM_RF, INT_CLR); INT_PRIORITY (INUM_RF, INT_HIGH); // Select RF bytemode

Page 107: All_New(Luan Van Son)

- -

107

RFCON |= 0x01; // Enable RF interrupt based on bytemode RF_SET_BYTEMODE(); // Setup preamble configuration RF_SET_PREAMBLE_COUNT(PREAMBLE_BYTE_COUNT); RF_SET_PREAMBLE_COUNT(16); RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE); // Make sure avg filter is free-running + 22 baud settling time MODEM1=(MODEM1&0x03)|0x24; // Reset preamble detection PDET &= ~0x80; PDET |= 0x80; // Enable global interrupt INT_GLOBAL_ENABLE (INT_ON);

Phụ lục 2: Chương trình thử nghiệm vấn đề tiết kiệm năng lượng Phần mềm viết cho Master bao gồm các file: Common.h, Master.c Phần mềm viết cho Slave bao gồm các file: Common.h, Slave.c, Slave.h, MS5535.c, MS5535.h

1. Common.h #ifndef common_h #define common_h// Only include this header file once #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <chipcon/reg1010.h> #include <chipcon/cc1010eb.h> #include <chipcon/hal.h> /************************************************************************** * RF RX/TX-pair settings extracted from Chipcon's SmartRF studio * **************************************************************************/ RF_RXTXPAIR_SETTINGS code RF_SETTINGS = 0x4B, 0x2F, 0x15, // Modem 0, 1 and 2 0xAA, 0x80, 0x00, // Freq A 0x5C, 0xF4, 0x02, // Freq B 0x01, 0xAB, // FSEP 1 and 0 0x58, // PLL_RX 0x30, // PLL_TX 0x6C, // CURRENT_RX 0xF3, // CURRENT_TX 0x32, // FREND 0xFF, // PA_POW 0x00, // MATCH 0x00, // PRESCALER ; // Calibration data RF_RXTXPAIR_CALDATA xdata RF_CALDATA; #define PREAMBLE_BYTE_COUNT 18 #define PREAMBLE_BITS_SENSE_INIT 81

Page 108: All_New(Luan Van Son)

- -

108

#define PREAMBLE_BITS_SENSE 16 #endif 2. Slave.c #include "ms5535.h" #include "..\common\common.h" // Temperature packet: #define TBC_NODE_ID_LENGTH 2 // word #define TBC_NODE_NAME_LENGTH 5 //20 #define TBC_TEMP_OFFSET (TBC_NODE_ID_LENGTH + TBC_NODE_NAME_LENGTH) #define TBC_TEMP_LENGTH 2 #define TBC_TEMP_OFFSET1 (TBC_NODE_ID_LENGTH + TBC_NODE_NAME_LENGTH + TBC_TEMP_LENGTH) #define TBC_TEMP_LENGTH1 2 #define TBC_TEMP_OFFSET2 (TBC_TEMP_OFFSET1 + TBC_TEMP_LENGTH1) #define TBC_TEMP_LENGTH2 2 #define TBC_TEMP_OFFSET3 (TBC_TEMP_OFFSET2 + TBC_TEMP_LENGTH2) #define TBC_TEMP_LENGTH3 2 #define TBC_TEMP_OFFSET4 (TBC_TEMP_OFFSET3 + TBC_TEMP_LENGTH3) #define TBC_TEMP_LENGTH4 2 #define TBC_TEMP_OFFSET5 (TBC_TEMP_OFFSET4 + TBC_TEMP_LENGTH4) #define TBC_TEMP_LENGTH5 2 #define TBC_DATA_LEN (TBC_TEMP_OFFSET5 + TBC_TEMP_LENGTH5) // Radio related: #define TBC_MY_SPP_ADDRESS 2 #define TBC_RX_INTERVAL 50 // Node registration #define TBC_INVALID_NODE_INDEX 255 #define TBC_UNUSED_NODE_ID 0x0000 #define MAJOR_PERIOD 1500//30000:5minutes, 360000:1 hour, 1500: 15sec #define MINOR_PERIOD 100 #define AVG_COUNT 10 // Speed related byte xdata waitMultiplier; // The temperature "table": #define TBC_MAX_NODE_COUNT 16 word xdata nodeIDs[TBC_MAX_NODE_COUNT]; byte xdata nodeNames[TBC_MAX_NODE_COUNT][TBC_NODE_NAME_LENGTH]; word xdata nodeLastT[TBC_MAX_NODE_COUNT]; bit initrunflag = 1; unsigned long xdata TMajorPeriod; byte xdata rxDataBuffer[TBC_DATA_LEN]; byte xdata txDataBuffer[TBC_DATA_LEN]; byte xdata avgcnt; bool xdata bSample; // Function prototypes void tbcWait1sec (void); void GetParameters (void); void setupTimer0(); void RFSetupTransmit (void); void SelectClockMode(char iMode); // Unit name, stored in Flash byte code flashUnitName[TBC_NODE_NAME_LENGTH];

Page 109: All_New(Luan Van Son)

- -

109

// RAM buffer for Flash copy byte xdata ramBufNonAligned[128]; byte xdata received_byte; word xdata counter,counter2; //---------------------------------------------------------------------------- // MAIN PROGRAM //---------------------------------------------------------------------------- void main (void) byte xdata n; byte xdata m; // Initialize peripherals WDT_ENABLE(FALSE); RLED_OE(TRUE); YLED_OE(TRUE); GLED_OE(TRUE); BLED_OE(TRUE); // Startup macros for speed and low power consumption MEM_NO_WAIT_STATES(); FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS); // ADC setup halConfigADC(ADC_MODE_SINGLE | ADC_REFERENCE_INTERNAL_1_25, CLKFREQ, 0); RFSetupTransmit(); // Reset the node IDs for (n = 0; n < TBC_MAX_NODE_COUNT; n++) nodeIDs[n] = TBC_UNUSED_NODE_ID; // Reset our name buffer for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) nodeNames[0][n] = 0x00; // Load name from Flash memcpy(&nodeNames[0][0],flashUnitName,TBC_NODE_NAME_LENGTH); nodeIDs[0] = TBC_MY_SPP_ADDRESS; // Prepare the id+name part of the packet txDataBuffer[0] = (nodeIDs[0] >> 8) & 0xFF; txDataBuffer[1] = nodeIDs[0] & 0xFF; for (n = 0; n < TBC_NODE_NAME_LENGTH; n++) txDataBuffer[n + TBC_NODE_ID_LENGTH] = nodeNames[0][n]; InitMS5535(); // Configure realtime clock to support wake-up from IDLE halConfigRealTimeClock(15); // Enable realtime clock (implicit: interrupt enable) RTC_RUN(TRUE); SelectClockMode(1); // Loop forever

Page 110: All_New(Luan Van Son)

- -

110

while (TRUE) if(bSample) SelectClockMode(0); BLED = LED_ON; GetParameters(); halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); halRFSendPacket(PREAMBLE_BYTE_COUNT, txDataBuffer, TBC_DATA_LEN); halRFSetRxTxOff(RF_OFF, &RF_SETTINGS, &RF_CALDATA); GLED = !GLED; tbcWait1sec(); halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); halRFSendPacket(PREAMBLE_BYTE_COUNT, txDataBuffer, TBC_DATA_LEN); halRFSetRxTxOff(RF_OFF, &RF_SETTINGS, &RF_CALDATA); GLED = !GLED; bSample = 0; BLED = LED_OFF; SelectClockMode(1); //main void tbcWait1sec (void) halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); // tbcWait1sec void GetParameters(void) word xdata temp, temp1, temp2, temp3, temp4, p, i; temp = 0; temp1 = 0; temp2 = 0; temp3 = 0; temp4 = 0; // Indicate transmission for(i=0;i<4;i++) TIMER2_RUN(TRUE); halWait (1, CLKFREQ); readMS5535Values(&temp3,&temp4); TIMER2_RUN(FALSE); if(i==0) p = temp3; else p = (p+temp3)/2; tbcWait1sec(); ADC_POWER(TRUE); // Power up the ADC and sample the temperature ADC_SELECT_INPUT(ADC_INPUT_AD0); ADC_SAMPLE_SINGLE(); temp = ADC_GET_SAMPLE_10BIT(); ADC_SELECT_INPUT(ADC_INPUT_AD1); ADC_SAMPLE_SINGLE();

Page 111: All_New(Luan Van Son)

- -

111

temp1 = ADC_GET_SAMPLE_10BIT(); ADC_SELECT_INPUT(ADC_INPUT_AD2); ADC_SAMPLE_SINGLE(); temp2 = ADC_GET_SAMPLE_10BIT(); ADC_POWER(FALSE); // Update the TX buffer and the table with the new temperature txDataBuffer[TBC_TEMP_OFFSET] = (temp >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET + 1] = temp & 0xFF; txDataBuffer[TBC_TEMP_OFFSET1] = (temp1 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET1 + 1] = temp1 & 0xFF; txDataBuffer[TBC_TEMP_OFFSET2] = (temp2 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET2 + 1] = temp2 & 0xFF; txDataBuffer[TBC_TEMP_OFFSET3] = (temp3 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET3 + 1] = temp3 & 0xFF; txDataBuffer[TBC_TEMP_OFFSET4] = (temp4 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET4 + 1] = temp4 & 0xFF; txDataBuffer[TBC_TEMP_OFFSET5] = 0;//(temp5 >> 8) & 0xFF; txDataBuffer[TBC_TEMP_OFFSET5 + 1] = 0;//temp5 & 0xFF; // tbcTransmit void setupTimer0() TMajorPeriod = 0; bSample = 0; TH0 = 100; TL0 = 100; TMOD = TMOD | 0x1; //timer0 mode1-16 bit timer INT_ENABLE(INUM_TIMER0, INT_ON); INT_GLOBAL_ENABLE (INT_ON); CKCON = CKCON & 0xf7; IE = IE|0x80; TF0 = 1; // Flash interrupt handler (do nothing) // We need to handle the interrupt even though we do not do anything. // If not, the program will not run correctly except under the debugger, // which has its own Flash interrupt handler void FlashIntrHandler(void) interrupt INUM_FLASH INT_SETFLAG(INUM_FLASH, INT_CLR); return; //timer 10ms void TIMER0_ISR() interrupt INUM_TIMER0 TF0 = 0; TH0 = 0xd0; TL0 = 0; TR0 = 1;

Page 112: All_New(Luan Van Son)

- -

112

if(TMajorPeriod==0) bSample = 1; TMajorPeriod = MAJOR_PERIOD+1; TMajorPeriod--; // Setup RF for RX void RFSetupTransmit (void) halRFCalib(&RF_SETTINGS, &RF_CALDATA); // Turn on RF for TX halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); INT_ENABLE(INUM_RF, INT_OFF); // Select RF bytemode RFCON |= 0x01; // Enable RF interrupt based on bytemode RF_SET_BYTEMODE(); // Setup preamble configuration RF_SET_PREAMBLE_COUNT(16); RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE); // Make sure avg filter is free-running + 22 baud settling time MODEM1=(MODEM1&0x03)|0x24; // Reset preamble detection PDET &= ~0x80; PDET |= 0x80; //================================================================ void SelectClockMode(char iMode) if(iMode==0) // Enable high speed XOSC, switch clock source, then disable 32kHz XOSC XOSC_ENABLE(TRUE); MAIN_CLOCK_SET_SOURCE(CLOCK_XOSC); X32_ENABLE(FALSE); PCON = PCON & 0xfe; //disable idle mode else if(iMode==1) // Enable 32kHz oscillator, wait 0.5s to stabilize, // then switch clock source, then disable high-speed XOSC X32_INPUT_SOURCE(X32_USING_CRYSTAL); X32_ENABLE(TRUE); halWait(250, CC1010EB_CLKFREQ); halWait(250, CC1010EB_CLKFREQ); MAIN_CLOCK_SET_SOURCE(CLOCK_X32); XOSC_ENABLE(FALSE); PCON = PCON | 0x01; //enable idle mode

Page 113: All_New(Luan Van Son)

- -

113

// ISR (interrupt service routine) for RTC, priority 11 // The interrupt must be cleared by software void isr_rtc() interrupt INUM_RTC //RTC_RUN(FALSE); bSample = 1; INT_SETFLAG(INUM_RTC, INT_CLR); RLED = !RLED; 3. MS5535.h Sử dụng lại file MS5535.h của phụ lục 1 4. MS5535.c Sử dụng lại file MS5535.c của phụ lục 1

Phụ lục 3: Chương trình thử nghiệm truyền đa bước (multihop) Phần mềm viết cho Master bao gồm các file: Common.h, Master.c, Tree.c, Tree.h Phần mềm viết cho Slave bao gồm các file: Common.h, Slave.c, Slave.h, MS5535.c, MS5535.h, Tree.c, Tree.h

1. Common.h #ifndef common_h #define common_h// Only include this header file once #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <chipcon/reg1010.h> #include <chipcon/cc1010eb.h> #include <chipcon/hal.h> #define CLKFREQ CC1010EB_CLKFREQ #define CMD_ACK 0xF0 #define CMD_NACK 0xFF #define CMD_RTS 0xFE #define CMD_CTS 0xFD #define CMD_SYNC 0xFC #define CMD_HELLO 0xE0 #define CMD_GET_PARAMS 1 #define PREAMBLE_BYTE_COUNT 18 #define PREAMBLE_BITS_SENSE_INIT 81 #define PREAMBLE_BITS_SENSE 16 #define MASTER_ADDR 1 void RFSetup(void); void setupTimer0(); void InitRF(void); void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS); void Wait1sec (void); void SelectClockMode(char iMode); #endif 2. Master.c #include "..\common\common.h" #include "..\common\tree.h"

Page 114: All_New(Luan Van Son)

- -

114

// Temperature packet: #define NODE_ID_OFFSET 0 #define NODE_ID_PARENT_OFFSET 1 #define NODE_ID_NEXTHOP_OFFSET 2 #define NODE_CMD_OFFSET 3 #define TEMP_OFFSET 4 #define TEMP_LENGTH 2 #define TEMP_OFFSET1 (TEMP_OFFSET + TEMP_LENGTH) #define TEMP_LENGTH1 2 #define TEMP_OFFSET2 (TEMP_OFFSET1 + TEMP_LENGTH1) #define TEMP_LENGTH2 2 #define TEMP_OFFSET3 (TEMP_OFFSET2 + TEMP_LENGTH2) #define TEMP_LENGTH3 2 #define TEMP_OFFSET4 (TEMP_OFFSET3 + TEMP_LENGTH3) #define TEMP_LENGTH4 2 #define TEMP_OFFSET5 (TEMP_OFFSET4 + TEMP_LENGTH4) #define TEMP_LENGTH5 2 #define DATA_LEN (TEMP_OFFSET5 + TEMP_LENGTH5) // Radio related: #define MY_ADDRESS 1 // Node registration #define INVALID_NODE_INDEX 255 #define UNUSED_NODE_ID 0x0000 #define MAJOR_PERIOD 200 #define MINOR_PERIOD 10 #define RF_RX_BUF_SIZE 50 #define TEST_STRING_LENGTH 10 #define N_NODES 11 word xdata nodeIDs,nodeLastT; word xdata nodeTemps, nodeTemps1,nodeTemps2, nodeTemps3, nodeTemps4, nodeTemps5; byte xdata rxDataBuffer[DATA_LEN], txDataBuffer[DATA_LEN]; // Function prototypes void Receive (void); void PrintTable (byte nodeindex); void CmdGetParams(char node); void RFSetup(void); void setupTimer0(); void InitRF(void); void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS); void Wait1sec (void); byte xdata rf_rx_index,rf_rx_buf[50]; unsigned long xdata TMajorPeriod; bit bRF_Rxdone,bPolled; // X-tal frequency: 14.745600 MHz // RF frequency A: 868.277200 MHz Rx // RF frequency B: 868.277200 MHz Tx // RX Mode: Low side LO // Frequency separation: 64 kHz // Data rate: 2.4 kBaud // Data Format: Manchester // RF output power: 4 dBm

Page 115: All_New(Luan Van Son)

- -

115

// IF/RSSI: RSSI Enabled RF_RXTXPAIR_SETTINGS code RF_SETTINGS = 0x4B, 0x2F, 0x15, // Modem 0, 1 and 2: Manchester, 2.4 kBaud //0x43, 0x2F, 0x15, // Modem 0, 1 and 2: NRZ, 2.4 kBaud //0xA1, 0x2F, 0x29, // Modem 0, 1 and 2: NRZ, 38.4 kBaud //0xA0, 0x2F, 0x52, // Modem 0, 1 and 2: NRZ, 76.8 kBaud 0x75, 0xA0, 0x00, // Freq A 0x58, 0x32, 0x8D, // Freq B 0x01, 0xAB, // FSEP 1 and 0 0x40, // PLL_RX 0x30, // PLL_TX 0x6C, // CURRENT_RX 0xF3, // CURRENT_TX 0x32, // FREND 0xFF, // PA_POW 0x00, // MATCH 0x00, // PRESCALER ; RF_RXTXPAIR_CALDATA xdata RF_CALDATA; //---------------------------------------------------------------------------- // MAIN PROGRAM //---------------------------------------------------------------------------- void main (void) byte xdata n; BuildTree(); // Initialize peripherals WDT_ENABLE(FALSE); RLED_OE(TRUE); YLED_OE(TRUE); GLED_OE(TRUE); BLED_OE(TRUE); RLED = LED_OFF; // Startup macros for speed and low power consumption MEM_NO_WAIT_STATES(); FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS); // Setup UART0 for polled I/O UART0_SETUP(57600, CLKFREQ, UART_NO_PARITY | UART_RX_TX | UART_POLLED); nodeIDs = MY_ADDRESS; setupTimer0(); RFSetup(); // Calibration halRFCalib(&RF_SETTINGS, &RF_CALDATA); // Turn on RF for RX halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); RF_START_TX(); halRFReadRSSIlevel(RSSI_MODE_INIT); n=2; // Loop forever while (TRUE) if(bPolled) InitRF();

Page 116: All_New(Luan Van Son)

- -

116

CmdGetParams(n); PrepareRX(&RF_SETTINGS); n++; if(n>N_NODES) n=2; bPolled = 0; Receive(); // main void Receive (void) byte xdata i; word xdata nodeID,crc,crc1; if(!bRF_RXdone) return; crc = culFastCRC16Block(&rxDataBuffer[1], DATA_LEN, CRC16_INIT); crc1 = rxDataBuffer[DATA_LEN]; crc1 = (crc1<<8)|rxDataBuffer[DATA_LEN-1]; if(crc!=crc1) return; INT_ENABLE(INUM_RF, INT_OFF); if(rf_rx_buf[0]==RF_SUITABLE_SYNC_BYTE && rf_rx_buf[3]==MY_ADDRESS) BLED = !BLED; for(i=0;i<DATA_LEN;i++) rxDataBuffer[i]= rf_rx_buf[i+3]; // Get the node ID nodeID = rxDataBuffer[3]; //Endpoint // Update the table if (nodeID != INVALID_NODE_INDEX) nodeIDs = nodeID; nodeTemps = (rxDataBuffer[TEMP_OFFSET] << 8) + rxDataBuffer[TEMP_OFFSET + 1]; nodeTemps1 = (rxDataBuffer[TEMP_OFFSET1] << 8) + rxDataBuffer[TEMP_OFFSET1 + 1]; nodeTemps2 = (rxDataBuffer[TEMP_OFFSET2] << 8) + rxDataBuffer[TEMP_OFFSET2 + 1]; nodeTemps3 = (rxDataBuffer[TEMP_OFFSET3] << 8) + rxDataBuffer[TEMP_OFFSET3 + 1]; nodeTemps4 = (rxDataBuffer[TEMP_OFFSET4] << 8) + rxDataBuffer[TEMP_OFFSET4 + 1]; nodeTemps5 = (rxDataBuffer[TEMP_OFFSET5] << 8) + rxDataBuffer[TEMP_OFFSET5 + 1]; nodeLastT = 0; PrintTable(nodeID); InitRF(); INT_ENABLE(INUM_RF, INT_ON); // Receive void PrintTable (byte nodeindex) float xdata fTemp; printf("%d", nodeIDs);

Page 117: All_New(Luan Van Son)

- -

117

// Temperature: printf(" %d", nodeTemps); //ad0 fTemp = nodeTemps1; //ad1 fTemp -= 492; fTemp /= 8.192; if(fTemp<0) fTemp=0; printf(" %.1f", fTemp); printf(" %d", nodeTemps2); //ad2 printf(" %d", nodeTemps3); //ms5535_p printf(" %d", nodeTemps4); //ms5535_t printf(" %d", nodeindex/*nodeTemps5[n]*/); //level // Time after the last update //timeDiff = abs((int) sppGetTime() - nodeLastT[n]) * 10; printf(" %d\n", nodeindex/*timeDiff*/); // PrintTable // Flash interrupt handler (do nothing) // We need to handle the interrupt even though we do not do anything. // If not, the program will not run correctly except under the debugger, // which has its own Flash interrupt handler void FlashIntrHandler(void) interrupt INUM_FLASH INT_SETFLAG(INUM_FLASH, INT_CLR); return; // RF interrupt service routine: void RF_ISR (void) interrupt INUM_RF INT_ENABLE(INUM_RF, INT_OFF); INT_SETFLAG (INUM_RF, INT_CLR); if(!bRF_RXdone) // Get RF receive data rf_rx_buf[rf_rx_index] = RF_RECEIVE_BYTE(); if(rf_rx_index==0) RF_LOCK_AVERAGE_FILTER(TRUE); if(rf_rx_buf[rf_rx_index] != RF_SUITABLE_SYNC_BYTE) RLED = LED_ON; rf_rx_index++; if(rf_rx_index > rf_rx_buf[1] + 3) rf_rx_index = 0; bRF_RXdone = 1; PDET &= ~0x80; PDET |= 0x80; INT_ENABLE(INUM_RF, INT_OFF); YLED = !YLED; return; INT_ENABLE(INUM_RF, INT_ON); YLED = !YLED; return;

Page 118: All_New(Luan Van Son)

- -

118

//timer 10ms void TIMER0_ISR() interrupt INUM_TIMER0 TF0 = 0; TH0 = 0xd0; TL0 = 0; TR0 = 1; if(TMajorPeriod == 0) bPolled = 1; TMajorPeriod = MAJOR_PERIOD + 1; TMajorPeriod--; void CmdGetParams(char node) char xdata nexthop; INT_ENABLE (INUM_RF, INT_OFF); GLED = LED_ON; nexthop = FindNextHop(MY_ADDRESS,node); txDataBuffer[0] = MY_ADDRESS; //source address txDataBuffer[1] = nexthop; //next hop txDataBuffer[2] = node; //Endpoint address txDataBuffer[3] = CMD_GET_PARAMS; //command halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); RF_START_TX(); halRFSendPacket(PREAMBLE_BYTE_COUNT, &txDataBuffer[0], 4); GLED = LED_OFF; halRFSetRxTxOff(RF_RX, &RF_SETTINGS, &RF_CALDATA); RF_START_RX(); INT_SETFLAG (INUM_RF, INT_CLR); INT_ENABLE (INUM_RF, INT_ON); void setupTimer0() TMajorPeriod = 0; bPolled = 0; TH0 = 100; TL0 = 100; TMOD = TMOD | 0x1; //timer0 mode1-16 bit timer INT_ENABLE(INUM_TIMER0, INT_ON); INT_GLOBAL_ENABLE (INT_ON); CKCON = CKCON & 0xf7; TF0 = 1; // Setup RF void RFSetup(void) InitRF(); halRFCalib(&RF_SETTINGS, &RF_CALDATA); halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA);

Page 119: All_New(Luan Van Son)

- -

119

// Disable global interrupt INT_GLOBAL_ENABLE (INT_OFF); // Setup RF interrupt INT_SETFLAG (INUM_RF, INT_CLR); INT_PRIORITY (INUM_RF, INT_HIGH); // Select RF bytemode RFCON |= 0x01; // Enable RF interrupt based on bytemode RF_SET_BYTEMODE(); // Setup preamble configuration RF_SET_PREAMBLE_COUNT(PREAMBLE_BYTE_COUNT); RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE); // Make sure avg filter is free-running + 22 baud settling time MODEM1=(MODEM1&0x03)|0x24; // Reset preamble detection PDET &= ~0x80; PDET |= 0x80; INT_ENABLE (INUM_RF, INT_OFF); // Enable global interrupt INT_GLOBAL_ENABLE (INT_ON); void InitRF(void) bRF_RXdone = 0; rf_rx_index = 0; void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS) halRFSetRxTxOff(RF_RX, RF_SETTINGS, &RF_CALDATA); RF_START_RX(); INT_ENABLE (INUM_RF, INT_ON); void Wait1sec (void) halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); // Wait1sec 3. Slave.c #include "ms5535.h" #include "..\common\common.h" #include "..\common\tree.h" #include <cul.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <chipcon/reg1010.h> #include <chipcon/cc1010eb.h>

Page 120: All_New(Luan Van Son)

- -

120

#include <chipcon/hal.h> // Temperature packet: //#define NODE_ID_LENGTH 1 #define NODE_ID_OFFSET 0 #define NODE_ID_PARENT_OFFSET 1 #define NODE_ID_NEXTHOP_OFFSET 2 #define NODE_CMD_OFFSET 3 #define TEMP_OFFSET 4 #define TEMP_LENGTH 2 #define TEMP_OFFSET1 (TEMP_OFFSET + TEMP_LENGTH) #define TEMP_LENGTH1 2 #define TEMP_OFFSET2 (TEMP_OFFSET1 + TEMP_LENGTH1) #define TEMP_LENGTH2 2 #define TEMP_OFFSET3 (TEMP_OFFSET2 + TEMP_LENGTH2) #define TEMP_LENGTH3 2 #define TEMP_OFFSET4 (TEMP_OFFSET3 + TEMP_LENGTH3) #define TEMP_LENGTH4 2 #define TEMP_OFFSET5 (TEMP_OFFSET4 + TEMP_LENGTH4) #define TEMP_LENGTH5 2 #define DATA_LEN (TEMP_OFFSET5 + TEMP_LENGTH5) // Radio related: #define MY_ADDRESS 3 #define RX_INTERVAL 50 // Node registration #define INVALID_NODE_INDEX 255 #define UNUSED_NODE_ID 0x0000 #define MAJOR_PERIOD 1500 #define MINOR_PERIOD 100 #define AVG_COUNT 10 // The temperature "table": #define MAX_NODE_COUNT 16 word xdata nodeIDs[MAX_NODE_COUNT]; word xdata nodeTemps[MAX_NODE_COUNT]; word xdata nodeTemps1[MAX_NODE_COUNT]; word xdata nodeTemps2[MAX_NODE_COUNT]; word xdata nodeTemps3[MAX_NODE_COUNT]; word xdata nodeTemps4[MAX_NODE_COUNT]; word xdata nodeTemps5[MAX_NODE_COUNT]; word xdata nodeLastT[MAX_NODE_COUNT]; bit initrunflag = 1; byte xdata rxDataBuffer[DATA_LEN]; byte xdata txDataBuffer[DATA_LEN]; bool xdata bSample; byte ParentID; //ID of parent void RandomWait(byte waitMultiplier); // RAM buffer for Flash copy byte xdata ramBufNonAligned[128]; bit bPolled; byte xdata rf_rx_buf[50]; byte xdata rf_rx_index;

Page 121: All_New(Luan Van Son)

- -

121

unsigned long xdata TMajorPeriod; bit bRF_RXdone; // Function prototypes void tbcWait1sec (void); void GetParameters (void); void RFProc(); void RFSetupReceive (void); void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS); void InitRF(void); void Receive (void); // X-tal frequency: 14.745600 MHz // RF frequency A: 868.277200 MHz Rx // RF frequency B: 868.277200 MHz Tx // RX Mode: Low side LO // Frequency separation: 64 kHz // Data rate: 2.4 kBaud // Data Format: Manchester // RF output power: 4 dBm // IF/RSSI: RSSI Enabled RF_RXTXPAIR_SETTINGS code RF_SETTINGS = 0x4B, 0x2F, 0x15, // Modem 0, 1 and 2: Manchester, 2.4 kBaud //0x43, 0x2F, 0x15, // Modem 0, 1 and 2: NRZ, 2.4 kBaud //0xA1, 0x2F, 0x29, // Modem 0, 1 and 2: NRZ, 38.4 kBaud //0xA0, 0x2F, 0x52, // Modem 0, 1 and 2: NRZ, 76.8 kBaud 0x75, 0xA0, 0x00, // Freq A 0x58, 0x32, 0x8D, // Freq B 0x01, 0xAB, // FSEP 1 and 0 0x40, // PLL_RX 0x30, // PLL_TX 0x6C, // CURRENT_RX 0xF3, // CURRENT_TX 0x32, // FREND 0xFF, // PA_POW 0x00, // MATCH 0x00, // PRESCALER ; RF_RXTXPAIR_CALDATA xdata RF_CALDATA; byte xdata n; int xdata k; //---------------------------------------------------------------------------- // MAIN PROGRAM //---------------------------------------------------------------------------- void main (void) BuildTree(); // Initialize peripherals WDT_ENABLE(FALSE); // Enable the LEDs RLED_OE(TRUE); YLED_OE(TRUE); GLED_OE(TRUE); BLED_OE(TRUE); RLED = LED_OFF; YLED = LED_OFF; GLED = LED_OFF; BLED = LED_OFF;

Page 122: All_New(Luan Van Son)

- -

122

// Startup macros for speed and low power consumption MEM_NO_WAIT_STATES(); FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS); halRFCalib(&RF_SETTINGS, &RF_CALDATA); // Calibrate halRFSetRxTxOff(RF_RX, &RF_SETTINGS, &RF_CALDATA); // Turn on RF for RX // ADC setup halConfigADC(ADC_MODE_SINGLE | ADC_REFERENCE_INTERNAL_1_25, CLKFREQ, 0); // Reset the node IDs for (n = 0; n < MAX_NODE_COUNT; n++) nodeIDs[n] = UNUSED_NODE_ID; nodeIDs[0] = MY_ADDRESS; // Prepare the id+name part of the packet txDataBuffer[0] = nodeIDs[0]; InitMS5535(); RFSetupReceive (); // Loop forever while (TRUE) RFProc(); // main void tbcWait1sec (void) halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); // tbcWait1sec void GetParameters(void) word xdata temp, temp1, temp2, temp3, temp4; temp = 0;temp1 = 0;temp2 = 0;temp3 = 0;temp4 = 0; // Indicate transmission TIMER2_RUN(TRUE); halWait (1, CLKFREQ); readMS5535Values(&temp3,&temp4); TIMER2_RUN(FALSE); ADC_POWER(TRUE); // Power up the ADC and sample the temperature ADC_SELECT_INPUT(ADC_INPUT_AD0); ADC_SAMPLE_SINGLE(); temp = ADC_GET_SAMPLE_10BIT(); ADC_SELECT_INPUT(ADC_INPUT_AD1); ADC_SAMPLE_SINGLE(); temp1 = ADC_GET_SAMPLE_10BIT(); ADC_SELECT_INPUT(ADC_INPUT_AD2); ADC_SAMPLE_SINGLE();

Page 123: All_New(Luan Van Son)

- -

123

temp2 = ADC_GET_SAMPLE_10BIT(); ADC_POWER(FALSE); // Update the TX buffer and the table with the new temperature txDataBuffer[4] = (temp >> 8) & 0xFF; txDataBuffer[5] = temp & 0xFF; txDataBuffer[6] = (temp1 >> 8) & 0xFF; txDataBuffer[7] = temp1 & 0xFF; txDataBuffer[8] = (temp2 >> 8) & 0xFF; txDataBuffer[9] = temp2 & 0xFF; txDataBuffer[10] = (temp3 >> 8) & 0xFF; txDataBuffer[11] = temp3 & 0xFF; txDataBuffer[12] = (temp4 >> 8) & 0xFF; txDataBuffer[13] = temp4 & 0xFF; txDataBuffer[14] = 0;//(temp5 >> 8) & 0xFF; txDataBuffer[15] = 0;//temp5 & 0xFF; // tbcTransmit // Flash interrupt handler (do nothing) // We need to handle the interrupt even though we do not do anything. // If not, the program will not run correctly except under the debugger, // which has its own Flash interrupt handler void FlashIntrHandler(void) interrupt INUM_FLASH INT_SETFLAG(INUM_FLASH, INT_CLR); return; //timer 10ms void TIMER0_ISR() interrupt INUM_TIMER0 TF0 = 0; TH0 = 0xd0; TL0 = 0; TR0 = 1; if(TMajorPeriod==0) bSample = 1; TMajorPeriod = MAJOR_PERIOD + 1; TMajorPeriod--; void RF_ISR (void) interrupt INUM_RF INT_ENABLE(INUM_RF, INT_OFF); INT_SETFLAG (INUM_RF, INT_CLR); if(!bRF_RXdone) // Get RF receive data rf_rx_buf[rf_rx_index] = RF_RECEIVE_BYTE(); if(rf_rx_index==0) RF_LOCK_AVERAGE_FILTER(TRUE); if(rf_rx_buf[rf_rx_index] != RF_SUITABLE_SYNC_BYTE) RLED = LED_ON; rf_rx_index++;

Page 124: All_New(Luan Van Son)

- -

124

if(rf_rx_index>rf_rx_buf[1] + 3) bRF_RXdone = 1; PDET &= ~0x80; PDET |= 0x80; INT_ENABLE(INUM_RF, INT_OFF); YLED = !YLED; return; INT_ENABLE(INUM_RF, INT_ON); YLED = !YLED; return; void RFProc() byte xdata SourceAddr,NextHop,EndpointAddr; word xdata crc,crc1; if(!bRF_RXdone) return; if(rf_rx_index==0) return; crc = culFastCRC16Block(&rf_rx_buf[1], DATA_LEN-2, CRC16_INIT); crc1 = rf_rx_buf[DATA_LEN-2]; crc1 = (crc1<<8) | rf_rx_buf[DATA_LEN-1]; if(crc!=crc1) return; if(rf_rx_buf[0]==RF_SUITABLE_SYNC_BYTE) INT_ENABLE(INUM_RF, INT_OFF); SourceAddr = rf_rx_buf[2]; NextHop = rf_rx_buf[3]; EndpointAddr = rf_rx_buf[4]; if(NextHop == MY_ADDRESS) if(SourceAddr == Parent(MY_ADDRESS)) if(EndpointAddr == MY_ADDRESS) //Endpoint GetParameters(); txDataBuffer[0] = MY_ADDRESS; txDataBuffer[1] = Parent(MY_ADDRESS); //nexthop=parent txDataBuffer[2] = MY_ADDRESS; txDataBuffer[3] = CMD_GET_PARAMS; halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); RF_START_TX(); halRFSendPacket(PREAMBLE_BYTE_COUNT, &txDataBuffer[0], DATA_LEN); else //forward down tree Receive(); NextHop = FindNextHop(MY_ADDRESS, EndpointAddr); rxDataBuffer[0] = MY_ADDRESS; rxDataBuffer[1] = NextHop; halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); RF_START_TX(); halRFSendPacket(PREAMBLE_BYTE_COUNT, &rxDataBuffer[0], 4); else //forward up tree Receive(); NextHop = Parent(MY_ADDRESS);

Page 125: All_New(Luan Van Son)

- -

125

rxDataBuffer[0] = MY_ADDRESS; rxDataBuffer[1] = NextHop; halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA); RF_START_TX(); halRFSendPacket(PREAMBLE_BYTE_COUNT, &rxDataBuffer[0], DATA_LEN); PrepareRX(&RF_SETTINGS); InitRF(); void RFSetupReceive (void) bRF_RXdone = 0; rf_rx_index = 0; // Disable global interrupt INT_GLOBAL_ENABLE (INT_OFF); // Setup RF interrupt INT_SETFLAG (INUM_RF, INT_CLR); INT_PRIORITY (INUM_RF, INT_HIGH); INT_ENABLE (INUM_RF, INT_ON); // Enable RF interrupt based on bytemode RF_SET_BYTEMODE(); // Setup preamble configuration RF_SET_PREAMBLE_COUNT(PREAMBLE_BYTE_COUNT); RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE); // Make sure avg filter is free-running + 22 baud settling time MODEM1=(MODEM1&0x03)|0x24; // Reset preamble detection PDET &= ~0x80; PDET |= 0x80; halRFSetRxTxOff(RF_RX, &RF_SETTINGS, &RF_CALDATA); // Start RX RF_START_RX(); // Enable global interrupt INT_GLOBAL_ENABLE (INT_ON); void InitRF(void) bRF_RXdone = 0; rf_rx_index = 0; void PrepareRX(RF_RXTXPAIR_SETTINGS* RF_SETTINGS) halRFSetRxTxOff(RF_RX, RF_SETTINGS, &RF_CALDATA); RF_START_RX(); INT_ENABLE (INUM_RF, INT_ON);

Page 126: All_New(Luan Van Son)

- -

126

void Wait1sec (void) halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); halWait (250, CLKFREQ); // Wait1sec void Receive (void) byte xdata i; if(!bRF_RXdone) return; if(rf_rx_buf[0]==RF_SUITABLE_SYNC_BYTE && rf_rx_buf[3]==MY_ADDRESS) BLED = !BLED; for(i=0;i<DATA_LEN;i++) rxDataBuffer[i] = rf_rx_buf[i+2]; // Receive void RandomWait(byte waitMultiplier) byte xdata time; byte xdata i; time = rand(); for (i = 0; i < waitMultiplier; i++) halWait (time, CLKFREQ); 4. MS5535.h Sử dụng lại file MS5535.h của phụ lục 1 5. MS5535.c Sử dụng lại file MS5535.c của phụ lục 1 6. Tree.h #if !defined tree_h #define tree_h #define N_NODES 11 struct node unsigned char id; struct node *next; ; int EldestChild(int k); int Parent(int k); int NextSibling(int k); void FindHops(int k); void BuildTree(); char FindNextHop(int curNode,int dest); int IsChild(int curNode, int k); #endif 7. Tree.c #include "tree.h"

Page 127: All_New(Luan Van Son)

- -

127

struct node xdata Tree[N_NODES+1]; struct node xdata member[N_NODES+1]; int xdata RoutingTable[N_NODES+1]; //Tim con truong cua nut co id = k int EldestChild(int k) struct node xdata *p; if(k <= N_NODES) p = Tree[k].next; return p->id; else return -1; //không tìm thấy con //xac dinh xem nut k co la con cua nut curNode khong int IsChild(int curNode, int k) struct node xdata *p; p = Tree[curNode].next; while(p) if(p->id == k) return 1; p = p->next; return 0; //Tim cha cua nut co id = k int Parent(int k) struct node xdata *p; unsigned char xdata i; i = 1; while(i<=N_NODES) p = Tree[i].next; while(p) if(p->id == k) return i; else p = p->next; i++; return -1; //không tìm thay cha //tim em lien ke cua nut co id = k int NextSibling(int k) struct node xdata *p; unsigned char xdata i; i = 1; while(i <= N_NODES) p = Tree[i].next; while(p) if(p->id == k) p = p->next; if(p) return p->id; else return -1; //không có em lien ke

Page 128: All_New(Luan Van Son)

- -

128

else p = p->next; i++; return -1; //tim duong di tu Master toi nut k void FindHops(int k) unsigned char xdata par,i,j; for(i=0; i<=N_NODES; i++) RoutingTable [i] = -1; i = 0; j = k; do par = Parent(j); RoutingTable [i] = par; j = par; i++; while (par != 1 && i<=N_NODES); //Tim nut tiep theo cua nut curNode de truyen char FindNextHop(int curNode,int dest) unsigned char xdata i,j,nexthop; i = 0; nexthop = j = dest; while(j != curNode && i<=N_NODES) nexthop = j; j = Parent(j); i++; return nexthop; /* Tree: // 1 // / \ // 2 3 // / \ / | \ // 4 5 6 7 8 // / \ | // 9 10 11 */ void BuildTree() unsigned char xdata i; for(i=0; i<=N_NODES; i++) Tree[i].id = i; Tree[i].next = 0; member[i].id = i; member[i].next = 0;

Page 129: All_New(Luan Van Son)

- -

129

member[2].next = &member[3]; member[3].next = 0; member[4].next = &member[5]; member[5].next = 0; member[6].next = &member[7]; member[7].next = &member[8]; member[8].next = 0; member[9].next = &member[10]; member[10].next = 0; Tree[1].next = &member[2]; Tree[2].next = &member[4]; Tree[3].next = &member[6]; Tree[5].next = &member[9]; Tree[7].next = &member[11];