Sunday, 5 January 2014

4D Systems mbed Tutorial

uLCD-43 display mbed tutorial

Recently I have been playing with a new microcontroller - NXP's LPC1768 using the mbed development platform.

'mbeds' are incredibly powerful microcontroller development boards handily on a 40 pin dip package which makes it easy for prototyping.  Getting into prototyping with ARM microcontrollers is difficult because the devices are usually QFP (read lots of pins, really closely packed together in a surface mounting configuration) - or quad flat packed.....This makes it very hard for the development engineer to quickly prototype circuits.  Before protyping begins some sort of development breakout board has to be made which quickly turns into a design of it's own right.  There are so many facets and features to microcontrollers these days that prototyping and learning to use the device is a daunting prospect.  This is why the arduino development system is so popular....The arduino community have taken the stress out of development by making programming and using the Atmel 328p processor as simple as possible.  By then making addon PCBs (shields) available and easy to use the arduino family becomes one of the first development systems I would reach for when designing a microcontroller based electronic circuit

The mbed is a relatively new kid on my block.  I have heard about them and given them a cursory glance two years ago.  I found the device itself incredibly appealing - mbeds seem to have everything the arduino does and more...the issue was with coding the firmware for the device.  The development environment is completely online and this probably puts most professional designers off....control is something inherently closed in electronics design and not sharing is quite common.  I am attempting to rectify the situation a little. The other issue is that the mbed is coded entirely in C++.  I have dabbled with C++ in the past but I am by no means an expert.  To be honest my coding skills lack my electronics considerably!  Experienced software developers will revel in coding for the mbed; electronics engineers will struggle but hopefully catch up.

The mbed community website

There are plenty of beginner examples on how to use the mbed on the community website, I'm not going to repeat all of their good work here.  Sometimes though I still feel there isn't quite enough detail.  If I feel so inclined I might write some tutorials depending on how frustrated I get!

mbed Cookbook

I have recently been tasked with writing the firmware for controlling a touch screen display.  I have never played with one of these before and was quite excited at the prospect.  The display selected was the uLCD-43 PCT from 4D Systems:

uLCD_43 LCD display
I chose the capacitive touch version as for my application there is going to be a lot of touching and use on the display.  Resistive screens tend to get easily scratched and then not work as well, they can be covered but then the responsivity of the display is significantly affected.  Capacitive touch screens on the other hand don't lose responsitivity as much when covered and therefore won't be so affected by scratches!

This display was selected because it is controlled via a standard RS232 serial protocol.  Only 5 wires required! This should make controlling the display very simple to achieve.  I have used touch screen displays in the past that were parallel controlled and 16 wires were required to control the display....16 pins from the microcontroller used to control the display....painful!

There are several versions of touch screen displays available and prices to suit - the smaller the display with less features the cheaper the price!

One trap I found is that if you don't opt to buy one of the development kits 4D systems don't provide a programming cable with the screen.  Make sure you buy one or else you will be scuppered in trying to program the display!  You will also need a micro-SD card for storing the 'forms' on the display...It would also be beneficial to make sure you have a converter to change the microSD card into a standard SD card or a microSD card reader...I spent forever searching for one!


The development environment for the display provided by 4D Systems is excellent!  There are four flavours of environment available.  


Designer is for the hardcore software programming enthusiast with experience in coding the display using 4D's own development code.

Visi is a drag and drop object oriented programming experience for the controlling the device.  It is slightly more simple to use than the Designer option.

Visi-Genie is another even better version of the object oriented drag and drop system.  All the designer has to do is drag and drop the pre-coded objects and layout the screen as required.  Nothing could be easier and I found this to be the most efficient method of quickly getting the display up and running.

Serial - I haven't really looked into this section much, but according to the information provided it's a method of making the display completely controlled via the serial terminal.  I should really investigate further!

There is a very active forum for the use and control of the displays on 4D's website.


If a designer ever got stuck then posting their questions and issues on the forum soon yields some help.

Using Visi-Genie is very similar to a visual development environment and most people who have done any visual programming before will be quite at home.


 So to the business of using the screen with the mbed!

I looked at the application notes for using the display on the 4D Systems website and noticed that there were several examples available for use with the arduino and the raspberry Pi.  Unfortunately nothing for the mbed.  The application notes provided by 4D Systems discuss in great detail how to use the display but connection to the microcontroller is not discussed until the end of the document.  It took me a while to find it!  There is a specific shield for connecting the display to the arduino and the raspberry Pi and a photograph showing the wired connections to a micro if required.  It still wasn't particularly clear to me...so here is how you make connections to any microcontroller with just wires....


+5V is connected to the 5V positive supply - one will have to be provided for a 3.3V microcontroller
GND is connected to the 0V connection.
RES is connected to a 1k resistor and then to a digital GPIO pin on the microcontroller or not connected.
TX is connected to the TX pin of the RS232 Uart pin of choice on the microcontroller.
RX is connected to the RX pin of the RS232 Uart pin of choice on the microcontroller.

For the mbed connections see the following schematic:


I've added a potentiometer as in this tutorial like the arduino tutorial we are going to make a simple touchscreen controlled voltmeter.

I then connected the display to the programming cable and loaded up 4D workshop 4.  I selected the Visie-Genie environment and dragged and dropped the following objects onto the display to match the arduino tutorial -


  • an angularMeter object
  • an LEDdigits object 
  • two 4Dbuttons object
  • three staticText objects 




The original arduino tutorial used a rockerSwitch object but I wasn't able to get this working with the mbed....more on this later...

Make sure you set the display's serial communication rate to the same as the one you intend to use with the microcontroller.  In my case I selected 115200 as I wanted to see if speed made a difference to the display response.

Set the 4Dbutton objects to Report Message in OnChanged in the events tab.  This ensures the display outputs a serial message when the buttons have been pressed.

 
Once you have the display objects arranged to your satisfaction go ahead and upload the project to the display by clicking on the BuildCopyLoad button.  The 'form' will be compiled and loaded onto the display's firmware and then placed on the microSD card.  The software will prompt you as required.  Once complete remove the SD card and put it in the display.  The display will then load up with the form just designed in the development environment - Cool huh!

If you like you can check the display is working by probing the serial port using the serial terminal within 4D systems workshop.  When the buttons are pressed a hex message should appear in the serial terminal window.

If however you are like me you will want to connect it to your host micro of choice and use the display as intended - <very big grin>

So remove the USB programming cable and connect the wires up as shown in the schematic diagram previously.

Once you apply power to the mbed the display should load up but not do anything.

You will now need to load up the mbed's online compiler and log in and then you can either develop your own firmware or copy mine...I used a port of the arduino Visi-Genie library helpfully written by Christian B one of the other mbed users:

mbedVoltmeter code

Here is the text version for those that prefer to read through and copy and paste:

/* A port test of the arduino voltmeter example using the 
4.3' PCT 4d systems touch screen display.  

uses the mbed_genie library ported from the arduino
visie-genie library by Christian B

The display serial TX and RX pins are connected to pin 9
and pin 10 of the mbed

The reset pin is not connected as reset function is not implemented

Pin 15 of the mbed has a potentiometer wiper connected to it
The other connections of the potentiometer are connected to +3.3V
and 0V 

For setting up the display in Visie-Genie

The display has an angular meter objecr, a LED digits object, two buttons 
and three static text objects.

The program sends digital voltage readings to the LED digits and 
angular meter of the display module.

The On and Off button has been set to report on change

The baud rate of the display is set to 115200 baud

*/

#include "mbed.h"
#include "mbed_genie.h"

AnalogIn voltReading(p15);  //Potentiometer wiper connected to pin 15      

int flag = 0;        //holds the "power status" of the voltmeter. flag = 0 means voltmeter is "off", flag = 1 means the voltmeter is "on".
float voltMeter;       //holds the digital voltage value to be sent to the angular meter
float voltLED;         //holds the digital voltage value to be sent to the LED digits

//Event handler for the 4d Systems display
void myGenieEventHandler(void) 
{
  genieFrame Event;
  genieDequeueEvent(&Event);
  //event report from an object
  if(Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {
    /*
    for example here we check if we received a message from 4dbuttons objects
    the index is the button number, refer to the 4dgenie project to know the     index
    */
    if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)                // If the Reported Message was from a button
    {
        if (Event.reportObject.index == 0) 
        {
             //printf("Off Button pressed!\n\r");
             wait(0.2);
             flag=1;
        }
        if (Event.reportObject.index == 1) 
        {
             //printf("On Button pressed!\n\r");
             wait(0.2);
             flag=0;           
        }
    }
  }
  
  //Cmd from a reported object (happens when an object read is requested)
  // if(Event.reportObject.cmd == GENIE_REPORT_OBJ)
  // {

  // }

}

int main() 

{ 
    SetupGenie();
    genieAttachEventHandler(&myGenieEventHandler);
     
    printf("Langsters's mbed Visi-Genie Voltmeter demo \n\r");

    genieWriteContrast(15); //set screen contrast to full brightness

            while(1) 
            {                  
                if (flag == 1)
                    {
                        //printf("Flag status: %d \r\n", flag);
                        wait (0.1); 
                        voltLED = voltReading; 
                        wait (0.1);    
                        //printf("Volt bit Reading: %f \n\r",voltLED);
                        voltLED = voltLED * 3.3;                                    //convert float reading to voltage
                        //printf("voltLED: %f\r\n",voltLED);
                
                        voltLED = voltLED * 1000;
                        genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, voltLED);      //write to Leddigits0 the value of voltLED 
                        wait (0.1);
                        
                        voltMeter = voltLED/100;
                        genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, voltMeter); //write to Angularmeter0 the value of voltMeter     
                    }
                
                else if(flag == 0)
                    
                    {
                        //printf("Flag status: %d \r\n", flag); 
                        wait (0.1);
                        voltLED = 0;
                        genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, 0);      //write to Leddigits0 the value of voltLED 
                        wait (0.1);
                        
                        //voltMeter = voltLED/100;
                        genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, 0); //write to Angularmeter0 the value of voltMeter   
                    }                            
                                
            }
      
}

Import the program into your online compiler and then compile and download it.  You will then need to copy the associated .bin file onto your mbed.  Once complete, press the mbed's reset button and the magic shall begin!  If you press the 'On' button the display will show the voltage being applied at the analogue input pin 15 which is connected to the potentiometer wiper and should be somewhere between 0V and 3.3V.  If turn the wiper on the pot then the voltage displayed will update accordingly.  If you press the 'Off' button all measurement will stop and any changes on the potentiometer will not update the display.  Doesn't sound like much but the potential is huge (that and it took me ages to get this working...)

Here is a description of the code and how it works:

#include "mbed.h"
#include "mbed_genie.h"

These two lines tell the online compiler to include the header files mbed.h and mbed_genie.h.  These are header files which tell the compiler how to understand the syntax written in the program

AnalogIn voltReading(p15);  //Potentiometer wiper connected to pin 15      

int flag = 0;        //holds the "power status" of the voltmeter. flag = 0 means voltmeter is "off", flag = 1 means the voltmeter is "on".
float voltMeter;       //holds the digital voltage value to be sent to the angular meter
float voltLED;         //holds the digital voltage value to be sent to the LED digits

The next lines are some variable declarations: 

AnalogIn voltReading(p15); tells the compiler that pin 15 on the microcontroller will be using pin 15 to measure an analogue value.  In this case it will be measuring the voltage present on the potentiometer wiper pin between 0V and 3.3V

int flag = 0; tells the compiler to assign some memory for storing an 8 bit integer value, refer to this value as flag and give it an initial value of zero.  I could have and probably should have used a boolean value here to save memory and it's better practice however I am not a professional coder and this worked!

float voltMeter; tells the compiler to assign some memory for storing a 16bit floating point value or to keep things simple a number with decimals!  Refer to this memory location as voltMeter.  We will be using this memory location to store the decimal value we are going to display.

float voltLED; As above but in this case we are storing the decimal value to be displayed on the seven segment LED digits.

//Event handler for the 4d Systems display
void myGenieEventHandler(void) 
{
  genieFrame Event;
  genieDequeueEvent(&Event);
  //event report from an object
  if(Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {
    /*
    for example here we check if we received a message from 4dbuttons objects
    the index is the button number, refer to the 4dgenie project to know the     index
    */
    if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)                // If the Reported Message was from a button
    {
        if (Event.reportObject.index == 0) 
        {
             printf("Off Button pressed!\n\r");
             wait(0.2);
             flag=1;
        }
        if (Event.reportObject.index == 1) 
        {
             //printf("On Button pressed!\n\r");
             wait(0.2);
             flag=0;           
        }
    }
  }

The above function is the 'Event Handler' for the display.  An event handler is the section of a program for handling interrupts.  Basically the microcontroller and display will spend most of it's time showing the pictures of what the designer has provided.  When someone touches the display the microcontroller will receive a message from the display interrupting the program flow.  This function deals with that 'interruption' by processing it and providing the required response.

In the case above the event handler the following is occurring:

genieFrame Event; Call to the mbed_genie library function that deals with a touch being registered on the display.

genieDequeueEvent(&Event); If the event registered is genuine place it in the queue to be processed as an interrupt. 

if(Event.reportObject.cmd == GENIE_REPORT_EVENT)
  {

The above line is a conditional check that tells the microcontroller to perform the code below if the result of the check is 'true'.  If the result is false the function ends and the microcontroller stops processing this section of code.

if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)
    { 

Another conditional check asking the microcontroller if  a 4Dbutton object was pressed.

        if (Event.reportObject.index == 0) 
        {
             printf("Off Button pressed!\n\r");
             wait(0.2);
             flag=1;
        }

Was the button pressed the 4Dbutton0 object - the 'Off' button? If it was then send a message via the serial terminal to advise the user it was (not required but useful for debugging) and then wait 200ms to allow the required processing to occur and then set the flag variable from 0 to 1 to let the microcontroller know the button was pressed.

        if (Event.reportObject.index == 1) 
        {
             //printf("On Button pressed!\n\r");
             wait(0.2);
             flag=0;           
        }

The above code section is exactly the same as before but for the 'On' button.

int main() 

{ 
    SetupGenie();
    genieAttachEventHandler(&myGenieEventHandler);
     
    printf("Langsters's mbed Visi-Genie Voltmeter demo \n\r");

    genieWriteContrast(15); 

The int main() function is the part of the program that tells the microcontroller to process the functions in order from here.

The SetupGenie(); line is a call to the mbed_genie library telling the microcontroller how to setup the display. Tell the microcontroller what size of display is connected, in what orientation and at what speed the serial Uart is set at.  In this case I set it to 115200 baud.  If this needed to be changed you would need to search through the mbed_genie library for screen.baud (115200) and change it to whichever value you like.  You will need to ensure the display firmware is updated to reflect this change.  I hope to change this in the library to make it easier to change the screen serial baud rate.

printf("Langsters's mbed Visi-Genie Voltmeter demo \n\r");

The above line sends a message via the serial terminal to inform the viewer which program is running.  Not strictly necessary but useful for debugging purposes.  It lets the programmer know which section of the code is running.

genieWriteContrast(15);

The above line sets the displays contrast (brightness really).  You can set the display from 0 to 15.  15 is full brightness.  Useful if you wanted to turn the display off or down to conserve power when not in use.

while(1) 
            {                  
                if (flag == 1)
                    {
                        //printf("Flag status: %d \r\n", flag);
                        wait (0.1); 
                        voltLED = voltReading; 
                        wait (0.1);    
                        //printf("Volt bit Reading: %f \n\r",voltLED);
                        voltLED = voltLED * 3.3;                                    //convert float reading to voltage
                        //printf("voltLED: %f\r\n",voltLED);
                
                        voltLED = voltLED * 1000;
                        genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, voltLED);      //write to Leddigits0 the value of voltLED 
                        wait (0.1);
                        
                        voltMeter = voltLED/100;
                        genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, voltMeter); //write to Angularmeter0 the value of voltMeter     
                    }
                
                else if(flag == 0)
                    
                    {
                        //printf("Flag status: %d \r\n", flag); 
                        wait (0.1);
                        voltLED = 0;
                        genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, 0);      //write to Leddigits0 the value of voltLED 
                        wait (0.1);
                        
                        //voltMeter = voltLED/100;
                        genieWriteObject(GENIE_OBJ_ANGULAR_METER, 0x00, 0); //write to Angularmeter0 the value of voltMeter   
                    }                            
                                
            }
      
}

The rest of the code runs in a continuous while loop initiated in the while(1){ section.  Every line of code beyond this point will run over and over until power is removed.  

The if statement checks if the flag variable has been set and if it is set (the 'On' button has been pressed) then the analogue voltage signal measured on analogue pin 15 is stored and placed in the voltLED memory location.  The floating point value is then converted to decimal and formated for a measurement from 0 - 3.3V and then passed to the ledDigit0 display object.  The display then shows the result.  The same process is then performed to display the voltage measurement on the angularMeter0 display object.

That's it for the code explanation.  I hope it's understandable.  It took far too long for me to get this working and almost as long to write about it!

Here is a picture of the display and microcontroller in action:




   And finally here is the almost ubiquitous youtube video proving I didn't fake getting it working!



Well that's it for now.  I am hoping that given time I can help improve the ported 4D systems mbed library as there are still a few functions missing - resetting the display being one thing I found not present.  I also didn't manage to get the rocker switch object to work which is why I used two momentary buttons.  All in all I think both the mbed microcontrollers and the 4D systems display have great potential and hopefully more people will be able to use them with help from this tutorial.

Take care people - Langster! 























     

    

Thursday, 2 January 2014

Rendering an Eagle PCB layout for an LM311 LC Meter with Arduino Uno

Recently I have been learning to use 3d CAD packages so that I can design and build some cases and enclosures for these electronics projects I have been writing about here.  I have been using an EagleCad ULP (user language program) called eagleUp 4.4.  It provides a way of rendering the PCB layout with components so that it can be viewed in Sketchup.

You can download eagleUp 4.4 from here:

eagleUp4.4.zip

I would actually follow the instructions from the eagleUp Website though as there is more information to be found:

http://eagleup.wordpress.com/installation-and-setup/

Once you have the programs installed and setup it really is very simple to render your PCB into a 3d image so that you can view the 'populated' PCB and design mechanical enclosures ready for manufacture by 3d printing or using a laser cutter.

You will also need to obtain a copy of Sketchup Version 8

sketchup 8 download

I would install the programs as directed before continuing!  You will need to follow the instructions to tell sketchup where the eagle up addon is so that it's possible to load the .eup file into sketchup.  Don't worry it isn't hard!

I recently designed a version of the LC Meter for one of the blog readers using an LM311 comparator.  It uses exactly the same firmware as in the previous post but instead of using an LM339 quad comparator it uses an LM311 dual comparator.  The circuit works in exactly the same way as the previous version.  If people wish to know how it works they should check out the previous post:

Here is the Schematic Diagram:


Here is the PCB bottom layer:


The bottom layer is mirrored here so that it can be printed ready for toner transfer to manufacture the PCB.  It doesn't show whether any components are over lapping or fouling or how the top side of the PCB will look once populated with components.  This is where eagleUp 4.4 comes in handy!

In the eagle PCB layout screen click on the run ULP Icon:


Now select eagleUp_export.ulp from the open dialog box:


The following window will appear:


These are the parameters which can be changed depending on your requirements:

Image Export - the amount of pixels present in the render - the higher the dpi the larger the file size and the longer it will take to render the PCB

Outline Layer - select which the layer the image will use as the dimension

Silk Layers - Select whether you wish for the silk screen to be present and to use both place diagrams and component names and identifications or not at all

Misc - Choose whether you wish to render the PCB with or with components and vias

Board Thickness - The physical thickness of the glass fibre substrate supporting the copper tracks and components

Choose solder mask color - Which colour (I'm british!) should we use for the etch resist  - most people use green but OSH park like to use purple!  It's up to the user...

Choose plating - what colour do you want the tracks to be....I always choose gold but again it's up to the user.

Choose silk color - What colour will the silk screen be...Again I always choose white but it's the user's choice.

When ready click Ok and wait for the magic to complete - this may take some time although for most boards it was less than 2 minutes.  The PCB and components are being rendered and placed on the PCB in a sketchup image.


Load up Sketchup 8 and click on the plugins menu Item import eagleUp v4.4


Then when the dialog box appears navigate to the appropriate eagle directory for the project



Mine was callled LC Meter dif Ver...

Inside that eagle project folder there will now be a folder labelled eagleUp.  Select that folder and then select the .eup file inside it.


Once you click open again be prepared for a short wait of about two minutes...the program is running a script file which is placing the components and rendering the image.


Once the process has completed you will probably be presented with the following dialog box:


If we look closer at the dialog box it's telling us that the program did not have sketchup models with the correct names to place them on the PCB.  Make a note of all of the names in the dialog box as we will need this information for later:


Click ok when ready.  We are now going to find suitable models for the missing parts and then label the files with the correct names so that when if we were to re-run the import eup script all the missing items would be found and rendered correctly.

Click on the file menu in sketchup and navigate to the 3d warehouse section:


We are going to locate a suitable model for each of the missing items on the list and store them in the models folder in eagle so that all components are correctly rendered.  I'm not going through every item on the list as this would be repetitive.  Here is how I found a suitable model for the 1N4148 diode:


If a suitable model is available then the models will be displayed:


Click on the suitable model - in our case this would be any of the models on the left hand side.  If possible download the model and save it to the models directory within program files/eagle:


Make sure you when you save the file you give it the same name as the package that was missing - in this case DIODE-1N4148.  This will then store the model for use later and should ensure that the model is found next time we run the script.

In Order to save myself some time I went into eaglecad and created a bill of materials for this project.  The bill of materials contains the package names for all of these parts.  If I then browse the internet and locate the correct models I can then rename them to the required packages and then re-run the script - sneaky!

Once this was complete and the script has run you will be asked if you wish to re-size any of the models.  I suggest you say yes as resizing them yourself is difficult and time consuming.  From this point on it is a matter of moving the component models into position and aligning them and resizing as necessary.  It is quite tedious work but once complete the results are spectacular and useful.

I uploaded the model I made of this PCB to Sketchup 3D warehouse - it is available for download if poeple wish to search for it:

3d warehouse LC Meter Model

Here are some screen shots just for fun.






Well that is about it for now - The next post will discuss how to design a case for the LM311 LC meter.

Cheers for now - Langster!

Sunday, 1 December 2013

Finishing the Knock Clock!

Finally it's time to complete the knock clock!  The circuit is complete, working and tested.  The firmware for the microcontroller is written and proven to work...so now is the time to put everything into a box and get on with something else.  Don't get me wrong I have had great fun making this project and I am also very interested in making more and possibly making some kits available....


So the picture above shows the PCB top layer with components and dimensions.  We can use this to design an enclosure for the project.  For quickness and because its so easy I have decided to make a laser cut box out of wood!  Laser cutting is the simplest and quickest way I have found to make unit enclosures.  As this is essentially a display piece I've decided to use laser plywood.  I'll stain and varnish it to give it a good aesthetic appeal.  This isn't really my thing in honesty.  I normally just like things to work I don't care how they look but the customer (she who must be obeyed!) has more stringent criterion...

To design the box ready for laser cutting I used Inkscape an open source graphics package which is awesome -

Inkscape

After installing and setting up the program and checking it was working I then added an extension and this is where designing boxes becomes so simple and efficient - tabbed box maker!

Tabbed Box Maker Extension for Inkscape

Once installed I then set my page size and limits to A4, Landscape orientation and the grid dimensions to be in millimetres...because I am a shameless Brit and use SI units and paper sizes and I have a working knowledge of those units and dimensions.  If you want to use Imperial measurements that is fine too!


Next it's time to start the tabbed box maker extension:


A window will appear with some options about the box we are going to design.


So now is the time to make some decisions about the box....We know roughly what our internal dimensions need to be...As they will be the same as the PCB.  We also need to allow some space for the solenioid to be comfortable and we need to choose how deep we want the box to be....too shallow and it will sound poor when 'knocking' but too tall is a waste of material.  In the end it's up to the designer.  Here is what I chose:



I like to work with the internal dimensions as I want to be sure whatever I'm going to put inside the box or enclosure is going to fit.  I have made mistakes before when designing enclosures by using the internal dimensions for external dimensions...All I can say is be careful and check things before cutting material or getting something made.  It can get expensive!

For the length dimension I chose 145mm...it was a guess really, I looked at the PCB and my solenoid and from the dimensions of those I surmised 145mm would be ok.  For the width I chose 100mm as it's slightly larger than the PCB and should make it fit without being too tight.  From the PCB dimensions we have 94mm width.  So if we choose to make the internal box width 100mm we have a 3mm margin between the PCB and the box walls:

100mm - 94mm = 6mm

6mm / 2 = 3mm margin

For the height I made a guess and chose 75mm.  There was no real science involved I just chose a number! 
The tab width was set to 5mm because I like having 5mm tabs.  If you choose a different value here be sure you know what you are doing.  More tabs makes the box more secure as you are providing more surface area for the glue to act upon but it can make the box very difficult to put together.

The material thickness I set to 5mm because that's the thickness of my laser plywood which I bought from an art shop in Manchester called Fred Aldous:


They sell all manner of art materials and supplies and also provide laser cutting services.

I didn't change the kerf parameter (kerf  = the amount of material the cutting action removes) and the clearance parameter I also left unchanged.

I chose a 3 piece layout style because it makes it fit a page of A4 well.  I chose the space between parts to be 2mm because I didn't want to waste material.  

When it comes time to laser cut the box we will need to cut it twice to ensure we get all of the parts we need.  
Click apply when ready and this is what the extension generates:


I saved the file at this point as I wanted to be sure that whatever changes I make from this point I can undo if I needed to.  It's always a good plan!

Next I decided to get clever...In eagle on the PCB layout section I turned all layers off on my PCB view apart from dimensions and holes.


I then exported this image as a PDF.  I then imported this image into Inkscape on a new layer.  This will allow me to set the laser cutter to drill out the holes for the PCB mounts perfectly aligning them!  I then drew some circles over the top of the hole positions and then deleted the PCB image as it isn't needed.  Finally I grouped the holes with the bottom tabbed box shape so they wouldn't move.


I love getting laser cutters to do all the work for me!  Time is precious...

Next we need to add a hole in the side of the box for the DC power Jack.  This is a bit more complicated as I don't have a 3 dimensional representation of the box.  I could model this in Google Sketchup but it isn't necessary...I can guess where the hole needs to be from the dimensions of the DC jack and the PCB layout.


I added all of the components and a dimension from the edge of the PCB to the centre of the DC jack to help...technically not needed.  If we draw a line from the DC jack centre across to the left we can position the centre of the hole.  Next we draw another like from the edge of the tab section so that we know where the base of the side begins....I know this is difficult to understand hopefully the picture will make it clear:


The red line shows the base of the side when the box will be put together and the blue line shows where the centre of the DC jack plug will be.

What we need to do now is calculate of big a hole we need and where it needs to be positioned.  The size of the hole really depends on the size of the plug used.  I am using a 12Vdc adapter that I found in my junk pile.  I grabbed it and measured the diameter of the DC plug roughly using a ruler.  If you are making your own adapter then use the mechanical information from the datasheets!  It measured roughly 10mm and to be honest they will all be about this size.  So...Hole diameter is 10mm.

Next we need to calculate the height the DC jack will be from the base of the side.  This is where things get tricky and some luck is needed.  I used a standard DC jack socket on the PCB...I didn't even look for something specific as it's a standard part.  Here is a datasheet:

PCB Mount DC Jack Socket

From the mechanical information I know that it is 11mm tall and the height to the centre of the jack socket is 6.5mm tall.  The PCB thickness is 1.6mm and I intend using PCB stand offs 5mm tall. Therefore if we add the pertinent dimensions together we can calculate where the centre of the hole needs to be:

6.5mm + 1.6mm + 5mm = 13.1mm

So the centre of our 10mm hole needs to be 13.1mm from the base of the side.  No problem!  Lets add a 10mm hole to our side.

Lets draw another line that is exactly 13.1mm long and overlay it on top of the blue line and beginning at the red line.  Then lets add a 10mm diameter circle.


We can then delete the lines and group the hole.  Now we have a correctly positioned hole and are ready to cut the wood!

I saved the file with a different name as I will have to cut the material for six parts. One with holes and one without.  I decided to add some images to my file to make the box look a little more interesting.  The first box I designed was a little plain and boring.



If required I can provide the inkscape files so people can make their own box.

Here is a very quick video of the laser cutter in action:


Now it's finally time to put the box together.  The tabs make it very easy and all that was required was some PVA wood glue and some patience.  Once the glue set I put the PCB in the box, I was in a rush so I didn't use stand offs and the solenoid was secured with blu tac!  I will improve my version but I would recommend that people use stand offs and hot glue to secure their solenoid and PCB.

Here is the box!


In order to properly finish up this product I suppose I should provide a bill of materials and some rough costs.  So...here goes:

Part Value Device Cost (£)
       
C1 22pF Ceramic capacitor 0.04
C2 22pF Ceramic capacitor 0.04
C3 0.1uF Electrolytic Capacitor 0.036
C4 10uF Electrolytic Capacitor 0.052
C5 10uF Electrolytic Capacitor 0.052
C6 100nF Ceramic capacitor 0.028
C7 100nF Ceramic capacitor 0.028
D1 1N4001 Axial rectifier 0.056
IC1 LM7805 T0220 package  0.31
J1 Programming Header 6x 0.1' pitch header pins 0.7
J2 12Vdc power jack 3.5mm dc power jack 1.15
JP1 6 pin Header 6x 0.1' pitch header pins 0.7
JP2 5 pin Header 5x 0.1' pitch header pins 0.7
JP3 5mm Screw Terminal 5mm screw terminal phoenix connector 0.42
JP4 5mm Screw terminal 5mm screw terminal phoenix connector 0.42
KK1 Heatsink T0220 Heatsink 1.09
LED1 5mm Red LED 5mm Red LED 0.069
Q1 IRF630 MOSFET-N CHANNEL 0.57
R1 10k 1/4W axial resistor 0.018
R2 220R 1/4W axial resistor 0.016
R3 1k 1/4W axial resistor 0.017
R4 100k 1/4W axial resistor 0.017
R5 1M 1/4W axial resistor 0.017
S1 Microswitch momentary tactile switch 0.057
SP1 Piezo Buzzer Piezo Buzzer 0.37
U1 ATMEGA328P ATMEGA328P -DIP package 2.01
Y1 16MHz 16MHz crystal (through hole) 0.35
DS1307 Real time Clock Module DS1307 RTC module 7.99
PCB Circuit Board Printed Circuit Board 2.55
Total 19.873

Some of the components have to be ordered in multiples from Farnell Electronics so there would be some items left over and it would not be necessary to order three lots of header pins, one 36 row of pins would be enough.  The heatsink is also a little unnecessary for this circuit as the MosFET doesn't get hot without one. The 12Vdc 5mm screw terminal for the power input could be removed also.  If we now recalculate that brings the cost of making this device (not including enclosure) to £16.96

If we add on two sheets of laser plywood (£2.00) and time on the laser cutter (£1.00 for ten minutes) and it took about twenty minutes to cut the enclosure out:

That bring our total costs back up to £21.96!

Not too bad...It would have been nice to get the costs down below £20 and if I searched around for different suppliers I might be able to get some components more cheaply.  If I was in the business of manufacturing products I would be searching everywhere for a better deal.  I would also redesign the PCB to be smaller, use surface mount components and have the enclosures made in large numbers.  This would reduce costs considerably.

Anyway enough of the boring stuff.  I had great fun making this project and I probably will get some printed circuit boards professionally made by Seeed Studios.  Their fusion service is too good to miss!


Well that's it for now.  Enjoy people and have fun - Langster!