10BitWorks Homepage
 

What it is

History

In April 2011, David Alexander came up with the idea to do a wearable electronic art project for the Luminaria arts festival in downtown San Antonio. He and Jeremy Zunker talked about all sorts of various ways to do it. In fact Jeremy and a few friends kept talking about it and they decided that it was a great idea and do-able project. So Jeremy designed the hardware, and submitted an application (with a bunch of help from Meghan) to Luminaria. The application required a lot of work and included a thorough description of the project and it's design, a detailed budget, supporting artwork, a video and a few other things. It was submitted just before the application deadline on December 9th. The committees were to announce selections on January 6th 2012 but that got delayed until January 24th (We're guessing there were a ton of very good applicants). On January 24th we found out that we were one of about 80 artists selected (we were 1 of 14 in visual arts) to be fully funded and participate in Luminaria 2012.

Background story

Application process

Requirements

Visual Arts Guidelines 2012

The guidelines for the visual artists can be found here at luminariasa.org. In case that link dies, here is the page in PDF as it appeared May 3 2012 at 10:30PM CST

Application

Selection Process

late selection, list steering commitee and other involved in selection process

Out-of-town adjudicators were brought in an effort to "expose the local artists toan influential group of professionals in their own discipline". Unlike a curator, the adjudicators are judging the submitted artist applications for inclusion in the event.

For the Visual Arts discipline, Dean Daderko, curator at the Contemporary Arts Museum Houston (CAMH) chose to include us as 1 of 15 from a pool of 50+ visual arts applications.

The team

Jeremy Zunker - http://zunkworks.com - Project Lead, Hardware designer, Auxiliary embedded software designer, technician

Mike Perez - Primary embedded software designer, webmaster, technician

Greg Bluntzer - http://scriptblocks.com - Primary MCP software designer

Amy Middleton - http://boomyummy.com - Graphic artist

Meghan Regis - Paperwork, design/functionality sanity checks

David Alexander - Instigator, technician

Robert Vidal - technician

Mike Garis - technician

Mike Long - Additional macro development and second set of eyes during code troubleshooting

Chris Hardee - project support

Reception @ Event

Press coverage:

NowcastSA interviewed us live, here's a direct link to the video clip ("Rackspace Installation" live stream @ 2:08:07)

Express news interviewed us and mentioned us in their article Luminaria Lights Up Once Daylight Fades

Our photos of the event we're still in the process of adding more…

Many people had fun interacting with our shirts using the MCP and were either amazed or confused to find out they were all radio-controlled. More often the latter.

Amy wrote up a nice summary of the event/project https://boomyummy.wordpress.com/2012/05/15/bioluminescence/

Design details

Overview Video

T-Shirts

Design

T-shirt design by Amy Middleton

Sketched with pencil on paper, scanned, then drawn with a wacom tablet in photoshop. <more details>

Buy one of these shirts at http://www.10bitworks.com/shop/ !!!

early sketches

Printing

where printed and printing process

Electronics design

Design/selection process

Radio / microprocessor

Initial idea: Freaklabs' Freakduino Chibi which is an aduino + a 2.4GHz 802.15.4 transceiver. We didn't chose this one because it was too expensive (40-50 USD). However it may be a better option if we needed to communicate with more shirts or faster (more LEDs). Searching continued and we found the JeeNode by JeeLabs. It's an arduino + a RFM12B transceiver and costs about 18 USD. It's transceiver isn't as robust and feature filled, but we figured it'd be more than enough for this project.

In discussing our noise/range problems and the idea of building an amplifier, how it was a pretty bad idea in the practical sense, but how having a stronger base station signal was a good idea, the idea of building a higher gain base antenna came up. Specifically building a collinear antenna based on N1HFX's simple "Collinear Antenna from Coax" design.

After assembling the antenna we painted the PVC pipe black and attached an 8.5"x11" 10bitworks sign to the top. With the collinear antenna we were able to extend the range to more than 600 feet, which is fantastic for the JeeNode's max output power of 3.2 mW (5 dBm).

LEDs

data/clock at 3.3v means a 6v power supply will not work, bad signaling

Power source

We considered a number of battery power sources like lithium-ion, lithium-polymer, and standard alkaline. Initailly the most promising was the Deal Extreme SKU 73775 Rechargeable 3-Output Mode 15000mAh Li-ion Emergency Power Battery Model YSD-998. It cost 34.80 USD and would provide 15000mAh @ 5V, this would give us a very long run time even if we have high current high duty cycle loads. The build quality of the YSD-998 aka 73775 is decent see tear down pictures. There are a few problems with using the YSD-998, first it's pretty big, and fairly heavy, so it wouldn't be easy to wear or carry. Another and probably the biggest problem is that the long lead time on deal extreme orders. We would not be able to order and receive them in time, especially since the artist selection announcement was delayed by a few weeks. So we had to find an alternate power supply.

Next we considered standard alkaline batteries, they're fairly cheap and readily available. The drawback to using standard alkaline batteries is that they don't work well with the high current pulsed load that a bunch of flashing LEDs would produce. Calculations showed that C or D cell alkaline batteries might work but would cost about as much as the Deal Extreme pack when you considered the number of battery changes needed.

A friend suggested we look at the Energizer Lithium batteries. They're not cheap, but they do have high capacity and handle high current pulsed load very well. They only come in AAA and AA sizes. According to calculations we might need 3 battery changes per shirt.

After reading lots of battery datasheets and making large complicated spreadsheets for battery run time calculations I realized that one of the most important numbers was the load profile of the LEDs and associated electronics. If I underestimated we wouldn't have enough batteries, and if I over estimated we'd end up buying too many batteries. Trying to guestimate a load profile and it's effects on various batteries of various chemistries is very hard if not impossible, so I decided to actually hook up a set of LEDs and JeeNode to different battery packs and test to see how long it would run on each type of battery. So during Christmas holiday I bought some D and C cell alkaline batteries and a set of AA Energizer Lithium batteries. I then wrote some code that would flash various LED control patterns to simulate the kind of load profile the batteries would see during Luminaria. The first test was 3 x AA energizer lithium batteries. Every so often I would measure and log the battery voltage and elapsed time. The LEDs ended up running about 13 hours on just one set of 3 x AA Energizer Lithium batteries! With these results and after doing another cost comparison it would also be cheaper to use these AA batteries, additionally these batteries were much smaller which would help keep the electronics package much smaller. So without testing the alkaline batteries it was decided that the AA Energizer Lithium batteries were the best option.

Lots of Energizer Lithium Ultimate batteries

Case/switches/misc.

took a while to find a cheap and decent case, and switches

Schematics

Assembly

Bill of Material

PartPart no.DescriptionSupplierQty.UnitPer UnitExtendedShippingTaxTotal
LED pixel Addressable LED Do not use Bliptronics 264 unit $1.79 $472.03 $48.64 $0.00 $520.67
JeeNode v6 kit JL0016 5-pack uC + Radio module (434MHz) ModernDevice 25-pack $82.00 $164.00 $25.51 $0.00 $189.51
4 conductor 22 AWG Wire Do not use Bliptronics 50 meter $1.48 $74.00 $13.83 $0.00 $87.83
Batteries 3 36 pack $58.96 $176.88 $0.00 $0.00 $176.88
Case 563-CU-3242ABS enclosure Mouser Electronics 10 unit $4.52 $45.20 $4.11 $4.07 $53.37
Push Button Switches 107-N-RBB N/O Mouser Electronics 25 unit $0.91 $22.75 $2.07 $2.05 $26.86
Toggle Switches 108-0001-EVX SPST OFF-ON Mouser Electronics 25 unit $1.70 $42.50 $3.86 $3.82 $50.19
Battery holders 1BH331D-GR 3-AA Batteryholder w/tabs Mouser Electronics 10 unit $1.02 $10.20 $0.93 $0.92 $12.04
Double sided foam tape roll $0.00 $0.00 $0.00 $0.00 $0.00
3/4" PVC pipe unit $0.00 $0.00 $0.00 $0.00 $0.00
3/4" PVC pipe fitting 90deg unit $0.00 $0.00 $0.00 $0.00 $0.00
3/4" PVC pipe fitting T unit $0.00 $0.00 $0.00 $0.00 $0.00
3/4" PVC pipe fitting cap unit $0.00 $0.00 $0.00 $0.00 $0.00
Black spray paint unit $0.00 $0.00 $0.00 $0.00 $0.00
Fabric glue unit $0.00 $0.00 $0.00 $0.00 $0.00
Wax paper unit $0.00 $0.00 $0.00 $0.00 $0.00
Masking tape roll $0.00 $0.00 $0.00 $0.00 $0.00
Solder Pot Refurbished Hakko 96-1/96-1E-V12 Ebay (athomemarket)1 unit $162.99 $162.99 $0.00 $11.82 $174.81
Solder Bar KB-200Ultra Pure Solder, 1-2/3 lb Bar, Sn63Pb37All-Spec Industries 2 unit $23.59 $47.18 $10.91 $0.00 $58.09
Solder Flux MG-835-100ML MG solder flux Intertex Electronics1 unit $7.95 $7.95 $0.00 $0.64 $8.59
Heat shrink tubing Altex 4 ft $0.00 $0.00 $0.00 $0.00 $0.00
1/8" Heat shrink tubing HST-1/8-CL Intertex Electronics4 4 ft $1.25 $5.00 $0.00 $0.41 $5.41
Hot melt glue $0.00 $0.00 $0.00 $0.00 $0.00
Quick Disconnect CON-4404-Conductor locking connectors w/leads www.allelectronics.com12 unit $1.85 $22.20 $7.00 $0.00 $29.20
Hanes Crew Shirts 040020724plain white Ts to make LED pockets Target 1 5 pack $13.49 $13.49 $0.00 $1.11 $14.60
Screen printed shirts 44 unit $5.43 $238.92 $59.79 $0.00 $298.71
Artist Fee 1 unit $250.00 $250.00 $0.00 $0.00 $250.00
$0.00 $0.00 $0.00 $0.00 $0.00
$0.00 $0.00 $0.00 $0.00 $0.00

= Assembly Tasks =

  Cutting wire to proper length
  stripping insulation
  tinning wires
  soldering wires
  inspection, testing and fixing assemblies
  hot gluing assemblies
  cutting heat shrink
  heat shrinking assemblies
  re-testing assemblies
  cutting patches for shirts
  gluing patches to shirts
  
  drilling cases
  integrating switches and battery holder into case
  integrating JeeNode and packing case with 

Shirt integration

paper cutter shortcut, fabric glue The LED strands were attached to the shirts using rectangular cloth patches cut from t-shirts.

We used pieces of cardboard to help stabilize the shirt and make gluing easier. This worked pretty well on the first side of the first shirt, but the second shirt didn't fare so well.

When we removed the cardboard from the second shirt after the glue had dried, the cardboard stuck to the shirt.

We solved the gluing shirts to cardboard problem by covering the cardboard with wax paper.

We used a couple quartz flood lights to help accelerate the glue drying process. It dropped the drying time from several hours to approximately a half hour.

We initially cut the patches out using cloth scissors, this was very time consuming and produced patches that were not consistent. On about the 3rd or 4th shirt we came up with the idea of using a paper cutter to cut the squares. With the paper cutter we were able to cut out a couple hundred uniform squares in 30 to 45 min.

Problems and solutions

Soldering

To help with soldering we purchased a refurbished Hakko 96-1 solder pot. We used it to tin the ~2000 wires before we soldered them to the LEDs and other components. Using the solder pot and with solder flux really made the soldering much easier. It also helped make clean and neat solder joints which reduced the number of problems that we had to troubleshoot.

This video shows the rough procedure we used to tin all of the wires. It also shows thermal expansion of metal. Please note that we did not dip the wires into the bottle of solder all the time, instead we poured a very small amount into a bottle cap and dipped the exposed wire into that. Without the flux tinning would have been very difficult. The Hakko 96-1 was filled with 1 2/3 lbs (756 g) of Kester KB200 Ultra Pure Solder (Sn63Pb37).

Problems and solutions

initial development strands were made by just soldering the LEDs together using the 4 conductor wire. After some time the wire would bend enough that individual strands of wire would start breaking. These would occasionally short causing strange LED behavior. After enough time all of the strands in a wires would completely break and this would cause some additional strange behavior. These "little" problems caused major headaches when we were trying to debug the software. We couldn't easily tell if the problem was software or if it was hardware so we decided to rebuild the dev strands. To quickly solve the problem we rebuilt the dev strands. The first dev strand was rebuilt using header pins instead of wire to solder the LEDs together. This resulted in a pretty rigid line of LEDs that were free from shorts/opens and could be easily verified. We attached the whole strand to a piece of scrap wood to reinforce the LEDs. The second strand we built to develop the construction techniques used on the strands for the t-shirts.

{{:img_6298.jpg?200|}}

Slightly off topic, but we did play with taking long exposure photos while waving the dev strand attached to the board.

We had one other interesting short. After adding the hot glue and heat shrink to a strand we tested it and it failed for all LEDs down line from the eighteenth LED. We thought there was a short or maybe there was a cold solder joint or something. After removing the heat shrink and hot glue from several LEDs we found the culprit. There was a very tiny particle of solder between one of the vias and the yellow wire which was shorting out the control signals for all the LEDs downline from number eighteen.

Very tiny particle of solder stuck in hot glue.

Another type of short also caused a bit of head scratching. Early on when devloping version one of the second dev strand, we noticed that it didn't quite work right when plugged in. After plugging into a USB wall power supply (and killing it) I hooked it up to my 35 A bench supply and noticed the strand was pulling around 6 A! After thouroughly checking the wiring and confirming it was correct and there were no shorts, we found that the LED wasn't soldered properly to the circuit board and was bridging several contacts namely the power and ground lines.

LED soldering fail, causing a short between the power and ground lines.

Shipment of bad pixels from bliptronics, terrible support, ignored email, quick to help get your money. Had to spend a lot of time modifying code and the colors are off since the chip and other board components compensate for LED brightness differences. When we started the development I ordered 60 LED pixels, since we didn't know how many shirts we were going to make or if the LEDs were even compatible with the JeeNodes. It turns out they were compatible and that we were going to need 240 pixels and a few extras just incase… So we placed a rush order for 260 pixels from Bliptronics. There were some issues with the order initially and Ben Moyes was very quick to respond and help get the order placed. When the LED modules came in I added them to the end of one of the early development strands since it was only 16 pixels long. When we ran some of the demo patterns the new LEDs didn't behave correctly so we suspected it was in issue with our construction (short, open, misconnected wire or something else). I triple checked the construction and even donned the magnifying headset. So then I started looking at the construction differences between the two and found that the manufacturer had mounted the RGB LED upside down! Ok, I thought, maybe this is a fluke… I checked every one of the 260 pixels and every single one of them was mounted upside down!

LED Mounted properly LED mounted upside down

So on February 4th I sent bliptronics/Ben Moyes an email detailing the problem and asking if there was any way to get a corrected shipment sent ASAP so that we could avoid having to make a bunch of code changes… 4 days go by without response so I resend my email and ask if he had any plans on helping us out with our 520 USD LED purchase problems… We've never gotten any sort of response from Bliptronics/Ben Moyes about the bad LED modules. So if you need to buy LED modules don't buy them from Bliptronics / Ben Moyes, if there's anything wrong with your order be prepared to get shafted. You're probably better off purchasing from someone else (Adafruit perhaps?). We probably would have been better off purchasing directly from China, at least in that case we could have gotten the LEDs at a lower cost… So fuck you Bliptronics / Ben Moyes for terrible customer service, you didn't even acknowledge the complaint, WTF… If you've had trouble with Bliptronics / Ben Moyes, please contact Consumer Affairs Victoria, Australia (it's where Bliptronics is registered) via http://www.consumer.vic.gov.au/contact-us/make-a-complaint, click the link General complaint (online) under the section General consumer issues. I'm not sure they'll act based on complaints made by foreigners but it certainly wouldn't hurt to let them know about this guy and his terrible business practices/assholery.

Here is the information about Ben Moyes / Bliptronics that you will need to file a complaint (click to enlarge):

I think next time we purchase a large number of LEDs we'll order straight from Taiwan or China and avoid the middle man. Worst case the parts are bad, you send them back and get your money back as companies like AliExpress hold the money in escrow. Even if that didn't work out it would definitely be better than dealing with Bliptronics / Ben Moyes.

Radio Interference at 433MHz

What if radio didn't work due to onsite interference or some other problem – enter the radio/autonomous switch and the A and B buttons.

We could tell that there was some kind of problem with the whole rig, as some of the strands would intermittently not respond to a packet in a long series of packets. Further investigation led to the discovery that the LED modules were emitting a bunch of RF noise right around the same frequencies that the radios are using (~433MHz). We had a few ideas like wrapping the LED wire through a ferrite bead to form an RF choke, possibly building one or more low pass filters using simple RC filters, or maybe even building an RF amplifier for the base JeeNode. We were also concerned that the noise problem would be even worse when all 8 shirts were running at once… We eventually solved the problem by building a 6dB collinear antenna for the base station JeeNode (see the above design discussion).

Software design

Source Code

Embedded/JeeNode software

Had to find a 6803 library that worked with the JeeNode radio library, ended up using adafruit's.

Firefly function

Clock sync function

All the shirts start by blinking randomly and out of sync. Each time a shirt turns on its LEDs, it broadcasts a packet and then starts listening for other packets. Each shirt counts and measures the average time it received each of the packets. after the end of a cycle it uses this data to determine how much it needs to temporarily adjust it's own clock. It makes the adjustment and repeats the cycle. As each shirt does this listening and adjusting after a little bit of time all of the shirts end up flashing in sync.

Adhoc mode

Master Control Program design

Notes and references

External links

---------------

LED placement on shirt

Sequence

Wire cutting lengths

Quantities listed are for 7 shirts

length using 1:20 scale Quantity
2.5 7
4 14
4.5 7
5 7
5.5 7
6.5 14
7 35
7.5 21
8 7
8.5 14
9 14
10 14
10.5 7
11 7
12 7
12.5 7
14 7

JeeNodes and Radios

JeeNode Connections

Buttons on-board JeeNodes

Autonomous mode function

Autonomous mode will be used when radio communications aren't working well or when we want to give the appearance of very complex algorithms/systems like flashing the lights to music. Or if we implement any mesh type algorithms. Our autonomous mode (i.e. shirt does not accept radio commands only local button presses) will be something like this:

  • T - toggle switch
  • A - push button switch
  • B - push button switch
  • – T is toggle switch for entering and leaving autonomous mode
  • – In autonomous mode
    • – the pattern running prior to switching to autonomous will continue to run
    • – A or B buttons flash the running pattern
    • – pressing A and B together enters a pattern selection menu
    • – the number of LEDs turned on will indicate the pattern to be selected
    • – A will increment the pattern selection
    • – B will decrement the pattern selection
    • – pressing A and B again will exit the menu and begin running the selected pattern
    • – N.B. some patterns expect extra parameters such as buffers of pixel colors or LEDs in a certain sequence. In autonomous mode, these patterns will instead use data in pre-programmed buffers.
  • – In radio mode
    • – A will speed up the running pattern
    • – B will slow down the running pattern
    • – the speed will be persistent across radio transmissions
    • – the speed can be reset by pressing both A and B buttons

Power

PROGRAMERZ NOTES

#define PATTERN_OFF 0 #define PATTERN_WHITE 1 #define PATTERN_WIPE_BLUE 2 #define PATTERN_WIPE_GREEN 3 #define PATTERN_WIPE_RED 4 #define PATTERN_RAINBOW 5 #define PATTERN_RAINBOW_CYCLE 6 #define PATTERN_TWINKLE 7

*Proposed change Jan 29 2012 mperez* Command to JeeNode over serial comms <pp>,<nn>z - Will set the LEDs at node <nn> (0-30) to run pattern <pp> (0-99)

If <nn> = 0 then it is a broadcast and all nodes will be set to run the pattern <pp> if <pp> = 0 then all LEDs will be turned off on at node <nn> JeeNodes only support node ID values from 0 to 31. 31 is a special case for broadcasting across netGroups (1-212). 0 is a special case to broadcast withing the originating node’s netGroup.

My arduino sketch will anticipate a byte, a char (the comma), another byte, and will ignore spaces until it reads the char ‘z’ or any other command (see RF12demo sketch).

Rationale: Instead of passing huge LED color arrays to base JeeNode for processing and then on to slave nodes over the air, this provides a minimal payload to maximize idle time of Rx/Tx ops and save power. With over 100 pattern codes available this should be adequate for the target event.

<pp>, <ss>, <aa>, [<aa>,<aa>,…], <nn>z

where pp=pattern
ss=array size
aa=0-32 color value
nn=shirt

mperez***

–PATTERN 0=OFF 1=INDIVIDUAL COLOR PER LED [R[32],G[32],B[32]]*30LED 2=TWINKLE 3=HIDE AND SEEK 4=INDIVIDUAL LARSON *5=COLOR WIPE *6=RAINBOW *7=RAINBOW CYCLE 8=DISCO –SHIRT 0=ALL

1=SHIRT NODE ID 1

–LED ARRAY –SUFFIX z

Examples: ALL Shirts OFF “0,0z”

ALL SHIRTS TWINKLE “0,2z”

—————–ARDUINO SKETCH———————– /* Test Code to Test Talking to Arduino over Serial Port

Based on Serial Event example http://www.arduino.cc/en/Tutorial/SerialEvent

*/

String inputString = ""; a string to hold incoming data boolean stringComplete = false; whether the string is complete const String RED = "1"; const String GREEN = "2"; const String YELLOW = "3"; const String P1= "4"; const String OFF= "0"; boolean playPattern = false;

void setup() {

// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
pinMode(13, OUTPUT); //RED
pinMode(12, OUTPUT); //GREEN
pinMode(11, OUTPUT); //YELLOW

}

void loop() {

// print the string when a newline arrives:
if (stringComplete) {
  Serial.println(inputString); 
  // clear the string:
  int commaIndex = inputString.indexOf(',');
  int patternIndex = inputString.indexOf( 'z' );
  String shirt = inputString.substring(0,commaIndex);
  String pattern = inputString.substring(commaIndex+1,patternIndex );
  Serial.println("shirt" + shirt);
  Serial.println("pattern" + pattern);
  if(RED.equals(pattern)){
    setRed();
  }else if(GREEN.equals(pattern)){
    setGreen();
  }else if(YELLOW.equals(pattern)){
    setYellow();
  }else if(P1.equals(pattern)){
    playPattern = true;
  }else if(OFF.equals(pattern)){
    setOff();
  }else {
    Serial.println("UNKNOWN"+inputString+"XXX"); 
  }
  
  inputString = "";
  stringComplete = false;
}
if(playPattern){ 
 patternOne();
}

}

void setRed(){

digitalWrite(13, HIGH);   // set the LED on
digitalWrite(12, LOW);
digitalWrite(11, LOW);
playPattern = false;
Serial.println("setRed");

}

void setGreen(){

digitalWrite(13, LOW);   // set the LED on
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
playPattern = false;
Serial.println("setGreen");

}

void patternOne(){

digitalWrite(13, HIGH);  
delay(100);
digitalWrite(13, LOW); 
digitalWrite(12, HIGH);
delay(100);
digitalWrite(12, LOW); 
digitalWrite(11, HIGH);
delay(100);
digitalWrite(11, LOW); 

}

void setYellow(){

digitalWrite(13, LOW);   // set the LED on
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
playPattern = false;
Serial.println("setYellow");

} void setOff(){

digitalWrite(13, LOW);   // set the LED on
digitalWrite(12, LOW);
digitalWrite(11, LOW);
playPattern = false;
Serial.println("setOff");

} /*

SerialEvent occurs whenever a new data comes in the

hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available. */ void serialEvent() {

while (Serial.available()) {
  // get the new byte:
  char inChar = (char)Serial.read(); 
  // add it to the inputString:
  inputString += inChar;
  // if the incoming character is a newline, set a flag
  // so the main loop can do something about it:
  if (inChar == 'z') {
    stringComplete = true;
  } 
}

}

—————–Running on Windows—————————- I unzipped the zip file I copied the lib folder from arduino dist I copied all the dll from the arduino directory into the lib folder as well

Made a bat file and put it in the unzipped folder. Note I used the java that came with arudino to run it needs to be 32 bit one. C:Usersgbluntzertoolsarduino-1.0-windowsarduino-1.0javabinjava -classpath .lib*; -Djava.library.path=".lib;%PATH%" org.twobitworks.luminaria.Main

ledshirts.txt · Last modified: 2012/12/06 01:45 by zunkworks
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki