Luận văn Mạng cảm Nahanj không dây và đánh giá bằng thực nghiệm một số thôi số qua điều khiển thâm nhập môi trường

 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 Slavenào có mặt nó sẽ trả lời, và được Masterghi 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 Masterlạ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à Masterghi nhận được.

pdf100 trang | Chia sẻ: lylyngoc | Lượt xem: 2291 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Luận văn Mạng cảm Nahanj không dây và đánh giá bằng thực nghiệm một số thôi số qua điều 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:

  • pdfLUẬN VĂN-MẠNG CẢM NAHANJ KHÔNG DÂY VÀ ĐÁNH GIÁ BẰNG THỰC NGHIỆM MỘT SỐ THÔI SỐ QUA ĐiỀU KHIỂN THAAM NHẬP MÔI TRƯỜNG.pdf
Luận văn liên quan