Upgraded Laser CNC

Last week I took delivery of a nice laser CNC engraver/cutter. This was a very cheap chinese machine, model number K40-III. When I got it, I knew the controller and the machine itself were very limited but there was an open hardware project call LaOS that I hoped would solve some of the issues. Couple that with a bit of my own customisation, hopefully I am going to end up with a fairly decent machine, for a lot less than a commercial model. I’m not the first to attempt this, as these machines are very common on eBay. I haven’t seen any success stories on my browsing so hopefully I will be the first.

I’m not going to put all the details on here, as I am updating the project wiki so its all in one place. This is going to be more of a log of what I do, so if you want the nitty gritty details, take a look at the wiki page for this machine.

So, on with the log. After making sure it was all in working order, the next job was to figure out what all the connections did, and what to do with them. Starting with a load of photos, I started to trawl the net. The controller board I knew was a chinese model, so punching the numbers off the silk screen into Google I managed to find a pdf with the technical details. One drawback, it was all in chinese! Thankfully Google translate came to the rescue and gave me enough details, coupled with details on the Laos wiki about other laser machines, to know what each of the connectors did. The other part that needed tracing was the power supply. Thankfully this turned out to be a simple case of checking continuity between the pins and the components on the control panel. After all this investigation, I knew how the stepper motors, the endstops, the control panel, and the power were connected.

The only difficult part was how to control the laser. This is a bit I struggled with as the documentation for the LaOS project is still being written, and there seemed to be multiple ways to control the laser. One of the power supply connectors allowed me to fire the laser, which was great for testing, but it didn’t honour the laser enable/disable button which I would rather leave in place and active. There was also another connector pin that was labelled as Laser, which in theory will control turning the laser on and off from the controller board. Experimentation will be needed I think.

With this knowledge in hand, I purchased a LaOS PCB, along with the PCB for the i2c LCD addon, and started putting the electronics together. Again, due to the project wiki being fairly new, and the team behind it being very small, it wasn’t quite as easy as other projects I’ve encountered such as RepRap. I’m fairly confident this will change over time, and I know I’ll be going through the wiki adding information once I’ve got it all working.

Once the electronics were constructed and ready, I unplugged the old controller, plugged in the new one, loaded up a test firmware and turned it on. I rather quickly encountered my first problem. A total school boy error of putting the wrong voltage capacitor on the board meant it blew up in my face… literally. Still, no harm was done to either the board or myself, apart from a bit of an adrenaline rush. I quickly swapped out the old capacitor with a newer one of the correct voltage and plugged it all in again. Nothing blew up this time, and I could confirm that all the voltages seemed correct. Next step was to try some of the motors and end stops. Moving the head back and forth showed that both home position endstops were working fine thankfully, and were inverted so that they turned off when homed. I guess its safer that way, and it told me I needed to set that up in the configuration.

Happy that things seemed fine, I put the real firmware onto the board and fired it all up. Success… kind of! The X axis homed nicely, but the Y axis sat and juddered in place. After a few posts on the forums, and a lot of messing with config files, and checking of connections, finally it homed to the correct position. With that seeming to work, I fired up the interface software called visicut, and tried to send a few test files to the machine. Well, things moved, but not exactly in the right way. Still, better than nothing and I was fairly certain that it was all down to settings in the config file. I was beginning to understand that the config file is the hardest part of setting it all up, but finally after a lot more tweaking of the file, I had both axis moving in the correct way and the correct amount.

Next came the laser. In some ways, I was dreading this. So far I’d been messing with things I knew about from building a couple of reprap machines, namely stepper motors and pololu stepper drivers. I was fairly confident if I blew either of these things, then I could fix or replace them. The laser was something totally new. However, from reading the documentation, and putting a multimeter onto the connection marked L on the PSU, I was fairly certain all I needed to do to active the laser was to pull the L pin down to ground. All this took was a single wire from L to one of the Laser On pins on the LaOS board, and the other Laser On pin I simply tied to a handy ground point (ie, the screw terminal on the board that came from the PSU ground).

With a little bit of trepidation, I powered up the printer and started visicut. I loaded a simple rectangle file to test with, and hit the execute button. A nice little rectangle was cut out of the test bit of card! Wow, that was easy! To say I was happy would be a little bit of an understatement. I quickly grabbed a bit of acrylic I’d got to test with and fired up inkscape to draw something. I only wanted something simple, so I decided to try and engrave my name into the acrylic, so a quick click on the text button, and I typed my name in. Up to the extensions menu, and select Lasercut Path and the image I created was loaded up in visicut. A click on engrave, and execute, and my name was being etched into the acrylic! It turned out rather nicely! 🙂

Frickin laser!

All in all, I’m very happy. I got a cheap machine off eBay with a lot of limitations and with the help of an Open Source hardware project, I’ve turned it into a networked laser CNC machine. It is still limited in the strength of the laser and the bed size, but I now feel confident enough that if I end up using it a lot, I can get a higher end cutter and convert that.

I’ve still got a way to go yet on this project. The CUPS driver isn’t working properly, so I’m relying on using visicut to do the actually printing work, but that isn’t too bad as it is a pretty easy to use program. I also need to put PWM onto the laser output so that the controller board can vary the laser cutting power itself. Lastly, there is the i2c LCD module to get working. For some reason if I plug the module in, the controller board won’t boot properly, but I haven’t done any investigation yet to find the reasons. Oh, and I think a few safety measures are needed such as a water flow sensor and lid sensor which deactivate the laser in the case of anything not working… better safe than sorry!


Dell and Linux FAIL!

Well, my laptop is playing up and getting a bit old so I’m in the market for a new one. I only want to buy one with Linux pre-installed, not for any anti-Microsoft reasons as such but just so that it can be noted that there is a market out there for Linux computers. My current laptop was bought from Dell with Ubuntu installed on it, which has done me well for the last few years, so I decided to give them my repeat business. Checking their Linux website shows no current devices available, so I decided to try and contact them to see if there were any future plans.

First off, when trying to contact Dell for any reason, they don’t supply an email address! I find this most bizarre as I don’t necessarily want to phone, snail mail, or chat online with a sales person. I bit the bullet and went to the online chat to ask the question and here is the conversation:


13:46:21 Customer Darren Poulson Initial Question/Comment: Are you going to be offering any more linux (ubuntu) systems? I need a new laptop and would rather buy one linux installed
13:46:51 System System You are now being connected to an agent. Thank you for using Dell Chat
13:46:51 System System Connected with rayees_fatima
13:47:01 Agent rayees_fatima Thank you for contacting Dell Sales Chat. This is Rayees Fatima, your Sales Advisor. Please give me a moment while I review your query. In order to serve you better, may I have your telephone number&email address, just in case of disconnection I can either call you or email you back. My email address XXXXXXX@dell.com and direct dial number XXXXX Ext: XXXXX
13:47:06 Agent rayees_fatima no

So, a one word response from their sales team. I guess they must be very, very busy and don’t have the time to answer properly. Granted, they did actually answer my question, but a two letter answer is rather abrupt.

Needless to say, they won’t be getting any repeat business from me, and seeing as I generally get asked for advice on buying laptops and desktops they’re probably going to be loosing a bit more business too. Time to find somewhere else that sells linux laptops!

Ubuntu 8.10 on my Dell Inspiron 1525

I got a new laptop about a year ago directly from Dell. I did this for two reasons, they had a good deal, and I wanted to support a company that supported Linux! So far I’ve been very impressed, it worked right out of the box and about the only thing that I did to it in the first few months was upgrade the OS to 7.10 (Gutsy).

Of course, that didn’t last long. I soon started messing around with beta versions of Ubuntu, doing some messy upgrades and installing patches in a fairly piecemeal fashion. After about 9 months of this and breaking various things, 8.10 (Intrepid) came out and I decided a fresh install was called for.


After backing up any files I needed (and took the opportunity to get rid of a lot of rubbish I’d accumulated on the harddrive) I booted up from a fresh Ubuntu 8.10 DVD. After a fairly standard install which has been documented in many places on the web, I booted into a fresh copy of Ubuntu.

All I can say is, fantastic, everything just worked. Even down to pairing up one of my bluetooth headsets and being able to use it automagically in Skype. The only thing that I would like is the ability to specify LDAP authentication as part of the installation process. I had the option many years ago with Mandrake/Mandriva, but for some reason Ubuntu is lagging behind.

This brings me to a point. Even a long term Linux user is still shocked that an install on a supported laptop worked flawlessly. I think that if Linux gets to the point where I am shocked that something doesn’t work as it should, then Linux is ready for prime time. Tho’ on that note, we’re still waiting for Windows to get to that stage!

About the only main configuration that I’ve done so far is LDAP authentication with credential caching incase the network isn’t available. The last thing that I want to get working is some form of syncing for some of the more critical configuration files, such as my pgp keyring, mail config and bookmarks.

As far as Ubuntu is concerned, 8.10 is a great step forward. Bluetooth works well, hot plug of devices detects the correct type of device and offers various options. Network Manager has taken a great step forward with, for me, just the addition of being able to configure a mobile phone as a bluetooth 3g modem missing, but supposedly this is on its way.

Next step is to re-install my main desktop and see how it handles the triple monitor! 🙂

Sony E-Book Reader + Linux

Guess what, I’ve got another gadget! I decided to take the splash and get one of the new Sony ebook readers, the PRS-505. I’d heard a lot about the e-ink displays, but never seen one in real life.

Well, so far I’m impressed. The resolution is fantastic, very readable in just about any light, infact it is pretty much just like reading a real book. Even better, it plays very well with Linux due to the fact that the reader itself, along with any memory cards inserted, act as a simple usb mass storage device. Plugging the reader into my laptop simply opens up the drives in seperate windows meaning I can just drag and drop any supported document. Of course, some formats work better than others. TXT and RTF files are the simplest format and work well, tho there are no chapters or any other fancy information. PDFs are more or less usable, tho they usually need to be zoomed in which ruins the layout. The best format that I’ve found so far is LRF which is Sony’s binary format for the PRS-500 and PRS-505.


This is all well and good, but there is a better way to move the files over, and also convert different formats. Calibre is a free python program which acts as conversion software, ebook library, and will also copy the files to your reader. Installation under Ubuntu is extremely straight forward, just run the following:

 sudo apt-get install  python-setuptools python-imaging  libqt4-core libqt4-gui \
                      python-qt4 python-mechanize imagemagick \
                      xdg-utils python-dbus python-lxml python-beautifulsoup \
sudo easy_install -U calibre
sudo calibre_postinstall

Instructions for installing on other systems (including Windows and OS X) can be found on the Calibre download page.

The library functionality lets you add any ebooks that you have and search for cover images, the ISBN, publisher and sometimes a brief synopsis. The conversion software will allow you to convert any type of supported file into either EPUB or LFS, even automatically detecting chapters in TXT and RTF files. Finally, once you’ve added your books and converted them to your prefered format, simply plug your reader in and click the copy button. Once the files have been copied over you can unmount the filesystems and read the books on the reader!

Conversion settings that I recommend are to convert all files to LFS format with 8pt fonts and 2pt spacing which is fine for me, but can be zoomed in if you want bigger print. Also, I like to insert a blank line between each paragraph to make the text more presentable. Lastly, I make sure that the chapter detection inserts any chapters found into the table of contents. So far I’ve found that these settings work with just about all my files. I’ve still to mess around properly with PDF files to find the best results for these.

Before converting any files, make sure that you have filled in as much of the information as possible for the book as some of this information will be included in the converted output making organisation a lot easier on the reader, especially if you fill in the series information to group books together.

All in all I’m glad I bought the reader. I think it will come in very useful, tho’ there are a few things that I hope will be improved on in future versions. One of which is a larger screen. The reader is about the same size as a standard paperback, which is fine, but the screen doesn’t fill the whole device. Sony could easily do away with the big round buttons on the bottom edge and make the screen a fair bit bigger which would improve the reading of PDF files no end. I’d also like to see slightly better contrast on the screen to make it more book like. As it is the background is grey and the black isn’t exactly a deep black so it can look a little washed out. I may be nit picking, but isn’t that what the net is for?! Of course the benefits definitely outweigh these couple of problems. Battery life so far seems phenominal, with the battery meter not moving off full charge yet! Supposedly I should be able to do about 6800 page turnsper charge, seeing as the e-ink technology only uses power when actually changing the screen. So far I’ve read a couple of books on it and not really noticed that I was reading a screen rather than a standard book, only noticing when my hand slipped and the cover closed without losing my place!

Well, hopefully I’ll get PDF files playing happily soon and then it will be pretty much perfect. In the meantime, it came with 100 free books, and I’ve been scowering project Gutenberg to find some books to read. Should be enough to keep me going!


OpenID working with LDAP

Something I’ve been meaning to get round to for quite a while is setting up an openID server. I’ve finally done it! Even better, this server is linked into my ldap server which allows for consistent passwords for everything. Getting it working took quite a while. The openid-ldap software was fairly tricky to configure and the apache configuration was a nightmare for me of regular expressions, something that in all my geek years I’ve managed to stay away from in any depth. (I’ve learnt a fair bit through osmosis, but never sat down and looked at some regexp documentation). Read on for my instructions on setting this up.

Before we start

Before we begin, a few assumtions. This article assumes that you have:

  • A working permanent internet connection (DSL/Cable/Better)
  • An apache web server running and accessable from the internet over SSL, preferably with virtual hosting set up
  • A domain name that you want to tie your openid into and full control to add/change A/CNAME records
  • I did this on Debian, most distro’s should be similar but may use different directories
  • An LDAP server up and running (and working! – ie, tied into user logins, imap, etc)


My first step was to download the openid-ldap software and uncompress it into the root of your web server (eg. /var/www on Debian), then rename the directory to something easier to type.

cd /var/www
wget http://www.openid-ldap.org/releases/openid-ldap-0.8.7-noarc.tar.gz
tar xfzv openid-ldap-0.8.7-noarc.tar.gz
mv openid-ldap-0.8.7 openid
chmod a+r openid/ldap.php

You should be able to now access http://yourserver/openid to make sure it works. If you get any errors you’ll need to check your apache config. If everything is working then the next step is to get the ldap section working. In the openid directory open up the ldap.php and you will see a load of configuration parameters to edit. The important ones are:

$GLOBALS['ldap'] = array (
        # Connection settings
        'primary'               => 'yourldapserver',
        'fallback'              => 'yourbackupldapserver',
        'protocol'              => 3,
        'isad'                  => false, // are we connecting to Active Directory?
        'lookupcn'              => false, // should we extract CN after the search?
        'binddn'                => '',
        'password'              => '',
        'testdn'                => 'uid=%s,ou=People,dc=example,dc=net',
        'searchdn'              => 'ou=People,dc=example,dc=net',
        'filter'                => 'uid=%s',
        'nickname'              => 'uid',
        'email'                 => 'mail',
        'fullname'              => 'displayName',
        'country'               => 'c'

binddn and password shouldn’t be needed at all for most ldap servers to check if a user exists. If your server needs authentication, fill in these fields. You’ll also have to lock down the ldap.php file to restrict people seeing the plaintext password. testdn is the dn used to see if a uid exists. searchdn is the base under which to search for valid users.

To check that the ldap configuration is working, go to the url http://yourserver/openid/?user=at which you should see a welcome message. If not, go back and check your ldap configuration. There are some handy hints and tips in the openid-ldap README.

My next step was to set up some virtual hosting. This isn’t strictly nescessary, but it is the difference between an openid of http://www.example.net/openid/user and http://openid.example.net/user. Not much of a difference, but I wanted a challenge. For now, I will assume that we’ll just do a normal set up and I’ll leave the virtual hosting option up to the reader.

Because openid-ldap sends the username and password over basic authentication you should take it as a requirement to use your openid over SSL. I had a fun time getting this working along with the virtual hosting, but will leave this again up to the reader. There are countless helpful web pages out there to get ssl working on an apache web server.

Ok, once you have openid-ldap talking to your ldap server, SSL working, and possibly virtual hosting, it is time for the final bit of configuration. This part took me the longest to get working due to the mod_rewrite instructions that came with openid-ldap not working for me. For the openid to be kept simple and in the form url/user, rather than url/index.php?user=user, openid-ldap makes use of mod_rewrite in apache to (funnily enough) rewrite the url. To do this you need to edit the apache configuration for the directory under which openid sits to add:

RewriteEngine On

   RewriteCond %{REQUEST_URI}      !^/(.+)\.php(.*)$
   RewriteCond %{THE_REQUEST}      ^[A-Z][A-Z][A-Z]\ \/([A-Za-z0-9]+)\?(.*)\ HTTP/
   RewriteRule ^(.*)$        /openid/index.php?user=%1&%2

   RewriteCond %{REQUEST_URI}         !^/(.+)\.php(.*)$
   RewriteRule ^/([A-Za-z0-9]+)$  https://www.example.net/openid/index.php?user=$1

Restart apache and go to the url http://www.example.net/openid/. Hopefully you should see a welcome screen and a login button at the bottom. Click on the login button and a login box should appear. Type in your username and password, click ok, and you should be taken back to the login screen with a message that you are now logged in.

Thats it, you’ve got openid working. As mentioned, you can fine tune this to produce an easier url to type in, but this is a matter of preference. Hopefully someone may find this article useful. If you do, please drop me a mail or add a comment.


Caller ID from Asterisk to all phones, MythTV’s and SqueezeBoxes

Well, I had some spare time and finally got round to getting CallerID sorted on my phones. I’ve had it enabled on the line for a while now, and even had it doing database lookups to display a name on the phone handsets as well as the number, tho’ that broke when I upgraded Asterisk. I have, however, sorted out that problem and expanded everything a little.

Now, when the phone rings, the number is looked up in a database of known numbers, then sent out to all the phone handsets as well as any active MythTV frontend or Squeezebox on the network! If we are watching the TV a box pops up with the time, date, number, and if found, name of the incoming call. Likewise if we are in the library where we can’t actually hear the phone, then the Squeezebox display will change to the name and number and we can decide wether to answer it or not!

All this is done using a feature in Asterisk call AGI, or Asterisk Gateway Interface. This is very similar to CGI scripts found on web pages. AGI scripts are run from the Asterisk dialplan to do various things. In this case the AGI perl script is run and the incoming call number is passed to it. This number is looked up in a database to see if its a known number. Wether it is known or not, the script sets the full CID info in Asterisk.

It then procedes to use a utility call cidbcast that is in the contrib directory of MythTV. This cidbcast sends out a UDP broadcast over the network to any listening machine, in this case the MythTV backend server which has the mythudprelay program running, another one from the MythTV contrib directory. This picks up the broadcast and sends the message to all MythTV frontends using mythtvosd.

Lastly the AGI script connects to the SlimServer which controls all the Squeezeboxes. Talking over the CLI port (9090) on the server it gets a list of all current players and proceeds to send a simple two line display message consisting of the number and name. The majority of this part of the script is a simple cut and paste of the relevant parts of the Squeezebox plugin written by Max Spicer.

All in all this is a fairly simple thing to implement, but is very useful for those as lazy as me!



use DBI;
use IO::Socket;

# MySQL settings for asterisk
my $dbhost = 'localhost';
my $dbuser = 'asterisk';
my $dbpass = 'asterisk';
my $dbname = 'asterisk';

# Slimserver Settings
my $serverAddress = 'mythbe-1';
my $serverPort = 9090;
my $maxVolume = 75;
my $displayTime = 30;
my $debug = 0;

# Mythtv Setting
my $mythxmlfile = '/usr/lib/asterisk/cidbcast.xml';

# Get name from mysql for the incoming number

#Get the initial data
     my %input;
     while() {
         last unless length($_);
         if (/^agi_(\w+)\:\s+(.*)$/) {
         $input{$1} = $2;

my $dbh = DBI->connect ("dbi:mysql:host=$dbhost:database=$dbname","$dbuser","$dbpass") or die "Can't connect to database: $DBI::errstr\n";
my $sth = $dbh->prepare( "SELECT cid FROM known_numbers WHERE source='$input{callerid}'" );
@row = $sth->fetchrow_array();
$cidname = @row[0];
print "SET CALLERID \"@row\"<$input{callerid}>";

# Broadcast info to MythTV
my $command;
$command = "cidbcast --once --file=$mythxmlfile 6947 $input{callerid} \"$cidname\" line";
system("$command &> /dev/null");

# Send out to squeezeboxes
# Code ripped from Squeezebox CID plugin by Max Spicer
# http://www.thespicers.net/cid.html

my $socket = IO::Socket::INET->new (PeerAddr => $serverAddress,
                                    PeerPort => $serverPort,
                                    Proto    => 'tcp',
                                    Type     => SOCK_STREAM)
or die 'Couldn\'t connect to server';

# Get the number of players
my $playerCount = sendAndReceive('player count ?');
$debug && print "$playerCount players found\n";

# Display message on each player and adjust volume if necessary
for (my $i = 0; $i < $playerCount; $i++) { my $playerId = sendAndReceive("player id $i ?"); # Put the players display at max brightness if it's currently 0 my $powerState = sendAndReceive("$playerId power ?"); my $brightnessPref = $powerState ? 'powerOnBrightness' : 'powerOffBrightness'; my $brightness = sendAndReceive("$playerId playerpref $brightnessPref ?"); $debug && print "brightness: $brightness\n"; if ($brightness == 0) { sendAndReceive("$playerId playerpref $brightnessPref 4"); } $cidname =~ s/\s/%20/g; $debug && print("Sending: $playerId display Incoming%20call:%20$input{callerid} $cidname $displayTime\n"); sendAndReceive("$playerId display Incoming%20call:%20$input{callerid} $cidname $displayTime"); # Drop the volume if necessary my $playerMode = sendAndReceive("$playerId mode ?"); $debug && print "playerMode: $playerMode\n"; if ($playerMode eq "play" && sendAndReceive("$playerId mixer volume ?") > $maxVolume) {
    $debug && print "Decreasing volume\n";
    sendAndReceive("$playerId mixer volume $maxVolume");
$debug && print "\n";
exit 1;

# Send given cmd to $socket and return answer with original command removed from
# front if present.  Routine nicked from code by Felix Mueller. :-)
sub sendAndReceive {
  my $cmd = shift;
  return if( $cmd eq "");

  print $socket "$cmd\n";
  $debug > 1 && print "Sent $cmd to server\n";
  my $answer = <$socket>;
  $debug > 1 && print "Server replied: $answer\n";
  $answer =~ s/$cmd //i;
  $answer =~ s/\n//;

  return $answer;

Database table structure

mysql> describe known_numbers;
| Field  | Type        | Null | Key | Default | Extra |
| source | varchar(13) |      | PRI |         |       |
| cid    | varchar(26) |      |     |         |       |

When two heads aren’t enough!

Just having a dual head display just wasn’t enough. I went the whole hog, bought myself a PCI graphics cards and another identical monitor!

Its all up and running, but I just can’t get 3d acceleration to work on it properly. I’ve only had a quick go, and everything seems to be right, but glxgears just crashes. Its only really a problem if I want to play games, and for the time being I’ve got too many other things to do!