Hi,
Right from my childhood I wanted to control appliances and had an eye for Automation
may be I'm just too lazy , two years back I wrote the software for this !
Video of my WSN NRF24L01+Arduino
code is somewhat like this .
NRF24L01 packet
class packet {
public :
unsigned char frame_type; // data or synchronization
unsigned short int to_add; // packet destination address
unsigned short int from_add; // packet origin address
unsigned short int h_from_add; // packet immediate hopped address
unsigned short int frame; // packet send on frame
unsigned long data1; // data holder
};
Arduino setup function , here were are setting up nrf24l01/serial/ZCD .
void setup()
{
if ( cid == 0 ) {
pinMode(2, OUTPUT);
} else {
pinMode(2,INPUT);
}
pinMode(DETECT, INPUT); //zero cross detect
digitalWrite(DETECT, HIGH); //enable pull-up resistor
pinMode(GATE, OUTPUT); //triac gate control
Serial.begin(57600);
while (!Serial) ;
Serial.println("start ");
if (!nrf24.init())
Serial.println("NRF24 init failed");
if (!nrf24.setChannel(B_Freq))
Serial.println("setChannel failed");
mask1 = mask | cid;
if (!nrf24.setThisAddress((uint8_t*)(&mask1), 5))
Serial.println("setThisAddress failed");
if (!nrf24.setPayloadSize(len))
Serial.println("setPayloadSize failed");
if (!nrf24.setRF(NRF24::NRF24DataRate2Mbps, NRF24::NRF24TransmitPower0dBm))
Serial.println("setRF failed");
ping_s = 0;
cnt =0;
frame = 150;
route_packet = 0;
route_pac_delay = 0;
num_retries = 0 ;
b_cnt = 0;
data.h_from_add = cid ;
data.frame_type = 0;
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 30000; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS11); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
if ( cid == 0 ) {
is_sync = 1;
} else {
is_sync = 0;
}
randomSeed(cid*10);
b_cnt = random(200,500);
ping_timeout=random(200,500);
ping_retries=0;
Serial.print("Curr ID ");
Serial.println(data.h_from_add,DEC);
attachInterrupt(1,zeroCrossingInterrupt, CHANGE );
}
Right from my childhood I wanted to control appliances and had an eye for Automation
may be I'm just too lazy , two years back I wrote the software for this !
Video of my WSN NRF24L01+Arduino
code is somewhat like this .
NRF24L01 packet
class packet {
public :
unsigned char frame_type; // data or synchronization
unsigned short int to_add; // packet destination address
unsigned short int from_add; // packet origin address
unsigned short int h_from_add; // packet immediate hopped address
unsigned short int frame; // packet send on frame
unsigned long data1; // data holder
};
Arduino setup function , here were are setting up nrf24l01/serial/ZCD .
void setup()
{
if ( cid == 0 ) {
pinMode(2, OUTPUT);
} else {
pinMode(2,INPUT);
}
pinMode(DETECT, INPUT); //zero cross detect
digitalWrite(DETECT, HIGH); //enable pull-up resistor
pinMode(GATE, OUTPUT); //triac gate control
Serial.begin(57600);
while (!Serial) ;
Serial.println("start ");
if (!nrf24.init())
Serial.println("NRF24 init failed");
if (!nrf24.setChannel(B_Freq))
Serial.println("setChannel failed");
mask1 = mask | cid;
if (!nrf24.setThisAddress((uint8_t*)(&mask1), 5))
Serial.println("setThisAddress failed");
if (!nrf24.setPayloadSize(len))
Serial.println("setPayloadSize failed");
if (!nrf24.setRF(NRF24::NRF24DataRate2Mbps, NRF24::NRF24TransmitPower0dBm))
Serial.println("setRF failed");
ping_s = 0;
cnt =0;
frame = 150;
route_packet = 0;
route_pac_delay = 0;
num_retries = 0 ;
b_cnt = 0;
data.h_from_add = cid ;
data.frame_type = 0;
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 30000; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS11); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
if ( cid == 0 ) {
is_sync = 1;
} else {
is_sync = 0;
}
randomSeed(cid*10);
b_cnt = random(200,500);
ping_timeout=random(200,500);
ping_retries=0;
Serial.print("Curr ID ");
Serial.println(data.h_from_add,DEC);
attachInterrupt(1,zeroCrossingInterrupt, CHANGE );
}
Below Function will send data to next hop address based on routing table .
bool route_data () {
routed = 0 ;
for ( cnt = 0 ; cnt <= luk_len ; cnt ++ ) {
if ( (data.to_add >= luk_tab[cnt][0] && data.to_add <= luk_tab[cnt][1] ) ) {
routed = 1;
if ( cnt == luk_len ) {
send_to(up_link);
} else {
send_to(luk_tab[cnt][0]);
}
break ;
if ( routed == 1 ) {
break ;
}
}
}
if ( routed == 0 || routed != 1 ) {
// NOT ABLE TO SEND THE data .
}
return (routed==1) ;
}
Actual function which will send data via NRF24L01 , it will also select frequency based on to_address and frame number .
bool send_to (unsigned short int to_addr ) {
if ( b_flag == 0 ) {
f = to_addr * 11117 + ( frame *31 ) ;
f = (f/13) % 11 ;
f = (f * 10) +1 ;
} else {
f = B_Freq;
}
if (!nrf24.setChannel(f))
Serial.println("setChannel failed");
mask1 = mask | to_addr ;
if (!nrf24.setTransmitAddress((uint8_t*)(&mask1), 5)) {
Serial.println("setTransmitAddress failed");
routed = 2;
}
delayMicroseconds(700);
if ( b_flag == 1 ) {
data.frame = frame;
rtt = TCNT1;
data.data1 = rtt + 1700 ;
data.frame_type = 3;
}
data.h_from_add = cid;
if ( debug == 1 && data.frame_type == 2) {
Serial.print(to_addr,DEC);
Serial.print(" to add ,S'dg ");
Serial.print(data.data1,DEC);
Serial.print(" frame is ");
Serial.println(frame,DEC);
}
if (!nrf24.send((uint8_t*)&data, sizeof(data),b_flag)) {
Serial.println("E4");
routed = 3;
}
if (!nrf24.waitPacketSent()) {
Serial.print("Sndg Fail ");
routed = 4;
}
return ( routed == 1 || b_flag ) ;
}
Receiver function , configures NRF24L01 in RX mode and selects frequency based on same formula used in TX mode .
bool listen_rx() {
f = cid * 11117 + ( frame *31 );
f = (f/13) % 11 ;
f = (f * 10) +1 ;
nrf24.powerUpRx();
if (!nrf24.setChannel(f))
Serial.println("setChannel failed");
if (nrf24.waitAvailableTimeout(5)) {
if (!nrf24.recv((uint8_t*)&data_junk, &len)) {
Serial.println("read failed");
return 0;
}
if ( debug == 1 && data_junk.frame_type==2) {
if ( serial_read == 'A' ) {
trigger_delay = data_junk.data1 -65 ;
Serial.print("setting val ");
Serial.println(trigger_delay , DEC );
}
Serial.print(data_junk.h_from_add,DEC);
Serial.print(" rx from add ,S'dg ");
serial_read = data_junk.data1;
Serial.print(serial_read,DEC);
Serial.print(" frame is ");
Serial.println(frame,DEC);
}
if ( data_junk.frame_type == 2 && data_junk.to_add != cid) {
data_in=data_junk;
route_packet =1;
route_pac_delay = random(2,8);
num_retries = 0 ;
}
}
return 1;
}
Function used for synchronizing two nodes , received beacon packet will have counter value which is used to load into TCNT1 of received node .
void sync_me (bool ip) {
nrf24.powerUpRx();
if (!nrf24.setChannel(B_Freq))
Serial.println("setChannel failed");
mask1 = mask | up_link ;
if (!nrf24.setTransmitAddress((uint8_t*)(&mask1), 5))
Serial.println("setTransmitAddress failed");
if ( ip == 1) {
}
if ( ip == 1 ) {
TCCR1B &= ~(1 << CS11); // stop counter
nrf24.waitAvailable() ;
TCCR1B |= (1 << CS11); // start counter
}
if (!nrf24.recv((uint8_t*)&data, &len))
Serial.println("read failed");
TCNT1 = data.data1 - 500;
frame = data.frame;
mask1 = mask | data.h_from_add ;
is_sync =1;
nrf24.setTransmitAddress((uint8_t*)"NULL1", 5);
}
Function used to send beacon packet for slave nodes
void send_beacon () {
// Serial.print("Send beac ");
// Serial.println(frame,DEC);
b_flag = 1;
send_to(cid);
b_flag = 0;
b_cnt = random(300,600);
}
Function calling route_data() and from there send_to() .
void send_packet () {
//Serial.println("send pack");
data=data_in;
data.frame_type =2;
if ( ! route_data() ) {
num_retries++;
if ( num_retries > 10 ) {
Serial.println("Droping pack");
route_packet =0 ;
num_retries = 0 ;
}
} else {
route_packet = 0;
num_retries = 0 ;
}
route_pac_delay = random(5,15);
data.frame_type = 0;
}
MISC functions used for book keeping
bool process_state () {
while ( ping_s == 0 ) {delayMicroseconds(1);}
ping_s = 0 ;
frame= frame+1 ;
if ( frame > 150 ) {frame = 0;}
}
bool post_processing () {
// nrf24.powerDown();
if ( route_pac_delay > 0 ) {
route_pac_delay--;
}
b_cnt ++ ;
ping_timeout++ ;
}
Functional loop used to send/receive/synchronize nodes .
void loop() {
loop_var = 10;
process_state();
if ( cid == 0 ) {
digitalWrite(2,HIGH);
digitalWrite(2,LOW);
}
if ( is_sync == 0 ) {
loop_var = 3;
sync_me(1);
Serial.println("sync'd");
} else if ((cid+2) == frame ) {
loop_var = 4;
send_beacon();
} else if ( (up_link+2)==frame ) {
loop_var = 5;
sync_me(0);
} else if (route_packet == 1 && route_pac_delay == 0) {
loop_var = 6;
send_packet();
} else if (route_packet == 0 && Serial.available()) {
loop_var = 7;
Serial.println(max_tcnt,DEC);
data_in.data1 = Serial.read(); ;
data_in.to_add = ping_node ;
data_in.from_add = cid ;
route_packet =1;
num_retries = 0 ;
} else {
loop_var = 8;
listen_rx();
}
nrf24.setTransmitAddress((uint8_t*)"NULL1", 5);
post_processing();
if ( ping_s == 1 ) {
Serial.print("Error ");
Serial.println(loop_var,DEC);
// delay(100000);
}
}
I'll update more information and few pictures explaining how routing between nodes work .
2019 ford edge titanium for sale
ReplyDelete2019 titanium chain ford titanium gold edge titanium. Find high quality antique used titanium alloy furniture, antique accessories, vintage vintage watches, titanium app and more titanium jewelry at affordable prices.