New boot loaders for the WidgetBoards have been uploaded to both SVN and to the downloads area.  The fuse settings have also been updated in the documentation.

I’ve also integrated the Atmega328P version of the WidgetBoard into the Arduino development environment so please update your boards.txt with the one from SVN.

I have successfully re-compiled and re-flashed the firmware source to remove the console on ttyS0, as suspected the console attached to ttyS0 was the root of my problems, now avrdude will talk to the WidgetBoard!

image

and here is my WidgetBoard booting my test blinky on ContikiOS as seen by the gateway ttyS0

image

now back to writing the contiki radio driver…..

I’ve had some mixed success with the serial port hack on the Airlive device since my previous post.

After setting up the uclib development environment I have now successfully compiled avrdude so I can program the RFM12WidgetBoard located inside the device, however I had a couple of issues when trying to talk to the WidgetBoard.

Nothing happens when trying to query the WidgetBoard…data is going out the serial port but nothing being returned.

First problem I found….crossed Tx and Rx due to a silkscreen error on the WidgetBoard, the silkscreen for TxO and RxI are wrong way around on the PCB.

After fixing this problem and re-testing Avrdude it’s still not working….so further testing…..

Serial port is definitely working and I now have a serial console to the device.   When I connect up a terminal program via my FTDI USB ttl serial cable I can see the boot process and logon to the console via ttyS0, which is probably one of my problems, the bootloader may be getting confused by the console chatter. 

image

The trace below confirms this.  I’ve re-flashed the WidgetBoard with my blinky  example from the Contiki port, besides blinking the LEDS it also outputs a string “There is” to the serial port, you can see by the trace what the WidgetBoard is sending, and the output sent back by the console.

image

By default this kernel has the console attached to ttyS0 (see my previous post and the dmesg dump) so one of my next steps will is to recompile the kernel and disable the  serial console access attached to ttyS0.

The WidgetMesh network development for the Widgets is now underway, the last couple of days I’ve been learning how everything fits together in Contiki OS, as far as drivers go and how they communicate with the upper stacks, lots of looking through existing code.  I now have a reasonable idea of how things should work and how I need to write my driver.

That said the biggest problem with the WidgetMesh is going to be on chip resources, especially with the ATMega168 and maybe even the ATMmega328P, I’m not looking at running an IP stack on the mesh (well at least not yet), but the gateway/coordinator device needs to keep track of the nodes in the network.  It’s role is to manage node associations, link forming and routing within the mesh, so this will require more ram than most of the nodes will have, especially in larger networks.  It’s also the gateway to the world for the data collected.

I’ve been scratching my head as to what I’m going to use.  I was leaning towards an ARM7 hooked up to a RFM12 or WidgetBoard, something along the lines of a make controller as I have a couple at home from past tinkering, or one of these ARM9 devices running Linux, the MMnet1001, from Propox, Both these have onboard Ethernet and plenty of resources for what I want.  But it turns out that I had a solution at home already, in the form of an Airlive NAS device, WMU-6000FS.  The Airlive NAS comes with Ethernet, WIFI and x2 USB ports, also PATA or SATA hard drive, all this runs from a 12V supply, so I could also run this from a SLA battery.

WidgetMesh Gateway

WidgetMesh Gateway

The Airlive WMU-6000FS is a not so great NAS device that I evaluated for work project involving offsite replication.  The project was eventually shelved. 

The great thing is that it runs embedded Linux, after a bit of research found that I can re-flash the current device easily with a distribution from http://mgb111.pradnik.net/ will allow me to make changes to the system, whereas the current flavour is embedded and is Read only, all changes are lost at boot, however no documentation anywhere regarding serial ports, or in fact if one exists onboard. 

I proceeded to re-flash the board with FW C009-M2 Advanced firmware, this gave me console access, once in I checked that Linux is detecting a Serial Port.

-bash-3.2# dmesg | grep ttyS0
Kernel command line: rw console=ttyS0,38400
ttyS00 at 0x03f8 (irq = 4) is a 16550A
-bash-3.2#
 

A UART is being detected and is used by the system as a console.

Here are the memory and CPU as reported by dmesg, so plenty of resource for what I want.

Initializing CPU#0
Calibrating delay loop... 44.33 BogoMIPS
Memory: 29984k/32768k available (1418k kernel code, 2396k reserved, 337k data, 56k init, 0k highmem)
Checking if this processor honours the WP bit even in supervisor mode... Ok.
Dentry cache hash table entries: 4096 (order: 3, 32768 bytes)
Inode cache hash table entries: 2048 (order: 2, 16384 bytes)
Mount cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 8192 (order: 3, 32768 bytes)
CPU:     After generic, caps: 00000000 00000000 00000000 00000000
CPU:             Common caps: 00000000 00000000 00000000 00000000
CPU: Cyrix Cx486SLC
 

This can only mean one thing.  Time for surgery!

Disassembly

Disassembly is very easy, two screws at the rear allow the extruded aluminium case to slide off , at least it’s solid.  Inside is a 1TB drive that I had swapped out with the original some time ago, so If all goes to plan then I’ll have plenty of storage available for the Wireless Sensor Network.

WidgetMesh Gateway

WidgetMesh Gateway

I love it when designers of hardware have fore thought to design in for future expansion, adding a second antenna is going to be simple enough, just drill out the rear cover to suit, actually the cover already as the markings on the inside for this.

WidgetMesh Gateway

Also another Spare antenna mounting hole, perfect for a reset button.WidgetMesh Gateway

 

Search for the Serial Port

Prime serial port candidate CN2 (10 pin socket centre of shot) ,  The processor (top left) is an RDC 3210, a 486 equivalent.  The  datasheets (no longer available from RDC website, but found via Google) tells me that the CPU has a single onboard UART that the pin outs coincide with the rough location of the CN2 header, either it CN2 or part of the larger connecter, but I doubt it.

Continuity tests of CN2 confirm that this in indeed the serial port, some further checking and voltage measurements confirm everything I need is there. Whoot!

1 RI
2 3.3V
3 CTS
4 RTS
5 Serial In (Rx-I)
6 DTR
7 DSR
8 Serial Out (Tx-O)
9 DCD
10 GND

 

WidgetMesh Gateway

 

Adding the WidgetBoard

I moved the Wi-Fi antenna SMA across to the spare and added in an SMA pigtail to suit a 915Mhz GSM antenna that I use for my WidgetBoards.

WidgetMesh Gateway

Next wire in the Serial port to an external header

WidgetMesh Gateway

WidgetBoard trying out it’s new home with SMA pigtail connected.  Actually this is the first of my Widgetboards to use the Atmega 328P processor.

WidgetMesh Gateway

I used the third spare antenna connecter on the right for an external reset button for the WidgetBoard, may not be required, but hey, if the DTR reset does not work at least I can force the issue.

WidgetMesh Gateway

All wired up and safe and sound in a simple card surround to stop any shorts from happening.

WidgetMesh Gateway

WidgetMesh Gateway

All boxed up to see how it all all goes together, 2.4Ghz and 915Mhz antennas side by side and reset bottom right.

WidgetMesh Gateway

 

Next Step

The next step is to get minicom and do some further testing, along with getting a version of avrdude working from the Linux console, this will allow me re-flash the WidgetBoard locally if the need arises.

I’ve just committed my current progress on porting Contiki Operating System to the RFM12WidgetBoard to SVN.

  • Serial working
  • LED API implemented.
  • Event timers now working.
  • Added blinky example that demonstrates all of the above.

Now compiling to 5166 bytes of flash and using 387 bytes of ram.

image

Next step is SPI and RFM12B drivers!

I’m still alive…… Its been awhile between blog entries, unfortunately this is the busiest time of the year for me at work, the few months after the Australian financial year, projects are kicking off due to funding etc.  There is however light at the end of the tunnel and I’m hoping to get back to geeking very soon :-D

I thought I’d let you know that a) I’m still alive, and b) what’s been happening on the development front.

In between work projects I’ve been porting the Contiki operating system to the widget as the underlying event framework for WidgetMesh.

I now have the Hello-world application up and running on the Atmega168 @10Mhz, no radio drivers or anything else for that matter just yet.  For those interested it’s been checked into SVN.  I’m learning a lot about Contiki and how it all fits in together (i.e. I know that I don’t know much at all about it)

On the hardware front the next iteration of the Widgetboard is idle, though pretty well stable as far as the design goes (might be a couple of small tweaks before boards get made).  I just need time and resources to get the next round of PCBs ordered and tested. 

Noteworthy design changes include:

  • Standard smd or PTH crystal footprint, allows the use of a standard HC49 crystal of your choice.
  • Lots of changes to the board supply side of things. Board voltage supply input range from 0.7V to 16VDC (probably beyond to 20VDC but just to be on the safe side…)  The core components are still powered  @ 3V
  • Minor changes based from user feedback of the current board.
  • A couple of optional onboard sensors to utilise the normally unused A6 and A7 analogue only ports, these can be disabled via onboard solder jumpers if these ports need to be used for something else, but has a temperature and light sensor, so the widget board can be used as a basic standalone wireless sensor.

I’ve been meaning to run off another batch of WidgetBoards and have been waiting for some processors, a month ago 40 Atmega328P processors arrived after a 5 week backorder, according to my vendor these were hard to get, hopefully supply issues will settle down after production catches up with the the initial demand for Atmega328P. 

All future widget boards will now have this processor as the default in the next batch of boards I make.

Sample parts I’ve been ordering for various future projects have been steadily rocking up and sitting in my ever growing inbox, the RFM22 arrived some time ago and I’ve not yet had time to play with them either :(   sigh

My sample order of the RFM22 were waiting for me when I arrived home late last night.

Here is a picture of the RFM22 (Left) next to the RFM12B (Right).  Pretty much the same physical size, but more pins, and a lot of very small discrete components.

RFM22 and RFM12B

 

So What’s New?

These new transceiver modules from HopeRF appear to be based on Silicon Labs Si4431 and Si4432 RF Chips.  Silicon Labs purchased Integration, from where the RFM12B were based on their EzRadio Series of transceiver chips.

It looks like there are a heap of new feature available, (too many to list here), including some onboard lower MAC smarts called EzyMac, while not as nice as the 802.15.4 MAC layer it looks like it can simplify things such as:

  • Automatically adding pre-amble and sync bytes.
  • Automatic packet size – you just push bytes into the Tx FIFO and it will create the packets of a fixed size and send for you.
  • Built in basic frequency hopping.
  • Built in Data Whitening, Manchester Encoding, and CRC

Some more niceties:

  • 64Byte FIFO.
  • Onboard A/D, allows access to read such things as an onboard Temperature Sensors, Voltage buses.
  • x2 configurable GPIO ports.
  • More Rx Sensitivity than the RFM12B.
  • More Tx power than the RFM12B
  • Lower Operating voltage.
  • 8bit RSSI value.
  • Three different modulation schemes to select from.

Some not so niceties:

  • More current draw on Rx than the RFM12B.
  • More current draw on Tx than the RFM12B (understandable seeing it also has a higher Tx Power).
  • Costs about twice as much as the RFM12B ~ $USD6.00 in sample quantities direct from HopeRf vs ~$USD3.00 for the RFM12B.
  • Heaps more commands/Registers to learn.
  • No onboard encryption.

Feature comparison:

 

RFM12B

RFM22

RFM23

Voltage 2.2-3.8V 1.8-3.6V 1.8-3.6V
Modulation FSK FSK,GFSK,OOK FSK,GFSK,OOK
Max Data Rate 115.2kbps 1-128Kbps 1-128Kbps
Max Power Output (Tx)

5dBm@433MHz
3dBm@868MHz
3dBm@915MHz

17dBm@315MHz
17dBm@433MHz
17dBm@868MHz
17dBm@915MHz

13dBm@315MHz
13dBm@433MHz
13dBm@868MHz
13dBm@915MHz

Sensitivity (Rx)

-105dBm@433MHz
-102dBm@868MHz
-102dBm@915MHz

-118dBm@315MHz
-118dBm@433MHz
-118dBm@868MHz
-118dBm@915MHz

-118dBm@315MHz
-118dBm@433MHz
-118dBm@868MHz
-118dBm@915MHz

Max Supply current (Tx)

22mA@433MHz
23mA@868MHz
24mA@915MHz

80mA@315MHz
80mA@433MHz
80mA@868MHz
80mA@915MHz

28mA@315MHz
28mA@433MHz
28mA@868MHz
28mA@915MHz

Max Supply Current (Rx)

11mA@433MHz
12mA@868MHz
13mA@915MHz

18.5mA@315MHz
18.5mA@433MHz
18.5mA@868MHz
18.5mA@915MHz

18.5mA@315MHz
18.5mA@433MHz
18.5mA@868MHz
18.5mA@915MHz

Standby Current ≤0.3uA ≤0.01uA ≤0.01uA
FIFO 16bit 64byte 64byte
Frequency Resolution 2.5-7.5kHz 156.25-312.5Hz 156.25-312.5Hz
Low Battery Detect Yes Yes Yes
Temperature Sensor No Yes Yes
Frequency Hopping Capable Yes Yes Yes
Wideband or Narrow Band Design Wideband Wideband or Narrowband Wideband or Narrowband
RSSI No Yes Yes

Hmm Its been a while since I revisited the RFM12 tutorials, so I thought I’d better write the next one.  Unfortunately it’s going to be too long to fit in one post so I’ll be splitting it across a couple of posts.

The last two tutorials covered a brief introduction and the physical connection to the MCU.  In this article I’m going to cover the internal commands and how we go about controlling to the RFM12 module.

It’s all done with Smoke and Mirrors!

Well not really, I wish it were that simple…as mentioned previously that the RFM12 needs to be connected as described in the previous article via SPI, the second thing we need to do is access the the internal registers of the RFM12 for it to be useful. 

The SPI transfers 16-bit commands to the RFM12, as part of the SPI transfer process it will receive results (if any) back to the MCU.  These commands do specific things, such as set the band, turn on the Transmitter and so on, therefore to get an understanding of what we need to do, we need to understand what the various commands do.

It also helps if you to have the RFM12 data sheet open as go through this as I’ll be explaining  things in roughly the same order as found on the current data sheet, most of this information is direct out of the datasheet.

SPI Interface

Just before we go through the commands, we need to be able to talk to the RFM12, and seeing that we have the SPI and NSEL correctly setup as described in Part 2 we need some routines to talk to the RFM12 and it’s registers. 

There are basically two ways to do this, 1) Bit banging the SPI or  2) using on-board hardware SPI peripheral.  The Hope RF programming guide offers a solution to bit banging the SPI interface so I won’t cover it here.

The following function for the AVR will provide hardware SPI support.  The important thing to note is the RFM12 SPI speed needs to be kept within the RFM12 Specs <=2.5MHz

// pins used for the RFM12B interface
#define RFM_IRQ  2
#define SPI_SS   10
#define SPI_MOSI 11
#define SPI_MISO 12
#define SPI_SCK  13
 
static void spi_initialize () { 
    DDRB &= ((1<<DDB2)|(1<<DDB1)|(1<<DDB0)); //spi pins on port b MOSI SCK,SS outputs     
#if F_CPU <= 10000000
    // clk/4 is ok for the RF12's SPI
    SPCR = _BV(SPE) | _BV(MSTR);
#else
    // use clk/8 (2x 1/16th) to avoid exceeding RF12's SPI specs of 2.5 MHz
    SPCR = _BV(SPE) | _BV(MSTR) | _BV(SPR0);
    SPSR |= _BV(SPI2X);
#endif
    digitalWrite(SPI_SS, 1);   // Pull SPI_SS High
}
 
static uint16_t rf12_xfer (uint16_t cmd) {
    // the 2 loops below each spin 4 usec with a 2 MHz SPI clock
    uint16_t reply;
    digitalWrite(SPI_SS, 0);      // SPI_SS Low
    SPDR = cmd >> 8;
    while (!(SPSR & _BV(SPIF)))
        ;
    reply = SPDR << 8;
    SPDR = cmd;
    while (!(SPSR & _BV(SPIF)))
        ;
    reply |= SPDR;
    digitalWrite(SPI_SS, 1);     // SPI_SS High
    return reply;
}

Communicating with the RFM12

Before sending any commands the the RFM12 the NSEL Pin needs to be pulled low, then pulled high when the command has been sent.

The MPU communicates with the RFM12 over the SPI by clocking 16-bit commands serially in via the SDI (MOSI) pin on the rising edge of the SCK. 

The data sent to the RFM12 consist of a command code then followed by a number of parameter or data bits, this command code and parameter/data bits total 16-bits in length.  

The command/data structure is then send MSB first so bit 15 is the first bit to be sent followed by bit14 and so on.  At the same time data is being clocked into the RFM12 on the SDI Pin, results (if any) are also being clocked out via the SDO (MISO) pin into the MCU MSB first, e.g. bit15 is clocked out first, then bit14 and so on.

clip_image002

RFM12 communicates back -NIRQ

While the NIRQ is not a required connection, it is handy for the RFM12 module to let the MPU know than an event of significance has occurred, and should be handled, instead of tying the MPU up with polling the RFM12 module to see if things have happened. 

But suffice to say, the NIRQ is an interrupt generated by the RFM12 module which pulls the NIRQ pin low whenever the following occur:

  • The TX register is ready to receive the next byte (RGIT)
  • The FIFO has received the pre-programmed amount of bits (FFIT)
  • Power-on reset (POR)
  • FIFO overflow (FFOV) / TX register under run (RGUR)
  • Wake-up timer timeout (WKUP)
  • Negative pulse on the interrupt input pin nINT (EXT)
  • Supply voltage below the pre-0programmed value is detected (LBD)

Handling the NIRQ will be covered in a future Transmitting and Receiving article.

Onto the Commands

There are 15 commands that deal with configuration, control and status of the RFM12 module.  these are listed below:

UPDATE:  Try this handy utility as you play with registers, it’s a RFM12b command  calculator  (thanks Frans, aka fotoopa, for the link!)  http://www.technofun.org/blog/2009/01/24/rfm12-rfm12b-calculator/

  Command Description
1 Configuration Setting Frequency band, crystal oscillator load capacitance, baseband filter bandwidth, etc
2 Power Management Receiver/Transmitter mode change, synthesizer, xtal osc, PA, wake-up timer, clock output can be enabled here
3 Frequency Setting Data frequency of the local oscillator/carrier signal
4 Data Rate Bit rate
5 Receiver Control Function of pin 20, Valid Data Indicator, baseband bw, LNA gain, digital RSSI threshold
6 Data Filter Data filter type, clock recovery parameters
7 FIFO and Reset Mode Data FIFO IT level, FIFO start control, FIFO enable and FIFO fill enable
8 Receiver FIFO Read RX FIFO can be read with this command
9 AFC AFC parameters
10 TX Configuration Control Modulation parameters, output power, ea
11 Transmitter Register Write TX data register can be written with this command
12 Wake-Up Timer Command Wake-up time period
13 Low Duty-Cycle Command Enable low duty-cycle mode. Set duty-cycle
14 Low Battery Detector and Microcontroller Clock Divider LBD voltage and microcontroller clock division ratio
15 Status Read Command Status bits can be read out

 

1) Configuration Settings Command

 

The configuration command as the name suggests is used to configure the RFM12  (POR denotes the Power on Reset Values)

bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

POR

1

0

0

1

0

0

0

el

ef

b1

b0

x3

x2

x1

x0

0×8008

 

el (bit 8): Enable internal data register. 

ef (bit 7): Enable fifo mode.

The el and ef bits are used to determine how the data is moved out of the RFM module.  Most of the time you will be using FIFO mode as this simplifies things.

bits 6 – 1 (b1 – b0): This determines the band of the RFM12 module being used and needs to match the physical RFM12 module you are physically using  e.g. you don’t set the band for 433 if you are using 915Mhz module.

b1

b0

Frequency Band (MHz)

0

0

315

0

1

433

1

0

868

1

1

915

 

bits 4 – 1 (x3 – x0): Determines the load capacitance of the onboard crystal.  This allows fine tuning of the crystal frequency.  Defaults of 12.5pf should be used.

The calibration procedure uses these settings to adjust the CLK output to 10Mhz. This procedure is in the data sheet, but is pretty vague, basically hook up a frequency counter or Oscilloscope up to the CLK pin of the RFM12B module, change the Frequency of CLK to 10mhz and measure it, it it’s not at 10MHz then use the load capacitance (x3-x0) to adjust it so it reads 10MHz.  From the couple of modules I’ve tested they have all been ok at the default of 12.5pF

x3

x2

x1

x0

Load Capacitance (pF)

0

0

0

0

8.5

0

0

0

1

8.0

0

0

1

0

9.5

0

0

1

1

10.0

 

 

 

 

1

1

1

0

15.6

1

1

1

1

16.0

 

2) Power Management Command

 

The power management command controls the power to the RFM12 sub-modules, it allows you to select what circuit within the RFM12 is turned on/off.  So by disabling these circuits when not required you can control the amount power savings of the device.

bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

POR

1

0

0

0

0

0

1

0

er

ebb

et

es

ex

eb

ew

dc

0×8208

 
 

Bit

Function of the control bit

Related blocks

er

Enables the whole receiver chain

RF front end, baseband, synthesizer, oscillator

ebb

The receiver baseband circuit can be separately switched on

Baseband

et

Switches on the PLL, the power amplifier, and starts the transmission (If TX register is enabled)

Power amplifier, synthesizer, oscillator

es

Turns on the synthesizer

Synthesizer

ex

Turns on the crystal oscillator

Crystal oscillator

eb

Enables the low battery detector

Low battery detector

ew

Enables the wake-up timer

Wake-up timer

dc

Disables the clock output (CLK)

Clock output buffer

 

The ebb, es, and ex bits are provided to optimize the TX to RX or RX to TX turnaround time as shown in the table below

Symbol Parameter Notes Min Typ Max Units
tsx Crystal oscillator startup time Crystal ESR < 100     5 ms
T tx_rx_XTAL_ON Transmitter -Receiver turnover time Synthesizer off, crystal oscillator on during TX/RX change with 10 MHz step   450   us
T rx_tx_XTAL_ON Receiver -Transmitter turnover time Synthesizer off, crystal oscillator on during RX/TX change with 10 MHz step   350   us
tx_rx_SYNT_ON Transmitter -Receiver turnover time Synthesizer and crystal oscillator on during TX/RX change with 10 MHz step   425   us
T rx_tx_SYNT_ON Receiver -Transmitter turnover time Synthesizer and crystal oscillator on during RX/TX change with 10 MHz step   300   us

 

This gives you an idea how the control bits are logically connected:

clip_image002

3) Frequency Control Command

 

Within each band (433, 868 or 915Mhz) we have control over what frequency the RFM12 module communicates on.  So we can have various communication links occurring at the same time on the same band, but using different frequencies, or if we are getting interference on one frequency we can switch to another clear one.

Depending on what the band is determines the resolution of the frequency steps.

bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

POR

 

1

0

1

0

f11

f10

f9

f8

f7

f6

f5

f4

f3

f2

f1

f0

0xA680

 

The frequencies available to each band are described below in this table

Band (MHz) Resolution (KHz) Min (MHz) Max (MHz)
433 2.5 430.24 439.75
868 5.0 860.48 879.51
915 7.5 900.72 929.37
 

The 12-bit number representing the frequency can be calculated by:

#define RF12_FREQUENCY_CALC_433(f) (((f)-430000000UL)/2500UL)  // Calculate the RFM12 register value for a given Frequency at 433MHz in 2.5khz increments
#define RF12_FREQUENCY_CALC_868(f) (((f)-860000000UL)/5000UL)    // Calculate the RFM12 register value for a given Frequency at 868MHz in 5.0Khz increments
#define RF12_FREQUENCY_CALC_915(f) (((f)-900000000UL)/7500UL)    // Calculate the RFM12 register value for a given Frequency at 915MHz in 7.5Khz increments
 
 

The 12-bit frequency value must be between 96 and 3903, if not then they will be set to these values automatically.

IMPORTANT: It is also important that you keep within your countries ISM spectrum management guidelines i.e. allowable frequencies and their use when selecting your operating frequencies.

4) Data Rate Command

This command sets the bitrate of the transmitted data or the expected bitrate of the received data.  This is the RAW physical bitrate of the module.

bit

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

POR

1

1

0

0

0

1

1

0

cs

r6

r5

r4

r3

r2

r1

r0

0xC623

cs: is set if the bitrate is < 2700 bps

Here is a table I’ve prepared for common values.

Bit Rate

r6 – r0 Value

115200

0×02

57600

0×05

38400

0×08

28800

0×0B

19200

0×11

9600

0×23

4800

0×47

2400

cs =1  0×11

1200

cs = 1  0×1E

 

If you want to calculate your own bitrates use the formula:

//calculate setting for datarates >= 2700 Baud
#define RF12_DATARATE_CALC_HIGH(baud) ((uint8_t)(344828UL/baud)-1)
//calculate setting for datarates < 2700 Baud
#define RF12_DATARATE_CALC_LOW(baud) ((uint8_t)(43104/baud)-1)
 

When setting bitrates you also need to take into account the receiver bandwidth settings (See  Receiver control command below)

5) Receiver Control Command

 

bit

15

14

13

12

11

10

9

8

7

6

5  

4

3

2

1

0

POR

1

0

0

1

0

p20

d1

d0

i2

i1

i0  

g1

g0

r2

r1

r0

0×9080

 

Bit 10 (P20): sets the function of INT/VDI pin on the RFM12 module, it configures it as input (Interrupt from MPU) or output (VDI Valid Data Indicator).  The VDI is the default setting.  This goes high when valid data has been detected by the RFM12 module, valid data is data that has made it past the Sync pattern.  If set as Interrupt input, we can use this to send an interrupt the RFM12.  The RFM12 will then stop what it’s doing and wait for the next command.

p20

Function of pin 20

0

Interrupt input

1

VDI output

 

Bits 9-8 (d1 to d0): VDI (valid data indicator) signal response time setting:

d1

d0

Response

0

0

Fast

0

1

Medium

1

0

Slow

1

1

Always on

clip_image002[1]

 

Bits 7-5 (i2 to i0): Receiver baseband bandwidth (BW) select:

The receiver bandwidth is the amount of frequency above and below centre frequency we are receiving on (See the Frequency command for more information on changing the frequency)  that the receiver is sensitive to.  So if 400Khz is select as the Receiver bandwidth and 915Mhz is the centre frequency, then the receiver will looking for a signal anywhere +200Khz above 915 and 200Khz below, i.e. 914.800 – 915.200.

The bandwidth settings is linked to both the data rate, and Tx Modulation (Deviation)commands.  When data rate is fastest a higher bandwidth is required.   There are optimal settings for the Bandwidth and Modulation for different data rates as shown below.  Having too much bandwidth can cause a higher SNR and can cause packet corruption.  Not enough bandwidth and the incorrect signal is not received.

Incorrectly setting Bandwidth and Deviation (Modulation) is usually one of the common problems.

Table of optimal bandwidth and transmitter deviation settings for given data rates (the data sheet was a bit vague in this area and did not specify frequencies etc so I don’t know how valid they are at different frequency bands but they could be used as a starting point)

Data Rate [bps] Bandwidth [KHz] Modulation (Deviation) [KHz]
1200 67 45
2400 67 45
4800 67 45
9600 67 45
19200 67 45
38400 134 90
57600 145 90
115200 200 120

i2

i1

i0

BW [kHz]

0

0

0

reserved

0

0

1

400

0

1

0

340

0

1

1

270

1

0

0

200

1

0

1

134

1

1

0

67

1

1

1

reserved

 

Bits 4-3 (g1 to g0): LNA gain select:

The LNA gain (Low Noise Amplifier) can be selected according to RF signal strength. It can be useful in an environment with strong interferers.  Or alternately if you have two RFM12 modules in close proximity then you can drop the sensitivity of the Low Noise Amplifier.

g1

g0

relative to maximum [dB]

0

0

0

0

1

-6

1

0

-14

1

1

-20

 
 
Bits 2-0 (r2 to r0): RSSI detector threshold:
 
r2 r1 r0 RSSIsetth [dBm]

0 0 0 -103
0 0 1 -97
0 1 0 -91
0 1 1 -85
1 0 0 -79
1 0 1 -73
1 1 0 -67
1 1 1 -61

Well, back from a short break away (kid free woohoo!) and onto some widget builds.  I thought I’d document how I do my widget construction.  I actually find building SMD devices much easier than the PTH variety.

I have all my components in some neat snap together containers, this allows me to have everything at hand for the build.

[Click on images for larger size)

1) Solder paste is applied to the boards sparingly, ready for component placement

Widget Board Construction 

2) Components placed on each board, I usually do a board at a time. You will see x3 boards without any RF modules, these will be added at a later time depending on what band is required.

Widget Boards construction

 

My SMD toaster oven setup.

The toaster oven is unmodified straight out of the box connected to the PID temperature controller.

SMD Setup

 

PID Ramp controller with Solid State Relay output driver from E-Bay, that allows me to store up to 64 different temperature/time steps, each step can have their own PID parameters.  The ramp controller allows me to set and store my solder temperature profiles and when enabled will cycle through the temperature profile. 

The PID controller is installed in an external SCSI case I salvaged from an old external tape drive.

0704-140759

 

The thermocouple is a K-type with the shroud removed to give a fast response to temperature changes, I also have it wired to a spare PCB to give me a good indication of the PCB surface temperature in the ovenThermocouple

 

Rear of PID controller case, I’ve wired a power point directly a 10A solid state relay and fuse.  The SSR is driven by the PID output, so power is only applied when heat is required.  This allows me to use any unmodified toaster oven. PID Controller - REAR

 

Batch ready for baking, carefully placed onto tray so no components are moved in the process.

Widget Construction

 

All I do now is start the Temperature controller and let it do the rest (after closing the door) Since the Toaster oven is unmodified in any way I just turn it’s temperature knob to the max temperature and the same goes for it’s timer.  The bottom power light turns on when temperature controller is heating.

SMD Toaster oven

 

My hi-tech fuse and bootloader programmer ready for programming.  The headers give me good connections and allows for easy changeover.

Widget Fuse & Firmware Programming

 

Fuse and bootloader being programmed

Widget Firmware programming

As I mentioned in an earlier post, the blog and domain has been re-named to reflect more of my interests.  As a result the domain has now been fully moved across to http://blog.strobotics.com.au/ 

Please update your RSS feeds and bookmarks with the new address.  The old address is still active and will re-direct to the new domain name.

For the next version of the widget,  I’m planning to have an on board boost regulator.  This design will allows the widget to run from just about any voltage source as low as 0.7v (so NiMh will be fine) and up to 5.5v, this boost regulator in conjunction with a standard LDO regulator will give me a nice input voltage range of 0.7v – 12V.  Before I finalise the design I wanted to test things to see how well it’ll work. 

I ordered in a couple of battery holders from Polou with an integrated boost regulator, since the widgets are designed for 3.3v operation I ordered this model http://www.pololu.com/catalog/product/796,  that provides a 3.3v 100mA supply from a single AA battery, I’m not too sure what the minimum voltage is, but is running fine on a single NiMh cell.

Well today they arrived and I now have one hooked up to my solar powered widget.  Installation was simple as the small pcb on the rear of the battery holder allows me to direct access to the cell contacts, so I soldered the solar cell +ve and –ve on the respective contacts.

Solar Widget Single AA Battery

From some previous tests with my solar powered widget, I was finding that the batteries would start charging when the solar cell output reached around 2.8 –2.9v, this is fine for during the day with the solar cell in direct sunlight, now with the single cell I’m finding that inside under artificial light I’m charging at around 1.5v, with plenty of overhead left.

You can see below the voltage output of the boost regulator is ~3.3v (3.322 to be exact) and the voltage from my solar cell is ~1.52v, this is inside under some standard down lights while writing this post at the kitchen table (actually one of the down lights is dead so I could expect a little more output from the cell)

image

Just to try something different I removed the battery, seeing if the regulator could run direct from the solar cell, unfortunately it doesn’t, I doubt the cell in the current light conditions can provide enough start up current for the regulator,  I will however try it in the natural sunlight tomorrow.

With the addition of the boost regulator, and the widget in max power savings between sensor reading (when asleep widget is drawing 1.5uA, which is most of the time) then the widget should run indefinitely from the single cell….or maybe I could just get away with a solar cell and a super cap now there’s a future project….

Just thought I’d post an update on what’s happening in the widget development world.

Limited Production Run

I have a very limited number of widget kits available for purchase.  This limited batch of widget kits also include a bare prototype personality at no cost with each widget to get you started in your wireless applications.

Introductory price of $US25ea (or $20ea for 5+)  include headers, bare prototype boards, 10Mhz low profile crystal, switch, all smd components are pre-assembled and tested, latest bootloader and RFM12 test program loaded.

Options:

SMA Pigtail: $2.50 for externally mounting SMA antenna.

SMA Edge: $2.50 for mounting SMA antenna onto PCB

SMA R/A antenna 900Mhz only: $4.50 to suit SMA connectors above

CR123 Battery Holder: $2.50

I’ve yet to get full details and pictures available or a means to order online yet, so contact me in the mean time if you’re interested, please let me know the band of the RF module required when ordering, e.g 915Mhz, 868Mhz or 433Mhz.

New Bootloaders

The v1.1 of the widget bootloader for 8Mhz and 10Mhz boards are now available in the download area.  These have been updated to incorporate the onboard LEDS and provide visual indication when entering the bootloader.

Source now in SVN

All the arduino source that I’ve changed for the widgets is now in SVN on the project page.  This includes:

  • Bootloader source.
  • modified boards.txt that include the 8 and 10Mhz versions of the RFM12Widget. 
  • Modified wiring_analog.c to read Widget battery voltage.

This can be checked out/copied directly to your arduino install directory by overwriting the existing files.  The arduino environment will need to be restarted for the boards.txt file to take effect.

V1.1 PCBs

I’ve started incorporating the user feedback into the next revision of PCBs.  Still a bit of work to be done on the PCB layouts.

Widget Mesh

Started preliminary design for a simple mesh network. 

Ultimately I would like to have the ability for the widgets to provide Zigbee type functionality (not compatibility)  along with frequency hopping as standard,  that is transparent to the application.  Only very early days so far.

The other day while playing around with the ADC on the widget I had some problems with noise causing the reading to bounce around, It needed some form filtering to remove the noise.   Normally almost everyone seems to take a number of readings and then average the result, unfortunately this takes time.

I came across this simple low pass filter on EDN.  A Low pass filter works by blocking the higher frequency (in this case noise) and allowing the low frequency signal (in this case the underlying signal) to pass. hence the name.  Perfect in cases where measuring slow moving signals, like temperature etc.  The algorithm is fast, simple to implement and works a treats.  It can be made to filter faster for a more response to change or slower to give more filtering.

#define FILTER_SHIFT 3
int32_t filter_reg;
int16_t filter_input;
int16_t filter_output;
 
filter_input = analogRead(0);                 // read ADC
 
// low pass filter to get rid of noise
filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input; 
filter_output = filter_reg >> FILTER_SHIFT;   

 

The algorithm is a classified as a leaky integrator, where the latest reading have more weight than the older reading.  So you take a single reading each cycle of the sensor loop and feed that into the filter, the output is used you would normally use the raw value.

The response of the filer can be adjusted by the FILTER_SHIFT, to make it more responsive, then lower this value, to give better filtering and hence a slower response then increase this value.  For my application I found that a value of 3 to 4 worked well, but will depend on the underlying application.

I suggest you read the full article for an in depth description.

I want to deploy widgets around the home, both inside and out,  so I needed to find something that would allow some protection from the environment to the electronics, cheaply and easily.

On the weekend while doing some shopping I found the solution in the kitchen area of the local discount store, at $1.50 a piece it was the right fit for the job.  They probably won’t like U/V in the long run, but will see how they go, at that price I can replace cheaply.

(click picture for more details)

Waterproof/Dustproof housing with easy access to the internals.

This will be the standard sensor node housing.  The widget Boards and battery pack are fixed via velcro so I can easily remove for reprogramming etc. 

I still need to look at airflow of sorts for temperature, humidity and pressure sensors, will probably look at putting a couple of small vents in, this will compromise the waterproofing.  

To mount these I can put some velcro on the back and mount it on any horizontal or vertical surface.

Widget waterproof Housing

 

Open and showing details of SMA pigtail connection, batteries (x2 AA side mounted) and widget board velcroed to the container (personality board removed)

Widget Waterproof Housing Detail

 

Same as above, but this is for my outside sensor nodes where I’ve mounted a Solar Cell sealed on the outside, I did some initial testing and there was a filtering effect of the plastic lid and the cell, so I  decided to put the cell on the outside to get maximum efficiency, it was a pretty messy job after I used silastic to seal everything, the cell now has a smear of silicone haze across it that is appearing very difficult to remove.  So in future I think I’ll live with the slight degraded Cell performance and mount it inside, where it fits perfectly, that way I can use a couple of blobs of hot glue to fix the cell to the lid.

Solar Powered Widget

In my previous blog entry I described adding a solar cell to the widget and how I could measure the voltage produced by the Solar Cell, however I still need to monitor actual battery voltage easily, and preferably with not a lot of additional hardware.

Problems reading ones own voltage.

Measuring ones own voltage has a couple of problems:

  1. You can’t just measure VCC directly, i.e. you can’t connect an analog pin to VCC.  The reason is the battery voltage varies, and since the default AREF is tied to VCC you will always read VCC unless you use some form of a reference not tied to VCC.

  2. I can also use a reference diode and a resistor between VCC and GND, to form an external reference voltage, the diode has a known voltage drop across it so this can be measured using the default AREF.  We can calculate the battery voltage by measuring the volt drop across the diode.  While this will work, the circuit will always consume a small amount of power, even when not being used, remember I want to get as much life out of my batteries as possible.  So it rules this out as a solution.

  3. For the same reasons as 1) I can’t use a simple voltage divider and the default AREF.  As the voltage varies so too will my readings.

  4. I can use a simple voltage divider and the internal 1.1v bandgap reference for my AREF, the same as I used for my solar cell voltage monitor in the previous blog entry.  Again this will work, but also as in 2) this will always consume  some power even when not being used, so is ruled out as a solution in this case.

No Extra components?

We can however measure VCC voltage with no external components by simply reading the value of the internal bandgap reference voltage (1.1v) which is always fixed regardless of the battery voltage,  and by using the default AREF which is tied to VCC, so will vary as the battery voltage changes.  We now have a way of measuring the voltage change against a fixed reference.

V_BAT =  (VREF * 1024) / analogRead(14);

Where:

V_BAT :

battery voltage

VREF:

fixed reference voltage in this case 1.1v, but could be referenced to an external reference.

analogRead(14):

raw ADC reading from MUX channel 14

 

You might see in the above formula, that analogRead() function is reading channel 14.  But analogRead() only supports channels 0-7 right? 

Correct, but what we are doing is to read the internal ADC channels after we make a small change to the Arduino source code.

Changes to “wiring_analog.c”

To take an ADC measurement of  the internal bandgap we need to switch to ADC MUX channel 14 (23.8.1 in reference manual).   However to do this with the arduino wiring library we need to make changes to “wiring_analog.c” as per http://code.google.com/p/arduino/issues/detail?id=10.  This change allows us to read from all ADC MUX channels, internal and external.

Example

Once you’ve made the change to “wiring_analog.c” then use the following example sketch to read your VCC/Battery Voltage.

uint16_t raw_bandgap = 0;      // Internal bandgap reference
float volt_battery = 0.0;
 
void setup(){
  Serial.begin(57600);
}
 
void loop(){
  // Read Battery voltage
  analogReference(DEFAULT);                          // use VCC as AREF
  raw_bandgap = analogRead(14);                      // read and discard first result after changing reference (see 23.5.2 of manual)
  raw_bandgap = analogRead(14);                      // measure internal bandgap voltage
  volt_battery = (1.1 * 1024) / raw_bandgap;         // calculate voltage
  Serial.print(volt_battery);
  Serial.println(" v_bat");
  delay(1000);                    
  
}

When this method won’t work.

If you have a voltage regulator or a protection diode inline between your battery and VCC, then this will only show the voltage at VCC, not the true battery voltage. 

If you have a voltage regulator then you will always read what it puts out, and not give a true indication of battery voltage.  I guess you could still use the method as a form of low battery measurement.  i.e. when the battery falls below regulation values I guess the regulator will fail to regulate and you should get a lower than normal reading.  however I haven’t tested this theory.

If you only have a protection Diode then measure the volt drop across it and compensate in your calculations, it will still give you a good indication of battery voltage.

Update:

Some other uses for this method is for auto-calibration of sensors as described by ladyada(you need to go to the bottom of the page)

Next Page »