- 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;
} }
// 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)
*rssiByte=halRFReadRSSI();
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] :
while (TRUE) {
// 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) { // Wait for the transmission to finish 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;
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.