Installing Laravel 4 on WAMP

I like developing my websites locally before I put them live. Since I’m on a Windows machine, I use WAMP (Windows Apache MySQL PHP). To install the Laravel 4 framework on WAMP, I took the steps outlined below. Ajust the values and version numbers to match your particular situation.

This was tested with WampServer 2.4.

Enable OpenSSL

OpenSSL must be enabled in the PHP configuration.

  1. Edit php.ini in your WAMP’s PHP folder, e.g.:

    C:\wamp\bin\php\php5.4.12\
    

    Note: This is not the php.ini in C:\wamp\bin\apache\Apache2.4.4\bin.

  2. Find the following line:

    ;extension=php_openssl.dll
    
  3. Remove the leading semi-colon:

    extension=php_openssl.dll
    
  4. Save php.ini.

Install Composer

Now we need to install Composer. This is a dependency manager that will download the latest release of Laravel and specific versions of Laravel’s dependencies, such as Doctrine and Symfony.

  1. Download the Composer Windows installer from getcomposer.org.

  2. Run the installer.

  3. When it asks for the location of php.exe, point it to the executable in your WAMP’s PHP folder, e.g.:

    C:\wamp\bin\php\php5.4.12\
    
  4. Finish the installation.

  5. Open a command-line interface (cmd) and type:

    composer
    

    It should return a list of options. If you get an error, restart your computer and try again.

Composer has now been installed and added to your PATH environment variable. This means you can run it from any directory using the command-line interface.

Install Laravel

Now that Composer has been installed, Composer can download and install Laravel onto your system.

  1. Open a command-line interface (cmd).
  2. Go to the directory in which you want to install Laravel. This is usually your development directory. In this tutorial, we’ll use C:\Users\Me\Documents.

    cd C:\Users\Me\Documents
    
  3. Instruct Composer to install Laravel into a project directory. In this tutorial we use the project name myproject.

    composer create-project laravel/laravel myproject --prefer-dist
    

    Note: This will install Laravel in a subdirectory myproject of the current working directory.

Add a virtual host

Finally, we need to create a virtual host to point Apache to our new Laravel installation.

  1. Go to the directory of your hosts file:

    C:\Windows\System32\drivers\etc
    
  2. In this tutorial we’ll bind the website to http://myproject.dev/. Edit the hosts file to add the following line:

    127.0.0.1 myproject.dev
    

    Note: Try running Notepad as Administrator to edit the hosts file; or copy it somewhere else, edit it, and copy it back.

  3. Edit httpd.conf from this directory:

    C:\wamp\bin\apache\Apache2.4.4\conf
    
  4. Find these lines:

    # Virtual hosts
    #Include conf/extra/httpd-vhosts.conf
    
  5. Remove the leading hash sign from the Include line, and save the file:

    # Virtual hosts
    Include conf/extra/httpd-vhosts.conf
    
  6. Edit httpd-vhosts.conf from this subdirectory:

    C:\wamp\bin\apache\Apache2.4.4\conf\extra
    
  7. Add the following just after the big block of comments in the file:

    <Directory "C:/Users/Me/Documents/">
        AllowOverride All
        Order Deny,Allow
        Allow from all
    </Directory>
    

    Note: The slashes in the path are forward slashes.

    Note: The path is a parent directory of your website.

  8. Add the following to the end of the file, and save it:

    <VirtualHost *:80>
        DocumentRoot "C:\Users\Me\Documents\myproject\public"
        ServerName myproject.dev
    </VirtualHost>
    

    Note: There might be dummy entries in the httpd-vhosts.conf file. You can safely remove them.

    Note: The document root is the website’s public directory.

  9. Click the WAMP tray icon to open its menu.

  10. Click Restart all services.

  11. Go to your local site in your browser, e.g.:

    http://myproject.dev/
    

    You should see the Laravel 4 welcome page: You have arrived.

Installing SEUS shaders mod in Minecraft 1.7.2

Once you’ve seen a peek of Sonic Ether’s Unbelievable Shaders mod, you’ll want nothing else.

Here’s a video of Captain Sparklez demonstrating the mod:

Here I’ll provide a step-by-step guide to installing the SEUS shaders and GLSL shaders mods in Minecraft 1.7.2. I assume you know your way around a computer, are working on Windows, and know how to find the Minecraft folder %appdata%\.minecraft. Let’s begin!

A quick note: Some people have issues where Minecraft crashes after following these instructions. This may happen to you regardless of how old or new your computer or graphics card is, and I’m not sure why. For example, I was able to execute these instructions successfully on one laptop, but Minecraft crashed on another very similar laptop.

Forge

First we’ll have to install Forge into Minecraft. This allows other mods to integrate more easily with Minecraft.

Minecraft 7.2 - Mods button

  1. Launch the Minecraft Launcher.
  2. Add or change a profile and set it to load Minecraft 1.7.2.
  3. Save the profile, and click Play to start Minecraft using that profile.
  4. Exit Minecraft and the Minecraft Launcher.
  5. Download the 1.7.2-Recommended Minecraft Forge Windows Installer.
  6. Run the installer.
  7. Choose Install client and click OK to begin the installation.
  8. Finish the installation.
  9. Launch the Minecraft Launcher.
  10. Select the Forge profile and click Play to start Minecraft with Forge.
  11. Verify that the Mods button is present in the menu under the Multiplayer button.
  12. When you click it, you should see three mods already installed.
  13. Exit Minecraft.
  14. (Optional) You may delete the 1.7.2 profile you made in step 2.

SEUS and shaders mod

The shaders mod allows the installation of all kinds of fancy shaders for Minecraft. SEUS is one such shader that provides the fancy graphics.

Minecraft 7.2 - Shaders button

  1. Download ShadersModCore.jar.
  2. Copy the downloaded .jar-file into the %appdata%\.minecraft\mods folder.
  3. Launch the Minecraft Launcher.
  4. Select the Forge profile and click Play to start Minecraft with Forge.
  5. Click the Options... menu button, then Shaders.... > If you don’t see the Shaders... button, be sure to use the vanilla Minecraft Launcher and not some other launcher such as Magic Launcher. Also double-check that you’ve selected the Forge profile.
  6. Click the Open shaderpacks folder button.
  7. Download SEUS v10.1.
  8. Copy the downloaded .zip-file into the %appdata%\.minecraft\shaderpacks folder. Don’t extract it!
  9. In Minecraft, click on seus-v10.1-Preview2.zip to select it as the shader pack.
  10. Set Cloud shadow to false.
  11. Click Done.
  12. Click Video Settings..., then set Clouds: OFF.
  13. Click Done, and Done again.
  14. You’re now ready to play! Start Minecraft with the Forge profile in the future.

Some people report error messages such as [Shaders] Error: Invalid program gbuffers_weather. In my case the shaders mod still worked perfectly (as far as I could tell), and the second time I ran Minecraft the errors did not appear. If you have errors and it stops the mod from working correctly, try searching the Sonic Ether’s Unbelievable Shaders forum for a solution.

Redesigning Arrays in C#/.Net, Part 4: Adding Contains()

Since the last time we have a covariant and a contravariant array interface:

public interface IReadOnlyArray<out T>
{
    T this[int index]
    { get; }
}

public interface IWriteOnlyArray<in T>
{
    T this[int index]
    { set; }
}

And one invariant interface that combines them both:

public interface IArray<T>
    : IReadOnlyArray<T>, IWriteOnlyArray<T>
{ }

The Contravariant Contains() Method

The Contains() method is very common on collections to determine whether it contains a certain element. Its signature is:

bool Contains(T value);

Between IReadOnlyArray<T> and IWriteOnlyArray<T>, to which interface can we add this method? Only the contravariant IWriteOnlyArray<T> interface, as the Contains() method has T on an input position.

public interface IWriteOnlyArray<in T>
{
    T this[int index]
    { set; }

    bool Contains(T value);
}

Does this make any sense? Let’s see… You can pass Contains() an object of type T or any type derived from T. This seems to be okay, since I want to be able to test whether my array of Animal contains an Elephant.

But why is this on the write-only interface? First of all, asking whether the array contains a specific element is kind of reading the array, which is definitely not something a write-only interface should allow. On the other hand, anyone that uses the read-only interface has no way to determine whether the array contains a specific element. We really need to move Contains to IReadOnlyArray<T>.

The New Contains() Method

Simply putting the Contains() method on IReadOnlyArray<T> will give a compile-time error.

public interface IReadOnlyArray<out T>
{
    T this[int index]
    { get; }

    bool Contains(T value);
}

Invalid variance: The type parameter ‘T’ must be contravariantly valid on ‘IReadOnlyArray.Contains(T)’. ‘T’ is covariant.

But we really want this method on this interface. What can we do?

Well, we can remove the T from the method’s signature. But what will we put in T‘s place?

Since our interface must work for any T, we need a type that is a base class to all T. Something like… Object. That should work:

public interface IReadOnlyArray<out T>
{
    T this[int index]
    { get; }

    bool Contains(object value);
}

That takes care of the issue. It all compiles fine now. But does it make sense? I can call Contains() now with literally any object of any type I want. What if I ask whether the array of Animal objects contains a particular Knife?

Well, what if I give you a bag and I say it contains Animal toys. Then an acquaintance comes along and asks: “Hey, does that bag contain a Knife?” What do you do? Do you freak out, throwing an exception? Nah, don’t think so. You’ll simply reply, without looking in the bag: “No, the bag does not contain a Knife.”

So that’s what we’ll do here:

public sealed class Array<T>
    : IArray<T>
{
    private readonly T[] innerArray;

    // ...

    public bool Contains(object value)
    {
        if (value is T)
        {
            return this.innerArray.Contains((T)value);
        }
        else
        {
            return false;
        }
    }
}

Type Checking

The only ‘downside’ to this is that you won’t get a compiler error when you ask whether an array of Animal contains a Knife. Instead, you’ll just get false.

If you really want that compile-time type check, then you can implement IReadOnlyArray.Contains() explicitly, and provide another overload that accepts only T:

public sealed class Array<T>
    : IArray<T>
{
    private readonly T[] innerArray;

    // ...

    public bool Contains(T value)
    {
        return this.innerArray.Contains((T)value);
    }

    bool IReadOnlyArray<T>.Contains(object value)
    {
        if (value is T)
        {
            return Contains((T)value);
        }
        else
        {
            return false;
        }
    }
}

Next time we’ll look at other collection interfaces that any array should implement: IEnumerable, ICollection and IList.

Redesigning Arrays in C#/.Net, Part 3: Combining Covariance and Contravariance

In the first part we created a covariant array interface:

public interface IArray<out T>
{
    T this[int index]
    { get; }        // NOTE: No setter
}

In the second part we created a contravariant array interface:

public interface IArray<in T>
{
    T this[int index]
    { set; }        // NOTE: No getter
}

Now we’re going to take a look at our options when we want to combine the two.

One Interface to Rule Them All

When generic type parameter T is covariant, the set of types we can use instead of T is: T or any base type of T. When T is contravariant, the set is: T or any more derived type of T.

// Covariance
IEnumerable<Elephant> elephants = ...;
IEnumerable<Animal> animals = elephants;

// Contravariance
IEqualityComparer<Animal> animalComparer = ...;
IEqualityComparer<Elephant> elephantComparer = animalComparer;

So, if we would want T to be both covariant and contravariant at the same time, then what types can we use instead of T? Well, the only member common to both the covariant and the contravariant set of allowed types is T itself.

Our interface would be restricted to using only exactly T as specified; the interface would have become invariant:”

public interface IArray<T>  // NOTE: No 'in' or 'out'
{
    T this[int index]
    { get; set; }
}

While this would work perfectly fine, we can no longer treat an array of Elephant as an array of Animal (covariance) or the other way around (contravariance).

IArray<Elephant> elephants = ...;
IArray<Animal> animals = elephants; // Not allowed

Can we do better?

Two Separate Interfaces

We could create two separate interfaces. One for those consumers that only want to read from the array, and one for those consumers that only want to write to the array.

public interface IReadOnlyArray<out T>
{
    T this[int index]
    { get; }
}

public interface IWriteOnlyArray<in T>
{
    T this[int index]
    { set; }
}

Our Array<T> class would then implement both:

public sealed class Array<T>
    : IReadOnlyArray<T>, IWriteOnlyArray<T>
{
    private readonly T[] innerArray;

    public Array(int length)
    {
        this.innerArray = new T[length];
    }

    public T this[int index]
    {
        get { return this.innerArray[index]; }
        set { this.innerArray[index] = value; }
    }
}

Now we can do this:

Array<Mammal> mammals = new Array<Mammal>(8);

// Covariance
IReadOnlyArray<Animal> animals = mammals;
Animal firstAnimal = animals[0];

// Contravariance
IWriteOnlyArray<Elephant> elephants = mammals;
elephants[0] = new Elephant();

And to have both read and write capabilities, you’d simply stick to Array<T>. Or add an invariant interface IArray<T> that extends both variant interfaces:

public interface IArray<T>
    : IReadOnlyArray<T>, IWriteOnlyArray<T>
{ }

Next time we’ll look at how we can add the Contains() method to our array interfaces.

Redesigning Arrays in C#/.Net, Part 2: Contravariance

Last time we saw how we can create an interface IArray<out T> with covariant generic type parameter T for arrays. The caveat is that such an interface must be read-only. This is what we ended up with:

public interface IArray<out T>
{
    T this[int index]
    { get; }        // NOTE: No setter
}

public sealed class Array<T>
    : IArray<T>
{
    private readonly T[] innerArray;

    public Array(int length)
    {
        this.innerArray = new T[length];
    }

    public T this[int index]
    {
        get { return this.innerArray[index]; }
        set { this.innerArray[index] = value; }
    }
}

And we got array covariance:

IArray<Elephant> elephants = new Array<Elephant>(8);
IArray<Animal> animals = elephants;
Animal firstAnimal = animals[0];

Contravariance

Contravariance is the opposite of covariance. It allows you to use T or a more derived type of T. For example, an equality comparer that can compare animals should be able to compare elephants, right?

IEqualityComparer<Animal> animalComparer = EqualityComparer<Animal>.Default;
IEqualityComparer<Elephant> elephantComparer = animalComparer;

Here the IEqualityComparer<in T> interface has a generic type parameter T which is contravariant (denoted by the in keyword). And this works beautifully.

In the context of arrays, you can imagine that when you have an array of Animal then you should be able to set an element to an Elephant. So, perhaps you could use array contravariance to do something like this:

Animal[] animals = new Animal[8];
Elephant[] elephants = animals;
elephants[0] = new Elephant();

In theory, there is no reason this code should not do exactly what you’d expect it to do. However, arrays in C# are not contravariant, so you can’t specify an array of Animal where an array of Elephant is expected.

Can we make our IArray<T> interface contravariant?

Desiging a Contravariant Array Interface

Let’s start with the obvious interface again, but this time with an in T generic type parameter:

public interface IArray<in T>
{
    T this[int index]
    { get; set; }
}

Again, the compiler refuses our code:

Invalid variance: The type parameter ‘T’ must be invariantly valid on ‘IArray.this[int]‘. ‘T’ is contravariant.

This time T may only appear on input positions (i.e. as method parameters), hence the in keyword. So, we really have to remove the indexed getter which returns a value of T.

public interface IArray<in T>
{
    T this[int index]
    { set; }
}

That leaves us with only the mutating part of the interface. In general, any collection interface must be write-only if we want to have contravariant generic type parameters.

Now everything compiles, and we can do stuff like this:

IArray<Animal> animals = new Array<Animal>(8);
IArray<Elephant> elephants = animals;
elephants[0] = new Elephant();

This is useful, for example, when a method wants an array of Elephant to modify, then you can simply pass it an array of Animal.

Next time we’ll look at ways by which we can combine our covariant and contravariant array interfaces.

Redesigning Arrays in C#/.Net, Part 1: Covariance

In this series I want to explore covariance and contravariance in the context of arrays. If generics had existed way back when C# arrays were designed, how could arrays have been designed?

Broken Array Covariance

Arrays in Java and C# are covariant. Since Elephant extends Animal, it is perfectly legal to do this:

Elephant[] elephants = new Elephant[8];
Animal[] animals = elephants;
Animal firstAnimal = animals[0];

Treating Elephant[] as Animal[] is covariance. After all, you can treat any array of elephants as an array of animals. Or can you?

As Giraffe also extends Animal, the following code won’t raise any compiler errors:

Elephant[] elephants = new Elephant[8];
Animal[] animals = elephants;
animals[0] = new Giraffe();         // ArrayTypeMismatchException

However, at run-time it throws this exception:

ArrayTypeMismatchException: Attempted to access an element as a type incompatible with the array.

Array covariance was copied from Java and added to C# before generics existed, and it is broken. Eric Lippert discusses array covariance in more detail, and Jon Skeet shows how array covariance makes arrays slower.

Generics to the Rescue

Since C# 4, the language supports covariant and contravariant generic type parameters on interfaces. This allows us to do things like:

IEnumerable<Elephant> elephants = new Elephant[8];
IEnumerable<Animal> animals = elephants;
IEnumerable<Object> objects = animals;

Here the IEnumerable<out T> interface has a generic type parameter T which is covariant (denoted by the out keyword). When T is a reference type, it can be cast to any base type of T, since a sequence of elephants is also a sequence of animals, which is also a sequence of objects.

Perhaps if generics has existed when C# 1 was released, array covariance wouldn’t be broken. Let’s try to recreate that situation using C# 4 generics.

Designing a Covariant Array Interface

Only generic type parameters on interfaces can be variant, so we need to create an interface. Since an array’s indexed getter and setter are the most important, we add those while we’re at it:

public interface IArray<out T>
{
    T this[int index]
    { get; set; }
} 

Just to be complete, we need an actual class that implements this interface:

public sealed class Array<T>
    : IArray<T>
{
    private readonly T[] innerArray;

    public Array(int length)
    {
        this.innerArray = new T[length];
    }

    public T this[int index]
    {
        get { return this.innerArray[index]; }
        set { this.innerArray[index] = value; }
    }
}

The above code doesn’t compile, but if it did, we could do stuff like this:

IArray<Elephant> elephants = new Array<Elephant>(8);
IArray<Animal> animals = elephants;
animals[0] = new Giraffe();         // This shouldn't be possible

Uh oh, same problem! We’re assigning a Giraffe to an array of Elephant, but the type checker would simply assume it is legal to set a Giraffe in an IArray<Animal>, so no compile-time error there.

But in reality the compiler wouldn’t even allow us to have an indexed setter T this[int index] { set; } on the IArray<Animal> interface. Why not?

Invalid variance: The type parameter ‘T’ must be invariantly valid on ‘IArray.this[int]‘. ‘T’ is covariant.

Fixing the Interface

Covariant type parameters can only appear in output positions (hence the out keyword). That is, as the return type of a method. The hidden signature of the setter would be:

void set_Item(int index, T value);

Note that T appears in an input position, as the type of a method parameter, which is not allowed when T is covariant.

So, if we want to keep T covariant, we are required to remove the setter:

public interface IArray<out T>
{
    T this[int index]
    { get; }
}

Now everything compiles, and we can do this:

IArray<Elephant> elephants = new Array<Elephant>(8);
IArray<Animal> animals = elephants;
Animal firstAnimal = animals[0];

But not this, as there is no indexed setter on the IArray<T> interface:

animals[0] = new Elephant();

In fact, any collection interface must be read-only if we want to have covariant generic type parameters.

Next time we’ll look at contravariance, the opposite of covariance, and how we can apply it to our array interface.

Nuttige tips voor je Londen stedentrip

Londen is een geweldige stad, en er is genoeg te zien en te doen. Maar er zijn wat dingetjes die handig zijn om te weten als je naar Londen gaat.

Gatwick Airport

Gatwick Airport Hoewel Heathrow de grootste en meest bekende luchthaven van Londen is, is het soms goedkoper om naar één van de kleinere vliegvelden te vliegen. Wij vlogen dit jaar naar Gatwick Airport. Vlieg je op Gatwick Airport, dan is het handig om te weten dat er een gratis shuttle is van de Noord terminal naar de Zuid terminal. Vanaf de Zuid terminal vertrekken de treinen naar Londen. Negeer alle reclames en borden voor Gatwick Express en reis in plaats daarvan met First Capital Connect van Gatwick Airport naar Blackfriars. Dat kost je £ 10,- per rit in plaats van £ 14,90, en kost nauwelijks meer tijd. Koop daarvoor bij een kaartjesautomaat (kan ook bij die van Gatwick Express) een Anytime Day Single naar London Blackfriars. Je kan contant met munten of biljetten betalen, en er zijn pinautomaten op Blackfriars. Andere reismogelijkheden vanaf Gatwick Airport vind je op [visitlondon.com](http://www.visitlondon.com/nl/vervoer_en_informatie/luchthavens/de-luchthaven-london-gatwick).

Underground

London Underground In Londen is het enorm handig om met de metro te reizen. En daarbij liggen zowat alle leuke attracties in zone 1, de centrumzone. Eenmaal aangekomen op Blackfriars (of Victoria, of één van de andere metrostations) dan kan je daar een London Travelcard kopen. Die zijn verkrijgbaar als papieren dagkaart voor zowel alleen buiten de spits (na 9:30 uur) als voor de hele dag, en als 7-dagenkaart. Maar wil je vier of meer dagen de hele dag kunnen reizen, of vijf of meer dagen buiten de spits, dan is het goedkoper om een 7-Day Travelcard te kopen. Haal je 7-Day Travelcard bij de balie en vraag om een Oyster card. Je betaalt £ 5,- borg voor de Oyster card, maar het maakt alles zo veel makkelijker. En bij je vertrek lever je de Oyster card gewoon weer in bij een willekeurig metrostation en je krijgt je vijf pond ook weer terug. Meer informatie over de London Travelcard vind je op [londontravelpass.com](http://visitorshop.tfl.gov.uk/travelcards/7-day/product/7-day-travelcard.html).

Oude ponden

Old British Pounds Neem je je oude Britse bankbiljetten weer mee naar Londen? Controleer dan of ze nog wel geldig zijn op de website van de [Bank of England](http://www.bankofengland.co.uk/banknotes/Pages/denom_guide/default.aspx). Zo kan het zijn dat je 20 pond biljet drie jaar terug nog geldig was en nu niet meer. Oude biljetten worden nergens in Londen geaccepteerd, maar je kan ze gratis inwisselen bij de Bank of England aan Threadneedle Street, metrohalte Bank. Let op, de bank sluit al om 3 uur.

Nieuwe ponden Haal geen ponden bij het GWK in Nederland, zelfs al betaal je daar maar 0% provisie. Want het GWK houdt z’n eigen koers er op na die wel 7 procent slechter voor je kan uitvallen dan de koers van je bank. Je kan het beste gewoon je ponden in Londen pinnen bij een pinautomaat.

Pinnen

ATM Currency conversion Je pinpas werkt alleen bij pinautomaten (_ATM’s_) met het [Maestro-logo](https://upload.wikimedia.org/wikipedia/en/thumb/f/fd/Maestro_logo.svg/500px-Maestro_logo.svg.png), maar gelukkig ondersteunen bijna alle pinautomaten in Londen Maestro-kaarten. Maar let op! Pin alleen bij automaten die geen extra transactiekosten rekenen (zogenaamde _free cash ATM’s_), en pin het bedrag in _ponden_. De automaat wil graag het bedrag alvast voor je omrekenen naar euro’s, maar dat moet je niet doen. Dat is zonder uitzondering slechter voor je portemonnee dan wanneer je in ponden pint en je eigen bank het omrekenen laat doen, zelfs als je bank nog wat provisie rekent.

Prusa i2, deel 6: Plastic onderdelen kiezen

plastics
De plastic onderdelen van de Prusa i2 zijn in de loop der tijd verbeterd door allerlei mensen. Een aantal van die verbeteringen hebben zich een weg gevonden naar het officiële Prusa Mendel Github project waar alle onderdelen beschreven worden.

In de officiële onderdelenlijst zijn plastic poelies (pulleys) opgenomen voor T5 tandriemen. Behalve dat de plastic poelies onnauwkeurig zouden zijn, zou de T5 tandriem niet geschikt zijn om door een kleine poelie te worden aangedreven. Veel mensen raadden daarom de T2.5 tandriem aan, maar tegenwoordig zweert men bij de GT2 tandriemen. Die laatste zouden door de rondere tanden juist geschikter zijn om door een poelie te worden aangedreven. Ik ga voor de GT2, maar aangezien niemand plastic GT2 poelies aanbiedt moet ik daar ook een paar GT2 aluminium poelies bij kopen.

Om de tandenriem niet van de rollagers te laten lopen zijn plastic ringen met opstaande rand onderdeel van de plastic onderdelenlijst. Maar veel mensen geven de voorkeur aan M8 30 mm carrosserieringen (fender washers) aan weerszijden van de lager. Ik kijk wel wat er in het onderdelenpakket zit dat ik ga bestellen.

In het standaardpakket zitten ook plastic lagerbussen voor op de assen, maar er is ook een officiële Prusa i2 variant die geschikt is voor LM8UU metalen lineaire lagers. Natuurlijk werken echte lagers beter dan geprintte bussen, dus kies ik voor de LM8UU variant.

De officiële LM8UU variant heeft een X-wagentje (X-carriage) dat maar drie lineaire lagers nodig heeft, maar sommige aanbieders hebben varianten van dit X-wagentje die vier lagers nodig hebben of die ruimte bieden voor een ventilatortje. Ik zoek het standaardwagentje, want ik kan altijd nog een beter wagentje printen als mijn printer eenmaal werkt.

De standaard eindstophouder is geschikt voor mechanische eindstops, maar sommige aanbieders van platic onderdelen geven je eindstophouders voor optische eindstops. Ik heb ‘gewone’ mechanische, dus ik hou het standaard. Later kan ik de eindstops altijd nog zelf vervangen door de duurdere optische eindstops met zelfgeprinte eindstophouders.

Er zijn verschillende mogelijkheden om de Z-draadeinden aan de stappenmotors te verbinden. De standaard plastic onderdelen gaan ervan uit dat je een flexibel buisje of krimpkous (shrink wrap) gebruikt om de 5 mm motoras met het 8 mm draadeind te verbinden, en dan een plastic klem eromheen schroeft. Anderen zweren bij aluminium koppelingen, al dan niet op maat gemaakt. Een nadeel van de plastic verbinding is dat de overbrenging van de draaiing van de motor een beetje vertraagd en onnauwkeurig kan worden. Tenslotte moet eerst het buisje of de krimpkous gaan torderen voordat het draadeind meebeweegt. Een nadeel van de aluminium koppeling is dat die niet meebuigt met de bewegingen van het draadeind. Ik ga toch voor de plastic koppeling omdat het goedkoper is en omdat ik niet zeker weet of de aluminium koppelingen ook werkelijk een verbetering zouden zijn.

De extruderassembly heeft ook nog een evolutie doorgemaakt. Een van de eerste ontwerpen kwam van Adrian Bowyer. De bekendste verbeterde versie is Wade’s Geared Extruder, maar tegenwoordig is Greg Frost’s Accessible Extruder de standaard. Ik ga het me niet te moeilijk maken en hou het bij Greg’s extruderassembly. Het is een beproefd concept en de onderdelen daarvoor zijn goed verkrijgbaar.

Prusa i2, deel 5: Extruderkop kiezen

J-Head
De extruderkop (hotend) is waarschijnlijk het duurste onderdeel van de hele printer. De kop bestaat uit een koude kant en een warme kant. Aan de warme kant wordt het plastic draad gesmolten en de extruder duwt het dan uit de spuitmond (nozzle). Om het draad te smelten wordt gebruik gemaakt van een verwarmingselement. Dit kan een simpele nikkel-chroomdraad zijn, een weerstand zijn die gewoon erg warm wordt, of een speciale keramische heater cardridge. De weerstand wordt eigenlijk oneigenlijk gebruikt, maar het schijnt goed te werken. Om de temperatuur in de gaten te houden heeft een extruderkop één of twee temperatuursensoren.

Er zijn veel verschillende ontwerpen, en van de beste ontwerpen zijn veel klonen met wisselende kwaliteit. De Extruder categorie op de RepRap Wiki geeft een overzicht van de extruderkoppen.

Er zijn twee gangbare diameters van het plastic draad: 3,00 mm en 1,75 mm. De 3 mm variant wordt het meest verkocht, dus de extruderkop die ik zoek moet 3 mm draad accepteren. Daarnaast is de grootte van de spuitmond van belang. Een grotere spuitmond (bijvoorbeeld 0,5 mm) zorgt dat je sneller kan printen, maar een kleinere spuitmond (bijvoorbeeld 0,35 mm) geeft meer detail. Voorlopig hou ik het bij een grote spuitmond van 0,5 mm, en dit is gelukkig ook een standaardmaat voor veel extruderkoppen.

Verder zoek ik een goede en betrouwbare extruderkop die ook nog een beetje betaalbaar is. De bekendste extruderkoppen zijn de J-Head van Brian Reifsnyder en de Arcol van Krekács László.

De Arcol exteruderkop kost ongeveer 100 euro, terwijl de J-Head ongeveer 50 euro kost. eBay heeft ook een boel extruderkoppen in de aanbieding, maar of ze goed en betrouwbaar zijn kan ik niet beoordelen. Ik heb besloten om de J-Head te bestellen via Reifsnyder’s eigen site. Dan weet ik tenminste zeker dat ik mijn geld uitgeef aan het originele product, en daarmee steun ik ook direct de maker. Daarnaast bestel ik een aluminium montageplaat (mounting plate) en een keramische heater cardridge (voor de zekerheid).

Prusa i2, deel 4: Werkvlak kiezen

Verhit werkvlak
Het werkvlak (printing bed) waar de objecten op geprint gaan worden is ook nog een punt van zorg. Verwarmd of niet? Wat voor ondergrond?

Na het printen krimpt het plastic als het afkoelt. En daardoor kan het gaan vervormen, vooral aan de onderkant. Een verhit werkvlak (heated bed) zorgt ervoor dat het onderdeel minder snel afkoelt en dus z’n vorm behoudt. En doordat het onderdeel warm is hecht het nieuwe plastic aan de bovenkant beter. Dus een verhit werkvlak komt de algehele kwaliteit ten goede. Een klein nadeel van een verhit bed is de prijs van de plaat en de stroom die het slurpt (rond de 6 A). Maar ik vond dat wel tegen de voordelen opwegen, dus ik koos voor een verhit werkvlak.

Nu kan je zelf zo’n verhit werkvlak maken met ongeisoleerd nikkel-chroomdraad (NiCr) of met grote weerstanden. Maar het is allemaal niet zo makkelijk, niet zo mooi, en het is lastig om het werkvlak egaal verhit te krijgen. Gelukkig is er al een goede oplossing: een geëtste PCB. Dat is een printplaat met een 35 μm koperlaag waaruit de banen geëtst zijn. Doordat de plaat zo’n uniforme dikte heeft is de weerstand van de banen ook uniform, en wordt de plaat mooi gelijkmatig heet.

Zulke platen zijn redelijk goed verkrijgbaar. Er zijn eigenlijk twee versies: de door Josef Průša ontworpen MK1, en de nieuwere MK2a. Die laatste heeft een opdruk aan beide zijden, dus kan je de plaat ook met de printbanen naar boven gebruiken. Verder kan de plaat met drie bouten worden gesteld – en dat is makkelijker – in plaats van vier voor de MK1. Dus ik koos voor de MK2a.

Dan de ondergrond, want direct op de verwarmde plaat printen is niet zo handig. Die plaat vervormt een beetje door de warmte, en dan worden de printjes niet vlak. Ook is er het risico dat als de printkop op de plaat crasht (bijvoorbeeld door een verkeerde afstelling) de printbanen beschadigd raken.

Dan de ondergrond. Er zijn verschillende mogelijkheden, maar de meestgebruikte zijn: hittebestendig glas, fotolijstjesglas, een IKEA spiegeltje of direct op Kapton tape of blauw schilderstape. Direct op de verwarmde plaat printen is niet zo handig, want dan is er het risico dat als de printkop op de plaat crasht (bijvoorbeeld door een verkeerde afstelling) de printbanen beschadigd raken. De tapes zijn ook niet ideaal omdat ze moeilijk vlak te krijgen zijn. Daarnaast kan de verwamde plaat eronder een beetje gaan vervormen door de warmte, en dan worden de printjes niet vlak. Glas of een spiegel is mooi vlak, maar voordat ik me ga wagen aan duur hittebestendig glas probeer ik eerst eens te printen op een IKEA Sörli spiegeltje. Voor die prijs heb je er zelfs vier, dus is het geen ramp als er eentje breekt door de warmte. Vastzetten met vier papierklemmen van de Action.