2016年4月9日 星期六




2015-10-24 updata
雙向資料傳輸,兩台裝置使用相同程式上傳即可
提供1個類比通道及2個數位通道(可擴充,只要接腳夠用)
應用上可作為遙控開關並將遠端設備狀態回傳


心得:nRF24L01模組便宜,收發一體很方便,但訊號好弱阿!































程式碼

/* 雙向資料傳輸,兩台裝置使用相同程式上傳即可


優化參數 2015-10-24 by yulie~
數位狀態使用Bit方式減少資料傳輸量 2015-10-10 bu yulie~
Analog channel x1 A0 Input to Remote D5 PWM Output
Digital Channel x2 D3 & D4 Input to Remote D16(A2) & D17(A3) Digital Output
2015-09-22 by yulie~
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 10); //CE_PIN, CSN_PIN Create a Radio
const byte Channel = 121; //0-127
const byte DataLongAdj = 20; // 0~255 不穩或不通,傳送的資料量加大時必須時加大數值 0/34;10/26; 20/21; 30/17; 50/12;  
const byte Sw_1 = 3; // pin D3
const byte Sw_2 = 4; // pin D4
const byte Pwm_1 = 5; // Analog Output map remote A0 input
const byte Led_1 = 16; // pin D17 = A2
const byte Led_2 = 17; // pin D17 = A3
const byte RT_Led = 8; // R/T state pin 8
const uint64_t pipe = 0x0937168940LL; // Define the transmit pipe 傳送與接收兩邊的值必須相同,共有10個位元組(10BYTES)
unsigned long data[2]; //(收&發共用一組資料陣列, 共2
unsigned long t, u, v, w, txCount, retry = 0;


void setTx() {
radio.begin();
radio.openWritingPipe(pipe); //transmit mode
radio.setChannel(Channel); //0-127
radio.setPALevel(RF24_PA_MIN); //MIN=-18dBm,LOW=-12dBm, HIGH=0dBm.
radio.setDataRate(RF24_250KBPS); //2M,1M,250K
//radio.setCRCLength(RF24_CRC_DISABRT_Led); //RF24_DISABRT_Led if disabRT_Led or RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit
delay(3);
}
void setRx() {
radio.begin();
radio.openReadingPipe(1, pipe); //receive mode
radio.startListening();
radio.setChannel(Channel); //0-127
radio.setPALevel(RF24_PA_MIN); //MIN=-18dBm,LOW=-12dBm, HIGH=0dBm.
radio.setDataRate(RF24_250KBPS); //2M,1M,250K
//radio.setCRCLength(RF24_CRC_DISABRT_Led); //RF24_DISABRT_Led if disabRT_Led or RF24_CRC_8 for 8-bit or RF24_CRC_16 for 16-bit
delay(5); // < 5 unstable
}


void Tx() {


// data[1] = (analogRead(1)/4); //Analog Input #2
bitWrite(data[0], 0, digitalRead(Sw_1)); //Digital Input #1  讀取數位輸入資料並存放到陣列 0 的Bit 0位置
bitWrite(data[0], 1, digitalRead(Sw_2)); //Digital Input #2  讀取數位輸入資料並存放到陣列 0 的Bit 1位置
data[1] = (analogRead(0)); //Analog Input #1  讀取類比輸入資料並存放到陣列 1 的位置, 0~1023 --> 0~255
setTx();
digitalWrite(RT_Led, HIGH);
radio.write( data, sizeof(data) ); //Radio Send data
digitalWrite(RT_Led, LOW);
}


void setup() {
Serial.begin(9600, SERIAL_8N1);
setRx();
pinMode(Sw_1, INPUT_PULLUP);
pinMode(Sw_2, INPUT_PULLUP);
pinMode(Led_1, OUTPUT);
pinMode(Led_2, OUTPUT);
pinMode(RT_Led, OUTPUT);
pinMode(6, OUTPUT); //Sw_2 GND
digitalWrite(6, LOW);
}


void loop() {
t = millis();
if (t - u >= (random(3, 6) * 500)) //兩台的重發時間由隨機數1500,2000,2500 錯開 (手動為 1500 & 2500 )
{
Tx(); // data[2]內部的資料被更新為"本地"裝置讀取的數值
u = millis(); //未接收到資料時發送,後重置計數
retry++;
Serial.print("Link down Tx retry count : "); Serial.println(retry);
}
delay(5);
setRx();
delay(DataLongAdj);


if (radio.available() )
{
// digitalWrite(RT_Led, HIGH);
bool done = false; // Read the data payload until we've received everything
while (!done)
{
done = radio.read( data, sizeof(data) ); // 這裡data[2]內部的資料被更新為"遠端"裝置讀取的數值
digitalWrite(Led_1, bitRead(data[0], 0)); // 讀取陣列 0 的Bit 0位置,輸出到 Led_1 對應的數位接腳
digitalWrite(Led_2, bitRead(data[0], 1)); // 讀取陣列 0 的Bit 1位置,輸出到 Led_2 對應的數位接腳
analogWrite(Pwm_1, (data[1]) / 4); // 讀取陣列 1 的值 ,輸出到 Pwm_1 接腳 rx 0~1023 to 0~255


// digitalWrite(Led_1, (data[2]));
delay(0); //Rx to Tx delay timeu
Tx(); // Tx Data~~~~~~~
txCount++;
u = millis(); // 接收完資料後再發送後重置計數


v = millis();
if (v - w >= 10000) {
Serial.print("( Sec) Tx counter : "); Serial.println(txCount / 10);
w = millis();
txCount = 0;
}
}
}
else
{
// Serial.println(" ---> No radio available");
}
// digitalWrite(RT_Led, LOW);
}//--(end main loop )---

沒有留言:

張貼留言