Arduino


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.

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 got a chance to do some testing on the boards. 

State of play so far:

  1. Checked for shorts on power – OK
  2. Did a board level continuity test – everything as per schematic.
  3. Power at the correct levels and at the right places.
  4. Found that my USBASP programmer needs sw2 set and now all working, I can now read and set fuses etc.
  5. Arduino lillypad bootloader successfully loaded and working – Whoot!
  6. ASCII sketch loaded via Arduino development environment, serial port tested at 9600, all working.
  7. Jean claudes RFM12B Test Sketch loaded and working.  Can configure device and some random data is being read back from RFM12B, need a second board operational to fully test the RF side of things.

TODO:

  1. Build a second device now that the basic circuit is working and verified.
  2. Fully test RFM12B and wireless comms.
  3. Test I/O i.e. Analogue and Digital ports, LEDS  etc
  4. Customise boot loader to use onboard LEDS.
  5. Document all of the above for others on the project’s website.

All in all I’m pretty happy :)

As one does while in bed at 3am and unable to sleep, I was thinking of the Strobit Triggr (which is probably why I couldn’t get to sleep in the first place) an idea presented itself for Arduino type shields (in particular Strobit Triggr personality boards) where they could be given some real personality.

Currently Arduino shields provide the hardware interface to the world for the base Arduino board.  On the Arduino resides the code that provide the functionality i.e the personality, in the form of a sketch.  The sketch and the shield have a one to one mapping, i.e. a sketch for one shield will not work with another shield type and visa-a-versa.  So whenever a shield is changed, the base Arduino boards needs re-programming with a new sketch to give it it’s personality from the host PC/MAC this provides the new functionality associated with the shield.

The idea is for the shields to have onboard flash memory that contains the actual Arduino sketch associated with it.  When the Arduino is powered up, it then checks for this flash first, if present then it proceeds to load  from here, reprogramming itself with the new code, reboots and now has the functionality associated with the shield.  If there is no flash available (a shield with no personality e.g. current shields) then the Arduino proceeds to load as per normal.

This way you could easily swap a shield/personality board without having to reprogram the Arduino, it keeps the functionality of the shield with the shield, thus giving shields a personality.

Ok here is the 1st basic trigger personality board.

Features:

  • x4 LEDs for visual indication.
  • x2 Push Button Switches, one tied to input for manual triggering/testing, the second independent, could be used for channel or function selection, both could used in conjunction with LEDS for advanced function selection.
  • 1 Strobe output. 400V Max (so will work with older type strobes)
  • 1 protected TTL trigger input. 
  • Small prototype area.
  • Low profile, All large components are mounted underneath.

Still a little cleaning up required but basic functionality is there.

Still TO DO:

  • Change MOC3023 to SMD footprint, I don’t really want the possibility of a large strobe voltage right where a thumb might be.

Basic Triggr Personality PCB

image

I know I’m a bit slack in updates on the blog.  If you haven’t noticed I now have a twitter account  http://www.twitter.com/madeinoz so you can follow what I’m doing when it’s not getting updated here.

However since the blog is way over due for an update here is what’s been happening in a nutshell.

Strobit Trigger:

I have finally gotten off my butt and done a redesign (hah and you thought the project had died a slow death, it may have stalled slowed, but certainly not dead!)

Features worthy of note in the new design (in no particular order):

  • 3V design, will run from x2 AA Alkaline or single CR123A 3V battery.
  • Fairly compact board, 30mm x 70mm. (without battery)  slightly lalonger on 2.4ghz design due to antenna.
  • Onboard on/off switch to save batteries when not in use.
  • FTDI 3.3v breakout cable port for connecting to either RS232 or USB using the FTDI cable.
  • Onboard ISCP port for programming.
  • Personality daughter boards.  Will allow users to create their own hardware modules, i.e. sound trigger, light trigger, LCD UI, or whatever they like etc
  • Atmega168V processor, low cost, low voltage design = longer battery life.
  • Can run Arduino bootloader, so developers have access to Arduino development libraries.
  • I’ve designed 2 different boards.  One using the RFM12B module at either 433Mhz or 915Mhz.  The second board I’m going to try a 2.4GHZ design using Microchips FCC certified MRF24J40MA 802.15.4 module, this is purely experimental so I don’t have any testing done yet, but I have some of these modules and would like to try them out, also being FCC certified will be an added benefit.  (not to mention I’ll be using these for a mesh sensor network project I have planned around the house)
  • RFM12B board design has external SMA antenna.
  • Base PCB board designs are done and I’m fairly happy with them so far, I’m just finishing a basic personality modules which I can used for testing and maybe another one so I can make up the  max designs I can have on a single panelized board (may as well get the most designs I can get fabricated when I send it off to GoldPheonix).  I’ve done some initial Eagle3D runs to get an idea of the boards and so I can post them on the blog, but I really need to learn how to create components in Eagle3D as it leaves unknown components blank, i.e. the RF modules and therefore looks incomplete.  (anyone that can help me here please contact me)

Still To Do:

  • Panelize boards
  • Send to GoldPheonix for PCB fabrication.
  • Assemble and test.

I’ve also been playing with learning Alibre, a fantastic 3D design package (they have a free version) so I can get some ideas for building enclosures design for these boards.

RFM12B PCB

image

MRF24J40MA PCB

image

For those interested I found an RFM12 library for the Arduino  http://jeelab.equi4.com/2009/02/10/rfm12b-library-for-arduino/

Switch to our mobile site