RFBee firmware updating

1.Change method of receiving RF data from interupt to polling, making RFBee more stable and when in transv mode.

2.Add state check, avoiding RFBee into dead state.

3.Modify ATDR command response info.

RFBee firmware v1.03
Main changes:

  1. Txoff-> IDLE
  2. Only transmit the threshold length every time.
  3. Delay 10ms in every transmitting.

RFBee firmware v1.1a3 (by Hans and Icing)
Main feature(compared to v1.03):

  1. More clear and extenable code structure.(Do not need to modify arduino library)
  2. More free RAM space for user applications.
  3. More stable

Main changes(compared to v1.1a2):

  1. Keep RFBee staying in command mode excepting the ATMD* command.
  2. Make the ATBD* command work ok.
  3. Add ATSI* command to control if adding RSSI byte or not. ATSI0 disable RSSI, ATSI1 enable RSSI.
  4. Modify the readSerialData(),so that the RFBee can properly transmit the last buffer data before entering command mode.
  5. Default dest and source address are both set as ‘A’(0x65).

Still existing problems:
Command ATDR1 for RF datarate 1200bps and ATCF1(2,3) do not work properly.

BTW, from here you can get the latest firmware and join to the RFBee open source project developing. http://code.google.com/p/rfbee/
RFBee_v1_1.zip (39.5 KB)
rfBee_v1_1_a3.zip (38.4 KB)
RFBee.zip (27.1 KB)
RFBee v1.01.zip (14.8 KB)


I have been looking at the firmware and have a question out of curiosity:

The original Hayes spec (http://en.wikipedia.org/wiki/Hayes_Microcomputer_Products ) used “+++” and then a one second pause to avoid an accidental switch to command mode. This also avoids problems caused by “+++” in the datastream.
Is the current behaviour intentional ?



Hi Hans,

RFBee will change to command mode immediately as “+++” is checked in the data stream. And we do not do other protection method.


I am having issues communicating with the RFBEE from a terminal emulator, as far as I can tell the input routines only support if the whole line is sent as a unit. looking at the code I am confused as to why you changed the HardwareSerial to play with the Ring buffers, which makes it much more complicated. Is there a reason for this complexity that I am missing?

Hi rich,

Do you mean the terminal emulator can not receive data from RFBee unless the data are sent as a unit?
There is a threshold in the RFBee controlling the data unit size, the default is 4, and you could change it using command “ATTH”.

As for the ring buffer of Hardwareserial, the reason is it is more convenient to use it directly from the arduino library, and the buffer designed like this is space saving than two different bufffers operated in “pingpang” mode.

However, it may not be the best design, and it can be optimized more clear and efficient. So you can do it :stuck_out_tongue:



Actually it is the opposite problem I am seeing if I a write a program that sends +++\nAT?? it seems to work, but if I type it from a terminal emulator I always get an error. As this is the first way many people test things I think it needs fixing. I am thinking of reworking some of it, but I wanted to understand why before I start changing things. (I prefer not to look like a fool so I ask questions first.)

What I am thinking of is adding a couple commands to tell it to transmit or poll the value of a pin at a fixed interval. Probably a bit map for digital and a separate one for analog. There would be some software channelization so that a UART stream could be sent at the same time.(Not a priority at the moment.)

First I was going to add a read/set local pin digital
Then read local analog
Then read remote pin command. (Either poll or broadcast value.)
Then a read analog pin.
Then set a period value and repeat the steps. This way you could track pins, and get started quickly.

I am undecided whether it should be a broadcast or poll model used here. Polled might have better behaved radio traffic, but broadcast would be simpler to write.

So you could
ATD1 set destination

ATRA # analog pin to read on remote. RA ReadAnalog
ATRD # digital pin to read remotely RD ReadDigital
ATSD # digitial pin to set. SetDigital
ATPM # pin mode for named pin mapping to arduino pin model. PinMode
Then maybe a track mode where I can set
ATTP 0xff TrackPinstate
ATTI # frequency at which to poll/transmit. TrackInterval

So in command mode it would be simple to read, set, or track a remote pin. Anyway this is what I was considering. Comments?

Hi rich,

When you reset the RFBee, does the terminal receive “ok”?
Then you should type “+++” and send it, the terminal will receive “ok”. The RFBee is now in command mode.
Then you can send “AT***” to configure the RFBee.

If your RFBee couldn’t work like that, you may scratch and submit some pictures to let me check it out.

As for adding the command, take care the resource of ATMega168, it is no much left. So if you find some of your code are not working, may be the problem of lacking of flash or ram space.

PS:Try to reduce the frequrency of using “Serial.print(”") ".

All the best,



I don’t have an RFbee myself so I can’t check what I’m preaching but looking at the firmware and looking at the CC1100 datasheet I think it can be optimized a bit :slight_smile:

a) you don’t need to latch CS on every operation, but only during the init phase of the SPI
b) there seems to be no need to wait for the SPI Data In to complete on every operation, only after a init/reset of the CCx
c) using an SPI class like http://www.arduino.cc/playground/Code/Spi makes the code more readable
d) the status byte returned by the CCx is currently ignored, although it contains info which could be usefull to handle errors like underflow and overflow
e) I think CCx reception using interrupts can be made to work using cli() and sei()
f) CCxSetup code of the CCx can be simplified by using an array instead of a struct, as all values are bytes one could have a loop to setup the CCx, this also makes CCxreadSetup much lighter :wink:
g) the TestIo stuff (factory test ?) can be #defined so its not always linked in.
h) serial data is already copied into the dstBuffer so we already have the ping and the pang, no need to have the complex ringbuffer imho
i) CheckCMDMode has a quirck, if gplus is 2 (we already saw ++) then with the next round we will ignore the first 2 chars :wink:
j) the serial-in can be made to sleep as well and wake on interrupt, which would increase the battery life of an RFbee
k) encryption can be added (if resources permit, need about 2K :wink:
l) there is some debug code in it which can be optimized.

So… thats my view (could be very wrong of course :wink:)
If anyone is interested I’m happy to give it a go to put the above into code, however I don’t have a rfbee to verify and I’m not to keen on becoming lifelong maintainer of the code :wink:




here is my take on a new firmware version for the rfBee, learned a lot while writing it :wink:

Remember: I don’t have a pair of RFbee’s to test it out, so its an alpha version at best :slight_smile:

Main differences with the official 1.01 version:

  • no need for ring buffer modifications, only a single global buffer used for transmission
  • use of PROGMEM for CCx config stuff to save on RAM
  • the ability to switch between the 5 CCx configs using the new ATCF command
  • more robust AT parameter checking (e.g. 999 is not allowed as Destination Address :wink:)
  • Serial AT handling separated from main RFbee stuff
  • Clean isolation of the CCx code in a CCx class
  • optional Interrupt Driven Receiver (see #define INTERRUPT_RECEIVE) using a state machine
  • no latch CS on every operation, but only during the init phase of the SPI
  • use of a (simple) SPI class
  • factory selftest rewritten to reduce memory footprint (see #define FACTORY_SELFTEST)
  • code compiles both on 168 and 328 without modification


rfBee-v1.1-alpha.zip (34.3 KB)

Hi Hans,

Thank you so much, it looks great. We will test it on our RFBees.

Please send your address to me(icing.chang@seeedstudio.com). We will send you a couple of RFBee as a small reward. :slight_smile:




I have been thinking about the remote pins as well.

Best thing to make this work is to define a protocol between the rfbees.
Tricky part is deciding whether one should design a new protocol or port something existing. (e.g. same tricks as the Xbee, see ftp1.digi.com/support/documentat … 0982_B.pdf )

If the protocol is defined correctly you can interleave data and commands on the same connection.

e.g. send(cmd,data)
then you can define commands like:

  • set (set a remote config item, e.g. pin state or config to send a message on pin state change)
  • get (read a remote item, e.g. pin state)
  • send (just transfer the data to the remote serial pin)
  • receive (read data from the remote serial pin)

Funny thing here is that this is basically the functionality of the CC1101 in the RFbee :slight_smile:
The added value of the rfBee is that it simplifies the CC1101 operation by doing the complex handling of the CC1101



How did this work out? I am still having problems getting the basic unit responding to a terminal. +++ gives me okay, but any char I type gives me an immediate error. Including “A”. Does this device require line buffered writes? I was going to try your new firmware first. Can you point me at the upload instructions? I am not clear on how one writes to the device.

Have you built under arduino-18? I am not having much luck there.


Like mentioned in my post of the code I don’t have the RFbee’s myself (yet :wink:, Seeed has kindly offered a pair to aid in debugging !). So my firmware is alpha version at best and should not be tried unless you exactly know what you are doing.

With regards to your issue, can you describe your setup ? E.g do you have your rfBee connected on an arduino (clone) or an uartSB etc.
If arduino, do you use a shield in between or do you use jumper wires etc. If you use something else, what pins do you have connected , voltage used etc…
Picture of your setup might be worth a thousand words :wink:



Btw: I build my stuff under arduino 17, but 18 will most likely do the trick as well.

Icing already wrote me there was an issue with my firmware (CCx init failed) so please don’t try this until it is resolved.


setup is an seeed uart-sb switches on 3.3 and xbee, connected to a mac 10.6.3 usb port accessed via screen /dev/tty.usbserial-ANNNNHRK 9600,8,n

I will not load your code until I hear a go. I can’t get the seeed code base to compile under 18, I think I am going to reinstall 18 and try again.


I use 8 databits, 1 stopbit, no parity xon/xoff using putty on windows to talk to my arduino. Since the rfBee is basically an arduino (at least at the serial side) this should work. Don’t have the uartSb so I can’t judge if that adds anything to the mix.

With regards to compiling 1.01 under Arduino 17 or 18 , please make sure that you select “Arduino Diecimila , Duemilanove or Nano w/ATmega 168” from the “Tools>Board” menu.

If you use the Arduino Serial Monitor you need to press enter to send each set of chars.
e.g. +++ATFV or +++ATFV
+++ should give a “ok” as reply from the rfbee.

Hope this helps,


Hi there,

It’s really late to update the latest information. These days I’m working on the RFBee firmware v1.1a by Hans.
Honestly speaking, the structure is really good and more clear than the seeedstudio version v1.01. :slight_smile:
Thanks again, Hans. And the Rewards is on the way now. :smiley:

Here is some bugs and main changes done by me, hope it can make the RFBee much better with the help of you seeedstudio fans :slight_smile:

  1. The number of parameters to be saved to EEPROM is different. So it will be failed in Intializing. When use the v1.1a, comment the “if (Config.initialized() != OK)” first time downloading the program.

  2. Use the sequence of v1.01 power on start up, select and deselect the CS in the read and write functions. When I use v1.1a, it failed, so I change it back.

  3. In the readSerialData(), the processing of “+++” would not return immediately
    as it is less than Threshold(4) in v1.1. So when you type another “+++” or other command,the RFBee will return “ok”(entering command mode) and “error”(the command is cut). I did some changes making it work ok. But not fully tested.

  4. In the using of txFisoSize(), the return value should be the number of bytes in TXFIFO but the empty space. However I’m not sure how to use it combining with the

  5. In the loop(),the two ways of receiving RF data is almost the same. One is interuption mode, and the other is polling mode. However they both rely on the GDO0(pin2). So we need to initialize the pin2 as the INPUT in polling mode,and only when it is HIGH should we receiveData(). I think this is much better.

  6. In the receiveData(),the processing of potential RX overflows is not proper. When overflows,the STAE[2:0]=110, so I change it to “if((stat&0xF0)==0x60)”, and it works ok.

  7. In the transmitting part, in the loop(),we may need delay some time when Serial.avaiable()>0 to wait enugh data. And in the transmitData(), there are several bugs. (1) destAddress should be in front of srcAddress. (2) The lenght of writeBurst should be the length of serialData.(3) After strobe(TX), it should be given some time as the state would be changed to IDLE or RX in the loop() before the data is really transmitted.

  8. I don’t think it is a good way to use strobe(RX) in the loop all the time. Maybe make RFBee into proper mode by configuring MSCSM1 is better.When using v1.1a, when we set rfBeeMode = RECEIEVE_MODE, however we can still transmit data.

Thank you so much,

rfBee.zip (36.5 KB)


Many thanks for the effort of debugging my code :wink:, and of course for your generous gift ! :smiley:

With regards to your fixes:

  1. I have been thinking about the change in eeprom parameters. I would like to suggest the following:
    a) change the marker to AB (or BB etc :wink:) , this will force a EEPROM config reset and will also ensure that when a user rolls back to a previous version the eeprom parameters match the 1.0 setup.
    (ATRS command will also do this, but automatic setup avoids user hassle)

b) add firmware version (without the “v” and multiplied by 10 to make it an integer, so 1.1 becomes 11 ) to the eeprom setup (ideally position 2 after the marker) and modify the CONFIG::initialized to check bothe the marker and if the firmware version in the code matches the firmware version in the eeprom. This means that for every new version of the firmware we automatically get an upgrade and we don’t need to change the marker in every new version of the firmware.

c) hardware version (position 1) should ideally be set at factory test and never during a firmware upgrade.

  1. After submitting my 1.1a I looked at TI code and to my surprise they also used your manual reset, it seems Automatic Power On Reset as described in the data sheet is not that reliable :wink:

  2. you are right , I think your fix will work fine !

  3. you are right, function txFifoSize should be renamed to txFifoFree and it should return (CCX_FIFO_SIZE - (stat & 0x7F))
    (CCX_FIFO_SIZE to be defined in CCX.h as 0x40) Then you can enable
    //if (len > fifoSize) len==fifoSize; // don’t overflow the TX fifo
    again. This will ensure that we do not overflow the fifo if the serial baudrate is higher than the RF baudrate.
    Since txFifoFree also uses the SPI we need to protect it against Receive interrupts as well by setting the state variable and resetting it afterwards. I also learned that the state variable (used in interrupt mode) needs to be declared as “volatile” to avoid problems.

  4. You are right.

  5. thanks :wink:

  6. 1 and 2 thanks, with regards to 3 the datasheet says that when you switch mode the CCX will first complete the current transmission.
    (see section 19.4 of the datasheet) So it seems we don’t need extra care here.

  7. I thought of that as well, however as we also need recalibration of the frequency synthesizer, returning to IDLE looked the safest to me :wink:
    I found it a bit strange that TI did not fix the recaliberation in another way :frowning:

Again: great to see you enjoyed my efforts ! :smiley:



attached my alpha 2, based on the version you posted on May 22.
I fixed the following:

  1. the HW version and FW version as described in my previous post. Mind you, they are now reported as 10 and 11 instead of v1.0 and v1.1.
    Its relatively easy to fix, but it takes precious flash space :wink:
  2. used volatile for the state variable, fixed state handling in all functions that use state
  3. rename of txFifoSize to txFifoFree, protection of this function against receive interrupts, and the use of CCx_FIFO_SIZE to calculate the number of free bytes.
  4. Modified readSerialData()
    a) to handle txFifoFree correctly
    b) to work correctly with the CONFIG_TX_THRESHOLD, if not enough data is captured, it is saved till the next round. In your version this data was lost as the buffer writing would start from position 0 again :wink:
    c) switched the “return” back to a “break” on finding the third plus sign. This ensures that any data entered before the 3 plusses is still transmitted.
    e.g. “blahblah+++” will lead to sending the “blahblah” and then going into command mode. Using “return” the “blahblah” is lost. I had to make a choice what to do when the buffer is smaller than CONFIG_TX_THRESHOLD when the third plus sign arrives , so I decided to send it anyway. So “Bl+++” will be transmit “Bl” and then switch to command mode.
    d) added comments to explain why we send i-2 bytes :wink:
  5. fixed the comments in CCx.cpp to explain why manual Power On Reset is being used
  6. Moved the initialization of GD00 to rfBeeInit() to keep setup() readable. Also made it conditional as it is not used if USE_INTERRUPT_RECEIVE is defined.
  7. made GD00=2 a #define instead of an int, saves two bytes :wink:
  8. fixed some spacing and added more comments here and there for readability
  9. updated the dates in all files I touched.

I also noticed you made some “temporary” changes in receiveData (not writing the addresses and the RSSI value to serial), are you sure you want to keep those in ?

Once you formally release 1.1, the datasheet probably needs an update as well, I’m happy to help out, if you have it in a format which I can edit.

If you are planning to do more development on the code it might be worth while to host the code on Google Code , SourceForge or Github as versioning can become a bit messy using a forum :wink:


ps. if you change the code, feel free to replace my name with yours in the comment headings :wink:
rfBee-v1.1-alpha-2.zip (36.5 KB)