Sunday 23 December 2012

Android app released under GPL

The android app has now been released under the GPL. You can find the source on GitHub

Website and ordering prototypes

I put together a simple website to summarize the important stuff. Also you can now purchase limited quantities of the prototypes.

http://alistairdickie.com/blueflyvario

Wednesday 19 December 2012

Prototype 0.4b

I have updated the hardware slightly for the next batch of prototypes. The circuit board size and layout is almost exactly the same, and it is still in a TicTac box. The new v4 circuit diagram is below.


Essentially, I have just added a line from pin 17 of the PIC to pin 5 of the RN42. This allows me to hold the RN42 in reset. I updated the PIC code to do this if the battery voltage is too low on start (below 3.6V). This means it is impossible to connect via bluetooth if the battery is too dead. If you are connected, it will keep on discharging all the way past 3.6V. To provide some feedback to the user, on startup the green LED2 now flashes fast if the battery is full, if it is below 3.6V it flashes slow (1 second on/off).

There is also a test point (TP1) to access PIO4 on the RN42 if that is needed. 

Android App Updated

Just a minor bug fix to stop the "BlueFlyVario has stopped working" that was happening when you exited the app. It was the way I was shutting down the audio stuff. All fixed now. It should push out via Google Play today. 

Monday 3 December 2012

Audio Updates

I just updated the audio aspects of the app, pushed the code to GitHub, and uploaded version 0.3b(4) to Google Play. Apart from a few little bug fixes the new things are:
  • Added preferences (in Setting|Vario|Audio) for:
    • Vario Audio Threshold - Above this value the vario starts beeping. The default is 0.2m/s
    • Vario Audio Cutoff - Below this value the vario stops beeping. The default is 0.05 m/s. This means that the vario continues to beep during the range 0.5 to 0.2 m/s. 
    • Sink Audio Threshold - Below this value the the sink Alarm sounds. The default is -2.0 m/s. The current sink alarm is a pleasant female English voice saying "Sink-Sink-Sink..." Should you not want to hear it set the sink alarm to something like -10. 
The sink alarm audio file is currently not user settable. I intend to do that at some stage. In the meantime I am seeking a better default sink alarm sound. I am not quite sure what the best sound is. Although I am sure there is something better than being told over and over again that you are in sink. If you have suggestions let me know.

I have not implemented it yet, but I do intend to change the speed of playback if the sink is greater (more sink = slower playback = lower pitch). 

Friday 16 November 2012

More Prototypes

The first batch of prototypes is delivered to testers. There was much more demand than I had anticipated. I have just ordered the components for the next batch. Make sure to contact me if you want one and I will put you on the list. 

Wednesday 7 November 2012

Code on GitHub

I have put the code for the Android app up on GitHub to coincide with the initial release of the app on GooglePlay and the shipment of initial prototypes to testers. If you want to get stuck into editing the code contact me

Prototype 0.3b Shipped


I have lots of good news. The best is that I have shipped the first batch of prototypes to testers in the US, Australia and Peru. Most of the information in this post is for lucky testers.

First - Thanks

A huge thank you for supporting this project as a tester!

Second - Install the app

If you scanned the QR code on the side of the box it would have taken you here.

You will need to install the app on your device. Get it from Google Play.
Android app on Google Play
Third - The hardware

To reiterate and update info from a previous post - some important stuff you need to know:

  • Turn on the switch on the side of the device and you should see the blue light flashing. 
  • Pair it with your Android device using the code 1234.  
  • Ignore the flashing green light, it is left over from some hardware debugging.
  • A full battery lasts 17 hours [at least - that was the old battery - I have not tested the new one]. Plug in a mini-USB connector to charge it. The red light goes on. When it goes off the BlueFlyVario battery is fully charged.
  • The USB connector does nothing other than charge the battery. The data pins are not connected to anything.
Fourth - Using the app

Saturday 27 October 2012

Battery Pain

I am still waiting on batteries for the prototypes. I have had two shipments go missing from China. I am beginning to think that they might be being stopped at Customs as Australia Post does not ship them airmail. Very frustrating. 

My solution is to get some of a different battery type from a friend. I should be able to get them in the next week and ship to prototype testers the following week. Thanks for waiting. 

In other news: I have been testing the app in real flight over the last few weeks. It is working better than expected. One other guy that flew with it said he thought the audio vario response and accuracy was better than his commercial competition vario that cost more than $1000. He said it just felt like the audio was more in tune with the lift. My favorite part of the app is the lift-drift display. This is where every point of lift in the last few minutes is plotted on a display and the points are drifted by the calculated wind speed. I have found this really helpful in staying up in light scattered lift and also for re finding thermals you pop out the side of up high as they punch through layers. 

Saturday 29 September 2012

Prototypes almost ready

The first batch of prototypes for beta testers is almost ready to ship. The pretty picture below shows how I turned all of those circuit boards and components to working, programmed, and tested prototype BlueFlyVarios. The only components missing from this picture are the case (which is a small TicTac box) and the battery. Unfortunately, my shipment of batteries from China went missing. A replacement shipment is supposedly on the way. Perhaps they will be here when I get back from vacation in a few weeks. If they are here, I expect to start shipping these prototypes around 11 Oct.


Prototype Assembly

With a bit of practice I reckon I could assemble, program and test a batch of ten of these prototypes in about two hours in my home setup. This batch probably took me three times as long as that, on average about 35 minutes for each one. It is a bit finicky to get the right amount of solder paste around the SSOP pins of the PIC micro and for most of the prototypes there was a bit of touch up work. Programming the micro and configuring the settings on the RN-42 also takes a bit of work.

Cost

The cost of these prototypes works out to A$60 (plus shipping), which is how much the components cost me and a little more to cover consumables. Shipping will be A$10 within Australia or A$15 internationally (if you want tracked postage this will cost more). As I write this blog there are still a few of the prototypes that have not been promised to beta testers. If you want one contact me via http://www.alistairdickie.com/home/index.php?option=com_contact&task=view&contact_id=1&Itemid=29

How to use the hardware

If you get one of these prototypes some important stuff you need to know:
  • Turn it on and you should see the blue light flashing. Pair it with your Android device using the code 1234. Open the BlueFlyVario app and press Menu|Connect device. 
  • Ignore the flashing green light, it is left over from some hardware debugging.
  • A full battery lasts 17 hours. Plug in a mini-USB connector to charge it. The red light goes on. When it goes off the BlueFlyVario battery is fully charged.
  • The USB connector does nothing other than charge the battery. The data pins are not connected to anything.
Next Steps

Once these prototypes are in the wild I will consider if I go down the path of making more of the same or redesigning the board and getting a different case. 


Friday 28 September 2012

Android app ready to play with

Most of my last month or so of BlueFlyVario development has been focused on getting the Android app to be usable and customisable. The BlueFlyVario android app is ready for technologically courageous testers to have a play with. You can install it as a non-market app from http://alistairdickie.com/blueflyvario/. [EDIT - Get it from Google Play now]. There are a few features left in from testing...

App Design

I have tried hard to design an app that allows for significant user customisation in the front end, and in the back end code allows developers to add new features. I would like to think that the app as you see it today is just the beginning.

Screenshots

The screenshots below shows what the current default layout looks like.


The first page shows some basic information and displays three of the component types. The icons in the top right change color based on the status. From right to left; BFV hardware connection, GPS location upated, vario audio, and flight started. All blue is all good. 

The component in the top right is the 'location' component. There are heaps of settings for it. It essentially shows a trace of your track over the last 120 seconds. The color of the track is the same as the color of the vario trace. Green bits of the track are where lift was. 

The 'vario trace' component shows the sensitive vario on the left and a trace of the averaged vario trailing out to the right. The grey underneath is the alititude over the same period.

Swipe the screen right to left to fling to the next page.



This page shows all fields currently available. A few of them were on the previous page. Like all other components these fields can be customised in position, size and colors for text, labels and lines. Additionally most fields can have different units and number of decimal places (in fact, full DecimalFormat pattern support). 

Also at the top of the page is a 'label' component. 


On the next page you can see another example of the location component. Pages can be added or removed, and you can add any components you want to any page, make them any size, background color, etc. Here we see the location component with the 'lineColor' set to be transparent. Tap in the middle of the component for its settings. If you are not sure where to tap there is a preference that can show you where the tap point are. This location component has 'rotate' set to false which means it always has North up. 
On this last page you see a location component again and some fields, but also the wind trace component. I really developed this for testing the algorithm I outlined in the last post. The data you see drawn above is from a development feature that simulates a flight track. You need to run it for at least three minutes to see the data picture above. Note that the location track points are 'drifted' based on the wind speed and direction that was associated with that point. Combined with vario data, and selectively only showing those points on the location trace that are in lift, this essentially maps out pockets of lift in the sky. 

What you don't see

There are many features you don't see in the screenshots above:
  • The very many preferences for making the app do what you want.
  • How you can press and drag on components to move them around or resize them.
  • The way you can customise almost everything about what you see, then export and share layouts with others.
  • The flight functionality, which is only simple at this stage, but works. A flight is recorded as a simple csv file in the Android/com.bfv/files directory. 
Further App Development

I have hundreds of ideas. Here are a few:
  • More component types (a map component is next I think).
  • Comp features like waypoints, tasks, etc. 
  • IGC and KML flight saving. 
  • Live tracking options. 
  • Auto flight start (I meant to put this in, I just realized I forgot)
  • Airspace 
  • Flight events which automatically switch screens
  • Fix bugs...
Next Steps

As soon as the app is in the hands of testers (with some hardware) I hope to get it working on GitHub and use that for bug tracking and development discussion. 











Friday 7 September 2012

Calculating wind speed from the GPS track


Coding the android app is progressing well and I have most hardware parts for the first ten prototypes. In coding the Android app I got a little fixated on developing an algorithm for estimating wind speed and direction from the gps location flight path. I think what I have done is new. [EDIT: See the comments below from Edgar, I guess what I did was not new]. If it is not new, then as far as I can tell from pretty extensive Google and literature searches, it is undocumented in the public arena. This post gets pretty technical, so first..

The bottom line

Using information from only the GPS, this algorithm provides a pretty good estimate of windspeed, wind direction, and airspeed. The algorithm does not rely on turning circles or airspeed measurements. It does assume that the aircraft is flying at a reasonably constant airspeed over a time period, or at least that the airspeed is not overlay biased towards any heading. It also assumes that the wind speed is pretty constant over the same time period. It does rely on some changes in heading over the time period. If the aircraft heading is distributed over a 60 to 90 degree arc then the windspeed, direction and airspeed will be calculated pretty accurately. By pretty well, I mean less than about 20% error, which is kind of like the variation of windspeed and wind direction caused by gusts in any case.

For a typical paraglider boating around in thermal or on a ridge the assumptions above hold true. Even with a little speed bar our airspeed range is reasonably confined, and most people do not use it while thermalling. A time period of 90 seconds works well from my testing so far. I think that this algorithm would work less well for hang glider and sailplane pilots as they vary airspeed much more often. It will be interesting to get some practical feedback.

My main motivation for working out the windspeed and wind direction is to ensure I can predict where a packet of lift that you have just flown through will have moved to later in time. That magic is for a later post. Now the technical stuff.

What the GPS gives us

Most GPS spit out position information every second. In addition to position we get heading and ground speed. The GPS is not merely taking two location points and calculating the vector between them. Rather, it measures the Doppler shift in the signal from each satellite and converts that to a heading and speed. This is quite nifty and I imagine particularly more accurate than just taking the difference between two points.

The wind triangle

The picture below tells a thousand words. On the left is a 2D flight path in pink. I have marked three points on the path (p1, p2 and p3). The green arrows represent the ground speed and heading vectors at each point. You can also see the blue arrow representing the windspeed and wind direction. Notice that groundspeed at point p2 and p3 is much greater (longer arrow) when the wind is from the side at point p1. On the right side are these three groundspeed vectors plotted on the XY velocity plane, and the windspeed plotted. Note that each of the red airspeed vectors have the same magnitude |a| (our assumption of constant airspeed), and the the windspeed vector is assumed to be the same at each point. The greyed out triangle is the 'wind triangle' for a particular point in time. The most important thing in this picture is the circle. For any three points drawn on a plane (not on a straight line), there is only one circle that fits them all. To work that circle out we only need our three groundspeeds. The centre of the circle gives us the windspeed vector, and its radius is the airspeed.




Practical data

In theory, with just three gps heading and speed readings, provided we were not travelling in a straight line, we could determine windspeed and direction. In practice there are all kinds of errors, our assumptions do not hold exactly, and so on. But with more data we can find the circle that best fits our points. The image below is a graph of all speed and headings from a ~35 min scratchy paragliding flight on a ridge. The units are in m/s.  When I first saw this I was amazed at how consistent both my airspeed and the windspeed was over the 30 minutes. In flight I experienced the range of gusts and direction changes that we are used to when flying a ridge. Yet, it is still easy to see where the circle fits if you were to draw it by hand.



Below is 90 seconds of data from the middle of the flight. This time I have hand drawn a circle on it. The errors of the points are much less.



Circular Regression

To fit a circle to a bunch of points requires the use of advanced math. It is called circular regression. Nikolai Chernov from the University of Alabama had an excellent summary of his work presented here.  He has provided a bunch of algorithms. I chose the Taubin-based Newton method for a number of reasons: Speed (it runs fast enough on Android), I am not worried about numerical stability for the kind of data we will get, it does not need matrix functions, and it is characterised as 'perhaps the best algebraic fit'. The Kasa fit worked well enough but the Taubin was much better at small arcs. In addition to the 'fit' produced I then calculate the mean squared error of the predicted centre and radius of the circle. Some of the methods in JBone code provided inspiration. I will share the actual Java code from the Android app with the initial release in a few weeks time.

Below is an animation of successive circle fits over time. The red dot is the origin. The fits start at 90s. The center pink dot size represents the mean squared error of the circle location. The two circles represent the mean squared error associated with radius.




The graph below is the calculated windspeed and direction over time associated with the above flight. It matches what I experienced.

I have added a simple IIR filter on the windspeed (the yellow line). This smooths out second to second fluctuations and is what will be implemented in code.

Further work

This can be better. The circular regression algorithm tries to minimize the sum of the square errors from all of the points. If it could be altered to weight the points over time, with the most recent having the highest weight, then it might be possible to get a more time sensitive fit. In addition, the current algorithm calculates a full fit with each new point. It might be possible to alter it to reduce the computational intensity by saving some of the computed data for older points, and by using the previous fit as a starting point for the next fit.





Friday 24 August 2012

Circuit boards have arrived

I ordered some boards from SeeedStudio for the prototypes. Ten boards no more than 5cm by 5cm for less than $14 delivered to Australia was an offer I had to test out. From ordering to delivery took 18 days. I actually got 11 boards. Below are pics of the Eagle screenshot and the pile of boards with the first one I populated with components. I recovered the RN42 and MS5611 from an earlier prototype so they look  a little heat stressed.



Putting together the prototype with my soda can solder paste stencil and the skillet method took about an hour. Rather than put in the right angle headers for the programmer I just filled in the holes with solder and programmed using some pogo pins in the end of the PICKit2.

Based on the success with the first of these boards prototype I have ordered components to populate the rest of the boards. While I am waiting for these to arrive it will give me time to get back to improving the Android app.

Battery Rundown Test


The bottom line is that the BlueFlyVario prototype has a battery life of 17 hours. This is about three or four times the life of most Android devices that will run the app. It think it is enough.

Battery life in real world situations is important. Indications of charge level is something that routinely frustrates me with many devices. I get really annoyed when a device tells me that it goes from 90% charge to 50% charge in a few minutes, then stays there for a while, then all of a sudden goes down to 10% or completely flat. In most cases I think that the algorithm programmers use is screwed up. My aim for the BlueFlyVario is to be able to indicate charge level of the device to the user in a way that makes a lot of sense. Percent charge should mean percent of time remaining from a fully charged device.

Measuring charge level

Battery voltage can be used to give an indication of charge. The BlyFlyVario measures the battery voltage using an AD pin by measuring the voltage across the resistor divider (R6 -- R3). The resistor divider together is about 200k, and at about 4V 'consumes' only about 0.02 mA. It is only on when the switch is on so does not drain the battery when the device is off.

Calibration constants for battery charge level

My approach to battery charge level indication is to have the device spit out the voltage once every ten seconds. To calibrate the voltage requires two constants, one for the voltage from the TC1015 regulator (Vdd), and one for the ratio of the resistor divider network RDratio = R6/(R6+ R3). As each regulator and resistor is slightly different (manufacturing tolerances!) these constants are measured on each device after it is built using a multimeter, and the constants are programmed into the EEPROM of the pic. In practice Vdd is about 3.01 to 3.04, and RDratio is between 0.95 and 1.05. The battery voltage can then be calculated from the voltage measured at the AD pin (Vpin[16]). The formula used for the battery voltage is then:

Vbat = RDradio * Vdd * Vpin/1024

The value 1024 is because it is a 10 bit AD on the PIC.

Run Down Test

The battery voltage for LiIon/LiPO batteries follows a known curve, but it is slightly different for each battery model. I am using a Nokia type BL-5B battery (890 mAh). The graph below shows the battery voltage vs. time. In this test I connected to my PC test program via Bluetooth and let it run. From 'full' charge at about 4.16V it takes about 17 hours to get to 3.6V, which for practical purposes I will use as zero charge. It is possible to squeeze a little more from the battery, but to preserve battery health it makes sense to recharge the battery at that point. In the prototype it will continue to run past that point. I am not yet sure what I will do for production devices (auto shutdown or keep running).



Charge level

To get charge level from battery voltage I use a piecewise linear function. The pink line on the graph below is the piecewise linear approximation of % charge vs. time. It is just the same data as above with 3.6V equals 0%. The Android app uses this function to give charge level for a particular battery voltage.






Thursday 2 August 2012

The Circut

Below is a picture of the current circuit I am using for the prototypes. I will spend a little time describing how it work and how to make it better. (Click on the picture for a full size one).

 
Battery Management

U1 (MCP73831) is a LiPo charge controller. The value of R2 controls the circuitry to charge the LiPo at 500mA. C1 and C2 stabilise the output and input voltage. R1 limits the current of LED1, which switches on when 5V comes in through the USB connector and sets the Status Pin (1) high. Note that the data lines of the USB connecter do nothing. With the switch S1 off, nothing no power is being drawn and nothing works.

Power Management

U2 (TC1015) is a 3V low voltage dropout regulator. C3 and C4 stabilise the output. R3 and R6 form a voltage divider so the voltage of the battery can be measured at a microcontroller input (configured as an AD converter). The input range for the PIN is 0 to 3V, the battery range is 3.30 to 4.20V. Splitting it to 1.65 to 2.10V allows the 10 bit AD to measure to about two decimal places, which is good enough as a battery monitor. I have updated the PIC code to output a battery measurement once every ten seconds. The exact value of R3 and R6 is not critical, but they must be matched as closely as possible. If the ohmmeter matches to two decimal places that is good enough. Generally you need to test about ten to get two which match that closely. As soon as power is applied U4, U3 and U6 all start working.

Microcontroller

The PIC24F16KA101 has a simple circuit for basic operation. C6 is the standard decoupling cap between VDD and GND. C7 and R4 stabilise MCLR.  JP1 is currently a five pin right angle 0.1" header for programming via ISCP. I am planning to replace it with pogo pads to make it less clunky. I use LED 2 connected to pin 6 for microcontroller feedback. Currently it just flashes to let me know the microcontroller is working correctly, except when the RN42 is connected to a bluetooth host.

The PIC's pins 4 and 5 are connected to the UART on the RN42 for transmitting characters back and forth. PIC pin 14 is connected to the RN42 PIO2, which goes high when the RN42 is connected to let the microcontroller start sending data.

The PIC's pins 10, 11, 12 and 13 are connected to the MS5611 which uses the SPI interface.

RN42 Bluetooth transmitter

C5 is the standard decoupling cap between VDD and GND. RN42 pins 1, 12, 28 and 28 are all connected to GND. Pins 15 and 16 are connected for UART CTS and RTS feedback. This is not necessary, but is a legacy from some earlier testing. Pin 21 (PIO5) is connected to a status LED, which flashes to indicate connection state (flashing once a second - not connected, solid on - connected, solid off - not working, flashing faster - in special command mode).

MS5611 Pressure Sensor

Pin 2 (PS) is connected to GND to put the MS5611 into SPI mode (rather than I2C). C9, L1 and C8 work together provide the most stable power input possible. They form a pi filter. I think that I can further mess with these values to get it more stable, but really need an oscilloscope to see what frequencies the noise is.

Further work

There are a couple of changes that I might implement in future designs:
  • PIO4 (pin 22) of the RN42 should really have a exposed pad somewhere to allow me to factory reset the device.
  • I should connect RESET (pin 5) of the RN42 to a spare microcontroller pin so I can hold it low once battery power gets below a certain level (I think 3.5V).
  • The form factors of LED2, C9, C3, C1 and C2 could be smaller, particularly the caps. I used what I had. There are cheaper smaller options that will work just as well.

Prototype 2 and 3

Below are pictures of BFV prototypes 2 and 3. They both work just as well as the initial alpha prototype. You can probably see that prototype 2 was hand soldered using an iron and hot air, and has many 'green wire' hacks as I fiddled with the circuit design. Prototype 3 is the one that was soldered with the paste stencil and it is much neater.

I chose this size for the PCB as it fits perfectly in a tic-tac box. I chose the Nokia BL-5B battery form factor as this ~800 mAh battery is widely available, cheap (less than $3 including shipping from ebay), and has easily accessible electrodes. The SMD side switch I chose is also readily available from ebay.

Cost update

I did a quick analysis of the raw component cost to get this far. These costs are all in Australian Dollars but US Dollars are about the same (currently). The cost, including shipping of components to me and consumables used in prototype manufacture, adds up to about $47. This is less than the prediction of $55 I made year ago, and less than my target of $50. It includes battery, box (with free candy), pcb (from SeeedStudio - if that works out), and all components. The two most expensive components, the RN-42 and MS5611, together cost about $27 base price (about $35 with shipping to me).

Shipping of prototypes from me to Australian customers is about $5, but $10 -$15 to the rest of the world. Each one will take me a few hours to assemble, program and test. I am planning for $70 to be 'unit cost price' to have 10 prototypes shipped to testers. I would love to do it for free but there is no big company to pay.

I think I can reduce component cost by about 30% down to $30 to $35 if I was to make 100, and perhaps down below $25 if I was to make 1000+. But I am going to start with 10 if there is enough tester interest.



Below is a better picture of Prototype 3.



DIY Solder Paste Stencil - Etched soda can

Sparkfun have a great tutorial on how to use a solder stencil to make placing SMD components easier prior to using the skillet reflow method. It is awesome just how well this works. However, getting a stencil made and shipped takes time, and it is not cheap for one off prototypes. This post describes what worked very well for me. If I was going to do hundreds of boards I might use steel, but this is cheap and easy. The soda can aluminium can thickness is also about perfect to put just the right amount of paste on. Read the following like a tutorial. I assume you can do toner transfer and you know how to handle chemicals safely.

You will need: A soda can (full helps), scotchbrite scourer, toner transfer stuff (see above), Phosphoric Acid (sold as rust or aluminium cleaner from a hardware store), Hydrochloric Acid.

Step 1: Make sure you select an un-dented soda can, scour off the paint on the outside of the can until it is smooth aluminium and clean with water. This is easier when the can is full. Empty out the soda (don't drink it - that stuff will kill you!)

Step 2: Carefully cut the can to get a sheet of aluminium. Try really hard not to bend it. You want a smooth sheet. Flatten it by pulling across the edge of a table, or under a ruler smoothly. Cut out a bit about 2cm larger all around than the PCB. Use the scotchbrite again to remove the coating from the inside of the can to get to bare aluminium. You might be tempted to leave the inside on as a resist, but it will probably have micro holes in it by the time you etch. Also it is more difficult to remove after etching.

Step 3: Prepare the artwork. Ensure you come in from the edge of your pads by 4 mil all around. The etched area will be larger than your artwork, especially in fine areas. In eagle you can use the design rule setting Cream|Masks to change the tCream layer to be smaller than the pads. Export the artwork, make it negative (using MS Paint), and mirrored. The last part is important. You might think you can just flip the stencil over, but the etched hole walls are at an angle and smoothing on the paste works best if the holes are larger on the top than the bottom.

Step 4. Transfer toner like you are used to.

Step 5. To prepare for the etch mask the bottom side of the board and around the edges of the toner with clear tape. It needs to be clear so you can judge the end of the etch properly.

Step 6. Prepare the enchant. I use a 50:50 mix of Phosphoric Acid (mine is about 600g/L) and HCl (30%). The exact proportions do not matter. This etch works because the Phosphoric acid removes the oxidation, while the HCl attacks the bare metal. I dilute the etch mix with water to about half strength to slow the etch. I think diluting with methylated sprits is probably a better idea. That would help to reduce the foaming I think.

Step 7. Etch. It will start really slow, then gradually speed up as the Phosphoric Acid removes the oxide layer. Soon you will see bubbles forming and it will start to foam. Constant agitation is your friend. For me it takes about 10 minutes to etch through the thickness of the soda can. As it progresses make sure to regularly check for the end point (like every 30 seconds or so). If you etch for too long the undercut will make your paste stencil holes to big and join up. For most pads you will see that they etch faster near the edges. The trick is to stop as soon as the edge of each pad is 'cut' by the etch. Check by dunking in water and looking at the bottom with light from behind. Do not worry about the middle of each pad, the bottom tape will pull that away when it is removed.

Step 8. Remove all of the tape carefully then remove the toner with toluene or xylene.

Step 9. Dry and check. Follow the Sparkfun tutorial to do the pasting. I smooth the paste on with a razor blade. I got my paste from DealExtreme, it seems to work with fine pitch SMD components.

Below is a picture of one of my stencils. Note the fine pitch SSOP components.


Playing with PCB's

For most of the last few months of messing around with the development of the BlueFlyVario I have been playing with prototyping PCB's. Before I go on I have some important advice:

DON'T DO THIS! At one point I figured it would be a good idea to be able to produce PCB's myself for a run of about 10 to 50 prototypes. After a few months of fiddling around, trying all kinds of different methods, I have one PCB that I am happy with. Just one. I think it has cost me quite a bit to produce it. I am about 50% confident I could produce another in about two hours, but I might screw it up. In this post I am going to describe what worked for me and what didn't. The bottom line is that I recommend getting PCB's produced in a fab house. I have just ordered a batch from SeeedStudio to check them out.

Artwork

I used Eagle. It is pretty common amongst hobbyists. After a few hours I got used to the interface. Sparkfun has some good tutorials.

Substrate and Etching

I started with standard double sided 1.6mm FR4, the 1 oz copper kind. After screwing up quite a few times I now understand how important it is to prepare the surface very carefully. The method that works best for me involves using wet 400 grit sandpaper in a random fashion. This works best with a small sanding block to ensure the surface is completely flat.

I tried all kinds of methods for etch resist. Drawing using a sharpie is useful only in patching up areas where fine detail is not important. I spent some time messing with dry film negative acting photo resist (the DuPont stuff you can get in small quantities on ebay). This is used in professional fab houses and I thought would be a great idea. It comes with the promise of being able to get 6mil traces in optimised production environments. In practice I was able to get 16 mil traces, but with most boards there were always errors. The obstacles to overcome include:
  • Getting the film to stick with no bubbles. This is tricker than trying to get a screen protector on with no bubbles. Just one small bubble with screw things up as the etch gets under the resist in the wrong places. Being very careful and using a pouch laminator helps a lot.
  • Producing artwork thick enough. Toner on clear film worked best.
  • Getting exposure right. I used a BugZapper lamp (40W I think) at 30cm for three minutes. That worked well.
I have ended up relying on toner transfer. I can now get 10mil traces and spaces with no problem. There are tutorials all over the net on how to do this. Some pointers that worked for me:
  • I use a cheap HP mono laser printer. The toner seems to be heavy enough, even on ground plane pours, and it melts at the right temperature.
  • I tried lots of different paper. In the end paper from an Australian Who magazine works best. The idea is to get the glossiest possible paper that is very thin and breaks down well in water. Glossiness prevents the toner getting too intertwined with the paper fibres, thinness ensures the heat and pressure gets through the paper to remelt the toner, and being easily dissolvable in water helps the paper come away.
  • I used a cheap A4 pouch laminator. It takes 4 to 12 passes to get the board hot enough to melt the toner. It is all about the right temperature, not the number of passes. If you do one pass, then wait until the board cools down, you need to start again. It is also important to ensure the paper does not move around. The best method I found was to ensure the paper was a little smaller than the board (so it does not hang over the side and get stretched in funny ways, attaching only one side with a piece of tape (the side fed into the laminator first).
  • To release the magazine paper it just needs a few minutes soaking in warm water, then very carefully pealing off the paper. Some will stick to the toner which is stuck to the board. I used light rubbing with my thumb under water to carefully remove the paper from between fine SSOP pads. If any toner comes off the fine bits you will need to start again. If the board is too dirty or too smooth the toner will not stick. This is tricky to get right.
This bit is dangerous if you do not know what you are doing. I use an etch consisting of one part HCl at 30% strength (Mutaric acid or Hydrochloric Acid from the hardware store) and two parts 3% H2O2 (Hydrogen Peroxide from the chemist). Constant agitation should see the exposed copper come off in a few minutes.
 
To remove the toner I use toluene/xylene based paint thinners. Any strong non-polar aprotic solvent will work better than acetone, which for some strange reason seems to be the standard.

Holes and vias

I thought it might be a good idea to have a crack at through hole plating the vias. This in theory involves drilling holes prior to etching, and some electrochemistry. I failed at the hole wall activation stage, mostly because I could not source a fine enough graphite powder without forking out a wad of cash and waiting weeks for delivery. I figured a really good hole wall activation mix would be toluene, graphite powder, and polystyrene. Polystyrene dissolves in toluene well, the resulting mix is not very viscous and flows well into the holes, it also allows a fine suspension of graphite powder to be maintained. Once dry, a very thin film of polystyrene holds the graphite in place. It further smooths if heated and forms a thin film of very conductive polymer, provided the graphite powder is thin enough. I gave up once I worked out that wire is good enough.

Quality fine PCB drill bits can be got on ebay for about $1 each. My solution for working diy vias involves drilling with a 20mil bit (after etching). I make the via pads 70mil in diameter which helps to ensure that even the two copper sides are not perfectly aligned, then it might still be ok. I then put a small copper wire through the hole (I use single core wire from stripped down CAT 5 cable - it is just about the perfect size). I make the wire flush on top, but with about 0.2 to 0.4 mm of protrusion on the bottom side which is stamped flat with a modified hole punch prior to a small flat dab of solder on the bottom side only. After SMD components are in place I then put a dab of solder on top.

Tuesday 19 June 2012

BlueFlyVario Android App

Android has many quirks but I have a better than expected working app. Together with the prototype bluetooth module it functions better than my first vario from 15 years ago, and I think as well as my current vario. The video at the bottom of this post shows how far I have got. Adding vario functions is just a matter of writing code. Below I mostly describe challenges, but overall I found my first foray into Android Java an easy transition from the J2SE Java desktop environment.

Android version

The latest version of android is ‘Ice Cream Sandwich’. I needed to make some choices what ‘legacy’ devices I will support. Here is a summary of the distribution of devices by Android version. I have three android devices at home, a Froyo (2.2) HTC Aria, a Gingerbread (2.3.3) Samsung Galaxy S, and a ICS (4.0.3) ASUS tablet. Based on what I have, and the distribution of devices, I plan to see if I can choose API level 8. If that does not work then API level 10 is a must.

Android Bluetooth

I started with the Bluetooth Chat sample distributed with the Android SDK. After hacking away for a few hours I was able modify this to get the stream of pressure data arriving just fine. There were a few challenges. The principle challenge was about using BluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID). Unfortunatly this method is a little buggy and causes an error on API level 8 devices. I used the reflection based work around described here and it worked fine.

The Bluetooth connection is still not perfect. I often get a ‘Connection Refused’ on my first attempt, and occasionally on the second attempt. It might be some combination of settings on the RN42. I will need to code in some sort of failsafe.

Graphics

Custom graphics were going to be required to get the look and feel I wanted for the vario. After a little reading I decided to go down the 2D graphics path using a SurfaceView object. Having spent way to many hours in the Java2D libraries this proved pretty easy, in fact, I think it is easier than Java 2D. Even without code optimisation it has ended up being plenty fast enough.

In the video below you can almost see how the desktop vario/alt trace has translated onto Android. I am really happy with this. The drawing is super quick on the ‘old’ HTC Aria. You can see how the trace colour changes depending on the vario value. I have added a little blue dot for the highest vario value in the trace.

What I am aiming for in my reference app is a super thermal hunting machine. I plan to add to the vario/alt trace with a similar trace for location, not on a map, but just graphically. I plan to scribble the same coloured trace (with the blue dot) on a location graph. The idea is to map out the last x seconds of lift/sink to assist with coring thermals. This will need me to read the location (every second or so) and work out wind drift of the trace (based on assuming constant speed). I plan to include this feature in the reference app.

Sound

Making Android go beep was tricky. Android devices have a nasty lag playing sounds. This can be overcome somewhat by using the SoundPool class, but still playing a sound is tricky. I have ended up with a nifty workaround that is acceptable.

To begin with all of the sound stuff needs to happen in a separate thread. This required some synchronization tricks to ensure data being used for the sound (the vario) was not being updated at the same time by the pressure reading / vario calculating thread. I ended up generating a 1s long .ogg file of a 1000 Hz sine wave tone (using Audacity). When beeping is turned on this file just plays in an infinite loop. To adjust the tone the file is sped up or slowed down. This will give tones of 500 Hz to 2000 Hz. If I need tones outside of this I can use other files if needed, but for the moment this range sounds fine.

To adjust the beep I use Thread.pause(ms) for some timing. In each loop I adjust the volume of the tone from 0 to maxVolume to turn the tone on and off. This does not alter the overall device music volume, just the volume of the playing tone. There is negligible delay from setting the volume to maxVolume until the time the tone is heard, compared to ‘play’ which has a slightly noticeable lag. This trick allows the beeping on and off to be quick. The cadence (delays inserted in the Thread.pause(ms)) varies between about 450ms (for 0.2 m/s up) and about 150 ms (for 4.5+ m/s up).

Overall I now have an acceptable beep, although not optimized quite yet. I am not sure if the constantly playing tone is expensive from a battery perspective. I think this will be device dependant, but I don’t think it will be an issue compared to bluetooth and screen use. 

In the future I need to add a sink alarm. I think I might also add in some surprise easter egg sounds for lift above 3m/s!

Battery Life

I have done nothing to preserve battery life yet. I think I can do some things, but overall this app is going to be pretty heavy on the Android device’s battery. If it can last a typical day worth of flying with a few phone calls etc then I will be happy.

Way Ahead

The next steps in app development are:
- Add the location thing.
- Clean up the Bluetooth connection, reconnection, etc.
- Add in ‘start flight’ and flight time recording functionality.
- Add in the user preferences functionality for vario damping, displayed components, units (ft/m), etc.
- Add a few extra altitude displays (height above launch, custom alt based on QNH or a particular reference height.
- Cleaning up code and documenting (comments).

I am aiming for replicating the functions of a basic GPS/vario, adding in my super thermal hunting trace tools. Comp features such as waypoints, routes, etc can wait until future versions. I am aiming to open source this code as soon as I can get the first 10 or so hardware prototypes out. If you are a paraglider pilot and can code Android let me know if you are interested in testing by responding to this thread on paragliding forum.

I am deliberately putting the app coding on hold until I have the next prototype of the BlueFlyVario hardware. That is what will take some time. Components ordered over the internet are starting to arrive…

The video below is a little shaky. Wait until the end of it for some screenshots. The Android devices are an ASUS Transformer tablet and a HTC Aria phone.


Latency and Timing

My experience with latency and timing is worth a blog post. I have now have a working Android app with acceptable timing issues, but not without some pain. The alpha Android app will be described in my next blog post. A few days ago a friend asked me about the project (alight - I offered an explanation). Her immediate question surrounded the latency and what issues I was having. Was the latency acceptable?

Latency

I am going to start by describing the complex pipeline that starts with air pressure, and ends with the Android device displaying something on the screen and going beep.

1. The air pressure and temperature exists at a point in time around the device. Below is a very close up picture of the MS5611 without the protective cap. This is one that I broke. On the left is the actual sensor, the right is the microprocessor circuitry that is part of the sensor. A particular air pressure does something funky to micro diaphragms in the MS5611. I am not quite sure what micro devices bend, or change resistance or capacitance or whatever, but what does happen is that the sensor part of the MS5611 is virtually instantaneously put into a particular state. (I am guessing in pico or nano seconds). 



2. The PIC Micro-controller (operating at 8 MHz) goes through the loop of:
  • 2a. Triggering a temperature sample on the MS5611.
  • 2b. Waiting up to about 9ms for the temperature to be measured internally in the MS5611's microprocessor 4096 times and averaged (at least I think it is averaged and not some other algorithm). It is possible to select a lower oversampling rate and hence be quicker, but the trade off is accuracy. I think it makes more sense to allow that math to be done in the MS5611 microprocessor rather than do it on the PIC.
  • 2c. Then reading the temperature (negligible)
  • 2d. Then triggering a pressure sample (negligible)
  • 2e. Waiting about 9ms again for the MS5611 to do a 4096 oversample of pressure reading for reading.
  • 2f. Then reading the pressure (negligible)
  • 2g. Then triggering a temperature sample (negligible)
  • 2h. Then calculating the pressure from the read temperature and pressure. To do this also takes bunch of  calibration constants which are read from the MS5611 at startup (negligible on the 8Mhz PIC)
  • 2i. Then formatting and sending the pressure characters to the RN42 bluetooth module over UART. I thought that this process would not take much time, but for some time I was using the microchip c++ function sprintf. This is really expensive on the PIC and took heaps of time so I changed to just pushing a sequence of chars to the UART (for those like 'P', 'R' and 'S') and doing a custom int (32 byte unsigned) to char sequence conversion for the pressure (representing the Hex value of the right five nibbles of the 4 byte calculated pressure). This was much quicker, but it still takes time as the PIC to RN42 bluetooth module connection is working at 58k. I guess that this whole print characters thing happens in a few ms. What is important is that I am pretty sure it happens in less than time it takes for the temp measurement on the MS5611. So when we loop back to reading the temperature from the device we will not be waiting for much of the rest of the 9ms.
  • 2j. Then looping back to 2b (I already trigged the temperature at 2g).

In total this takes just less then 20ms. I was able to get it to less than 19 ms (or about 52 Hz) with some tweeking. For reasons described below I slowed this loop down to exactly 20ms. Note that it is about 13 ms from the time of the pressure measurement 2f, to the time it is sent to the RN42 (2i).

3. The RN42 (when established in a bluetooth SPP connection with the Android device), does its thing in some mysterious way. There is this 'bluetooth stack' thing that each character needs to go through, then over the air via the 2.4GHz bluetooth signal, then back through the bluetooth stack on Android. I am not sure how long that takes. From others tests I am guessing about 20 ms. I might do some more tests on this in the future. [probably not – it seems to work ok]

4. The characters then pop out of the bluetooth stack on Android and are read by the Java application code. Here is where things get really unpredictable. I measured the interval between pressure measurements on Android (using System.nanotime(), which I don't really trust but there is nothing better). I found the time intervals to be very erratic. Overall the average time interval is 20ms after I changed it to 50Hz. All pressure measurements are getting through. What I am pretty sure is going on is that the Android threading means that other things, like all that stuff you have going on the background of your PC right now, takes up processor time. At GHz clock speeds the Android device eventually gets around to measuring the data from the bluetooth input stream, sometimes reading a few measurements in a row with less than 1ms in between. My guess is that the average latency here is about 10ms.

5. The vario averaging then adds quite a lot of latency depending on the degree of averaging (damping). With a damping factor of 0.05 at 50Hz it takes about 860ms to reflect 90% of a change. But that is not the latency I am really concerned about. I am more concerned about the latency in 1, 2, 3 and 4.

In total, my guess was that pressure change to pressure available to Java on android latency is about 13 + 20 + 10 ms. So less than 50ms. This should be barely perceptible providing the App can display visually and using audio quickly enough (that story is for the next post).

Timing

Initially I tried spitting out the pressure as quickly as possible from Bluetooth device. I planned to measure the time of the ‘read’ and use this time for the integration of a window of a bunch of pressure measurements. The inconsistency of timing of ‘reads’ of this measurement from Android meant that I was getting screwy results. I tried averaging the pressure time reads, but this was confounded by the few initial measurements that happened at startup. Initialising the vario values worked, but as I tweaked the code on the microchip the pressure intervals would change slightly, screwing up the initialisation.  At the same time I was coding up the display on the android device and it was tricky to relate windows of time to the number of measurements.

The solution to all my timing problems was simple. I implemented a timing loop on the PIC using an interrupt to execute a pressure read and send every 20 ms exactly (50 Hz). The android device just needs to make the same assumption that the pressure measurements are 50 Hz apart, which I now do. Everything with timing is mostly good.

I assume that the internal clock is running exactly at 8MHz. In practice the FRC clock on the PIC is up to 1% or 2% inaccurate. At a particular temperature and operating voltage the clock should be pretty much constant. At 3.0V and 25 degrees Celsius it is most accurate. In practice I do not think that this error is going to matter much. If the vario says 5m/s up when it is really 4.9 m/s I am not sure anyone will care. At some point in the future I could add a crystal to the device to fix this up. Or alternately implement some code on Android to properly measure pressure intervals and add a correction factor. At this stage I am going to do neither.






Thursday 7 June 2012

The MS5611 - a resounding success

I got a few MS5611 samples through a friend in Europe to integrate onto the BlueFlyVario prototype just before I went away a year ago. My initial attempts at soldering on some legs and making dodgy breakout boards failed. I ruined at least one of the samples by melting the protective plastic case. During my time away more people started to use the sensor and I managed to get a few breakout boards from ebay.

To solder the MS5611 onto the PCB breakout board I first put a few very small dabs of solder on the PCB SMD pads. This is easily achieved by first using liquid flux on the pads, then loading up the tip of a standard soldering iron with a lump of molten solder, then just finely touching the molten lump to the pad. The idea is to get a small bit of solder on each pad (with the same amount on each pad!) Next I cleaned the contacts on the MS5611 with flux and wiped it all off - the idea is to remove the oxidation layer. Then I took the PCB and put in on an electric frying pan (skillet). As soon as the pan warmed enough to see the solder melt I put the MS5611 into place with a pair of tweezers. The surface tension from the molten solder held the component in place with a little wiggle of the board. As soon as it was cool I found that I had a perfect SMD solder joint.

I put the associated other components on the breakout board, really only a capacitor and headers, then tested them with the prototype. I had to remove the BMP085 and all of the associated circuitry, then put the breakout board in place. I used the SPI interface functionality rather than I2C as the datasheet said I could expect better noise performance (hence, lower error). It took me a few hours to get everything up and working again. I had to remember how to properly configure the PIC programmer and desktop prototype app. Modifying the PIC 24F code to do SPI ended up being pretty easy, there were a few examples on the net. The first time I properly compiled the program and ran it I got a huge shock, it was working with good, not too noisy, pressure data coming out. I lifted up the prototype vario and my computer went beep.

Some fiddling with the desktop app allowed me to see the altitude graphically and I added in a RMS error to debug the noise. Initially I was getting about 25cm RMS noise with about 50 samples per second. The 50 samples per second actually measures the both the pressure and temperature 50 times a second, then outputs the pressure only. It should be possible to measure the temperature only about 10 times per second, using each temp measurement for about 9 pressure measurements. That would give us about 90Hz for the pressure measurements. I am not sure we need that much...

The prototype was pretty sensitive and it was defiantly an improvement over the BMP085, but I was not happy yet. I added a RF Choke on the V IN line of the MS5611 and the noise went down to about 15cm, although sometimes it floats up if I touch the wrong component on the prototype. I am not sure what the value of the RF Choke is, it was just one that I grabbed from the workbench. The source of the noise could be the linear voltage regulator, the Bluetooth transmitter, or the switching of the PIC microcontroller. It does not really matter, what does matter is that the the noise suppression works really well. I have ordered some ferrite beads for the next prototype. I should get even better noise performance if I filter out noise from the ground plane as well. I don't have an oscilloscope so I can't actually measure what frequencies I am trying to filter and perfectly match the ferrite bead to it. If only I was rich.

Below is a short video of the vario in hand with the prototype desktop app overlayed on it. Note the white altitude display with the vario data (damped) on top of it.



The settings are:
altDamp=0.05 (i.e. 5% of each new measurement is added to the 'current' measurement - see the previous post about the IIR filter to understand what this means)
varioDamp=0.3
varioWindow=50 (about 1 second at the 50 Hz I am measuring at)
vario2Damp=0.05
vario2Window=100 (about 2 seconds)

Next steps:
- Order components for the next round of prototypes (done). I am going to make a couple, with pretty much all SMD components.
- Order PCB prototyping stuff.
- Prepare Eagle circuit diagram and PCB artwork.
- Develop prototype Android app.

Stay tuned, I am back on track. I aim to have a few working SMD prototypes and the prototype Android app by the end of July. Circuit diagrams and code are coming.

Wednesday 6 June 2012

A year of developments

After returning home from almost a year away on a work assignment I now have a little time to continue with my BlueFlyVario project. I have had a lot of success, but that is for the next post. In this post I will provide an update of what has changed over the past year. The bottom line is that the concept I first had some years ago, then started developing in earnest about 18 months ago, remains a worthwhile pursuit.

There has been a little movement in the availability and price of some of my chosen components. The RN42 Bluetooth module has come down in price a little, it is still the cheapest one available and now appears to be more widely used. Microchip has recently bought Roving Networks so I expect that their marketing might will make it even more available in a few months time. The Microchip PIC's are cheaper, as are the batteries and most of the passive components.

The MS5611, the key pressure sensor module I selected, has been used by a range of hobbyists. The Arduino microcopter folks have successfully integrated it. The module is now available in hobby quantities on at least a few specialist websites (http://www.drotek.fr/shop/en/43-ms5611-pressure-barometric-sensor.html for example). You can also get the sensors on breakout boards on ebay occasionally. I got my hands on a few samples from a friend, and ordered got some breakout boards from ebay while I was away. Moreover, there is at least one commercial vario using the MS5611, the Flytepark microvario (http://flytepark.com/Store/Microvario). This is the culmination of Hari Nair's work and I once more congratulate him, not only for this vario, but his ongoing commitment to share his work with an open design.

I am not the only one looking at a bluetooth vario and over the past year others have got similar products to market and further discussed them on forums. The FlyNet vario is one example of something very similar to what I want to build (https://www.asinstrument.ch/pages/home). It is more expensive than I am targeting (over $200) and it seems like the application and design are not open. However, the interface protocol is. I am considering using the same interface protocol as it is very similar to what I am currently using. For me to change will only take a few lines of code. I would add semi regular (once every few seconds) temperature updates, but I am less keen to allow users to change the device name.

Android, the target platform, has continued to get stronger and there are now a wider range of much more capable devices. Importantly, it is easy to pick up a cheap second hand 'old' android phone that should work really well as a front end for the vario. A few recent Android devices now have integrated pressure sensors, but I am unsure if it is possible right now to use these sensors as the basis of a sensitive vario. I think not from my initial research. The sensors are either not sensitive enough (like 30 cm RMS at best) and in many cases the operating system will not return measurements faster than a few Hz. I am aiming for 10cm RMS measurements at 50Hz. There is a discussion about this on pgforum.

Based on all of that I recommenced the hardware prototype development with the aim of integrating the MS5611...