Thursday, October 2, 2014

What's The Channel Capacity Of The ADS-B System

If you've seen my twitter feed lately you may have noticed I've been playing around with ADS-B, the system used by commercial planes to report their position and other details.  I find it an interesting topic and a great way to get into software defined radio.  For just $20 you can start to play around with a TV tuner dongle and map air traffic in your local area.  As usual I wanted to get down into the nitty-gritty and find out more about how the protocol works, particularly how many planes it can support at once.

First of all we'll take a quick overview of how the system works.  The ADS-B traffic I'm interested in occurs at a frequency of 1090 MHz and consists of frames/packets that are 112 microseconds long with a 8 microsecond preamble, a total of 120 microseconds.  All of the data a plane transmits can't fit into a single frame, so there are different types transmitted, some are initiated by the plane, some are initiated by ground radar systems, some are required twice a second, some are required every 5 seconds.  We'll get to this later, but for now I want to look at the pure throughput of the channel.  It may seem simple, but as the number of planes/stations transmitting increases, the probability that they'll "talk" over each other increases, and frames start to collide.  If we take this example to an absurd extent and assume there are infinite planes, the throughput of the channel will be zero because the planes will always be talking over the top of each other.  There's a sweet spot that can be found.

Grey frames are ones that have collided

If messages are 120 microseconds long, it should be easy to determine the probability of collisions at certain data rates.  First though, a few assumptions need to be made.  Planes transmit their ADS-B frames whenever they want.  There are communication systems that only transmit at certain time periods (slotted systems), and some listen to the channel and wait for it to be clear before sending (carrier sense multiple access), these methods reduce collisions, increasing the throughput of the channel.  In the case of ADS-B, it's hard to find information on how it's actually done, so I'm going to assume the random transmit method, which is the basis for ALOHAnet, the first public demonstration of a wireless packet data network.  So most of the analysis has been done for us.  In fact the images (with attribution) in this blog have come from the Wikipedia article for ALOHAnet.  This article is going to apply the theory of the ALOHAnet to ADS-B.

Another assumption that needs to be made is the signal strength coming from different stations/planes.  We'll assume that all the signals are received at the same level, and will therefore collide.  In reality a plane transmitting 150 km away, will get lost in the signal of a plane transmitting 500 m away and will not be seen as a collision.

The final assumption to make is that the simple CRC checks in some of the ADS-B messages aren't used to correct the signal.  If that were the case small collisions would be OK, but let's keep things simple.

Frames transmitted between t0-T and t0+T will collide with the yellow test frame

Firstly define the time taken to transmit a frame as T, and also define G as the average number of transmission attempts per frame in Erlangs.  In the above image it can seen that any frames transmitted in the period from t0-T to t0 will collide with the start of the yellow test frame, and any frames transmitted in the period from t0 to t0+T will collide with the end of the yellow frame.  From this we can see the probability of a successful transmission of the yellow test frame is equal to the probability that no other frames are transmitted during the period between t0-T to t0+T.  A period of 2T.

If the arrival distribution is modelled as a poisson process the probability that k frames are sent in a time period of 2T is equal to


By setting k to zero we can see the probability of no other frames sent in this time frame.


This gives a throughput in frames per frame period of


The maximum value of S can be easily found.


So, the maximum throughout is 0.184 frames per frame period, and this occurs at a channel load of 0.5 Erlangs.  This is demonstrated in the graph below for the Pure Aloha system.
Throughput vs load for slotted and pure Aloha
Now to bring this all back to ADS-B is rather simple.  T is simply the 120 microseconds mentioned earlier.  We know the maximum throughput is 0.184 frames per frame period, which in this case is 0.184 frames per 120 microseconds which is equal to 1533 frames per second.

1533 is the number of frames per second supported in this instance, but it's not the number of planes.  Each plane is required to transmit location and velocity frames twice a second.  They are also required to transmit a flight ID frame every 5 seconds.  This means at a bare minimum the plane is transmitting 4.2 frames per second.  I'm unsure if the plane is required to transmit it's position twice a second or position frames twice a second (there is a difference).  ADS-B uses a strange compression method called compact position reporting to transmit the latitude and longitude of a plane.  Two frames are required for a full latitude and longitude position.  I'm going to stick with 4.2 frames a second but it could be 6.2 frames per second.

Taking the number of 4.2 frames per second per plane as a minimum means that there can't be more than 1533/4.2 = 365 planes visible to a receiver at any one time.  Even that's an unlikely scenario, because at that point there are quiet a few frame collisions occurring. Having said that there will always be some collisions.  At maximum capacity of G equal to 0.5, the probability of no collisions in two frame periods is equal to e^(-1) = 0.368, if the load were reduced by a factor of 10 this becomes e^(-0.1) = 0.905, so although the probability of a collision is reduced.  It's still around 10% which is not insignificant.  This load represents a more realistic number of planes, 36 (365/10) , detected by an ADS-B station.  So obviously there's somewhere in the specification for ADS-B that defines an acceptable level of frame collisions, but because it seems to be a propriety standard, we can only guess what that number is.

The point of this article was to get a feel for the capacity of ADS-B.  My numbers are a ballpark figure.  I'm doing some coding and I need to figure out if I can handle the incoming data using the method I plan to use.  I'm pretty sure I can.

Further Reading
http://defenseelectronicsmag.com/site-files/defenseelectronicsmag.com/files/archive/rfdesign.com/mag/512RFDSF3.pdf
http://www.homepages.mcb.net/bones/SBS/Article/Barebones42_Socket_Data.htm

References
http://users.ecs.soton.ac.uk/sqc/EL336/CNL-7.pdf
http://en.wikipedia.org/wiki/ALOHAnet

Sunday, September 21, 2014

Convert a Monochrome Bitmap Image to a Vector Image

In my last couple of posts I've been writing about barcodes.  When generating them, some programs are able to output a vector image, which makes rescaling them later on easy, but some programs can only output a raster image of pixels.  Converting them to a vector image like an SVG file makes the work-flow easier.  So in this post I'll show how to convert a sample raster image to a vector image.

The sample image to convert is a simple 2D barcode.  It's made up of square elements 2x2 pixels in size.  The processing will be done in Inkscape and GIMP.


barcode
Image to convert to vector
The first step is to enlarge the image.  This is done because the conversion process only works if the edges in the barcode are long and straight.  You may have to try different values until you come across a size that works.  Enlarging the image by 500% was enough in this case.  It's also important to set the interpolation to "None".  This ensures that each pixel in the original image will exactly match a 5x5 group of  pixels in the enlarged image.

instructions
Resize image with no interpolation
Using the colour selector tool in GIMP, click on the colour you want to convert to a vector shape, in this case it's the black of the barcode.

instructions
Select Colour
In GIMP convert the selection to a path.

instructions
Convert Selection to Path
Open the path dialog box and right click on the path just created, then select "Export Path".  This will create an SVG file containing the barcode we are trying to convert.

instructions
Export Path to SVG
When opening the SVG file in Inkscape it'll look wrong.  At first, all that's shown is the outline of barcode.
barcode
SVG with Stroke on and No fill
To correct this, select the object, set the fill to black and then turn off the stroke (outline).  There you have it, an SVG file containing the barcode.  There is a "trace bitmap" function in Inkscape, but it seems to be oriented towards graphics.  When it comes to a doing pixel accurate tracing of an image, this seems to be the easiest way to do it.
barcode
SVG with Fill on and no Stroke

Wednesday, September 10, 2014

Barcodes and GS1 Application Identifiers

Recently I looked at the case study of Alice and Bob running a lemonade stand, and how their choice of product barcode was negatively impacting their stock management system.  In this post we'll look at a couple of barcodes that can be used to overcome this problem.

To fully understand the issues involved I suggest reading my previous post, but to sum things up, the barcode symbology they were using only encoded the price of the product and not the volume.  This caused errors in the stock management system because it inferred the volume by dividing the price by the price per volume.  It seems logical, but in a certain situations things can go wrong.

To solve their problem Alice and Bob came up with the idea of encoding the product volume in the barcode as well, and as it turns out other people have encountered this problem before and have already devised a solution.  GS1 have a released a standard defining a set of numerical application identifiers that refer to a specific product attribute and the format of the data that it refers to.  There are over a 100 different attributes that can be encoded.  When printed in human readable form, the application identifier is surrounded by brackets followed by data. For example, 10 is the application identifier for encoding a batch or lot number and can hold up to 20 alphanumeric characters.

(10)a0b1c2d3e4f5g6h7i8j9

Application identifiers can be chained together to create a GS1 element string which can then be encoded into a barcode.  The first thing that needs to be done is to decide what data will be recorded in the barcode.  Alice and Bob look at their existing labels to consider what to encode.

Product label
Old EAN-13 label

There are five different pieces of information on the label

1. Item type
2. Best Before Date
3. $/L
4. Volume (L)
5. Price

It's decided that encoding most of this information will be beneficial.  Everything but the $/L will be recorded as it can be derived from the other information and isn't needed for an accurate stock management system.  They go through the list of available application identifiers and choose 4 that will encode all of this data in a standardised way.

(01) Global Trade Item Number (GTIN)

The GTIN provides manufactures with a way to assign globally unique identifiers for their products.  This removes ambiguity between product identifiers.  The field for a GTIN is exactly 14 digits in length and is a unique reference to what the product, is and is made up of several components.

The first digit is an indicator digit.  There appears to be some confusion about what this digit should be for a variable measure trade item scanned at point of sale.  There are quite a few sources that say it should be 9, but the latest GS1 general specification released in January 2014 indicates that only applies to items not scanned at a point of sale.  For POS scannable items it should be zero.  I'm not 100% sure what it should be, but zero seems to be correct according to the latest standard.

The next 12 digits are the company prefix and the item reference.  The company prefix is assigned to your company when you apply for one, and the item reference is assigned by the company itself.  The length of each will depend on how the GS1 member organisation in a particular area assigns company prefixes.  For example, since 1996, Australian company prefixes are 9 digits long.  This leaves 3 digits for the item reference.

The first three digits of the company prefix are the country prefix, and identify the GS1 member organisation that assigned the company prefix.  In this case it's 930, indicating Australia, as it's responsible for country prefixes 930 to 939.

The last digit is a modulo 10 check digit.  In this case that's equal to 2.
GTIN-14
GTIN-14 breakdown

So the first part of the GS1 element string that Alice and Bob are going to use on their lemonade is

(01)09303141590012


(15) Best Before Date

Application identifier 15 encodes the best before date of the product, and although it isn't essential to have for a stock management system, it has other uses.  For example, when in use, a customer will never be able to buy an out of date product because it'll be flagged at the point of sale, the item can then be replaced with a newer one.  It could also allow automatic repricing of products for clearance and promotional purposes.  The format of this application identifier is basic, it holds 6 digits and is of the form YYMMDD.  So in this case the next part of the lemonade GS1 element string for the best before date 10/10/2014 will be

(15)141010


(315x) Net Volume Litres

This application identifier is a little different. 315x is the application identifier for encoding the number of litres in a product.  The last digit (x) of this application identifier indicates at what position to put a decimal place in the following data.  It's six digits long.  So for the lemonade label above with 1.521 L on it, the next part of the GS1 element string will be

(3153)001521


(392x)  Amount Payable For a Variable Measure Trade Item

Unlike the other application identifiers encountered so far, the length of the Amount Payable is variable and can be 1 to 15 digits long.  It also uses the last digit of the application identifier to encode where a decimal point is placed in the following data.  The price of this bottle is $3.02 and will be encoded in the GS1 element string as follows.

(3922)302


Encoding the GS1 Element String

Alice and Bob now have all the components of their GS1 element string, and when written it will look like this.

(01)09303141590012(15)141010(3153)001521(3922)302

That's all great, but it's not a barcode.  The next step is to pick a symbology to encode this data.  Alice and Bob look at three different symbologies to use on their labels.


GS1-Databar Expanded

Databar used to be known as reduced space symbology (RSS) but has since changed its name. It allows much more data to be stored, improving traceability and stock management.  There are few quirks to encoding the element string in a Databar-Expanded barcode, but all good software packages should mange this transparently without the user ever knowing.  For example, the above element string can be encoded using zint barcode software to give the following barcode.

barcode
GS1-Databar Expanded

If you're playing along at home you may or may not be able to read this barcode from the screen using a phone.  It all depends on your screen resolution.  It's a good starting point.  All the data is encoded in the barcode, but it is rather wide.  It would be great if there was another option.


GS1-Databar Expanded Stacked

Due to space limitations a stacked version of the previous version was needed.  It splits the barcode up into shorter pieces and stacks them on top of each other.  It's not as simple as just splitting the original into small pieces, the information is re-encoded in a different way.  The following barcode was made using an online generator from the site www.terryburton.co.uk/barcodewriter/generator/.  It was the only one that was able to reliably create a barcode that could be decoded.  Zint was able to produce a stacked barcode as was RSSENC from GS1, but there weren't any scanners that could reliably decode them.

barcode
GS1-Databar Expanded Stacked
The scanner app from zxing was able to reliably decode this type of symbology once the exposure control was altered.  Below is the result of scanning the barcode above.

scanned barcode
GS1-Databar Expanded Stacked scan result

Technically GS1-Databar Stacked Expanded is capable of being scanned by a 1D laser scanner, but the scan line has to be swept over the barcode to read all parts of it.  Not ideal but it works.  The key to reading this type of code is that all of the sub barcodes need to be read and reassembled by the scanner in software.  An omnidirectional scanner is fine for this, as is a high quality 2d scanner.  However If we need a 2D scanner why not go for a 2D barcode?


GS1 DataMatrix

This one is just purely theoretical because it's a 2D barcode.  The last two barcode symbologies are cleared for scanning at a point of sale according to the GS1 specification, this one isn't because it requires the use of a 2D imaging scanner.  It's included because in my opinion it's likely that it will be in the future (and it's such an elegant solution).

Retailers are starting to see the advantages a 2D imaging scanner has.  It allows dense bar codes to be read from phone screens or promotional material, and having an imaging scanner also allows identification to be scanned at point of sale when people are buying restricted products like mobile phones.  The technology is available right now.  The NCR Realscan 78 Hybrid scanner uses a combination of laser scanning and imaging techniques to scan 1D and 2D barcodes.  It's capable of scanning GS1-Databar and GS1-Datamatrix symbologies fast and reliably.

NCR Realscan 78


So what does a 2D datamatrix code look like.

barcode
GS1-Datamatrix

The above datamatrix encodes the GS1 element string that Alice and Bob are using to label their lemonade.  In addition to being easy to scan, datamatrix codes also carry error correction coding that make the code more resilient.

Now that they have a barcode it can be compared with the old label.

product label
Barcode comparison

The new datamatrix code has the GS1 element string under it in a human readable form, this allows it to be entered into a computer if the symbol is damaged.  Even that's less likely with a symbology like datamatrix.  A lot of bar codes for variable volume products are printed by an array of printer elements.  It's not uncommon for part of the printhead to fail or become covered in dirt leaving an unprinted stripe down the printout that makes traditional barcodes unreadable while datamatrix codes can still be read. The image below demonstrates this with a vertical white line through each label.  It's visible starting at the a in the word lemonade.

product label
Damaged barcodes

The printhead failure causes the first barcode to be unreadable, while depending on the quality of the reader used the Datamatrix code will be easily read.


Conclusions

Alice and Bob have some decisions to make, GS1 have been aiming for 2014 as the adoption goal for Databar, so it's likely that any recent POS equipment will be able to scan databar expanded and databar expanded stacked.  So their current equipment might be able to scan these symbologies.  By using either of these barcodes they'll be able to improve the integrity of their stock management system while taking advantage of the other features offered.  The food safety benefits of encoding the best before date in the barcode is a compelling reason to further investigate this option.  It also allows the system to monitor things like how well stock is being rotated.  Ideally stock should be sold on a first in first out (FIFO) basis.  The order that stock is sold can be recorded by monitoring the  use by dates that go through the point of sale.

Now that the volumes going through the registers are accurate, they can be used to calculate metrics, such as average bottle volume, this can be fed back into the stock management system to detect errors introduced through other means.  For example if the average bottle of lemonade is 1 Litre and the stock management system says there are 10 bottles with a total volume of 2 Litres you know there's something wrong and the counts need to be investigated.

The benefits are indisputable, it just comes down to how much the barcode migration and initial set-up will cost.  It may or may not be the right fit for their business at the current time, but Alice and Bob should keep it in mind as a long term goal when purchasing or investing in future infrastructure.


Note:

I should make it clear that all labels and barcodes generated for this post are just to illustrate a point.  If you were to actually design a label there are many more things to pay attention to.  Guard spaces, barcodes sizes, and font placement are a couple that spring to mind.

Saturday, August 30, 2014

How Barcodes Can Negatively Impact Stock Management Systems

Today's post is going to be a little different.  It's about bar codes and how they they interact with stock management systems for products with a varying volume or weight.  The purpose of this post is to get down in writing what I have in my head and formalise what's going on.  My intent is to demonstrate that inferring the volume or weight of a product from it's price when given a price per Litre or kg can lead to subtle errors that cause errors in stock on hand counts.

Now to do all this we need an example of a business that sells a product with a varying volume.  So what about a lemonade stand.  Our proprietors are going to be named Alice and Bob, and because they're only starting, they're bottling their product in recycled bottles, so all the volumes are different.

Setting the scene

Initially Alice and Bob put up a sign with the price per Litre of their lemonade and calculate what to charge customers by multiplying this value by the volume of the bottle at the register.  For example $1.99/L * 0.434L = $0.86.  Remembering to round down to the nearest cent so the customer isn't disadvantaged.  This works for a while, but customers are complaining that it takes them too long at the checkout, so it's decided to calculate the price beforehand and put price labels on the bottles.  This improves things, but there still problems, occasionally the price is miskeyed at the register and customers are overcharged resulting in refunds.  It's costing them money and making customers unhappy, a bad combination for any business.

To fix these problems they move to a system that places bar codes on the bottles.  It allows them to have all the information the customer needs to see on one label.  It also decreases pricing errors and the time spent at the register.

Alice and Bob know that the best option is to go with an industry standard, so they follow common retail practice and use an EAN-13 bar code.  It allows them to encode the price and an item identifier into the bar code.  Usually an EAN-13 bar code starts with a country prefix, followed by a company number allocated from the GS1 organisation in your country, an item reference number, and then a check digit, but Alice and Bob are aware that in Australia the prefix 26 is reserved GS1 members to use how they want internally in an RCN-13 format.  That sounds complicated, but all it means is that the first two numbers are "26", the next five are an Item ID, the next five are the price of the item in cents.  The last digit is a check digit.

Bar Code

During the implementation of the bar code system they also thought that it'd be great idea to include a stock management system to keep track of their inventory, it could also feed data into a possible future automated ordering system.  They decide to keep track of how many bottles they have and the total volume of lemonade in stock.  As the bar code only contains the price of the item, they use this in combination of the price per Litre in the computer system to calculate the volume sold.

To demonstrate how the stock management values change I've put together a small inventory sheet showing all the labels of what they have in stock.  Calculations are also shown.  To make things easier to understand I've colour coded the calculations.

red number indicate price
blue numbers indicate volume

Stock on hand calculations are done in a vector form (number of bottles, volume)

purple is for what's in the computer system
orange is for what's actually in stock

1. Initial allocation of stock

Their first batch of lemonade is labelled and ready to be put on show.

Inventory Sheet
Stock on hand

2. Stock starts to sell

After trading for a while, the store has sold two bottles from the initial allocation of stock.  As they pass through the register, the number of bottles and the volume of lemonade in the system needs to be adjusted.

If the price in the computer is 1.99 per Litre we can perform the following calculations for the two bottles sold to calculate the associated volume sold.  The volumes are rounded to the nearest mL.  As they are only for our benefit it doesn't matter if they are rounded up or down.

       /1.99
$3.02  ---->  1.518L
$0.77  ---->  0.387L

The total volume sold is equal to 1.905 Litres.  This needs to be deducted from the volume inventory and two bottles need to be taken from the item count inventory.

(4,4.694) - (1,1.518) - (1,0.387) = (2,2.789)   (2,2.783)

This leaves a volume count of 2.789 L, which is in close agreement with the actual count if you were to add the volume of the remaining stock.  This demonstrates the first source of error a system like this introduces.  Rounding error.  It's nothing major and it's only a couple of mL here and there.

Inventory Sheet
Stock on hand

3. Week long special promotion and more stock arrives

After their initial success Alice & Bob have run into trouble, Eve has opened up a competing lemonade stand across the road.  To combat this they have spoken to their supplier and arranged a special deal on their lemon order.  This allows them to run a week long special on lemonade, dropping the price to $1.49 per Litre from $1.99 per Litre.  The inventory management computer still records the regular price at $1.99, but it's aware of the week long special at $1.49.

This special has also been advertised, so they need to reprice any old stock at the higher price they currently have to the special price.  To do this they have come up with the idea of scanning the bar code on the product and automatically printing a special yellow sticker with the new price and bar code.  This is placed over the old bar code so the bottle will scan at the right price when it goes through the register.

To do this the system reads the price from the original bar code, calculates the volume based on the regular price ($1.99/L) and recalculates the price at the special price ($1.49/L)

       /1.99*1.49
$1.27  --------->  $0.95
$4.26  --------->  $3.18

This doesn't change any of the stock counts, it just reprices some of the products, but they've received more stock that was made after the special was announced.  This allowed them to print bar codes with the correct prices so these don't need to be altered, but the stock does need to be added to the stock on hand values.

(2,2.789) + (1,1.443) + (1,0.821) = (4,5.053)   (4,5.047)

Inventory Sheet
Stock on hand

4. Sold some promotion stock

The special was a success and they sold two more bottles, the computer assumes that they are priced at $1.49 per Litre and calculates the volumes accordingly.

       /1.49
$3.18  ---->  2.134L
$1.22  ---->  0.819L

2 bottles and the associated volumes need to be removed from the stock on hand counts.

(4,5.053)  - (1,2.134) - (1,0.819) = (2,2.100)   (2,2.082)

The bottle count is still accurate, but the volume count in the computer system has drifted a little more, it's still not much in the scheme of things and shouldn't effect anything.

Inventory Sheet
Stock on hand

5. Restock after the promotion

Now that the special has ended they need to restock.  Two more bottles are made and added to the stock on hand counts.  Now that the promotion is finished these are labelled at the regular price of $1.99 per Litre

(2,2.100) + (1,0.281) + (1,3.009) = (4,5.390)   (4,5.372)

Once again the counts in the computer are still very close to the actual stock on hand.

Inventory Sheet
Stock on hand

6.  Another Promotion

Recently an oversupply has caused the price of lemons to plummet.  This has allowed Alice and Bob to run an incredible special of only $0.99 per Litre.  Once again the computer knows that the special runs for a week at $0.99 per Litre and the regular price is $1.99 per Litre.  Again, all the stock on show is repriced with the yellow special stickers.

       /1.99*0.99
$0.95  --------->  $0.47 Wrong!
$0.55  --------->  $0.27
$2.15  --------->  $1.06 Wrong!
$5.98  --------->  $2.97

This is where things start to go wrong.  The computer doesn't know the actual volume of the bottles, it has to infer it from the price, and because there are bottles remaining from previous promotions, it will get these wrong. For example the bottle priced at $0.95 is repriced to $0.47, when it should be $0.63 (0.99*0.639).  This is because these bottles have been priced at prices other than $1.99 per Litre.

Inventory Sheet
Stock on hand

7.  More stock is sold

This special promotion went great as well, and two more bottles were sold.  Once again the stock on hand needs to be adjusted and the computer assumes that the price of each bottle is calculated at $0.99 per Litre.

       /0.99
$1.06  ---->  1.071L Wrong!
$2.97  ---->  3.000L

(4,5.390) - (1,1.071) - (1,3.000) = (2,1.319)   (2,0.920)

As we can see, assuming that each bottle is priced at $0.99 per Litre has caused the stock on hand counts to drift significantly.  They are now out by about 0.4 Litres.

Inventory Sheet
Stock on hand

8. The price returns to normal and the stock sells out

The special has ended and the price has returned to the standard price of $1.99 pre Litre.  Bad weather has however now caused a shortage of lemons, and all the remaining bottles sell and they have no stock left.  The computer thinking that the price is back to $1.99 Litre, uses this number when calculating the volumes to be deducted from the stock on hand values.

       /1.99
$0.47  ---->  0.236L Wrong!
$0.27  ---->  0.136L Wrong!

(2,1.319) - (1,0.236) - (1,0.136) = (0,0.947)   (0,0.000)

So after all the stock had sold, the ordering system is in a state where the bottle count is 0, which is correct, but the volume count is equal to 0.947 Litres.  That doesn't make much sense does it.

Inventory Sheet
Stock on hand

Inferring the volume of each bottle from the price introduces errors in a couple of ways.  There are small errors introduced by rounding, these are insignificant and can usually be ignored.  When repricing stock for a promotion that has already been on a promotion, the system will calculate the wrong volume.  Lastly, when stock that has been on promotion is sold after the promotion has ended, and the price in the computer system returns to normal, the volume reported will also be wrong.

All of these errors have the effect of under reporting the volume sold to the stock management system, which over time causes the stock on hand volume to drift higher.  It's important to note that the count of bottles is always correct, it's just how many Litres of lemonade remaining will be wrong.  This happened even though Alice and Bob followed procedure and recorded all stock movements like they were meant to.

You may ask, who cares?  If you know how many bottles you have, that's all that matters, and to a certain extent you'd be correct.  However if you want to be able to automate something like an end of year stock take, you need all of this data.  It also helps to plan for future sales and promotions.

There are ways to deal with all of these problems that at some point require a person to read the volume on the bottle and enter it into a computer.  This is time consuming and prone to error.  What if we could come up with a way to do this automatically?  You're going to have to wait until my next post to find out how to go about doing it, but there's a way to do it simply and elegantly.

Note
If you need to generate any barcodes like the ones in this post I highly recommend Zint.  It supports many formats and produces barcodes that can be saved in raster or vector formats.

Monday, August 18, 2014

Using a Solar Panel to Keep a Generator Starter Battery Charged

Just a quick post this week.  I thought I'd do an update on the solar project I'm doing for my father.  There isn't anything too complex involved, just a solar panel connected to a charge controller that keeps a battery topped up that's used to start a back up generator.  The generator is used infrequently and the battery has a habit of being flat when needed.  The generator is in the shed that the solar panel will be mounted on. so installation is pretty easy.  To make the project more interesting the load terminal of the charge controller was connected to an LED light to give extra light at night and indicate the condition of the battery.

My previous testing of the MP-3720 solar charge controller can be seen here.

The charge controller was mounted to the frame above an unused door.  It's not an ideal place, but any higher and it would be too close to the hot corrugated iron roof.  The kind of heat involved would significantly reduce the life of the controller.

Solar Charge Controller
Solar Charge Controller
As the installation was unplanned, I was flying by the seat of my pants.  The solar panel, battery, LED light and charge controller wiring was bought together in the best way I could.  With more time and planning I could have done a neater job, but you work with what you've got, and what I had was a strip of terminals.  I plan to revisit this and make it neater, but it does the job for now.

Wiring
Wiring (don't look at it, it's shocking I know)
The LED light was an afterthought, the terminals were there and a small light in the backyard at night seemed like a good idea.  It also serves another purpose, it indicates the condition of the battery.  The light only comes on at night and will only come on if the battery voltage is above 11.5 Volts.  If it doesn't come on it shows that there's something wrong with the system.

Solar Panel and LED Light
LED light connected to the solar charger
There are still a few things to tidy up, but the job is almost done.  I have a high current switch on order that will allow the battery to be switched between the solar charge controller and the generator.  It may not be absolutely necessary,  but I didn't want to start the generator while the charge controller was connected to the battery.  The starter motor draws a lot of current, and where there's large current into an inductive load there's the possibility of voltage spikes caused by inductive kickback.  Yeah, I could come up with some kind of snubber circuit, but this is simple and foolproof.

Solar Panel
Solar Panel

Friday, August 8, 2014

100th Blog Post Retrospective

This is my 100th blog post and to celebrate I thought I'd do what all great TV shows do for milestones episodes, a cheesy clip show.  So I'm going to go through a couple of my favourite posts along with my most popular ones.

OpenGL


My attempt at OpenGL seems to be a good place to start.  I wanted to take the timetables from all our public transport providers and calculate a transit time map for Brisbane.  This would make it easy to visualise what parts of the city were over and under serviced.  To do this I needed a way to visualise the raw data and the results, so I thought I'd write my own viewer.  It used a custom set of tiles from the Open Street Map project I rendered myself and with c++ and openGL it was able to swap in and out tiles with appropriate resolution depending upon the users location in the map.  The project didn't get much further than the results below, I underestimated the scale of the task and overestimated my abilities.  To top it off I lost the project due to a corrupt file, but I was proud of the results nonetheless.  Before this I'd never used OpenGL and had only toyed around with c++.  I also learnt the value of backing up projects.




Off Axis Magnetic Field of a Circular Current Loop


Next up is my second most popular post and the one I'm proudest of.  I wanted to work out the off axis magnetic field of a circular current loop so I could simulate the effect of a magnetic lens on an electron beam.  Not only was the maths difficult, but speaking isn't really my thing.  From memory, the 10 minutes of  video took around 200 takes at recording the audio. If it wasn't me getting tongue tied, it was a noise from outside or something like that.

The video itself was done by combining images created with asymptote.  One drawing was made with a parameter I could change, Linux scripting was then used to render images with different values for the parameter.  That in itself was a nightmare.  The best thing about this post is that I've had a couple comments from people that said it was useful.





Surface Mount Circuit Board


Now for my first surface mount circuit board.  I'd been involved in designing a couple of PCB's for university team projects, but this was the first one I'd designed entirely by myself.  It was also the first time I'd used surface mount parts.  Up until this point I was terrified of them, but after this project I wouldn't use anything else.  The circuit wasn't anything fantastic it was just a breakout board for an MCP9808 temperature sensor and a reason to design a PCB.


PCB with parts in position

Vacuum Pick Up Tool


This project follows on  from designing my first PCB.  I wanted a way to place SMT components.  I'd had reasonable success using tweezers but I wanted to try a vacuum pick up tool.  It works for pick and place machines why not me?  So I made my own tool to see what the advantages and disadvantages were.  I learnt a lot in the process, particularly silver soldering.  I was so happy with my soldering results I polished up the hand piece until it looked like something you'd buy in a jewellery store.  If I were to go back and do it again there are a few things I would change, but it works reasonably well.


Vacuum pick-up tool hand piece

Flaring the End of a PVC Pipe


The popularity of my next post was a bit of a surprise.  I was building a chicken coop for my sister and was short on content so I was just documenting what I was doing during the build.  When it came time to put the down pipe on the gutter I had to flare the end of the PVC pipe so I thought I'd show how I did it.  To date, this post is my most popular and has had almost twice as many hits as my next most popular one, and it's only been up about half as long.  To top it off it took about 20 minutes to photograph and post, my second most popular post was the culmination of about six months of on and off work.


Flaring a PVC pipe

Harmonic Elimination Pulse Width Modulation


This is one of the posts I'm quite proud of as well.  Years before I started this site I came across the concept of harmonic elimination PWM.  It allows a designer to alter the switching times of a PWM signal to control or eliminate certain harmonics in the output waveform.  At the time I worked out the equations, scribbled them down on paper and put them away for later.  That's not much use to anyone, I eventually got around to putting them up so they could be useful to others.  There's lots of information about HEPWM out there, but it's rather high level.  I wanted to give people a starting point with some code to generate the switching waveforms.  There are plenty of ways to slightly alter the design for different requirements, but having an understandable starting point to branch off from is helpful for others.

Octave Code For Generating Harmonic Elimination PWM Waveforms
Fourier Series Of Harmonic Elimination PWM Waveforms
Fourier Series of a Quarter-Wave Symmetric Pulsed Waveform
Harmonic Elimination PWM Comparison and Uses


HEPWM example spectrum


Now it wouldn't be a proper post without me doing something new.  I decided to grab a screen shot of each post including this one and assemble them into a single image.  I thought it would be a nice way to visualise my output over the past three years.  Usually I'd try to use some clever trick to accomplish this, but in this case I just brute forced it.  I took screen shots with the awesome screen shot add-on for chrome.  The images were then batch processed with ImageMagick and Irfanview.  The assembly was done manually.

100 blog posts assembled into one image


So where to now for the blog?  I'd like to do more video, but that's unlikely at this point, so I'll just keep doing what I'm doing.  Writing for the site is a motivator for me, committing to writing a post every 11 days gives me a reason to learn new things and in general keep busy.  Without it, I don't really have a reason to do half the stuff I do.  The blog also has an ulterior motive, it's a bit of a showcase of my abilities.  For someone with no formal qualifications I need all the help I can get to get a job that doesn't bore me to death.  If need be I can use this to prove I'm not just a pretty face :-).

The main reason I keep blogging, apart from innate curiosity, is the occasional bit of feedback I get from people that tell me my posts have helped them.  It's a good feeling that people all over the world have benefited from my work in some way.