Pages

Friday, August 10, 2018

OpenSCAD: Camera case for the Raspberry Pi camera module

Introduction

At the end of 2015 I placed a DIY security camera in our house with a view on our backyard. The camera consists of a Raspberry Pi model B and a 5MP camera board module (It's been replaced by a 8MP version). I used Motion, a very flexible program that monitors video signal, on top of Raspbian. It worked all these years without problem but over time the wooden case that I made was starting to fall apart. I therefore decided to create a 3D printed camera case to replace it. I also wanted to use this opportunity to eliminate the problem of glare on sunny days.


Design of the Camera Case

The camera case consist of five parts. A back and a front of the case, a camera holder and lens to protect the camera module and easily insert it into front of the case, and a lens hood to prevent glare.  I used OpenSCAD, a free and open source program to design 3D CAD models. The Constructive Solid Geometry properties of OpenSCAD are excellent for these kind of designs. The back case has mounting points for the Raspberry Pi. I use the Raspberry Pi B but the mounting points are easily changed for other Raspberry Pi models, in fact I already added the coordinates for some other models.

I updated the design with stop ring for the lens module to prevent the lens to slide into the camera a little so this is a link to version 2. If you want to make the case yourself or just want to tinker with it here is a link to the OpenSCAD file: https://drive.google.com/open?id=1qJ7picRoSDI_HNSntF7nptrMazSRV3FF


Thursday, April 5, 2018

Maintaining the Raspberry Pi Squeezebox server (aka Logitech Media Server)

Introduction

I wrote earlier about the Logitech Media Server (LMS), open source software that I've used to turn a Raspberry Pi into a music server for my Squeezebox devices. I'm using my Raspberry Pi based Logitech Media Server a couple of months and I've grown very fond of it. What started as an experiment now has become a device I'm starting to rely on. I guess that eventually I have to replace it with something like the WD PiDrive Node Zero. In the meantime however I do need to maintain the LMS. In this blogpost I'll explain how I add and remove music files from the LMS and create a simple backup of your music files. Finally I provide a tip to debug problems with the Logitech Media Server. All software that I used for this project is free and open source.

My Raspberry Pi turned into an LMS with 3D printed case on my desk.

Adding, changing and deleting music files

I partly ripped my CD collection and still add new albums. All the ripping is done on my Thinkpad T40 laptop using Asunder, a low resource ripper for Linux, on the Puppy Linux operating system. In the beginning I unmounted the USB hard disk from the LMS, removed it and connected it to the laptop and copied the new albums. This proved to be be a clumsy method and I quickly found myself looking for an alternative.

I decided to use FTP to transfer files over the network to the Raspberry Pi. FTP is a network protocol to transfer files between a client and a server. The software that I'm using is either FileZilla or gFTP. They have basically the same functionality but gFTP is not available for Windows while FileZilla is available for GNU/Linux, OSX and Windows. Working with both is easy enough the only problem that I had was to set the ownership for the USB hard disk on the Raspberry Pi. Only root was able to write to the disk. The reason is a bit technical and maybe confusing but I had used the Windows FAT filesystem for the USB hard disk and when I mounted it on my Linux laptop (Puppy Linux distro), ownership of all files was changed by Puppy Linux to root. At this point it was impossible to change ownership and permissions with chmod and chown from the media server. To solve this problem I had to unmount and mount the USB hard disk using the following general command:
mount device mount-point -o uid=foo -o gid=foo
or in my case
mount  /dev/sda1 /media/usb-drive -o uid=pi -o gid=pi
This command sets the ownership of all files on the USB hard disk to pi instead of root enabling me to use FileZilla and gFTP.

Creating a backup of the music collection

I invested a lot of time in ripping my CD collection so it would be a shame if I lost my music files due to a hard disk crash. I therefore use a very simple backup method, largely copied from the Raspberrypi.org website to ensure that my files are safe.
cd /home/media/usb-drive
sudo tar czf usbdrive.tar.gz
This creates a file 'usbdrive.tar.gz' that contains files in /media/usb-drive, the mounting point of my USB drive and places it in the same map. Next I use (again) Filezilla to move the backup file to my desktop computer.

Debug problems with the Logitech Media Server (tip)

I didn't encounter much problems with the LMS but if you do take a look into the log file of the server. This can be done opening a terminal on your PC and login into the Rasperry Pi with:
ssh pi@<your_network_ip_address_of_the_server>
cat /var/log/squeezeboxserver/server.log
The sudo ssh command prompts for the password of the Raspberry Pi.  Now look for anything suspicious in the log, copy it and do an internet search with your preferred search engine. Chances are someone already encountered the same problem.

Earlier posts about the Logitech Media Server:

Setting up a Raspberry Pi Logitech Media Server
https://eribuijs.blogspot.nl/2017/08/creating-raspberry-pi-squeezebox-server.html

3d printed enclosure for the Raspberry Pi Logitech Media Server
https://eribuijs.blogspot.nl/2017/11/raspberry-pi-squeezebox-server-with-3d.html

Thursday, February 15, 2018

OpenSCAD: A Curved 3d Printed Lithophane

Introduction

How can I wrap a flat surface around a cylinder in OpenSCAD. This was a question I asked myself. OpenSCAD doesn’t provide a ready made method so we need to write our own. Luckily we don’t have to invent the wheel here, others have done that already. Justin Lin has written a very handy tutorial on his website Openhome.cc how to wrap a text around a cylinder.  In this project I took it a step further and wrapped a png image over part of a cylinder resulting in a curved image.

3D printed curved lithophane

Curved lithophane

It seemed like fun to combine this technique of wrapping with the 3D print of a lithophane. A lithophane is an engraved image on translucent material. Many 3D printers have already produced lithophanes sometimes with stunning results. For this experiment I’ll use white PLA because it  has excellent translucent properties.

Now first let me explain the basics on how to wrap a 2D image around a cylinder. First we create a circle out of triangles. These triangles are then extruded to segments to form a cylinder.  Next all segments of the cylinder are lined up in a row and the image is place on the far side but just within the limits of the segments. When we intersect the image with every individual segment and return the segments to their original position in the cylinder, a curved image emerges (see images below).

A circle created out of triangles
The extruded triangles form a cylinder
The segments are lined up in a row

Image placed on the far side of the triangles
The triangles returned to their original positions
The image intersected with the triangles and returned to their original position.

If you want to know more please watch my video. In this video the OpenSCAD script is explained and demonstrated. Also is shown how to import the stl file in Cura and what settings are used.

Thursday, December 14, 2017

OpenSCAD: Generating Triangles and Poyhedron

Polyhedron, vertices and faces

OpenSCAD offers three methods to make 3D model. First is Constructive Solid Geometry where primitive objects are combined using boolean operations. The second method uses two dimensional shapes that are extruded either in the z direction (linear_extrude)) or around the the z-axis (rotate_extrude). In the third method vertices (or points) and faces are defined to shape the surface of a 3D model (polygon mesh). This, at least in theory, provides us with a method to create the most complex 3D shapes.

Polygon mesh of a dolphin. In this example a triangle mesh is used. A public domain image from Wikipedia (https://en.wikipedia.org/wiki/Polygon_mesh#/media/File:Dolphin_triangle_mesh.png)

The third method can be achieved with the polyhedron function of OpenSCAD. The description polyhedron function in the OpenSCAD manual is more than adequate but it only provides the user with examples where the vertices and faces are manually entered in OpenSCAD. This can be a cumbersome process that is prone to bugs, leading to a non-valid solid. Having OpenSCAD generate these vertices and faces is a method that is more favorable (at least to me) for two reasons. First once the algorithm is correct the chance to generate non-valid solids is minimized but more importantly computer is so much faster in calculating the vertices needed.

Triangle mesh of a sphere

An important question is what kind of faces are needed for our polygon mesh. From OpenSCAD version 2014.03 onward a face description can have any number of vertex larger than two however I think that the triangle mesh is still the best choice. If the user chooses more than three vertices OpenSCAD subdivides the faces to triangles and this can cause problems as is demonstrated in an article of Justin Lin where a cube that consist of four vertex faces and one of the faces is not planar with the other three. So in conclusion the triangle mesh provides the best control over the 3D model in OpenSCAD.

In the following video tutorial I'll explain how to create such a 3D model of a sphere, cone, torus and cylinder in OpenSCAD.

Wednesday, November 1, 2017

Raspberry Pi Squeezebox server with 3d printed enclosure

The need for a enclosure

Back in August I created a Squeezebox server using a Raspberry Pi 2 and a USB harddrive I had both lying around. I quickly had the server up and running and I'm using it ever since but I didn't have a enclosure. A 3D printed enclosure would enable me to give the server a more permanent place and at the same time I'm getting rid of these components and cables lying around on my desk.

The Squeezebox server sitting nicely into the 3d printed enclosure that I designed for it.

Solvespace for the enclosure

As a 3D CAD tool to design the enclosure I choose Solvespace. Solvespace is free and open source available for Windows, OSX and Linux. I use Solvespace a lot and it has it's limitations but I felt it was fully capable for this job and indeed it didn't disappoint. Before starting I made a couple of simple drawings with pen and paper, I measured the size of the harddisk and the Raspberry Pi. I also used a template for the Raspberry Pi mounting holes that I found online.

With all this information I started drawing with Solvespace. The power of Solvespace (and other 3D CAD programs) is that's it's very easy to make changes to the 3D design. While working on the design I noticed that USB harddisk can become hot so I figured it needed to be cooled. In the drawing I elevated the harddisk a bit by adding four supports one on each corner of the disk and made four ventilation slots in the bottom of the enclosure thus allowed air to flow freely around the harddisk. The Solvespace files of this enclosure are here. Make sure to adjust the size to the USB HDD you're using.

The 3D design I came up. The printed parts, bottom and lid, are grey, the green part is the Raspberry Pi and the red part is the USB harddrive.

3d printing and assembly

I printed all the parts on my Hephestos 2 printer using black PLA filament and the result looks pretty good. Assembly of the parts is simple. First I used 2.5mm bolts and nuts to mount the Raspberry Pi upside down to the lid of the enclosure. Next I insert the USB HDD into the bottom placing it on the elevated supports.  The enclosure is fastened with four bolts 5x60mm and 5mm nuts. The nuts fall nicely into the hexagonal cavity of the feet. Finally the USB cable of the HDD is connected with the Raspberry PI and the ethernet cable is connected from my router to the Pi. The server has run for several weeks in the 3d printed enclosure without any problem. For those that want more information I made a YouTube video about this project.

Tuesday, October 3, 2017

OpenSCAD Essentials: Lists and list manipulation

Lists

This is the second part in a series on OpenSCAD (here is a link to the first). This series will not cover the very basics of OpenSCAD, there is plenty of good material on that, but it's for those who want to advance beyond these basics. This part is about Lists, sequences of OpenSCAD values. These are very important in OpenSCAD because they are the equivalent of arrays. They're also referred to as vectors. Lists can contain values numbers, booleans and strings. For most examples below version 2015.03 is required.

Quicksort example from the OpenSCAD User Manual demonstrates how to manipulate a list. The red row of cylinders represents the unsorted list while the green row represents the sorted list.

First let's create some lists by typing the following in the OpenSCAD editor.

lst = [1,2,3,4,5,6,7,8,9]; //a list of numbers
lst2 = ["red","yellow","blue"]; //a list of strings
lst3 = [false,true,undef]; //a list of booleans
echo(lst);
echo(lst2);
echo(lst3);

In OpenSCAD the user is able to automatically generate lists with for, if and let. A couple of examples

lst4 = [for (i = [0:9]) i*i];

This generates a list of [0, 1, 4, 9, 16, 25, 36, 49, 64, 81], so for every i the results is i multiplied by i. OpenSCAD even allows nested loops

lst5 = [for (i = [0:2]) for (j =[0:2]) for (n=[0:2]) [i,j,n]];

This generates a list of a long list of vectors ECHO: [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 2, 0], [0, 2, 1], [0, 2, 2], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 2, 0], [1, 2, 1], [1, 2, 2], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 2, 0], [2, 2, 1], [2, 2, 2]]

Manipulate a list

A list in OpenSCAD can be manipulated with a function. Manipulation is needed in order to make changes to the list. Since OpenSCAD is a Functional Language we can't just for example change value in the list. We need a function to do this. Lets assume we want to create a partial list from an existing list. We then create the following function:

function partial(list,start,end) = [for (i = [start:end]) list[i]];
echo(partial(lst,1,8));

In the Console of OpenSCAD the following is displayed ECHO: [2, 3, 9, 5, 6, 7, 8, 4]. The function has three parameters: a list, a start number and an end number. The function iterates through the list and then creates a new list with the items with indices 1 to 8. Note that the first item in the list with index 0 has been excluded from the new list. Another example.

echo(partial(lst,4,7));

This prompts ECHO: [5,6,7,8], a list with the 4th to the 7th item of lst. Remember that lst itself hasn't changed (you can check this yourself). Next we write a function to remove a number in a list.

function remove_item(list,position) = [for (i = [0:len(list)-1]) if (i != position) list[i]];
echo(remove_value(lst,2));

This prompt ECHO: [1,2,4,5,6,7,8,9], the third item in the list has been removed. The function, that has the parameters list and position, loops through the items of the list and if the index i is not equal to the parameter position it is added to the new list. In this example it means that the item with the index 2 is not part of the new list. The following function inserts a value instead of removing it.

function insert(list,value,position) = let (l1 = partial(list,0,position-1), l2 = partial(list,position,len(list)-1)) concat(add_value(l1,value),l2);
echo(insert(lst,10,4));

It cuts the list on the position 4 in two new lists, inserts a number of 10 between the two lists, using the function partial that was created above. The result in the console is: ECHO: [1, 2, 3, 4, 10, 5, 6, 7, 8, 9]. BTW: It's entirely possible that there's an easier way to do this.

The last and most complicated example is taken from the OpenSCAD User Manual and implements the quicksort algorithm. The quicksort function uses an unsorted list as input and produces a sorted list with a recursive method.

lst6 = [1,4,6,7,3,5,7,2]; //a list of numbers
function quicksort(list) = !(len(list)>0) ? [] : let(
    pivot   = list[floor(len(list)/2)],
    lesser  = [ for (i = list) if (i  < pivot) i ],
    equal   = [ for (i = list) if (i == pivot) i ],
    greater = [ for (i = list) if (i  > pivot) i ]
) concat(
    quicksort(lesser), equal, quicksort(greater)
);

echo(lst6);
echo(quicksort(lst6));

It produces the following output ECHO: [1,2,3,4,5,6,7,7]. The function starts with a base case !(len(list)>0) ? [] meaning if a the length of list is 0 return an empty list (or the boolean value false) else continue. Next a pivot is determined being the number in the middle of the list, in this case the number 3. Next all numbers in the list smaller than 3 are placed in a list lesser, all numbers equal to 3 are placed in a list equal and all numbers larger than 3 are placed in a list greater. These three list are then concatenated to a new list however, and now we get to the recursive parts, the lesser and greater lists are the new parameters for quicksort. This iteration continues until the base case, the length of the list is equal to zero or less, is reached.

Understanding lists and list manipulation is essential to advance in OpenSCAD. Without it would for instance be near impossible to work with the all important vectors in both 2D and 3D. But also in other areas, such as iterating through a row, lists are essential.

Friday, September 15, 2017

OpenSCAD Essentials: Functional Programming

Functional programming

OpenSCAD is a 3D CAD program where the 3D model is created with a script. Although the basics are very simple there is a point on the learning curve where the OpenSCAD programming language can become confusing. OpenSCAD is a Functional Programming Language and behaves differently than most people, used to the Imperative Programming Paradigm, expect. With Imperative Programming a value can be assigned to a variable and later another value can be assigned to same variable later in the program. This changes the state of the program. This approach will not work in OpenSCAD.

Sierpinski triangle in OpenSCAD. A program I made earlier that demonstrates recursion in OpenSCAD.

An example

The easiest way to explain this is with a simple example. In this example we want the program to add the numbers 1 to 10 (1+2+3+4+5+6+7+8+9+10).

total = 0;

module count(number) {
    for (i = [1:number]) {
        total=total+i;
    }
    echo(total);
}

count(10);

You might expect that the answer is 55 however to your horror you'll find in OpenSCAD that it actually is 0. What happened? Instead of assigning a new value to the variable total for every interation, total keeps it's initial value. The program written in OpenSCAD is a mathematical expression that is evaluated by pressing F5. OpenSCAD supports powerful functional constructs to support these expressions. In the case of the example above we write.

function sum(number) = (number == 0 ? 0 : number + sum(number-1));

echo(sum(10));

The result of this program is 55 as intended but how does it work. We define a function (hence the name Functional Language) sum with a parameter number. On the right side of the function there is an evaluation, in pseudocode: if n == 0 then 0 else number + sum(number-1). Notice that the function is recursive so for example for number is 3 the function evaluates as follows

sum(3) = 3 + sum(2) = 3 + 2 + sum(1) = 3 + 2 + 1 = 6

Iteration in OpenSCAD is usually accomplished via recursion. If you are not used to recursion it's takes effort and practice to understand but it's often simple and elegant. Now let's do a somewhat more complicated example, the greatest common devisor (gcd). When we look at gcd algorithms on wikipedia we find the recursive Euclidian algorithm which is described as follows:

gcd(a,0) = a
gcd(a,b) = gcd(b, a mod b)

Even if we would not understand the algorithm it's easy to translate it to OpenSCAD

function gcd(a,b) = b == 0 ? a : gcd(b,a%b);

Where a%b means a modulo b (BTW: the syntax used in the functions above is similar to the programming language C). It's worthwhile as a training to find recursive algorithms and try to implement them in OpenSCAD.

Further reading

If you want to advance in OpenSCAD it is necessary to read the manual at some point. This discloses valuable information that is hard to find by just using the Cheatsheet or the watching YouTube videos. The user manual can be found here: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language