Embedded


For the open Hardware Rallylog device I’ve been working on, I’d based my design around fitting into the handy Sparkfun Project Case and since most of my projects never get to the “enclosure” stage, they are either used bare PCB or thrown into anything that may provide some protection against the elements, such as the widget sensor housing.
(http://blog.strobotics.com.au/2009/06/15/widget-sensor-housings/). 

This project was different for me since I’m required to build 10 of them for the local motorbike club, something a bit more “finished” than your standard geek project.  Throughout this project I’ve learnt how to use 3D modelling to check mechanical layout and tolerances, also to use mechanical data supplied in technical data sheets in selecting my components.  This along with taking into account PCB heights, button heights.  Overcoming challenges like how do I get my LEDs to the outside without using panel mount LEDS, or how do I protect or mount my LCD display again with out using a panel mount.  I then used all this to make things easier for me when it came to production to produce CNC tool path G-Code to cut my enclosures.

I thought I’d document the process that I’ve gone through to get my Rallylog nice and snug in the Sparkfun Project Case.  BTW this may not be the right way, but it’s the journey I took, I would love to hear from people who do this professionally for a living to get a feel of the full product design process.

It has to be easy to make and assemble

Right from the outset of the project I wanted this to be easy to assemble.  Seeing I have to make 10 of them (to start with) I wanted everything to be mounted on the PCB so all I have to do is get my enclosure and put in the finished PCB, screw it all up and its working, i.e. I didn’t want to have a panel mounted LCD or LEDS that I had 1) manually fix to the Enclosure, and then 2) “wire” back to the PCB.  I wanted something that I can reproduce easily and with the least amount of human work, I love my projects, but quickly hate having to manually do a lot of repetitive work like solder up individual LEDS etc. (I guess I ‘m lazy).  I also have a small CNC machine at home, A Zenbot Mini that I purchased off eBay some time ago, so I wanted to automate the panel cut outs as much as possible.  I wanted this to be repeatable, using a handheld Dremal is not my idea of fun, especially if I have 10 to do now I will quickly loose interest after the first one, and it’s definitely not repeatable. Also if I get an order for another 1, 10, 100 down the track I definitely don’t want to do it manually, and I don’t want to think too hard about getting things set up.

I could have also gone with an Arduino board and made up a custom shield or use the RFID shield, again it would have meant more painful hand assembly, so I decided to stick with a custom board fitted into a readymade enclosure.

It all starts with the User Interface

Whilst I already had my initial schematic laid out (in Kicad), before I started my PCB layout process I needed to work out what it was going to live in.  I was very eager to start laying down track as I love designing PCBs, but I had to hold myself back and ask a couple of questions first:

  1. What am I going to put it in?  It needs to be functional, fairly robust, and fit everything in, including the battery, the RFID module, the LCD, SD Card socket and so on.  It needs to be off the shelf that I can easily modify, no custom injection moulded case for this project ( I wish)
  2. What is the user interface going to look like?  I needed to keep to the KISS principle.  The majority of users at this motorcycle club are semi-retirement to retirement age, so not the most savvy when it comes to geek gadgets,
  3. Will it be easy to assemble?

When you stop and think about it, it makes sense to start with the user interface and how this will fit into an enclosure, then move onto the physical PCB layout and component selections, else my PCB might not fit into the case, it may be too big, too small, same goes for components selected. The user interface may not be functional and then we’d have to start again.

The User Interface design

My initial schematics included a Nokia LCD display and a joystick for user input.  Also a couple of LEDS for visual feedback.  

When I asked myself the three questions above I quickly went back to the drawing board, as the Nokia display failed Question 3), same went for the Joystick, also I felt that it was would have been a bit too had for the target audience to use, so it failed Question 2) as well. 

In the end I decided to go back to a tried and proven UI design that consisted of a simple and easy to read backlight 2×16 LCD character display with three push buttons for user input and two LED indicators, something a bit easier for the end user to use.

As yet I had not selected the parts i.e. the  LCD or switches, I just had the layout in my mind (or on paper) the UI layout that was a three button input under a standard 2×16 backlit character LCD, and x2 LEDS to the left of the LCD display, these LEDS would be Red and Green, which could be used to indicate different statuses easily, really simple!

UI sketch

The Enclosure

Once I had the basis of the interface this is where the engineering juggling started, I had to find an enclosure that would meet my requirement, and find components at the right price that would work with the selected enclosure in the way I wanted.

I had a look around on a number of sites and found there is a wide variety of enclosures out there, however without physically having one, its a bit hard to start working out measurements and getting a general feel for it in your hand.  As luck would have it I already had a couple of Sparkfun Project cases at home that I had purchased for a “future” project, well this was that “future” project, I used this initially as my enclosure of choice, it seemed to fit well in the hand and be spacious enough to seemingly fit everything in, i did this initial check by putting in the ID-20 RFID reader module and a 9V battery to see how things would fit.  At this point I still did not have an LCD or buttons selected.

Once I had my enclosure selected it is now a matter of finding the right size components to fit, as mentioned above I wanted everything mounted on my PCB, and now I had the dimensions of the enclosure I could start my PCB design and component selection, this process I found to be the most time consuming.  However I initially needed to start working out my clearances with my PCB in the enclosure, I’m also a visual person, I need to see things to make it easier for me to understand, so I decided it would be much easier to utilise 3D modelling and model the enclosure and mock up my UI, I’ve used Alibre in the past and this is what I modelled the Rallylog enclosure in. 

The 3D Model

Not wanting to re-invent the wheel I contacted Sparkfun customer support with a request for a 3D model of the Project enclosure and received an email from Casey Haskill, the designer of the enclosure, he was more than accommodating (Many Thanks Casey!!!)  and sent me the files in IGES format, one that Alibre supported……supposedly.

The great things with standards is that everyone has their own take on them, obviously Alibre was no exception, the problem was that each time I went to import it failed, after a bit of research I found a small utility program that I used in a two step process that allowed me to clean up the IGES and export it as an STP file, one that worked with Alibre.

image

Once imported I can now can get accurate measurements and start modelling individual components.  My modelling is very simple, make a basic 3D model using the supplied mechanical data, no fancy surface or trying to emulate the real thing. 

One of the immediate things I could see is that either I had to use a panel mounted PCB or I needed a two tiered PCB design as the headroom above the PCB was quite large.  The panel mounted LCD was ruled out due to easy of assembly rule, so I knew that I would be dealing with a two layered PCB design.

Alibre is great for quickly creating 3D objects and by changing dimensions it regenerates the 3Dmodel, so I quickly created a two tiered mock up of a PCB with the correct thicknesses of the PCB substrate being used, this was added to the enclosure assemble so I could visualise the internal dimensions.  The two PCB layers are separated by the dimensions of a standard 0.100 header and socket of 8.5mm.

image

 

image

From this I now had the dimensions required from the top of my PCB to the inside and outside of my case.

Now I needed to know what LCDs, buttons and LEDs out there that when mounted on the PCB  how they would interact mechanically as far as clearances with the enclosure, however I had to work into the constrains of my circuit design and of course price. 

Due to I/O restraints I couldn’t use the standard character LCD in 8 bit or even 4 bit mode, so that ruled out most of the cheapest LCD displays around.  So it had to be I2C, SPI or Serial,  my initial design was done with the Nokia LCD in mind and so used SPI, as I wanted it to mount onto my PCB, almost all LCD I’ve found have their own PCB with a connector that either plugs into a cable or you plug it into a socket onto the PCB, so another layer on top of the existing PCB was not feasible.  I located the I2C range of New Haven Displays and found one that would fit given the dimensions, however I couldn’t get them locally and ordering in from New Haven was approx. $USD50 per display, not economical!  Unfortunately there were not many alternatives. 

After talking with my local local supplier he put me onto the EA-DOGM Series of LCD Character displays, these can be run in SPI Mode or traditional 4 or 8 bit mode, there are also directly mounted on the PCB, and have an optional LCD backlight module that mounts under the LCD module. The price was even better, $AUD15 for 2×16 and $AUD4 for backlight, perfect pricing just need to check how they would fit.  From the Technical data sheet I whipped up a simple model and added it to the PCB

image

image

image

image

From this I could see that the LCD would fit if PCB mounted, but had an interference with the top of the Sparkfun case, this was acceptable as I would need to machine the cut-outs at some point.

I then did the same for switches and their buttons, I wanted the button to just clear the case and not be too pronounced or the reverse I didn’t want it to be recessed.  In the example below using 6mm Omron switches and their associated square buttons.  I found they were too pronounced out of the case.

image

I ended up finding the 12mm Sparkfun Push Button which met the right criteria and the button just cleared the case, after modelling it looked perfect, however the switch body itself has some interference with the top of the case, this meant that if I wanted to have a switch with the right height I would have to machine out the inside of the case.  

image

Engineering decision time….After weighing up the aesthetics and the work involved in machining out the case I decided to stick with machining out the inside as I would already have the top case mounted for cut outs, what if I just flip it around and machine from the inside, that way I could kill two birds with one stone.  I could pocket out around the switches ( and the LCD if required) and then perform the panel cut out.  I didn’t know how I was going to perform this but seemed doable. 

Just to make sure where my interferences I used a great feature of Alibre called “Assembly Boolean” where I can select the top of the project box as my blank, and then select all the buttons and the LCD as my tools, the Result is the top of the Project box with all interferences subtracted so I can I know where to machine.

image

Just to cover my bets I added both switches to my design, that way I could use either if the other didn’t work, much easier to add the extra footprint at design time that to find out after that I really should have used the other switch, so I had an escape clause Winking smile

image

The LEDS

What about The next thing I needed to worry about was what to do with the LEDS.  Where possible I now use SMD components rather that PTH, but using the PTH over SMD was going to be my only choice, however they would be standing quite tall off the board, and as the end user would have to remove the back of the case to eventually change batteries, I didn’t want them to be able to damage the LEDs if incorrectly re-assembled for any reason. 

I started looking around for solutions, not being in the industry I wondered how they did it, looking at every day consumer electronics I saw that pretty well every LED indicator is displayed through a plastic window, that’s what I needed, but what are they, after much Googling I found the correct term of “Light Pipe”, this made things easy.  I could stick with my 0603 SMD LEDS and have a standard 3mm vertical light pipe (they come in many different flavours) bought directly to the top of the SMD LED.

image

 

The Final PCB

Happy with the components selected I then proceeded to finished my PCB design, again to make things easy to assemble I designed the two layers as a single board separated by tabbed routes and tooling strips so the individual boards can be separated after assembly.  I also moved my LEDS over to the right hand side to accommodate for the PCB connectors finished result. 

To see the full assembly steps see my previous blog entry http://blog.strobotics.com.au/2010/07/21/rallylog-assembly-progress/

rallylog pcb

 

Next…How I machined my enclosure cut-outs

Last Friday I received my second revision of PCBs.  As mentioned in one of my previous posts I majorly stuffed up on my LCD footprint along with some additional board changes including the larger 3V regulator and the 5V regulator PCB.  

I’m very happy with my switch to Kicad also with it’s resulting PCB below.

(Click through to flickr images for more details. Some are commented and have notes)

rallylog pcb

After verifying the PCB again (this time successfully), I set aside some time over the weekend to assemble the first unit for testing.

 

Rally log with all SMD components assembled

rallylog smd assembled

 

Rallylog with all components assembled and removed from the tooling strips

rallylog assembled

 

Test fit in Sparkfun project Case, have yet to fit the top cover, i.e. drill holes for LEDs, Buttons and LCD, will be leaving this until after testing, but happy with the results so far :)

rallylog assembled

My latest toy acquisition arrived in the post today, it’s a small usb microscope from Deal Extreme – http://www.dealextreme.com/details.dx/sku.35636.  I purchased this so I could do my PCB inspections alot easier. 

 DinoLite_Digital_Microscope

Some of it’s specs:

  • max  resolution of 1600*1200 (these ones below were taken at VGA resolution – 640×480)
  • Manual zoom levels x25 – x200
  • 8 LED white light that you can control the brightness via a pot on the cable.
  • Measurements and markups via the software.
  • can use handheld and comes with a stand for hands free use.
  • snapshop button so you can quickly take still images.
  • Software filters to apply to the video stream.

The screen shot below shows me calibrating against a steel ruler with 0.5mm increments.  This is the outermost Zoom level of x25.

image

The calibration process is very simple once you work out how, the manual is written in “Chinglish” and not that helpful.  However I soon worked things out that to calibrate you pause the video source and then use the measurement tool to take a number of readings, from these you average the readings and enter the units and pixels measured into the calibration data, after the calibration has been performed then at the current zoom level you can make measurements, angle measurements, area calculations all through the software.

The down side is the calibration is only good for the zoom level you’re currently at so if you re-zoom you need to re-calibrate, so keep the steel rule on hand.

Here is a quick test on the rallylog board at the lowest zoom at VGA resolution.  The tracks are 10mil so not too far off with the measurements if you do the conversion.

 draw_Camera

 

Here is another couple, this is of the problem zone pour that I picked up in my previous blog post.

draw_rallylog-snap1

Zooming in on the above area with the microscope zoom function

draw_rallylog-snap2

 

Another using the emboss filter, you can see quality of the ATMega328 pads on the with HASL surface finish from Gold Phoenix (no so great on the one circled)

draw_rallylog-snap3

and with no filters applied and zoomed in.

draw_rallylog-snap4draw_rallylog-snap5

The best thing is the price, at USD42 it’s a great addition to my toolbox.

It has certainly been a while between posts, but I thought I write a few things about my conversion to Kicad as my EDA of choice.

Most All of my projects in the past I’ve use Eagle PCB, as it certainly has been the EDA of choice in the open hardware community.  However it was the only non-open piece in my open hardware arsenal, until now…..enter Kicad.

I’ve been keeping an eye on Kicad for the past couple of years and I’ve never really had time to try it out on a project until now. 

A bit of background

My Father is a member of a recreational collectors motor bike club and they have a number of timed competition rallies throughout the year that may go over the weekend and consist of many checkpoints across a course that are located throughout the district. 

In the past they did everything manually i.e. write down their time and details at each checkpoint, so at the end of the rally, times are tallied and winners announced etc. Since it is manual it doesn’t scale very well, at their annual run where a few hundred competitors took part it didn’t scale well at all.  Knowing the geek that I am, my father asked me if I could do anything  to make things simpler.  The club had investigated some commercial rally systems, but was pretty expensive. I volunteered to automate things a bit…..

Enter RallyLog!  An Open Hardware project that will use RFID tags to log competitor times at checkpoints.

So I now had the reason to learn Kicad for a totally Open Project.

Enter Kicad…

Kicad was originally written by Jean-Pierre Charras (more background on Kicad can be found here – http://www.lis.inpg.fr/realise_au_lis/kicad/)

It is actively being developed by a large number of volunteers at http://launchpad.net/kicad and runs on a number of platforms:

  • Windows
  • Linux
  • Mac

Kicad is made up of a number of different applications that run under the Kicad project manager they are:

  • kicad – the project manager.
  • eeschema – the schematic editor.
  • cvpcb – the footprint selector for components used in the circuit design.
  • pcbnew – the PCB layout program.
  • gerbview – the Gerber (photoplotter documents) viewer.
  • 3D PCB Viewer

First Impressions

Coming from Eagle I had to unlearn how I did things within Eagle and move to the  Kicad way, this means a lot of right-clicking to do things, many things were not the same as what I was used to in Eagle, but I quickly picked things up within a day of using Kicad and now find most things fairly intuitive.

If I had a problem I found the developers and the users to be very helpful answering questions on the mailing list.

What About Your Existing Libraries?

Yes this is a big thing, especially those who have build up their own footprint libraries over time, however all is not lost! a ULP Eagle Library conversion script has been written that is run from within the Eagle Library.  This converts the library to the Kicad library format of which the Components and PCB prints are separated out into two files.  One is a library *.lib file for eeschema that contains the schematic representation of the components, the other is in a *.mod format for module footprints used within pcbnew.

In Eagle a library contains the:

  • Symbol – Schematic representation, actual component and
  • Device – the PCB footprint , all of which represent a component.
  • Package – the actual component that links links the Symbol and Device

Kicad component library has been separated into the Schematic and the PCB side of thins, one library for each.  Now That I’ve been using things for a bit over a month I can see that it makes a lot of sense.  When I’m creating a schematic all I want to worry about is capturing the circuit, if I need a new component I create a new component in the library, not having to worry about the footprint at this point in time.  In eagle it is similar, i.e. you can create only the symbol and package without the device, but I found it long winded.

Another added bonus with the components is you can link data sheets to the individual components. Brilliant!

I successfully imported a my libraries across, I did have to manually replace the reference some components as it defaulted to U?

One thing I haven’t played around with yet is the 3D viewer.

The Process

  1. Create a new project within Kicad project manager
  2. Create a schematic (and components if required)
  3. annotate your schematic
  4. Design rules check
  5. Create a netlist
  6. run cvpcb and associate footprints to your components
  7. run pcbnew
  8. import your netlist
  9. layout your PCB
  10. Design rules check
  11. plot your gerber output and create drill files
  12. view with the built in gerber viewer.

Features and Anti-Features (pros and cons)

Pros

  • 100% Open Source!
  • Interface for FreeRoute build into pcbnew, so you can use a push and shove autorouter.
  • In build Gerber viewer
  • 3D Viewer of the PCB.
  • I love the professional looking schematics it generates, even including the border information.
  • Hierarchical schematics – you can place sheets with-in sheets and drill down by clicking on them
  • Hierarchical Pins – have signals displayed in your hierarchical sheets as shown below.image

    Cons

    • Drills – Kicad has no concept of drills or holes in the pcbnew program, so you have to put in a pad that has the drill and the pad size the same, unfortunately this results in plated holes unless you notify your manufacturer of the holes not to be plated.
    • Component layers – I like the ability within Eagle to have a document layer for my footprints, where I can put information that will not included in my final output. (this is actually implemented in Kicad just a bit harder to find and not so intuitive)
    • Lack of inbuilt scripting like eagle, however you can write scrips in any language you want and manipulate your schematics, PCB and components externally du to the open format it is all saved in.

    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 0x0B
    19200 0×11
    9600 0×23
    4800 0×47
    2400 cs =1  0×11
    1200 cs = 1  0x1E

    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

    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….

    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)

     

    Solar Powered Widget board

    One of the tasks I want to use the widget boards for is a Wireless Sensor Network around the house for measuring environmental values.  The sensors that I want to live outdoors will need to be self sufficient in terms of power, so I wanted to see if I could charge the batteries via solar, of course this can be done, but again I want to do it as cheaply and as simply as possible, I also want the widget board to monitor the solar voltage and report it back.

    I already had a 3.6v 0.2w cell that I picked up some time ago from Sure Electronics for about $10 for 5.  The spec for this cell is max voltage (under load) is 3.6v and max current is 60mA, more than enough to trickle charge x2 AA NIMH batteries. 

    The Batteries should not require much of a top up as the node will be sleeping most of the time, from the power saving discussion @ JEELabs, by adding the solar, I should be able to just leave the node without having to change batteries (replacing failed batteries aside).

    To measure the voltage produced by the solar cell I need a voltage divider that would produce 1.1v max @ 3.6v.

    Why 1.1v I hear you ask?  The reason for the A/D full scale input voltage of 1.1V is that I’ll be using the ATMega168 internal bandgap reference as the AREF source for the onboard A/D and not the default AREF. 

    There are a couple for reasons for this.  The internal bandap reference itself is a 1.1v voltage reference, because the battery voltage may change over time (remember I’m not using any onboard voltage regulators) so as the VCC / battery voltage changes, so would my A/D voltage readings unless I use a reference voltage.   Now as the reference is 1.1v this means that my input must not go above 1.1v else I will go over scale and get an incorrect reading.

    I’m not going to bore you with the math so a quick calculation using an online voltage divider calculator (http://www.daycounter.com/Calculators/Voltage-Divider-Calculator.phtml)

    Input Voltage = 3.6v

    Output Voltage = 1.0v  (remember I don’t want to go over 1.1V so I’ve given myself some headroom)

    Gave the values for R1 = 26K and R2 = 10K

    Luckily I had both these values, however for the 26K I only had  one in 5% tolerance, the 10K I had as 1% (I like to use low tolerance resistors for voltage dividers so my error is minimised),upon testing the 26K resistor actually read 26.4K on my meter, so after plugging these real values in my actual FS Vout is 0.989v, pretty close to 1.0V.

    A blocking diode is also required to prevent any damage to the Solar cell by the batteries, see the circuit and photo below.

    (Click for larger image)

    image

    (Click for larger image and notes)

    Solar Powered Widget Board

    Arduino Sketch to read the voltage produced by the solar cell, next step is to find a waterproof housing and add some environmental sensors. 

    Another benefit of taking voltage readings of the solar cell is I now have a light sensor.

    int raw_solar = 0;        // Raw Solar FS ~ 1.0v
    int raw_bandgap = 0;      // Intenal bandgap reference
    float volt_solar = 0.0;
     
    void setup(){
      Serial.begin(57600);
      analogReference(INTERNAL);  // select internal reference for AREF
    }
     
     
    void loop(){
      
      raw_solar = analogRead(0);                         // read solar voltage raw values
      volt_solar = (raw_solar * 1.1 * 3.617) / 1024;     // Scale ADC input.  (voltage divider r1= 26.4k  r2 = 10k  vi=vo/(r2/(r1+r2)) = vo/.2777 =  vo * 3.617
      Serial.print(volt_solar);                          // display raw solar voltage reading
      Serial.println("v");  
      delay(1000);                    
      
    }

    The other day when playing around with different fuse settings on the Widget Board, I incorrectly wrote the wrong values, oops one bricked board :(   However all is not lost.

    With a second working Widget Board and a simple Arduino sketch , I used the following procedure to recover from my mishap.

    First I installed the following sketch onto a working Widget Board

    void setup() {
      pinMode(3, OUTPUT);  
    }
     
    void loop() {
      while(1) {
        PIND |= _BV(3);
      }
    }

    What this sketch does is generate a 1.2MHz clock signal on the INT1 port of the Widget Board. (Click the picture below to see the the full trace )

    image

    Next I attached this signal to the XTAL1 pin (Pin 7) of the AtMega168v on the bricked board (I just held it against the crystal pin). 

    While holding this connection on the pin, I then fired up AVR-DUDE and rewrote the correct fuse settings, after confirming that the fuse values could be read back I then remove the wire and everything was back to normal.

    So all is not lost :)

    Version 1.0 of the boards is progressing to the point where I’ll be starting work on v1.1, integrating user feedback and any issues on the tracker, I’ve put a few up there so please check them out, comment or add your own.  Issue Tracker.

    I’m extremely happy to say that everything has progressed really well, there are not any show stoppers with the board and as they stand are very usable.  The range of the RF with the units I’ve tested is brilliant, mainly inside, I’m hoping to do some tests over the weekend outside.

    The rest of my components finally arrived yesterday and I now have fully complete boards, the low profile crystals look really slick, alas I’ve decided not to keep them in the next board revision and opted for a more generic and cheaper HC49 type crystal.   There are a few more changes, but check out the Issue Tracker.

    In the Wild

    A few of the extra PCB I sent out are finally arriving at their intended destinations and hopefully everyone will have time and skills to build them.  For those that have already built them I have received some great feedback.  Looking forward to their test results.

    Arduino

    Last night I installed the crystals on all my boards and they are now running after re-programming the fuse bits.  I’ve also re-compiled the lily pad boot loader for 8Mhz and 10Mhz along with updating the Arduino board files, I will have them online in SVN shortly.

    I’m also assuming that you know how to program your fuse bits and they are correctly programmed.  The fuse values I’m using are found below in the boards.txt file. I don’t have to remind you that programming incorrect fuse values can potentially BRICK your board.  If you’re unsure please ask on the discussion group.

    You need to have the correct boot loader up and running on your Strobit first.  I’ve yet to test the boot loader programming from the Arduino environment as I do all mine manually using avrdude, but here are the hex files, the 8Mhz is for if you don’t use a crystal, the 10Mhz is if you have the crystal installed.

    Below is the boards.txt found in the Arduino hardware directory, just copy and paste into this the boards.txt and restart the Arduino environment. 

    Then select the Widget Board of choice from the TOOLS|Board menu.

    ##############################################################
    strobit1.name=Strobit Wireless Widget (10 MHz) Atmega168
     
    strobit1.upload.protocol=stk500
    strobit1.upload.maximum_size=14336
    strobit1.upload.speed=19200
     
    strobit1.boot loader.low_fuses=0xE6
    strobit1.boot loader.high_fuses=0xDF
    strobit1.boot loader.extended_fuses=0x00
    strobit1.boot loader.path=strobit
    strobit1.boot loader.file=strobitBOOT_168_10MHZ.hex
    strobit1.boot loader.unlock_bits=0x3F
    strobit1.boot loader.lock_bits=0x0F
     
    strobit1.build.mcu=atmega168
    strobit1.build.f_cpu=10000000L
    strobit1.build.core=arduino
     
    ##############################################################
     
    strobit.name=Strobit Wireless Widget (8 MHz) Atmega168
     
    strobit.upload.protocol=stk500
    strobit.upload.maximum_size=14336
    strobit.upload.speed=19200
     
    strobit.boot loader.low_fuses=0xE2
    strobit.boot loader.high_fuses=0xDF
    strobit.boot loader.extended_fuses=0x00
    strobit.boot loader.path=strobit
    strobit.boot loader.file=strobitBOOT_168_8MHZ.hex
    strobit.boot loader.unlock_bits=0x3F
    strobit.boot loader.lock_bits=0x0F
     
    strobit.build.mcu=atmega168
    strobit.build.f_cpu=8000000L
    strobit.build.core=arduino
     
    ##############################################################

    I had a chance to grab a few photos of the progress so far, also helps that most of my components that I had on order arrived today so the boards has been kitted out with all the headers.  Now I can plug the prototype personality in, still waiting on my crystals, switches, and diodes.

    This gives an idea of size. (I don’t have big hands either)  This board has a 900MHz 2dB GSM SMA antenna, prototype personality board installed and battery holder for CR123A Lithium battery. 

    0515-1105040515-110420

     

    Different battery options, using x2AA with a switched battery pack soldered onto the board.

    0515-110726-01

    The SMA connector is a standard PCB straight SMA connector that has been soldered onto the edge of the board.  The board have been designed for the Sparkfun PCB edge mounted SMA connector (SKU: WRL-00593), however I found that a standard PCB SMA connector will do the same job, the distance between the centre pin and the ground pins is the same thickness as the PCB and all the pins line up with the Sparkfun footprint, the centre pin fits perfectly and so do the two bottom ground pins, only difference is the two top ground pins don’t get soldered.

    0515-110243

     

    One of the LEDs flashing….Its Alive!!!!0515-110702

    Today I did some testing on the RF side of things,  nothing scientific, just walking around the house seeing if it would dropout or report bad checksums, I’m happy to reports all is working as expected (using the 915Mhz RFM12B module)

    The tests are done by using the RFM12B Example sketch found in the JeeLab RFM12B library by Jean-Claude over at Jeelab (RFM12B Arduino Library)

    This library runs unmodified on the wireless widget board, just follow the instructions in the README about setting up node ids.

    From the preliminary testing using some compact 1/2 wave GSM 900MHZ/1800MHZ antennas (http://www.dealextreme.com/details.dx/sku.5237)  I’m easily getting all the way around the house with no dropouts, have yet to do outside tests.

    Next Page »

    Switch to our mobile site