Các nút cảm biến này yêu cầu tiêu thụ công suất thấp. Các nút cảm biến hoạt động có giới hạn và khó có thể thay thế được nguồn cung cấp. Do đó, trong khi mạng truyền thông tập trung vào đạt được các
dịch vụ chất lượng cao, thì các giao thức mạng cảm biến phải tập trung đầu tiên vào
tiết kiệm năng lượng.
100 trang |
Chia sẻ: lylyngoc | Lượt xem: 2305 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Luận văn Mạng cảm nhận không dây và đánh giá bằng thực nghiệm một số thông số qua ddieeud khiển thâm nhập môi trường, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
value = TH0;
value <<= 8;
value |= TL0;
fTemp = (value*0.2713 + 65535*counter);
printf("\n\nThoi gian truyen het 7 byte preamale + 8 byte data + 2 byte CRC16: %4.1f
us", fTemp);
Kết quả đo : thời gian truyền hết 137ms
Hình 3.7 Thời gian truyền hết 17 byte dữ liệu từ nút truyền đến nút nhận
Xác định thời gian nhận và xử lý dữ liệu tại nút nhận
counter = 0;
TH0 = 0x00;
-53-
TL0 = 0x00;
TF0 = 0;
TIMER0_RUN(TRUE);
// Tổng thời gian từ lúc bắt đầu nhận đến lúc hết hàm nhận
halRFReceivePacket2(byte timeOut, byte* packetData, byte maxLength);
TIMER0_RUN(FALSE);
value = TH0;
value <<= 8;
value |= TL0;
fTemp = (value*0.2713 + 65535*counter);
printf("\n\nThoi gian nhan het 7 byte preamale + 8 byte data + 2 byte CRC16: %4.1f
us", fTemp);
Kết quả đo thời gian nút nhận và phân tích dữ liệu: 138ms
Hình 3.8 Thời gian truyền hết 17 byte dữ liệu từ nút truyền đến nút nhận
-54-
d. Kết luận
Vậy Tổng thời gian thời gian nút truyền bắt đầu gửi dữ liệu 17 byte cho đến khi
nút nhận nhận và phân tích xong dữ liệu là : 137 + 138 = 275 ms
3.4.1.3 Đo cường độ dòng điện của các nút mạng các trạng thái : ngủ, truyền, nhận
dữ liệu ở chế độ lập lịch tập trung.
a. Chế độ lập lịch tập trung
Lập lịch tập trung là một trong nhiều cách tổ chức hoạt động của các nút mạng
trong mạng WSN. Với lập lịch tập trung, hoạt động của mạng sẽ do nút cơ sở điều
khiển. Tất cả các nút cảm nhận khác trong mạng sẽ hoạt động theo yêu cầu của nút
mạng cơ sở, các yêu cầu điều khiển này đã được nút mạng cơ sở sắp xếp cố định và trở
thành một lịch trình hoạt động cho mạng đó.
Hoạt động:
Nút cơ sở: Sẽ lần lượt yêu cầu từng nút mạng gửi dữ liệu truyền về. Mỗi nút
mạng khi nhận được yêu cầu sẽ phải gửi dữ liệu phản hồi về cho nút cơ sở.
Ban đầu, nút cơ sở gửi yêu cầu tới một nút cảm nhận n (NútID=n). Sau khi gửi
gói tin yêu cầu nút n ra ngoài môi trường thì các nút mạng khác cũng đều nhận
được yêu cầu đó chứ không riêng nút n nhận được. Tiếp theo nút mạng cơ sở
chuyển sang chế độ nhận dữ liệu từ nút mạng cảm nhận truyền về. Lúc này, nút
mạng cơ sở sẽ nhận dữ liệu, nếu nhận không thành công thì nhận lại lần nữa. Tuy
nhiên, quá trình nhận lại này sẽ được giới hạn về mặt thời gian. Tức là với mỗi một
nút cảm nhận, nút cơ sở chỉ dành cho một lượng thời gian nhất định, nếu sau
khoảng thời gian đó mà vẫn không nhận được gói dữ liệu truyền về thì tức là nút
mạng được yêu cầu đó đã không nhận được yêu cầu hoặc là gói dữ liệu truyền vễ
đã gặp phải lỗi truyền nào đó ngoài môi trường dẫn tới nút cơ sở không thể nhận
được. Lúc này nút cơ sở sẽ phải bỏ qua nút đó để chuyển tiếp sang yêu cầu nút
khác. Nếu trong thời gian đó mà nút cơ sở nhận được thành công gói dữ liệu của
nút cảm nhận truyền về thì sẽ tiến hành xử lý gói tin và hiển thị hoặc lưu trữ dữ liệu
nhận được đó. Sau khi xử lý xong gói tin, trước khi chuyển sang yêu cầu nút tiếp
theo (n+1) thì nút cơ sở sẽ trễ một khoảng tdelay. Lý do phải có khoảng trễ này sẽ
được giải thích tại phần hoạt động của nút cảm nhận. Như vậy là nút cơ sở đã hoàn
thành việc yêu cầu và nhận gói tin từ một nút cảm nhận trong mạng. Sau đó nút cơ
sở sẽ tăng thêm 1 vào địa chỉ của nút sẽ yêu cầu, tức là sẽ yêu cầu nút cảm nhận
tiếp theo. Quá trình được lặp lại liên tục, nút cơ sở yêu cầu và nhận dữ liệu của lần
lượt từng nút trong mạng, sau khi hết một lượt lại tiến hành quay lại với nút đầu
-55-
tiên.
while (TRUE) {
for(i=1;i<max;i++) // max là số nút mạng
{
tbcTransmit(i,0xFF);// gửi yêu cầu cho nút I, loại gói tin điều khiển
t = (int) sppGetTime(); // lấy thời gian trước khi nhận
do{ //Nếu nhận không thành công sẽ nhận lại cho
//toi khi hết 800ms thì thôi.
tbcReceive();
}while((RXI.status != SPP_RX_FINISHED)&&( ((int) sppGetTime()-t)<80));
tbcPrintTable(); // xử lý gói tin
delay(10000);//Thời gian Master đợi các Slave tính toán, xử lý dữ liệu
}
}
Giải thuật của nút cơ sở:
Hình 3.9 Giải thuật nút cơ sở
Khởi tạo
Addr = 1
Gửi yêu cầu
Nhận dữ liệu
Nhận ok? & tRx<0.8s
Xử lý
Trễ
Addr++
Addr>max?
Đ
S
S
Đ
-56-
Nút cảm nhận: Luôn ở trạng thái sẵn sàng nhận yêu cầu của nút cơ sở. Ngay
sau khi nhận được yêu cầu sẽ tiến hành gửi dữ liệu trở về.
Ban đầu, nút cảm nhận sẽ luôn ở trong trạng thái nhận dữ liệu, nếu nhận không
thành công thì nhận lại cho tới khi nhận được gói dữ liệu thành công. Sau khi nhận
được gói, nút cảm nhận tiến hành tách từng trường dữ liệu của gói đã nhận được và
kiểm tra xem đó có phải nút cơ sở yêu cầu chính nó hay không. Nếu đúng thì nút
cảm nhận sẽ trễ một khoảng thời gian ngắn rồi mới tiến hành gửi dữ liệu trở về cho
nút cơ sở. Rồi sau đó lại quay trở lại quá trình nhận yêu cầu để chờ tín hiệu yêu cầu
lần tiếp theo. Nếu gói tin nhận được không phải gói yêu cầu nó gửi dữ liệu thì có 2
khả năng: hoặc đó là gói tin yêu cầu của nút cơ sở tới một nút khác, hoặc đó là gói
tin dữ liệu của một nút cảm nhận khác đang truyền về. Khi đó, nó sẽ quay trở lại
việc nhận dữ liệu từ môi trường. Nhưng sau mỗi quá trình nhận thì nút cảm nhận
lại phải tiến hành tách các trường dữ liệu trong gói tin nhận được và kiểm tra các
trường đó. Các công việc này sẽ tốn một khoảng thời gian và khiến cho nút cảm
nhận quay trở lại quá trình nhận yêu cầu muộn hơn nút cảm nhận vừa nhận được
yêu cầu và đã gửi dữ liệu đi. Và cũng chính vì quá trình xử lý mất một khoảng thời
gian nên nút cơ sở phải trễ đi một khoảng để khi gửi tin yêu cầu thì các nút cảm
nhận khác có thể nhận được.
Giải thuật nút cảm nhận:
Hình 3.10 Giải thuật nút cảm nhận
Đ
Khởi tạo
Nhận yêu cầu
Nhận ok?
Kiểm tra địa chỉ
Trễ
Truyền dữ liệu
Đ
S
S
-57-
while (TRUE) {
do{
tbcReceive();
}while(RXI.status != SPP_RX_FINISHED);
if((nútTarget[n]==1)&& (nútType[n]==0xFF))
{
delay(20000); // Trễ để
tbcTransmit(0xFFFF,0xFF00);
}
}
Ơ
b. Lập lịch tập trung kết hợp với lịch ngủ:
Trên thực tế, mạng cảm nhận không dây là mạng có tần suất truyền nhận thấp.
Các gói tin truyền trong mạng không đòi hỏi phải có tốc độ nhanh. Trong một số ứng
dụng như theo dõi thông tin từ môi trường thì thậm chí còn được sắp xếp một lịch hoạt
động và lịch ngủ đều đặn theo chu kỳ. Việc đưa lịch ngủ vào quá trình hoạt động với
2
1
3
4
Nút cơ sở
Master
RS232
Các nút cảm
nhận (Slave)
Các nút cảm
nhận (Slave)
Các nút cảm
nhận (Slave)
Các nút cảm
nhận (Slave)
-58-
thời gian hợp lý sẽ giải quyết được vấn đề tiết kiệm năng lượng mà lại không ảnh
hưởng tới việc giám sát thông tin môi trường của mạng.
Ý tưởng cho mô hình này như sau: Nút cơ sở sẽ có một lịch hoạt động và lịch
nghỉ đan xen nhau và cố định về mặt thời gian. Các nút cảm nhận khác sẽ phải có biện
pháp nào đó để có thể hoạt động và nghỉ gần như trùng khớp với lịch hoạt động và lịch
nghỉ của nút cơ sở. Như vậy thì toàn mạng sẽ có một khoảng thời gian hoạt động và
thơi gian nghỉ tương đối là đều đặn. Trong thời gian hoạt động, mạng sẽ hoạt động dựa
trên cơ chế lập lịch tập trung mà ta đã giới thiệu ở trên. Trên thực tế, khoảng thời gian
hoạt động và nghỉ của các nút mạng sẽ phụ thuộc vào các yếu tố: yêu cầu đòi hỏi của
ứng dụng cho phép thời gian nghỉ là bao lâu, số lượng nút mạng cảm nhận là bao nhiêu
sẽ yêu cầu một khoảng thời gian hoạt động tối thiểu đủ để nút cơ sở thu thập dữ liệu có
thể thu thập dữ liệu từ tất cả các nút trong mạng.
Giải quyết bài toán: Ta thấy, nút cơ sở sẽ một quá trình hoạt động khá đơn giản,
đan xen giữa làm việc và nghỉ. Vấn đề khó khăn ở đây đó là làm sao để các nút cảm
nhận có thể cùng làm việc và cùng nghỉ với nút cơ sở một cách tương đối chính xác.
Các nút cảm nhận hoàn toàn tách biệt với nút cơ sở và chỉ có thể giao tiếp bằng truyền
nhận không dây khiến cho việc đồng bộ thời gian giữa các nút mạng ở đây gặp nhiều
khó khăn. Giản đồ mô tả quá trình hoạt động của các nút trong mạng như sau sẽ giải
quyết được vấn đề khó khăn đó:
Hình 3.11. Thời gian hoạt động và ngủ của nút mạng Master và Slaver
- Quá trình làm việc của nút cơ sở: nút cơ sở sẽ hoạt động đều đặn với thời gian
làm việc là tactive và sẽ nghỉ một khoảng tsleep. Sau đó lại lặp lại quá trình làm
việc và nghỉ. Trong quá trình làm việc, nút cơ sở sẽ hoạt động với cơ chế lập
lịch tập trung như đã đưa ra ở trên.
Giải thuật cho nút cơ sở:
N
tx
tsl
tactive
tsleep
T
Master
Slaver
-59-
Hình 3.12 Giải thuật nút cơ sở trong lập lịch tập trung kết hợp với lịch ngủ
Đoạn chương trình viết cho chu trình hoạt động, sau chu trình này là chuyển sang
chế độ nghỉ: Thời gian nhận tối đa dành cho một nút là không quá 800ms, tổng số nút
cảm nhận là max, tổng thời gian làm việc là time_active.
t3 = (int)sppGetTime();
do{
for(i=1;i<max;i++)
{
tbcTransmit(i,0xFF);
Đ
Khởi tạo
Addr = 1
Gửi yêu cầu
Nhận dữ liệu
Nhận ok? & tRx<0.8s
Xử lý
Trễ
Addr++
S
Đ
Addr > N
Nghỉ tsleep
S
-60-
t2 = (int) sppGetTime();
do{
tbcReceive();
}while((RXI.status != SPP_RX_FINISHED)&&( ((int) sppGetTime()-
t2)<80));
tbcPrintTable();
delay(10000);
if(((int)sppGetTime()-t3)>time_active)
break;
}
}while( ((int)sppGetTime()-t3) < time_active );
- Nút cảm nhận: cũng sẽ có khoảng thời gian làm việc và khoảng nghỉ đan xen
lẫn nhau. Tuy nhiên để có thể đồng bộ thời gian với hoạt động của nút cơ sở thì nút
cảm nhận sẽ phải mất một khoảng thời gian làm việc nhiều hơn chu kỳ làm việc bình
thường để xác định điểm làm việc trùng với nút cơ sở.
Ngay sau khi được khởi động, nút cơ sở sẽ tiến hành việc bám vào chu trình làm
việc của nút cơ sở. Nút cảm nhận sẽ tiến hành nhận gói tin, nếu nhận lỗi thì nhận lại,
tới khi nào nhận thành công (có thể là nút mạng cơ sở gửi yêu cầu một nút nào đó, có
thể là một nút mạng cảm nhận đang truyền dữ liệu về) thì chứng tỏ mạng đang trong
khoảng thời gian làm việc. Lúc này nút cơ sở đó mới bắt đầu đi vào một chu trình làm
việc cụ thể.
Chu trình làm việc của nút cảm nhận sẽ được chia làm N chu trình làm việc nhỏ.
Trong đó có chu kỳ đầu tiên sẽ khác biệt so với các chu kỳ còn lại và (N-1) các chu kỳ
tiếp theo sẽ giống nhau.
Chu kỳ đầu tiên: nút cảm nhận sẽ nhận gói tin yêu cầu và đáp ứng các yêu cầu nhận
được theo đúng như cơ chế lập lịch tập trung cho nút mạng cảm nhận đã giới thiệu ở trên.
Tuy nhiên, đây chính là chu kỳ làm việc để nút cảm nhận có thể xác định được thời điểm
làm việc và thời điểm nghỉ của mình trong các chu kỳ tiếp theo. Việc xác định được làm
như sau: Nút cảm nhận hoạt động bình thường, nhưng nếu khi nhận yêu cầu lỗi thì bắt đầu
lấy thời gian tại thời điểm đó lưu vào một biến t1. Sau mỗi một lần nhận gói tin không
thành công thì sẽ tiến hành kiểm tra xem lần nhận trước đó có thành công hay không. Nếu
có thì tiến hành lấy thời gian tại thời điểm hiện tại vào t1. Nếu trước đó cũng không nhận
thành công thì tiến hành kiểm tra khoảng thời gian hiện tại so với t1, nếu như vượt tx thì
-61-
chuyển qua trạng thái ngủ. Như vậy tx là khoảng thời gian mà nút cảm nhận liên tiếp
không nhận thành công một gói tin nào. Điều đó cũng có nghĩa là các nút mạng đã trong
trạng thái nghỉ được một khoảng tx. Sau đó nút cảm nhận sẽ chuyển sang trạng thái ngủ,
nhưng sẽ ngủ với một khoảng thời gian tsl = tsleep – tx.
Khi hết thời gian ngủ cũng là hết chu kỳ làm việc đầu tiên. Khi nút cảm nhận này
thức dậy, lúc đó các nút mạng khác cũng thức dậy cùng lúc. Như vậy chu kỳ này đã
hoàn thành được nhiệm vụ xác định mốc thời gian.
N-1 chu kỳ hoạt động tiếp theo: Nút cảm nhận sẽ hoạt động đều đặn với tactive
và tsleep giống như nút cơ sở.
Ta có thể thấy ở đây các khoảng thời gian giữa nút cơ sở và nút cảm nhận chỉ
được xác định chính xác ở chu kỳ đầu tiên và các chu kỳ sau sẽ là tương đối. Sau một
lượng lớn chu kỳ làm việc sẽ có thể dẫn tới một sai số lớn về mặt thời gian giữa các
nút. Chính vì thế mà sau mỗi N chu kỳ làm việc mà lại phải tiến hành lặp lại việc xác
định mốc thời gian. Với việc làm này, ta đã giải quyết được hoàn toàn vấn đề đồng bộ
thời gian giữa các nút cảm nhận và nút cơ sở.
Chương trình cho nút mạng cảm nhận với một số giá trị cụ thể:
do{
tbcReceive();
}while(RXI.status != SPP_RX_FINISHED);
while (TRUE) {
do{
tbcReceive();
if(RXI.status != SPP_RX_FINISHED)
{
if(i==0)
t1 = (int)sppGetTime();
i++;
}
}while((RXI.status != SPP_RX_FINISHED)&&(((int)sppGetTime()-
t1)<1000));
//tx = 10s
-62-
i=0;
tbcPrintTable(); //xử lý, nếu đúng yêu cầu thì gủi dữ liệu.
if( ( (int)sppGetTime()-t1 )>1000 )
{
t2 = (int)sppGetTime();
do{}while( ((int)sppGetTime()-t2)<1000); //tsl = 10s
for(i=1;i<30;i++) //N = 30
{
t1 = (int)sppGetTime();
do{
t2 = (int)sppGetTime();
do{
tbcReceive();
}while((RXI.status != SPP_RX_FINISHED)&&(((int)sppGetTime()-t2)<80));
tbcPrintTable();
}while(((int)sppGetTime()-t1)<2000); //tactive = 20s
t2 = (int)sppGetTime();
do{}while( ((int)sppGetTime()-t2)<2000); //tsleep = 20s
}
}
}
-63-
Giải thuật cho nút cảm nhận như sau:
Hình 3.15 Giải thuật nút cảm nhận trong lập lịch tập trung kết hợp với lịch ngủ
Đ
Đ
Đ
Khởi tạo
Nhận
Nhận ok?
Nhận ok?
i=0
Nghỉ (tsleep-tx)
Đ
S
S
Nhận yêu cầu
Đ
i!=0?
S
Đ
Kiểm tra địa chỉ
S
i++
t1=sppGetTim
Truyền dữ liệu
Trễ
j=0
t2=sppGetTime
Đ
Nhận ok?
i=0
S
Nhận yêu cầu
Đ
Kiểm tra địa chỉ
S
Truyền dữ liệu
Trễ
Đ (sppGetTime- t2)>tactive
S
Nghỉ tsleep
j++
j>N
Đ
S
(sppGetTime-t1)>tx
S
-64-
c. Đo dòng điện tiêu thụ của nút mạng trong chế độ lập lịch tập trung
* Các bước chuẩn bị thí nghiệm
Nạp phần mềm lập lịch cho các nút mạng
Chuẩn bị đồng hồ đo Hioki 3803 Digital Hitester sai số 1.5%
Osillo…
* Tiến hành đo đạc
Ta sẽ bố trí tiến hành đo dòng điện tiêu thụ của nút mạng ở các trạng thái ngủ, truyền,
nhận và không truyền, không nhận tín hiệu.
- Tiến hành đo dòng điện tiêu thụ của nút mạng lúc nút mạng nhận dữ liệu
- Tiến hành đo dòng điện tiêu thụ của nút mạng lúc nút mạng truyền dữ liệu
- Tiến hành đo dòng điện tiêu thụ của nút mạng lúc nút mạng ngủ
- Tiến hành đo dòng điện tiêu thụ của nút mạng lúc nút mạng không truyền
không nhận dữ liệu
a. Tiến hành đo dòng điện tiêu thụ của nút mạng lúc nút mạng nhận dữ liệu
Cho nút mạng hoạt động ở chế độ nhận dữ liệu, nạp chương trình cho nó luôn ở chế độ
nhận, sau đó tiến hành đo cường độ dòng điện.
Bao gồm các thủ tục:
+ Thiết đặt chế độ hoạt động cho module RF
+ Cho phép module RF bắt đầu thu tín hiệu (không quan tâm đến dữ liệu thu
được)
+ Chương trình lặp vô hạn
include
void main()
{
// 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
-65-
// Data rate: 2.
#include
#include
#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
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 => 4 dBm
0x00, // MATCH
0x00, // PRESCALER
};
// Căn chỉnh vùng nhớ con trỏ dữ liệu
RF_RXTXPAIR_CALDATA xdata RF_CALDATA;
WDT_ENABLE(FALSE);
// Set optimum settings for speed and low power consumption
MEM_NO_WAIT_STATES();
FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS);
-66-
// Calibrate
halRFCalib(&RF_SETTINGS, &RF_CALDATA);
// Kích hoạt modum RF trong chế độ nhận
halRFSetRxTxOff(RF_RX, &RF_SETTINGS, &RF_CALDATA);
RF_START_RX();// Bắt đầu nhận dữ liệu
// Endless loop
while (TRUE);// Lặp nhận vô hạn.
}
Cách đo dòng điện trên sơ đồ mạch :
CC1010 sử dụng nguồn nuôi 3V3, điện áp này được tạo ra từ jump test1 (được đánh dấu đỏ
trên sơ đồ) và đất.
Trong sơ đồ CC1010MB thì chỉ có chip CC1010 sử dụng nguồn nuôi 3V3 nên dòng qua jump
test 1 cũng chính là dòng tiêu thụ của chip CC1010.
Để đo dòng này ta đặt một đồng hồ đo dòng nối tiếp tại test1 như sơ đồ sau:
Hình 3.16 Sơ đồ chip CC1010, vị trí đánh dấu màu đỏ đo dòng điện tiêu thụ
Đồng thời nạp chương trình cho CC1010 chạy trong từng chế độ riêng biệt, ta
sẽ đo được dòng tiêu thụ của CC1010 trong chế độ tương ứng.
Vị trí đo
cường độ
dòng điện
tại TEST1
-67-
Hình 3.17 Thực hiện đo dòng điện trên chip CC1010
b. Tiến hành đo dòng điện tiêu thụ của nút mạng lúc nút mạng truyền dữ liệu
Cho nút mạng hoạt động ở chế độ nhận dữ liệu, nạp chương trình cho nó luôn ở chế độ
nhận, sau đó tiến hành đo cường độ dòng điện.
Bao gồm các thủ tục:
+ Thiết đặt chế độ hoạt động cho module RF
+ Cho phép module RF phát tín hiệu (không quan tâm đến dữ liệu phát ra)
+ Nhảy tại chỗ
#include
#include
#include
void main() {
// 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
-68-
// 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
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 => 4 dBm
0x00, // MATCH
0x00, // PRESCALER
};
// Calibration data
RF_RXTXPAIR_CALDATA xdata RF_CALDATA;
// Disable watchdog timer
WDT_ENABLE(FALSE);
// Set optimum settings for speed and low power consumption
MEM_NO_WAIT_STATES();
FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS);
halRFCalib(&RF_SETTINGS, &RF_CALDATA);
// Kích hoạt chế độ truyền dữ liệu
halRFSetRxTxOff(RF_TX, &RF_SETTINGS, &RF_CALDATA);
RF_START_TX(); // Bắt đầu truyền dữ liệu
// Lặp vô hạn
while (TRUE);
}
-69-
Cách đo cường độ dòng điện trên sơ đồ mạch giống trường hợp cường độ dòng
điện nhận.
c. Tiến hành đo dòng điện tiêu thụ của nút mạng lúc nút mạng ngủ
Thiết lập nút mạng hoạt động ở chế độ ngủ, nạp chương trình cho nó luôn ở chế độ
ngủ, sau đó tiến hành đo cường độ dòng điện.
CC1010 đi vào chế độ ngủ ngay sau khi bắt đầu chạy.
#include
#include
void main() {
// Disable watchdog timer
WDT_ENABLE(FALSE);
// Startup macros for speed and low power consumption
MEM_NO_WAIT_STATES();
FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS);
ENTER_SLEEP_MODE();// Đưa nút mạng về trạng thái ngủ
}
d. Tiến hành đo dòng điện tiêu thụ của nút mạng lúc nút mạng không truyền
không nhận dữ liệu
Bao gồm các thủ tục:
+) Thiết lập chế độ cho module ADC và kích hoạt ADC.
+) Chương trình nhảy tại chỗ.
// không kích hoạt modeum RF, chỉ cho CPU chạy ở chế độ chạy lệnh
#include
#include "CC1010MB.h"
#include
#include
void main(void)
{
wdt_enable(false);
// adc setup
halconfigadc(adc_mode_single | adc_reference_internal_1_25,
cc1010eb_clkfreq, 0);
-70-
adc_select_input(adc_input_ad1);
adc_power(true);// chạy adc tính dòng để đo nhiệt độ
// set optimum settings for speed and low power consumption
mem_no_wait_states();
flash_set_power_mode(flash_standby_between_reads);
while (true) {
}// lặp vô hạn, để cpu luôn ở chế độ chạy lệnh.
} // end of main()
* Các kết quả đo
- Đo dòng điện tiêu thụ của nút mạng lúc nút mạng ngủ :
Lần đo thứ Cường độ dòng điện Điện Áp
1 0.25mA 3.3V
2 0.24mA 3.3V
3 0.26mA 3.3V
4 0.25mA 3.3V
Bảng 3.2 Đo cường độ dòng điện lúc nút mạng ngủ
mASleep 25.0I
- Đo dòng điện tiêu thụ của nút mạng lúc nút mạng truyền dữ liệu
Lần đo thứ Cường độ dòng điện Điên áp
1 35mA 3.3V
2 34mA 3.3V
3 36mA 3.3V
4 35mA 3.3V
Bảng 3.3 Đo cường độ dòng điện lúc nút mạng truyền dữ liệu
-71-
d. Đo dòng điện tiêu thụ của nút mạng lúc nút mạng nhận dữ liệu
Lần đo thứ Cường độ dòng điện Điên áp
1 25mA 3.3V
2 23mA 3.3V
3 25mA 3.3V
4 24mA 3.3V
Bảng 3.4 Đo cường độ dòng điện lúc nút mạng nhận dữ liệu
mAI ceive 24Re
e. Đo dòng điện tiêu thụ của nút mạng lúc nút mạng không truyền không nhận dữ
liệu
Lần đo thứ Cường độ dòng điện Điên áp
1 16mA 3.3V
2 14mA 3.3V
3 17mA 3.3V
4 14mA 3.3V
Bảng 3.5 Đo cường độ dòng điện lúc nút mạng không truyền/nhận dữ liệu
mAI Free 15
mAI Transmit 35
-72-
Hình 3.18 Phần mềm viết trên môi trường Visual C++
d. Kết luận :
Từ các kết quả đo được trên ta đưa ra một số nhận xét sau :
Tỉ lệ tiêu thụ năng lượng giữa nút mạng lúc ngủ và truyền nhận dữ liệu là:
140
1
35
25.0
Transmit
Sleep
Transmit
Sleep
I
I
A
A
98
1
24
25.0
ReRe
ceive
Sleep
ceive
Sleep
I
I
A
A
60
1
15
25.0
Free
Sleep
Free
Sleep
I
I
A
A
Như ta đã thực nghiệm ở trên : Thời gian truyền dữ liệu giữa nút cơ sở và nút cảm
nhận bao gồm 2 phase :
Do vậy tổng thời gian truyền nhận giữa cơ sở và nút cảm nhận trong mạng là :
Tphase1 + Tphase2 = 137 + 138 = 275 (ms).
-73-
Trong khoảng thời gian này nút chủ và nút tớ có thời gian làm việc như sau :
Phase1 :
137 ms
Nút cơ sở
Truyền 7 byte
dẫn đường
Nút cơ sở Truyền từng byte
và tính CRC cho hết 8 byte
Truyền 2
byte CRC
Trang thái
nút cơ sở Truyền dữ liệu
Truyền dữ liệu Truyền dữ
liệu
Trang thái
Nút cảm
nhận
Nhận dữ liệu Nhận dữ liệu Nhận dữ liệu
Phase2 :
138 ms
Nhận 7 byte
dẫn đường
Nhận 8 byte dữ liệu
Nhận 2 byte
CRC và
kiểm tra
Trang thái
Nút cơ sở Nhận dữ liệu Nhận dữ liệu Nhận dữ liệu
Trạng thái
Nútcảm nhận
Nhận dữ liệu Nhận dữ liệu Nhận dữ liệu
Bảng 3.6 Bảng thống kê tổng hợp các chế độ hoạt động của nút mạng tham gia
vào một phiên gửi dữ liệu từ nút cơ sở tới nút cảm nhận
Sau khi nút cảm nhận nhận yêu cầu từ nút cơ sở nó đọc dữ liệu từ bộ ADC và tiến
hành truyền dữ liệu về cho nút cơ sở. Trình tự truyền về cũng bao gồm 2 phase giống
như trên.
Vậy tổng thời gian mà nút cơ sở gửi yêu cầu dữ liệu cho đến khi nhận được kết quả là :
(137+138) x 2 = 550ms.
Ta xem xét biểu thức năng lượng của nút cảm nhận trong khoảng thời gian 550ms. Nút
cơ sở trên thực tế được kết nối với máy tính.
Dựa vào bảng 3.6 ta thấy : trong khoảng 550ms nhận và trả dữ liệu về trạng thái của
nút cảm nhận như sau : 137 ms truyền dữ liệu, 313 ms nhận dữ liệu. Do vậy :
ceiveTransmitTotal AAA Re
ATotal = 3,3v [137.35 + 313.24]
Nếu trong khoảng thời gian trên nút cảm nhận mà ngủ thì năng lượng tiêu thụ của nút
mạng là:
-74-
A = Angu = 3.3v.550.0.25
Nếu trong khoảng thời gian trên modun RF bị tắt, tức là nút cảm nhận không truyền
không nhận thì năng lượng tiêu thụ của nút mạng là:
A = AFree = 3.3v.14.550
Angu /ATotal = 1/90 AFree /ATotal = 0.62
Nhận xét :
Trong cùng một khoảng thời gian thì năng lượng ngủ tiêu thụ so với năng lượng
làm việc của mạng rất nhỏ (cỡ 1% năng lượng làm việc). Do vậy trên thực tế nếu ta lập
lịch cho mạng làm việc T thời gian làm việc và 100T là ngủ tức là tỉ lệ thời gian mạng
làm việc và lúc mạng ngủ là 1/100 thì tuổi thọ năng lượng mạng tăng gần 100 lần. Tuỳ
theo từng yêu cầu cảm nhận thực tế mà ta lập lịch cho chu kỳ thức và ngủ khác nhau.
Nếu ta lập lịch tập trung cho mạng N nút, nút cơ sở sẽ tiến hành hỏi vòng các nút
N nút cảm nhận. Ta thiết lập như sau :
Lập lịch tập trung các nút mạng sẽ cũng ngủ cùng thức.
Sau khi một nút thực hiện yêu cầu truyền dữ liệu xong, thì modun RF (modun
cảm nhận sóng) sẽ tắt trong khoảng thời gian nút cơ sở hỏi vòng N-1 nút còn
lại.
Do vậy, giả sử sau khi nút cơ sở hỏi vòng tất cả các nút cảm nhận thành một chu
kỳ làm việc của mạng lúc đó :
Nút cảm nhận Wi sẽ tiêu thụ năng lượng của mạng N nút như sau :
Trong khoảng thời gian nút cảm nhận Wi thực hiện truyền dữ liệu về nút cơ sở thì sẽ
tiêu thụ một năng lượng là : ATotal.
Trong khoảng thời gian nút cơ sở truyền dữ liệu với N-1 nút còn lại nút Wi sẽ tiêu thụ
năng lượng là (N-1)AFree. Khi đó năng lượng mà nút Wi tiêu thụ là:
TotalTotalceiveTransmitTotaleN ANANAAA )1(62.0A)1()( FreeRe_
62.0.38.062.0
Total
Free
Total A
A
DoAN
Do vậy : khi mạng có N nút các nút cảm nhận sẽ tiêu thu năng lượng một chu kỳ
làm việc là (0.62N + 0.38) lần.
Qua công thức trên ta thấy nếu N càng lớn (tức là quy mô mạng của ta càng lớn
-75-
thì sẽ càng tiêu tốn nhiều năng lượng trong một chu kỳ làm việc của nút cảm nhận
càng lớn), do vậy thời gian sống đối với các mạng quy mô lớn sẽ ngắn lại giảm 0.62N
lần. Đây cũng là nhược điểm của phương pháp lập lịch tập trung trong mạng cảm nhận
không dây.
Ta có đồ thị tương quan giữa thời gian sống của nút mạng và số nút trong mạng
như sau :
Hình 3.19 Đồ thị tuổi thọ nút mạng tỉ lệ nghịch với số nút trong mạng
theo hàm
38.062.0
1
N
T
Biểu đồ trên đưa ra khi ta lập lịch cho các nút mạng cảm nhận cùng ngủ cùng
thức với nút cơ sở (nút Master). Giả sử nút mạng ta có N nút, theo nguyên tắc hỏi
vòng, khi nút cơ sở làm việc với nút thứ nhất trong thời gian t đầu tiên, thì (N-1)t thời
gian còn lại nút cở sở làm việc với N-1 nút còn lại , như vậy nút mạng đầu tiên làm
làm việc được t thời gian, sẽ ở chế độ không truyền không nhận (N-1)t thời gian. Do
đó lập lịch trên của ta chưa tiết kiệm tối đa được năng lượng. Để khắc phục đăc điểm
trên tác giả đưa ra ý tưởng lập lịch cải tiến theo sơ đồ dưới đây :
Thời gian sống (t)
Số nút mạng (N)
-76-
Hình 3.20 Sơ đồ lập lịch cải tiến
Trong sơ đồ hoạt động này khác sơ đồ trước ở chỗ, mỗi nút cảm nhận (nút slave)
chỉ hoạt động trong phiên làm việc của nó, còn tất cả các nút cảm nhận khác ngủ.
Tại chu kỳ hoạt động đầu tiên của mỗi nút cảm nhận :
Ta xây dựng trong mạng một thủ tục điểm danh: nút Master sẽ hỏi từng nút Slave
một, với các địa chỉ từ 0 đến 100 chẳng hạn, nếu con Slave nào có mặt nó sẽ trả
lời, và được Master ghi nhận.
Sau khi điểm danh hết, Master sẽ hỏi nút Slave có địa chỉ bé nhất, nút đó trả lời
xong và ngủ luôn với thời gian t_sleep. Rồi Master lại hỏi luôn nút Slave tiếp theo,
sau khi trả lời nó ngủ luôn với t_sleep....cứ tiếp tục cho đến hết các Slave mà
Master ghi nhận được.
Sau khi hỏi hết các Slave, Master sẽ ngủ một thời gian là (t_sleep - N*t_active) với
N là số Slave mà Master ghi nhận được.
Khi Master thức cũng chính là lúc nút Slave đầu tiên thức... và tiếp tục một chu kỳ
làm việc mới.
Mỗi khi thêm, bớt Slave hoặc hoạt động bị lỗi, ví dụ như khi Master hỏi 1
Slave mà không thấy Slave đó trả lời thì ta sẽ cho Master điểm danh lại (tự động
hoặc bấm 1 nút nào đó trên mạch Master).
Nếu muốn Master tự động nhận diện nút mới thì ta sẽ cho Master thức trước nút
Slave đầu tiên một khoảng thời gian (chắc chắn lúc đó chỉ có Master và các nút
Slave mới đang thức). Trong khoảng thời gian đó Master sẽ ghi nhận được Slave
mới và sắp xếp khe thời gian cho nó hoạt động.
Do thời gian thực hiện luận văn hạn chế, tác giả chỉ đưa ý tưởng cải tiến phương
pháp lập lịch tập trung, không đủ thời gian nghiên cứu thực hiện. Trong tương lai, tác
giả sẽ nghiên cứu và hoàn thiện.
-77-
KẾT LUẬN
Khi nghiên cứu mạng cảm nhận không dây và thủ tục thâm nhập môi trường, một
trong những đặc điểm quan trọng và then chốt đó là thời gian sống của các nút cảm
biến hay chính là sự giới hạn về năng lượng của chúng. Các nút cảm biến này yêu cầu
tiêu thụ công suất thấp. Các nút cảm biến hoạt động có giới hạn và khó có thể thay thế
được nguồn cung cấp. Do đó, trong khi mạng truyền thông tập trung vào đạt được các
dịch vụ chất lượng cao, thì các giao thức mạng cảm biến phải tập trung đầu tiên vào
tiết kiệm năng lượng.
Bản luận văn cũng đã giới thiệu về các phương pháp thâm nhập môi trường trong
mạng cảm nhận. Sau đó tác giả đã đi sâu nghiên cứu phương pháp thâm nhập môi
trường bằng phương pháp lập lịch tập trung một trong những phương pháp tiết kiệm
được năng lượng cho nút mạng, dễ triển khai trên thực tế.
Phần thực nghiệm đã tiến hành xây dựng phần mềm nhúng cho các nút mạng đo
và tính toán năng lượng tiêu thụ của nút mạng thời điểm mạng làm việc và ngủ, đó
đưa ra một số kết luận sau :
Công suất của nút mạng C1010 truyền trong khoảng cách D<100m thì các nút
mạng nhận được tín hiệu.
Năng lượng tiêu thụ của nút mạng khi ngủ rất nhỏ (dòng tiêu thụ cỡ 0.25mA nhỏ
hơn nhiều so với dòng tiêu thụ khi truyền là 37mA ) nên trong quá trình lập lịch,
nếu ta tăng tối đa thời gian ngủ thì nút mạng sẽ tiết kiệm được năng lượng.
Khi mạng tăng về quy mô, số nút mạng N lớn thì tuổi năng lượng sống của nút
mạng sẽ giảm theo hàm
38.062.0
1
N
T
Đưa ra được ý tưởng hoàn thiện phương pháp thực hiện thuật toán lập lịch tập
trung trong tương lai.
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 CC1010 cho thấy rằng
việc dùng vi điều khiển CC1010 cho WSN là hoàn toàn khả thi.
-78-
TÀI LIỆU THAM KHẢO
Tài liệu Tiếng Việt
[1] Nguyễn Thế Sơ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”
[2] Đỗ Thị Tuyết, “nghiên cứu và mô phỏng giao thức định tuyến Pagasis trong mạng
cảm biến”
[3] Vương Đạo Vy, Mạng truyền dữ liệu, Nhà xuất bản đại học quốc gia Hà Nội
[4] 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
[5] 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
Tài liệu Tiếng Anh
[6] Bhaskar Krishnamachari, Networking Wireless Sensors
[7] Chipcon, CC1010 DataSheet, www.chipcon.com
[8] Chipcon, CC1010 IDE Manual, www.chipcon.com
[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”
[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] 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
-79-
[14] 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”
[15] 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
[16] Wei Ye, John Heidemann, Deborah Estrin (2002), “An Energy-Efficient MAC
Protocol for Wireless Sensor Networks”, University of California, Berkeley
[17] ZigBee Specification, www.zigbee.org
-80-
PHỤ LỤC
Chương trình khảo sát đo nhiệt độ môi trường trong mạng WSN
Phần mềm viết cho Master bao gồm các file: CC1010MB.h, MainMaster.c
Phần mềm viết cho Slave bao gồm các file: Slave.c
1.CC1010MB.h // File thư viện định nghĩa các chân I/O
#ifndef CC1010EB_H
#define CC1010EB_H
#include // Include register definitions
//********** Constants ************
#define CC1010EB_CLKFREQ 14746
//********** LED macros ***********
#define RLED P3_2
#define YLED P3_3
#define GLED P3_4
#define BLED P3_5
#define LED_ON 0
#define LED_OFF 1
// LED pin output enable macros
#define RLED_OE(x) {P3DIR=(x) ? P3DIR&~0x04 : P3DIR|0x04;}
#define YLED_OE(x) {P3DIR=(x) ? P3DIR&~0x08 : P3DIR|0x08;}
#define GLED_OE(x) {P3DIR=(x) ? P3DIR&~0x10 : P3DIR|0x10;}
#define BLED_OE(x) {P3DIR=(x) ? P3DIR&~0x20 : P3DIR|0x20;}
//********** Switch macros ***********
#define SW1_PRESSED (!P1_7)
#define SW2_PRESSED (!P3_2)
-81-
#define SW3_PRESSED (!P3_3)
#define SW4_PRESSED (!P2_4)
//********** Misc macros ************
#define DCLK P0_2
#define DIO P0_1
#define DCLKIO_OE(b) {P0DIR=(P0DIR&~0x06)|((b)?0x00:0x06);}
// PUT IN EXAMPLE RF_RXTXPAIR STRUCTURES FOR 434/868/915 !!!
#endif //CC1010EB_H
1. MainMaster.c
#include
#include "CC1010MB.h"
#include "PACKET.H"
#include
#include
#include
#include
//LCD define
#define LCDPORT P2
sbit _RS=LCDPORT^0;
sbit _RW=LCDPORT^1;
sbit _E =LCDPORT^2;
#include "lcd.h"
// Protocol constants
#define Node_ID 0xFF
#define Node1 0x01
#define Node2 0x02
#define Node3 0x03
-82-
#define Node4 0x04
#define max 5
#define N 30
#define tx 2
#define tactive 20
#define sleep 20
#define PREAMBLE_BYTE_COUNT 7
#define PREAMBLE_BITS_SENSE 16
#define CRC16_POLY 0x1021
#define CRC16_INIT 0xFFFF
#define CRC_OK 0
PACKET xdata txDataBuffer;
PACKET xdata rxDataBuffer;
void halRFSendPacket2(byte numPreambles, byte* packetData, byte length);
byte halRFReceivePacket2(byte timeOut, byte* packetData, byte maxLength);
void main(void) {
unsigned int n;
byte result;
unsigned int node;
char so[20];
// 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
-83-
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
};
// Calibration data
RF_RXTXPAIR_CALDATA xdata RF_CALDATA;
// Initialize peripherals
WDT_ENABLE(FALSE);
RLED_OE(TRUE);
YLED_OE(TRUE);
GLED_OE(TRUE);
BLED_OE(TRUE);
BLED = LED_OFF;
RLED = LED_OFF;
GLED = LED_OFF;
YLED = LED_OFF;
// Set optimum settings for speed and low power consumption
MEM_NO_WAIT_STATES();
-84-
FLASH_SET_POWER_MODE(FLASH_STANDBY_BETWEEN_READS);
// ADC setup
//halConfigADC(ADC_MODE_SINGLE | ADC_REFERENCE_INTERNAL_1_25,
CC1010EB_CLKFREQ, 0);
//ADC_SELECT_INPUT(ADC_INPUT_AD0);
//ADC_POWER(TRUE);
UART0_SETUP(57600, 14746, UART_NO_PARITY | UART_RX_TX |
UART_POLLED);
// config timer0 mode 1
TMOD = (TMOD&0xF0)|0x01;
INT_ENABLE(INUM_TIMER0, INT_ON);
INT_GLOBAL_ENABLE(TRUE);
// Calibration
halRFCalib(&RF_SETTINGS, &RF_CALDATA);
P2DIR=0x00; // LCD port is output
lcd_init();
lcd_com(15);
lcd_goto(1,1);
lcd_puts("Coltech WSN Group");
lcd_goto(2,1);
lcd_puts("Coltech WSN Group");
lcd_goto(3,1);
lcd_puts("Coltech WSN Group");
lcd_goto(4,1);
lcd_puts("Coltech WSN Group");
// Build packet
// first 2bytes is Source of packet (here is Master)
// next 2 bytes is Destination of packet (target node)
// next 2 bytes is type of data or command (temperature or pressure...)
// next 2 bytes is real data or command.
-85-
// the transmiting function will add 2 byte CRC16(packet) at the end of packet
txDataBuffer.packet.source = Node_ID;
txDataBuffer.packet.target = 0x00;
txDataBuffer.packet.type = 0x00;
txDataBuffer.packet.dat = 0x00;
t3 = (int)sppGetTime();
do{
for(i=1;i<max;i++)
{
tbcTransmit(i,0xFF);
t2 = (int) sppGetTime();
do{
tbcReceive();
}while((RXI.status != SPP_RX_FINISHED)&&( ((int) sppGetTime()-
t2)<80));
tbcPrintTable();
sleep(tsleep);
if(((int)sppGetTime()-t3)>time_active)
break;
}
}while( ((int)sppGetTime()-t3) < time_active );
} // end of main()
// 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;
}
-86-
byte halRFReceivePacket2(byte timeOut, byte* packetData, byte maxLength) {
byte receivedBytes, pkgLen, crcData, i;
word crcReg;
halConfigTimer23(TIMER3|TIMER23_NO_INT_TIMER, 10000,
CC1010EB_CLKFREQ);
INT_SETFLAG(INUM_TIMER3, INT_CLR);
TIMER3_RUN(TRUE);
RF_SET_PREAMBLE_COUNT(16);
RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE);
MODEM1=(MODEM1&0x03)|0x24; // Make sure avg filter is free-running + 22
baud settling time
INT_ENABLE(INUM_RF, INT_OFF);
INT_SETFLAG(INUM_RF, INT_CLR);
RF_START_RX();
while (1) {
// Check if 10 ms have passed
if (INT_GETFLAG(INUM_TIMER3)) {
// Clear interrupt flag and decrement timeout value
INT_SETFLAG(INUM_TIMER3, INT_CLR);
if (timeOut && !--timeOut) {
timeOut=255;
break; // Timeout
}
}
// Check if sync byte received
if (INT_GETFLAG(INUM_RF)) {
EXIF &= ~0x10; // Clear the flag
break;
}
}
-87-
receivedBytes=0;
// Timeout or sync byte received?
if (timeOut!=255) {
// Lock average filter and perform RSSI reading if desired
RF_LOCK_AVERAGE_FILTER(TRUE);
// Get length of package
RF_WAIT_AND_RECEIVE_BYTE( pkgLen );
pkgLen+=2; // Add the two CRC bytes
// Initialize CRC-16
crcReg=CRC16_INIT;
// Receive as many bytes as packet specifies + 2 crc bytes
while (pkgLen--) {
RF_WAIT_AND_RECEIVE_BYTE( crcData );
// If there is space in the buffer at _packetData_ and we're not
// currently receiving CRC, store the byte
if ( pkgLen>=2 && maxLength ) {
*packetData++=crcData;
receivedBytes++;
maxLength--;
}
// Calculate CRC-16 (CCITT)
for (i=0; i<8; i++) {
if ( ((crcReg&0x8000)>>8) ^ (crcData&0x80) )
crcReg=(crcReg<<1)^CRC16_POLY;
else
crcReg=(crcReg<<1);
crcData<<=1;
}
}
-88-
// Check if CRC is OK
if (crcReg != CRC_OK)
receivedBytes=0;
}
TIMER3_RUN(FALSE);
RF_SET_PREAMBLE_COUNT(RF_PREDET_OFF);
return receivedBytes;
}
2. Slave.c
#include
#include "CC1010MB.h"
#include "PACKET.H"
#include
#include
#include
#include
//LCD define
#define LCDPORT P2
sbit _RS=LCDPORT^0;
sbit _RW=LCDPORT^1;
sbit _E =LCDPORT^2;
#include "lcd.h"
// Protocol constants
#define Node_ID 0xFF
#define Node1 0x01
#define Node2 0x02
-89-
#define Node3 0x03
#define Node4 0x04
#define N 30
#define node_max 10
#define tx 2
#define tactive 20
#define sleep 20
#define PREAMBLE_BYTE_COUNT 7
#define PREAMBLE_BITS_SENSE 16
#define CRC16_POLY 0x1021
#define CRC16_INIT 0xFFFF
#define CRC_OK 0
PACKET xdata txDataBuffer;
PACKET xdata rxDataBuffer;
void halRFSendPacket2(byte numPreambles, byte* packetData, byte length);
byte halRFReceivePacket2(byte timeOut, byte* packetData, byte maxLength);
/*********************************************************************
********
MAIN PROGRAM
*********************************************************************
********/
void main(void) {
unsigned int n;
byte result;
unsigned int node;
-90-
char so[20];
// 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
};
// Calibration data
RF_RXTXPAIR_CALDATA xdata RF_CALDATA;
// Initialize peripherals
WDT_ENABLE(FALSE);
-91-
RLED_OE(TRUE);
YLED_OE(TRUE);
GLED_OE(TRUE);
BLED_OE(TRUE);
BLED = LED_OFF;
RLED = LED_OFF;
GLED = LED_OFF;
YLED = LED_OFF;
// Set optimum settings 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,
CC1010EB_CLKFREQ, 0);
//ADC_SELECT_INPUT(ADC_INPUT_AD0);
//ADC_POWER(TRUE);
UART0_SETUP(57600, 14746, UART_NO_PARITY | UART_RX_TX |
UART_POLLED);
// config timer0 mode 1
TMOD = (TMOD&0xF0)|0x01;
INT_ENABLE(INUM_TIMER0, INT_ON);
INT_GLOBAL_ENABLE(TRUE);
// Calibration
halRFCalib(&RF_SETTINGS, &RF_CALDATA);
P2DIR=0x00; // LCD port is output
lcd_init();
lcd_com(15);
lcd_goto(1,1);
lcd_puts("Coltech WSN Group");
lcd_goto(2,1);
lcd_puts("Coltech WSN Group");
-92-
lcd_goto(3,1);
lcd_puts("Coltech WSN Group");
lcd_goto(4,1);
lcd_puts("Coltech WSN Group");
// Build packet
// first 2bytes is Source of packet (here is Master)
// next 2 bytes is Destination of packet (target node)
// next 2 bytes is type of data or command (temperature or pressure...)
// next 2 bytes is real data or command.
// the transmiting function will add 2 byte CRC16(packet) at the end of packet
txDataBuffer.packet.source = Node_ID;
txDataBuffer.packet.target = 0x00;
txDataBuffer.packet.type = 0x00;
txDataBuffer.packet.dat = 0x00;
n=0;
node = 1;
do{
tbcReceive();
}while(RXI.status != SPP_RX_FINISHED);
while (TRUE)
{
do{
halRFReceivePacket2(50, rxDataBuffer.buffer,
PACKET_LENGTH);
if(RXI.status != SPP_RX_FINISHED)
{
if(i==0)
t1 = (int)sppGetTime();
-93-
i++;
}
}while((RXI.status != SPP_RX_FINISHED)&&(((int)sppGetTime()-
t1)<1000));
i=0;
tbcPrintTable(); //xu lý, neu dúng yêu cau thì goi du lieu.
if( ( (int)sppGetTime()-t1 )>1000 )
{
t2 = (int)sppGetTime();
do{}while( ((int)sppGetTime()-t2)<1000); //tsl = 10s
for(i=1;i<30;i++) //N = 30
{
t1 = (int)sppGetTime();
do
{
t2 = (int)sppGetTime();
do
{
tbcReceive();
}while((RXI.status !=
SPP_RX_FINISHED)&&(((int)sppGetTime()-t2)<80));
tbcPrintTable();
}while(((int)sppGetTime()-t1)<2000); //tactive = 20s
t2 = (int)sppGetTime();
do{}while( ((int)sppGetTime()-t2)<2000); //tsleep = 20s
}
}
}
} // end of main()
// Flash interrupt handler (do nothing)
-94-
// 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;
}
void TIMER0_ISR() interrupt INUM_TIMER0 {
// Reset the timer to generate another interrupt
INT_SETFLAG (INUM_TIMER0, INT_CLR);
// TIMER0_RUN(FALSE);
TH0 = 0x00;
TL0 = 0x00;
// TIMER0_RUN(TRUE);
counter++;
} // TIMER0_ISR
byte halRFReceivePacket2(byte timeOut, byte* packetData, byte maxLength) {
byte receivedBytes, pkgLen, crcData, i;
word crcReg;
halConfigTimer23(TIMER3|TIMER23_NO_INT_TIMER, 10000,
CC1010EB_CLKFREQ);
INT_SETFLAG(INUM_TIMER3, INT_CLR);
TIMER3_RUN(TRUE);
RF_SET_PREAMBLE_COUNT(16);
RF_SET_SYNC_BYTE(RF_SUITABLE_SYNC_BYTE);
MODEM1=(MODEM1&0x03)|0x24; // Make sure avg filter is free-running + 22
baud settling time
INT_ENABLE(INUM_RF, INT_OFF);
INT_SETFLAG(INUM_RF, INT_CLR);
-95-
RF_START_RX();
while (1) {
// Check if 10 ms have passed
if (INT_GETFLAG(INUM_TIMER3)) {
// Clear interrupt flag and decrement timeout value
INT_SETFLAG(INUM_TIMER3, INT_CLR);
if (timeOut && !--timeOut) {
timeOut=255;
break; // Timeout
}
}
// Check if sync byte received
if (INT_GETFLAG(INUM_RF)) {
EXIF &= ~0x10; // Clear the flag
break;
}
}
receivedBytes=0;
// Timeout or sync byte received?
if (timeOut!=255) {
// Lock average filter and perform RSSI reading if desired
RF_LOCK_AVERAGE_FILTER(TRUE);
// Get length of package
RF_WAIT_AND_RECEIVE_BYTE( pkgLen );
pkgLen+=2; // Add the two CRC bytes
// Initialize CRC-16
crcReg=CRC16_INIT;
// Receive as many bytes as packet specifies + 2 crc bytes
while (pkgLen--) {
RF_WAIT_AND_RECEIVE_BYTE( crcData );
-96-
// If there is space in the buffer at _packetData_ and we're not
// currently receiving CRC, store the byte
if ( pkgLen>=2 && maxLength ) {
*packetData++=crcData;
receivedBytes++;
maxLength--;
}
// Calculate CRC-16 (CCITT)
for (i=0; i<8; i++) {
if ( ((crcReg&0x8000)>>8) ^ (crcData&0x80) )
crcReg=(crcReg<<1)^CRC16_POLY;
else
crcReg=(crcReg<<1);
crcData<<=1;
}
}
// Check if CRC is OK
if (crcReg != CRC_OK)
receivedBytes=0;
}
TIMER3_RUN(FALSE);
RF_SET_PREAMBLE_COUNT(RF_PREDET_OFF);
return receivedBytes;
}
//********** END ***********
void halRFSendPacket2(byte numPreambles, byte* packetData, byte length) {
byte crcData, i;
-97-
word crcReg;
// Set the first byte to transmit & turn on TX
RFCON|=0x01; // Ensure that bytemode is selected
RF_SEND_BYTE(RF_PREAMBLE_BYTE);
RF_START_TX();
// Send remaining preambles
while (--numPreambles)
RF_WAIT_AND_SEND_BYTE(RF_PREAMBLE_BYTE);
// Send sync byte + length byte
RF_WAIT_AND_SEND_BYTE(RF_SUITABLE_SYNC_BYTE);
RF_WAIT_AND_SEND_BYTE(length);
crcReg=CRC16_INIT;
// Send data
while (length--) {
crcData=*packetData++;
// Update CRC
RF_WAIT_AND_SEND_BYTE(crcData);
for (i=0; i<8; i++) {
if ( ((crcReg&0x8000)>>8) ^ (crcData&0x80) )
crcReg=(crcReg<<1)^CRC16_POLY;
else
crcReg=(crcReg<<1);
crcData<<=1;
}
}
RF_WAIT_AND_SEND_BYTE((crcReg>>8)&0xFF);
RF_WAIT_AND_SEND_BYTE(crcReg&0xFF);
// Send extra byte + 1 bit to empty buffer
RF_WAIT_AND_SEND_BYTE(0);
-98-
while (!RF_READY_TO_SEND());
RFCON&=~0x01; // Ensure that bitmode is selecte
}
void tbcPrintTable (void) {
int xdata n,m;
float xdata fTemp;
word xdata timeDiff;
if (RI_0) {
RI_0 = 0;
if (isdigit(UART0_RECEIVE())) {
waitMultiplier = toint(UART0_RECEIVE());
} else if (UART0_RECEIVE() == 'd') {
for (n = 1; n < TBC_MAX_NODE_COUNT; n++) {
nodeIDs[n] = TBC_UNUSED_NODE_ID;
}
}
else if (UART0_RECEIVE() == 'n') {
memset(&nodeNames[0][0],0,TBC_NODE_NAME_LENGTH);
printf("\nEnter node name (use up to 20 characters):");
scanf("%s", &nodeNames[0][0]);
// Write new name into Flash
halCopy2Flash(flashUnitName,&nodeNames[0][0],TBC_NODE_NAME_LENGTH,
ramBufNonAligned, CC1010EB_CLKFREQ);
// Get our ID from CRC16(our name)
nodeIDs[0] = culFastCRC16Block(&nodeNames[0][0],
TBC_NODE_NAME_LENGTH, CRC16_INIT);
// Prepare the id+name part of the packet
-99-
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];
}
}
}
// Header:
VT100_GO_TOP_LEFT();
// Items:
printf("TEMPERATURE LIST:");
for (n = 0; n < TBC_MAX_NODE_COUNT; n++) {
if (nodeIDs[n] == TBC_UNUSED_NODE_ID) {
continue;
}
// Node number and ID:
printf("\n%01X. (0x%X) ", n, nodeIDs[n]);
// Node name:
for (m = 0; m < TBC_NODE_NAME_LENGTH; m++) {
UART0_WAIT_AND_SEND(nodeNames[n][m]);
}
if((nodeTarget[n]==Node_ID)&& (nodeType[n]==0xFF))
{
halRFSendPacket(PREAMBLE_BYTE_COUNT,
txDataBuffer.buffer, PACKET_LENGTH);
halRFSetRxTxOff(RF_OFF, NULL, NULL);
}
// Temperature:
-100-
fTemp = nodeTemps[n];
fTemp -= 492;
fTemp /= 8.192;
printf(" - TEMP: %3.2f", fTemp);
// Time after the last update
timeDiff = abs((int) sppGetTime() - nodeLastT[n]) * 10;
printf(" - AGE (msecs): %d", timeDiff);
VT100_CLEAR_LINE_RIGHT();
}
// Available keyboard input options
VT100_INSERT_BLANK_LINE();
printf("\nPress '0'-'9' to change the waiting multiplier");
VT100_CLEAR_LINE_RIGHT();
printf("\nPress 'd' to empty the table");
VT100_CLEAR_LINE_RIGHT();
printf("\nPress 'n' to give the unit a new name");
VT100_CLEAR_LINE_RIGHT();
VT100_CLEAR_SCREEN_DOWN();
} // tbcPrintTable
Các file đính kèm theo tài liệu này:
- LUẬN VĂN-MẠNG CẢM NHẬN KHÔNG DÂY VÀ ĐÁNH GIÁ BẰNG THỰC NGHIỆM MỘT SỐ THÔNG SỐ QUA DDIEEUD KHIỂN THÂM NHẬP MÔI TRƯỜNG.pdf