- Lỗi không phát hiện được: Trong trường hợp này ta giải mã ra w*I nhưng khác với wi đã
3.4.2 Kiểm tra trong nhà
Khi thực hiện truyền dữ liệu ở 3 vị trí khác nhau trong nhà không sử dụng FEC thì tỷ lệ mất gói tin cũng khá lớn.[12]
Chương 4. ĐIỀU KHIỂN LỖI ỨNG DỤNG CHIPCON CC1010 4.1 Giới thiệu
Trong khi 1 mã sửa lỗi ECC có thể được chỉ định trong bất kỳ lớp nào trong network stack, thì thực tế ECC được sử dụng trong lớp MAC [4] như hình minh hoạ :
Hình 4.1 Interfacing ECC module with network stack
Bởi vì với vị trí này sẽ không làm thay đổi sự chuyển giao với lớp ứng dụng. Do đó, bất kỳ ứng dụng nào được viết mà không dùng ECC trong MAC cũng có thể thực hiện mà không cần điểu chỉnh mã nguồn.
Quá trình thực hiện mã sửa lỗi ECC tương tác với network stack qua giao diện RadioEncoding – Giao diện là 1 file được sử dụng ngôn ngữ TinyOS-nesC chỉ rõ toàn bộ các phương pháp và những bộ điều khiển sự việc cái mà 1 module sử dụng từ các module khác hay 1 module hiện hữu :
interface RadioEncoding {
command result_t encode_flush(); command result_t encode(char data); command result_t decode(char data);
event result_t decodeDone(char data, char error); event result_t encodeDone(char data);
}
Mã hoá được thực hiện ở lớp MAC (ChannelMonC module) cho mỗi byte dữ liệu trong gói tin. Dữ liệu vào được thông qua như một thông số được lưu trữ trong cấu trúc dữ liệu của mô-đun ECC. Sau khi một số lượng đủ của các byte dữ liệu vào – input được nhận, các byte dữ liệu đầu vào được mã hoá bởi hàm
radio_encode_thread (mạch mã hoá radio) và từ mã được chuyển tới ChannelMonC qua hàm encodeDone.
Tương tự như trên, ChannelMonC đưa ra quá trình giải mã cho từng byte của các gói tin nhận được. Sau khi đủ số lượng các byte dữ liệu vào được nhận, các byte dữ liệu được nhận sẽ được giải mã nhờ hàm radio_decode_thread (
mạch giả mã radio ) và các byte dữ liệu gốc được gửi tới ChannelMonC qua
DecodeDone.
Quá trình thực thi của radio_encode_thread và radio_decode_thread
phụ thuộc vào loại mã sửa lỗi. radio_encode_thread tính toán các bit chẵn lẻ nhờ vào việc so sánh từng bit trong các byte dữ liệu đầu vào. Quá trình này tương đương với uG. Trong đó u là thông tin cần truyền và G là ma trận sinh. Trong quá trình radio_decode_thread , syndrome – s được tính nhờ vào các bit dữ liệu nhận được. Việc này cũng tương đương với thực hiện vHT , với v là dữ liệu nhận được và HT là ma trận chuyển vị của ma trận H. Nếu syndrome – s
khác không (s # 0) có nghĩa là tồn tại lỗi và vị trí của các bit lỗi có thể được tìm thấy bằng việc so sánh syndrome – s với các vec-tơ cột trong ma trận H . Và quá trình tìm kiếm này có thể được thực hiện một cách nhanh chóng với việc sử dụng các biểu đồ tương ứng giữa các giá trị syndrome – s với các vị trí bit lỗi tương ứng.
4.2 Tìm hiểu chương trình truyền nhận dữ liệu trong CC1010
Thuật toán để xác định và sửa lỗi cho dữ liệu là CRC – 16 . Ta sẽ xem xét từng quá trình truyền và nhận giữa hai nút mạng.
4.2.1 Quá trình truyền dữ liệu giữa 2 nút mạng [14]:
- Sử dụng hàm halRFSendPacket (…) để điều khiển việc gửi gói tin sử dụng trong cấu hình RF hiện thời:
void halRFSendPacket(byte numPreambles, byte* packetData, byte length) {
byte crcData, i; 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);
- Nếu xuất hiện lệnh yêu cầu truyền ( tức là hàm halRFSendPacket được gọi ) cùng với cặp RX/TX phù hợp với chế độ RF_TX thì quá trình truyền sẽ được thực hiện : đầu tiên một byte đồng bộ sẽ được truyền đi để đảm bảo sự đồng bộ giữa bên truyền và bên nhận, sau đó là byte Preamble ( byte này có vai trò báo hiệu phần bắt đầu của gói tin ) và tiếp sau là dữ liệu cần truyền. Phần kiểm lỗi CRC sẽ được đặt ở vị trí cuối cùng trong gói tin để thuận tiện cho việc kiểm tra sau này.
word culFastCRC16(byte crcData, word crcReg) {
return (crcReg << 8) ^ crc16LUT[((byte)(crcReg >> 8)) ^ crcData]; } // culFastCRC16
word culFastCRC16Block(byte *crcData, word length, word crcReg) { word i;
for (i = 0; i < length; i++) {
crcReg = (crcReg << 8) ^ crc16LUT[((byte)(crcReg >> 8)) ^ crcData[i]];
}
return crcReg;
crcReg=CRC16_INIT;
// 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; } } // Send CRC-16 RF_WAIT_AND_SEND_BYTE((crcReg>>8)&0xFF); RF_WAIT_AND_SEND_BYTE(crcReg&0xFF);
Trong đó từ mã chứa trong hàm crcLUT[256] không được đưa ra ở đây, các dạng của từ mã đã được định trước trong CPU. Trường hợp này gồm có 256 từ mã.
Hàm sửa lỗi là hàm culFastCRC16(crcDaTa, CRC REg) . Trong đó
+ crcData : là chuỗi dữ liệu gốc cần để thực hiện CRC-16 một cách hiệu quả.
+ crcReg : giá trị hiện thời của thanh ghi CRC.
Quá trình thực hiện sửa lỗi dùng CRC 16 được xem là quá trình thực hiện nhanh chóng , hàm được gọi cho từng byte trong chuỗi dữ liệu.Với mỗi byte được gọi thì CRC được thêm vào phần cuối cuả byte dữ liệu đó, vị trí đặt như vậy sẽ giúp thuận tiện cho việc kiểm tra CRC sau này.
Quá trình thêm vào CRC sau mỗi byte dữ liệu tương đương với việc uG
với u là dữ liệu gốc, G là ma trận sinh. Vì ở đây là kiểm lỗi CRC-16 nên số bit được thêm vào là 8, đồng nghĩa với việc thanh ghi crcReg sẽ bị dịch trái đi 8 bit
sau khi thêm CRC, và trạng thái của nó sau đó cũng trở lại trạng thái lúc cuối cùng được cấp.
return crcReg : là giá trị cập nhật của thanh ghi CRC16, giá trị này tương ứng với giá trị syndrome - s. Quá trình kiểm lỗi kết thúc, giá trị này sẽ quay về 0 nếu dữ liệu không bị thay đổi gì.
Vì rằng để đảm bảo hiệu năng, hàm culFastCRC16 ở trên được thực hiện trong các khối dữ liệu thay vì cho những byte đơn lẻ, do đó hàm culFastCRC16Block(byte *crcData, word length, word crcReg) được sử dụng để đảm bảo cho quá trình kiểm lỗi của khối dữ liệu này.
4.2.2 Quá trình nhận dữ liệu giữa 2 nút mạng [14]:
- Sử dụng hàm halRFReceivePacket (…) để điều khiển quá trình nhận các gói tin được gửi tới từ hà halSendPacket trong một bộ CC1010 khác.
void halRFReceivePacket(...)
byte halRFReceivePacket(byte timeOut, byte* packetData, byte maxLength, char* rssiByte, word clkFreq) {
byte receivedBytes, pkgLen, crcData, i; word crcReg; halConfigTimer23(TIMER3|TIMER23_NO_INT_TIMER, 10000, 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;
} }
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
if (rssiByte)
Tính toán và kiểm tra FEC // 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; }
- Giả sử rằng RX đã được kích hoạt : khi đó bên nhận sẽ chờ nhận byte đồng bộ. Nếu quá thời hạn cho phép mà không nhận được byte đồng bộ nào thì hàm sẽ trở về 0, tức là sẽ tắt chế độ sẵn sàng nhận cho đến khi nhận được lệnh nhận tiếp sau. Nếu một byte đồng bộ được nhận trong khoảng thời gian chờ cho phép, thì các byte dữ liệu sau đó sẽ được nhận và được chuyển vào trong bộ đệm . Thứ tự các byte được chỉ ra trong trường độ dài gói tin.
Tuy nhiên CRC chỉ ứng dụng được trong trường hợp số bít lỗi là nhỏ. Chính vì vậy vẫn cần tồn tại thuật toán truyền dữ liệu trong mạng cảm nhận không dây dựa vào gói trả lời ACK. Quá trình đảm bảo độ tin cậy của truyền dữ liệu trong mạng cảm nhận không dây dựa vào gói trả lời ACK có thuật toán phức tạp hơn quá trình CRC. Hơn nữa ta thấy nếu trong quá trình truyền mà không nhận được ACK thì gói tin sẽ được yêu cầu truyền lại trong giới hạn n lần. Điều này sẽ gây nên thời gian trễ lớn và tốn dung lượng bộ nhớ, cộng với thuật toán phức tạp làm tiêu hao nhiều năng lượng hơn, đây là một điều rất đáng quan tâm với các nút mạng cảm biến.
Nguyên lý truyền dẫn giữa 2 nút mạng được mô tả như sau: + Quá trình truyền :
Nếu bộ thu phát ở trạng thái rỗi (sẵn sàng truyền) thì thành phần phát sẽ được kích hoạt. Qúa trình truyền được thực hiện trên RF ISR, và nút truyền chờ nhận lại ack (nếu được yêu cầu).
Nếu tại bộ phát (nút truyền) được cấp yêu cầu truyền lại với ( sppSetting.TXAttempts = n ) thì gói tin sẽ được truyền lại (n-1) lần cho đến khi nhận được gói tin phản hồi ACK.
Quá trình truyền được diễn ra liên tục ngay cả khi UART vẫn đang trong quá trình nhận, trong suốt quá trình truyền nó được đặt vào chế độ TX_Mode (chế độ đang truyền) hoặc chờ nhận ACK (TXACK_MODE). Kết thúc hoạt động truyền trạng thái của đường truyền sppStatus ( ) sẽ trở lại trạng thái rỗi (spp_IDLE_MODE).
+ Quá trình nhận:
Nếu bộ thu phát rỗi (ở trạng thái sẵn sàng truyền và nhận spp_IDLE_MODE); khi đó nếu nhận được yêu cầu nhận, thì thành phần nhận trong nút mạng sẽ được kích hoạt. Quá trình nhận được thực hiện nhờ RF ISR ( Radio-Frequency Interrrupt-Service-Routine ) và thực hiện truyền ACK ( nếu được yêu cầu).
Kết thúc mỗi lần nhận. Bộ nhận sẽ được tắt nguồn. Nhưng chức năng nhận sẽ được kích hoạt trở lại ngay khi ứng dụng được yêu cầu tiếp theo đó. Trong suốt quá trình nhận bộ nhận luôn ở trạng thái chờ nhận gói tin (RX_MODE) hoặc đang truyền ACK (RXACK_MODE).
Kết thúc hoạt động truyền, trạng thái của đường truyền sppStatus ( ) sẽ trở lại trại thái rỗi ban đầu (spp_IDLE_MODE) .
Giữa hai nút mạng cảm biến thì quá trình truyền và nhận luôn được chuyển đổi qua lại. Do đường truyền là bán song công nên trong cùng một thời điểm chỉ có một bên được phép truyền, kết thúc quá trình truyền nhận thường bộ thu phát sẽ thiết lập lại các giá trị. Dưới là một minh hoạ về cấu trúc chương trình truyền nhận trên RF được thực hiện trong vòng lặp while [13] :
// Receive a packet – Nếu nhận tin
if (sppReceive(&RXI) == SPP_RX_STARTED) {
do {
if (txRequest && (TXI.status == SPP_TX_FINISHED) && (RXI.status == SPP_RX_WAITING)) { sppReset(); }
} while (SPP_STATUS() != SPP_IDLE_MODE
if (RXI.status == SPP_RX_FINISHED) { if (SPP_SEQUENCE_BIT & (lastRXflags ^ RXI.flags)) { while (uartRXPos != rxDataLen[uartRXBuffer]); if ((rxDataLen[rfRXBuffer] = RXI.dataLen) != 0) dau // Switch buffers and initiate UART0 transmission
GLED = ~GLED; SWITCH(uartRXBuffer, rfRXBuffer); RXI.pDataBuffer = pRXBuffer[rfRXBuffer]; uartRXPos = 0; UART0_SEND(pRXBuffer[uartRXBuffer][uartRXPos]); } } lastRXflags = RXI.flags; } }
// Transmit packet, if requested - truyền tin nếu nhận được yêu cầu
if (txRequest) {
if (sppSend(&TXI) == SPP_TX_STARTED) {
YLED = LED_ON; // đèn vàng bật đang truyền } while (SPP_STATUS() != SPP_IDLE_MODE
Nếu đường truyền rỗi thi ta thực hiện truyền YLED = LED_OFF;
// Check out the results
if (TXI.status == SPP_TX_FINISHED) { sppSettings.rxTimeout = NORMAL_TIMEOUT; RLED = LED_OFF; txRequest = TX_REQUEST_OFF; } else { RLED = LED_ON; sppSettings.rxTimeout = RETRY_TX_TIMEOUT; } } }
// Recalibrate the transceiver if requested to --- xác lập lại tại bộ thu phát nếu có lệnh yêu cầu
if (recalibRequest) {
sppSetupRF(&RF_SETTINGS, &RF_CALDATA, TRUE); }
} } // main
Qua việc nghiên cứu chương trình tuyến nhận dữ liệu của CC1010, ta thấy chương trình này không sử dụng FEC. Hướng đến việc cải thiện hiệu quả sử dụng năng lượng cho node mạng, luận văn đề xuất cải tiến tuyến truyền nhận nói trên bằng cách sử dụng FEC. Sau đây là một số gợi ý cho việc cải tiến này.
4.3 Đề xuất sử dụng FEC cho tuyến truyền nhận dữ liệu giữa các node mạng CC1010
4.3.1 Giả định bài toán và cách tính các từ mã
Giả sử đoạn dữ liệu đơn giản 1101 + Xác định ma trận sinh G:
Thông tin cần mã hoá thì từ mã tương ứng sẽ là:
Ma trận sinh G sẽ được chọn sao cho đảm bảo nguyên tắc các hàng của G phải độc lập tuyến tính.
Gọi v = (a1,a2,a3,a4,a5,a6,a7) là một từ mã, ta có:
Suy ra:
Hay:
Công thức này cho phép chúng ta mã hoá được thông báo u thành từ mã v. Chẳng hạn nếu:
Biến đổi công thức trên thành dạng v = uxG, ta đưa được về dạng:
Ta suy ra được ma trận sinh G:
+ Xác định ma trận Hamming H:
Trong dạng mã hoá khối tuyến tính G có thể được chuyển thành dạng như sau: G = [Ik:C] khi đó ma trận kiểm lỗi H = [CT:Ir]
Hoặc G = [C:Ik] khi đó ma trận kiểm lỗi H = [Ir:CT]
+ Xác định từ mã:
Với dữ liệu cần gửi là u = 1101
Tại nơi thu dữ liệu u sẽ được mã hoá thành từ mã v:
Giả sử rằng truyền lỗi làm nơi nhận nhận sai bit thứ 5; nghĩa là từ mã v nhận được tại nơi thu sẽ có dạng w = [0111101]
Syndrome (s) sẽ được xác định tại bên nhận theo công thức:
Suy ra s = [011] trùng với hàng thứ 5 trong ma trận HT, vậy ta có thể kết luận dữ liệu thu được bị lỗi tại vị trí thứ 5. Khi đó dữ liệu đúng nhận được là v=[01111001] và giải mã ra ta được từ mã đúng cần nhận là u = [1101]
Trên cơ sở chương trình truyền dữ liệu đã nói ở mục 4.3.1 có thể chèn từ mã vào mã nguồn ở các vị trí sau:
Tuy nhiên với việc đưa các từ mã sửa lỗi vào dữ liệu ở phía truyền cũng cần thuật toán để giải mã và sửa lỗi ở phía nhận, sau đó tiến hành thử nghiệm để đánh giá hiệu quả của phương pháp này so với phương pháp cũ, nhưng vì thời gian có hạn, luận văn dừng ở đây, với mong muốn công việc này được tiến hành tiếp sau này bởi chính tác giả hoặc một người nào đó.
4.4 Kết luận chương 4
Nghiên cứu chương trình truyền và nhận dữ liệu của mạng WSN trên cơ sở CC1010 đã có. Đã đề xuất ứng dụng phương pháp FEC cho việc truyền dữ liệu của CC1010. Đã giả thiết bài toán và tìm được các từ mã tương ứng.
Trên cơ sở nhữn kết quả này có thể vận dụng vào các chương trình tuyến nhận dữ liệu nói trên, để thu được hiệu quả sử dụng năng lượng tốt hơn.
KẾT LUẬN
Đề tài “Nghiên cứu mã điều khiển lỗi trong mạng cảm biến không dây để nâng cao hiệu quả việc sử dụng năng lượng” đã đạt được những kết quả sau:
- Đã tổng quan về mạng WSN
- Đã nghiên cứu phân tích về các kỹ thuật phát hiện lỗi và các kỹ thuật sửa lỗi. Trong đó đặc biệt nhấn mạnh kỹ thuật sửa lỗi hướng thuận FEC, đây là kỹ thuật sửa lỗi phù hợp với mạng WSN, hứa hẹn đưa lại hiệu quả sử dụng tốt năng lượng của node mạng, kéo dài tuổi thọ toàn mạng.
- Đã tìm hiểu cụ thể các chương trình truyền nhận dữ liệu của mạng WSN trên cơ sở CC1010 có ở phòng thí nghiệm và phát hiện phương pháp sửa lỗi ở đây là truyền lại dữ liệu. Do vậy luận văn đề xuất và tính toán các từ mã để có thể ứng dụng phương pháp sửa lỗi hướng thuận FEC cho mạng WSN.
Tuy nhiên công việc này đòi hỏi phải bổ sung vào chương trình nguồn đã có các đoạn chương trình mới cho bên phát và bên nhận.
Do thời gian có hạn nên công việc này không kịp thực hiện. Tác giả đề xuất hướng nghiên cứu tiếp là bổ sung các từ mã của phương pháp FEC vào bên phát và bên gửi, sau đó tiến hành thực nghiệm đo hiệu quả truyền nhận dữ liệu và đo năng lượng tiêu hao của node mạng để đánh giá tính ưu việt của phương pháp FEC.