Using
- CC2530 with the Light Switch example application (swrc135b)
- Smart RF Packet Sniffer (Generic)
- IAR EW8051 8.10.1
The SmartRF sniffer shows that once one node is configured as the Switch and another as a Light, that a packet is sent by the Switch and ACK'd by the Light every time the joystick-switch is pressed. However, there appears to be a bug in the example code as the Light's LED1 only toggles (off) on the first packet Rx'd from the Switch. Thereafter it remains off.
In the appLight() forever loop, the call to basicRfPacketIsReady() only returns a true result when the first packet is received from the switch. The problem is related to the sequence number and the bug is actually in the Switch and not the Light. The Switch is not incrementing the sequence number.
The simple solution is to increment txState.txSeqNumber (e.g. pHdr->seqNumber= txState.txSeqNumber++) in basicRfBuildHeader().
Hi!
I tried the Light Switch App and it's fully functional without the use of the increment.
But, I am currently working on sending packets periodically using Timer 1. After 1 second, the code goes to the ISR and there, it sends the packet. I'm experiencing the same problem as this. The receiver only gets the first packet and is stuck at basicRfPacketIsReady() thereafter.
I've tried adding an increment to the Sequence Number and it's still not working.
Perhaps you know where the problem is?
Hello Nathaniel,
I'm also busy with basicRFPacketIsReady() and the problem I heva is that when I send my first packet everything is ok. But when I send a second packet (for example from another node) the basicRFPacketIsReady() is stuck.
Do you have any advice for this problem?
Thank you very much!
Hey Neils!Sadly, I haven't found a solution to the problem. It only gets stuck when I put the basicRfSend() funciton in the ISR. If it is in its usual function (which is in the Switch function of the Light-Switch example that I just edit), it works. I could not comprehend the problem.
So what I did was to rid off the Timer ISR and used the halMcuWaitMs() function instead for delays in between sending. The delay is not exact, (say you entered 500, it may be around 400-600) but what I can say is that it is consistent, only differing by +- 10 clock ticks (nanosecond region). Consistency is more important for my application than accuracy. How about yours?
Right now, I've switched to the SimpliciTI software stack. I haven't tried the Send function in the ISR function yet but I am having a good feeling that it would definitely work. Moreover, it's easy to familiarize with and in the end, you'll have to choose among the software stacks: SimpliciTI, TIMac, or Zigbee for your application since the BasicRF library is very, very limited and is meant only for familiarization.
What I can suggest is:
> If you DO NOT need very tight and very accurate sending intervals as to be generated by the interrupts, then you may use the halMcuWaitMs() alternative for periodic transmission.
> Else, you could go and try the SimpliciTI software stack, which is very easy to familiarize with, but the Sending functions are better as compared to basicRF.
Good luck and I hope I helped a bit.
Nathaniel :)
Thank you for your quick reply.
Can you tell me what I have to do to just get rid off the Timer ISR? Accuracy is for my application not so very important. In my current program I used the 32kHztimer interrupt for making a delay between sending. Do I have to disable some bit in some register to get ride of the Timer ISR?
My program on the receiver side is like this: Firts I send 30 packages (with a delay between sending) after that I switch to receive mode and I wait for 2 incomming packages from other nodes. So I think the problem is in the delay between my 30 packages if I understand you correct.
Unfortunately I have no experience with SimpliciTI. But when I look on the internet for SimpliciTI it seems to me that I always have to make a network before I can send data between nodes. And that is not what I need. I don't want to build up a network between my nodes because that would decrease the performance of my system. What I need is that every node stands on himself. And they just need to send and receive packages from other nodes.
That's why I used BasicRF. Do you know if I can do this with SimpliciTI?
Thank you very much for your help!
Hello Neils,
Firstly, by getting rid of the ISR, I meant totally removing it from the code and doing the alternative.
Okay, since now we know that accuracy between sending intervals is not important, I suggest you go with sending the packet in this fashion:
basicRfSend(...)halMcuWaitMs(time in milliseconds);
Have it looped 30 times for the 30 packets that you are about to send.
Now, for basicRF and SimpliciTI. As far as I know, there is no broadcast address for basicRF. It only has support for unicast sending among motes. Moreover, it's not quite flexible since a mote can only be either be a sender or listener at one time, cannot be both at the same time - which is critical in most applications. However, in your application, I think it's fixed that after it sent 30 packets, it switches to receive node. I believe it does not need to have the capability to send and receive at a given time, right? So I think basicRF would still be of use for you.
I don't think the linking stage deters SimpliciTI's system performance. It's just a way to save the addresses of the neighbor nodes for easier sending. Every node stands for itself as it can send and receive after linking. The Receive function is sort of a callback function so it goes to a function whenever it receives something. You do not have to do polling for messages, as what is done in basicRF.
I will test my program by removing the all Timer ISR function as soon as possible. I have used the "PER tester" to write my program so I think I have to do a lot of removing in that codes. Because I will have to remove all the function of timerconfig and everything around it, right?
But I have to write also another program where I have around 5 nodes. One of the nodes (node 1) sends 30 packages in broadcast (to all other 4 nodes) and than those 4 nodes will respond immediately to the node who sended the 30 packages (node 1).
I hope that basicRF support CSMA/CA otherwise I will have one big collision of packages of the 4 nodes.
But there i2 problem's in that new program.
frist: Because I use batteries to power my nodes I need a very low current consumption in the delay between sending of my 30 packages (node 1) so I need to set my node 1 in sleep mode, so I can set my µc in PowerMode 2. But I think that sleep mode will cause the problem of basicRFPAcketIsReady() function. Because Sleep mode is also a kind op TIMER interrupt.
second: After node 1 sended 30 packages it will wait 20ms to receive some packages from the other 4 nodes. But if no packages are received within those 20ms the node1 must go to the beginning of his program and send again 30 packages. and than wait 20ms in receive mode, and so on,... So I will always need a timer interrupt to know whether or not 20ms are beyond.
But I'm afraid that such a timer interrupt will cause again the problem of basicRFPAcketIsReady() function.
What do you think of this?
And would I than switch over to SimpliciTI to write the second program or would I stick to the BasicRF??
While using the basicRF code, I am using the Light-Switch application to write my program with since it had the basics of sending and receiving. For your application, I don't think BasicRF will suffice.
First, you need to broadcast. There is one way out of this though. You can assign the SAME addresses to your slave nodes so that when the master sends to THAT address, all of the nodes will be capable of receiving it. However, doing this, you could NOT do unicasts or sending to only one mote. Moreover, you won't know where the reply or acknowledgement came from since they all have the same addresses.
Next, basicRF, though it follows the 802.15.4 MAC protocol, does NOT support CSMA/CA since it is said in the datasheet that basicRF is only a subset of the MAC protocol. Therefore, collisions are possible.
For your problems in your program:
1) I honestly have not tested low power mode since power is not a major consideration in our application, so I am not sure.2) I see, so you will really need timer interrupts.
But, I am happy to tell you that SimpliciTI is capable of solving all your problems.
1) Capable of broadcasting2) Capable of unicasts3) Has the "Listen-Before-Talk" Protocol which is very similar to the 802.15.4 CSMA/CA protocol4) Capable of low power modes and sleeping of radios. I believe it is capable of receiving even if the radios are in sleep mode (check the sample program)
SimpliciTI is worth the shot. Familiarizing with it should be easy.
Hope this helps.
Hello Nathalien,
Thank you so much for your help!!! :)
I will finish my current program in BasicRF but I will write my following program in SimpliciTI.
In your last reply, you where speaking of a sample program for SimpliciTI. Where can I find that for the CC2430/31
Because I'am working with the CC2430/31 with a SmartRF04 evaluation board and some SOC_BB 's.
I am also working with IAR workbench 8051.
So where can I find a sample (example) program for the CC2430 for SimpliciTI. So that I can easy begin programming my code??
Thank you very very much for your help and advice!! And thanks again for all the advices you already gave me!!
Glad to be of help! Congrats on building your program!
Just download the SimpliciTI software stack here in the site and it comes with sample codes from various TI products. I am using the SRF05_8051 code since I am using a SmartRF05 Development Board and a CC2530EM.
I've looked through the folder and I saw SRF04, or CC2430DB. Not sure which one you need but you could try both.
Best of luck! Good job! :)
Nathaniel
Hello Nathaniel
I am learning the samples of SimpliciTI for 2 days now.
But I don't understand how I can send a broadcast massage. Can I send a broadcast message even when my nodes aren't already linked to eachother?
And which method do I have to use when I want to send a broadcast message?
I also don't find anywhere where I can get the RSSI values of my received packets.
Can you help me or give me some advice about these two issues I have?
Thank you very much!!!
Hey Neils,
For your first issue, please refer to this thread for broadcasting in SimpliciTI <http://e2e.ti.com/support/low_power_rf/f/156/t/33354.aspx#116047>
For your second issue, I am also not sure where you could get the RSSI values of the packets.
Good luck with your project!
Thank you very much for your answer!! by the way the function for the rssi values is MRFI.rssi()
But now I have one big problem. I need a time interrupt in my program but I really don't know how I must implememt that in my code. I don't know how I can make a time interrupt (of 33 msec.) and I don't know how I can make an ISR for the time interrupt in SimpliciTI.
Can you give me some advice about this?
Thank you so much!
regards, Niels
Hey Niels,
There are no timer functions in SimpliciTI so you have to create one for yourself.
To create the ISR, I am using the following syntax:
#pragma vector = T1_VECTOR__interrupt static void T1_ISR(void){ //code in ISR here}
Whenever the Timer 1 generates an interrupt, it jumps to this function.
Hey , Nathaniel,
is if I undertsand it correctly, I just need to put
#pragma vector = T1_VECTOR__interrupt static void T1_ISR(void){ //code in ISR here}somwhere in my code like a normal subroutine??One more question: How do I enable the TIMER 1 and how do I initialize TIMER 1 to e.g. 33ms?
Sorry for the late reply.
Yes, like a normal subroutine, put it anywhere in the code. I usually put them somewhere in the top.
In order to know how to initialize a timer, google for the CC2530 User Guide where you can see the registers of the microcontroller.