Monday 22 June 2020

OpenScad Useful Functions

Some useful OpenScad functions / code

row = array_lookup(search, array, column)

OpenSCad doesn't support variable as such, so things need to be done recursively.
function array_lookup(query, source, column) = _array_lookup_rec(query, source, column, 0) ;
function _array_lookup_rec(query, source, column, row) =
    row>=len(source) ? len(source)-1 :
   query==source[row][column] ? row :
  _array_lookup_rec(query,source,column,row+1) ;
srcarray = [
[ "green", "apple", 5 ],
[ "green", "pear", 9 ],
[ "yellow", "banana", 5 ],
[ "ERROR", "ERROR", 0 ]
] ;
row1 = array_lookup("pear", scarray ,1) ;

i = toint(s)

This function uses recursion to work along the string.  It converts the supplied 's' to a string just in case an integer is supplied to the function.

// Safe Convert Decimal String to integer
function toint(st) = _toint_rec(str(st),0, 0) ;
function _toint_rec(st, idx, value) = (
    idx>=len(st) ? value
    : _toint_rec(st, idx+1, ( value*10 + ord(st[idx])-ord("0")) ) ) ;


This module produces a prism with a base which is X x Y and a height Z
The top edges can be moved in with the X and Y margins.
// prism base = x by y. left margin = xm1, bottom margin = ym1 etc.
module prism(x, y, xm1, xm2, ym1, ym2, z, center){
    CubePoints = [
        [ 0,  0,  0 ],  //0
        [ x, 0, 0 ],  //1
        [ x, y, 0 ],  //2
        [ 0, y, 0 ],  //3
        [ xm1,ym1, z ],  //4
        [ x-xm1, ym1, z ],  //5
        [ x-xm1, y-ym2, z ],  //6
        [ xm1, y-ym2, z ]]; //7
    CubeFaces = [
        [0,1,2,3],  // bottom
        [4,5,1,0],  // front
        [7,6,5,4],  // top
        [5,6,2,1],  // right
        [6,7,3,2],  // back
        [7,4,0,3]]; // left
    if (center) {
        translate([-x/2,-y/2,-z/2]) polyhedron(CubePoints, CubeFaces);
    } else {
        polyhedron(CubePoints, CubeFaces);
} ;

USB Webcam(s) with Raspberry Pi

Configuration Steps

Update the Pi

sudo rpi-update

Ensure the right modules are loaded

lsmod | grep uvcvideo
uvcvideo               94208  1
videobuf2_vmalloc      16384  2 uvcvideo,bcm2835_v4l2
videobuf2_v4l2         28672  5 bcm2835_isp,uvcvideo,bcm2835_codec,bcm2835_v4l2,v4l2_mem2mem
videobuf2_common       57344  6 bcm2835_isp,uvcvideo,bcm2835_codec,bcm2835_v4l2,v4l2_mem2mem,videobuf2_v4l2
videodev              237568  8 bcm2835_isp,uvcvideo,bcm2835_codec,videobuf2_common,bcm2835_v4l2,v4l2_mem2mem,videobuf2_v4l2
mc                     45056  8 bcm2835_isp,uvcvideo,bcm2835_codec,snd_usb_audio,videobuf2_common,videodev,v4l2_mem2mem,videobuf2_v4l2
ls -la /dev/video?
crw-rw-rw- 1 root video 81, 0 Jun 22 14:17 /dev/video0
crw-rw-rw- 1 root video 81, 1 Jun 22 14:17 /dev/video1

Add any missing modules to  /etc/modules-load.d/video.conf

e.g.:  snd-bcm2835,  i2c-dev,  bcm2835-v4l2, uvcvideo

Disable PI (non USB) camera



In order for this to work, the /dev/video0 port must exist and be accessible.

Ensure the USB video is not blacklisted

sudo rm /etc/modprobe.d/ubcvideo-blacklist.conf

Ensure the port is accessible

chmod ugo+rw /dev/video?

(this is crude - the proper thing to do is ensure that the users accessing the camera are in the 'video' group).

Programs that use the camera

uv4l - conferencing tool
motion - security camera tool
ffmpeg - video streaming


Note that motion supports video, but not audio.  This example configures it for streaming, and disables the local snapshots.

sudo apt-get install motion

vi /etc/motion/motion.conf
daemon on
output_pictures off
output_debug_pictures off
ffmpeg_output_movies off
ffmpeg_output_debug_movies off
ffmpeg_video_codec mpeg4
stream_localhost off
webcam_localhost off
camera_id = 1
videodevice /dev/video0
input -1
width W
height H
framerate F
v4l2_palette P
stream_port 8091

W,H,F,P characteristics can be identified with: ffmpeg -hide_banner -f v4l2 -list_formats all -i /dev/video0
Compressed: mjpeg : Motion-JPEG : 1920x1080 1280x720 640x360 1920x1080
Raw :  yuyv422 :  YUYV 4:2:2 : 640x360
Options for P are found in the comments in motion.conf
MJPEG = 8, YUYV = 15
The next camera goes in camera2.conf - It's videodevice will be /dev/video2 (not /dev/video1).  Make sure you pick a different ID and stream port.

Enable motion daemon
# sudo vi /etc/default/motion
Start motion
# systemctl enable motion
Check log files:
tail /var/log/syslog


Building and Installing

Setup for cross-compiling on Linux PC
sudo apt-get install build-essential git-core
sudo git clone /opt/tools
Fetch Repositories and ready for build
git clone git://
cd ffmpeg
git clone
git clone
export CCPREFIX="/opt/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-"
Build ffmpeg and libraries
# Build x264
cd x264
./configure --host=arm-linux --cross-prefix=${CCPREFIX} --enable-static --disabl
cd ..
# Build ffmpeg with x264
./configure --enable-cross-compile --cross-prefix=${CCPREFIX} --arch=armel --target-os=linux --enable-gpl --enab
le-libx264 --extra-cflags="-Ix264/" --extra-ldflags="-ldl -Lx264/"
cd ..
Modify mkvserver/Makefile
LAV_LDFLAGS = -L ${FFMPEG}/libavcodec \
-L ${FFMPEG}/libavformat \
-L ${FFMPEG}/libavutil \
-L ${FFMPEG}/libswresample \
-L ${FFMPEG}/x264 \
-lavformat -l m \
-lavcodec -pthread -lm -lx264 -pthread -lswresample \
-lavutil -pthread -lrt -lm \
-lx264 -lpthread -lm -ldl
Build mkvserver
cd mkvserver
cd ..
Transfer 'server' to raspberry pi, name it mkvserver and place it in /usr/bin

Configuring and Launching

Useful Commands

udevadm info -n /dev/video0
arecord -L / arecord -l
vcgencmd get_camera
ffmpeg -hide_banner -f v4l2 -list_formats all -i /dev/video0
v4l2-ctl --all

Installing and Configuring Raspberry Pi


1. Download

Download Image from

2. Write Image

Plug memory card into a Linux PC

# Identify id of card which has just been plugged in

# Copy the image onto the card
dd bs=4M if=<imagefile.img> of=/dev/sd<x>

Configuring (via HDMI)


Connect Pi to HDMI screen, and connect USB keyboard
Plug card into Pi, and turn on

Logging In and Enabling ssh

# Login with user/password as pi/raspberry

# Enable SSH (interfacing options, select Yes to SSH)
sudo raspi-config

# Reboot Pi
sudo reboot

Enabling Wireless

sudo raspi-config

Configuring (Headless)

Enabling SSH

# Remove and re-insert card into the Linux PC
# The drive should auto-mount

# Create an 'ssh enable' file
touch /mount/<user>/boot/ssh

Enabling Wireless

# Create a wireless configuration file
cat > /mount/<user>/boot/wpa_supplicant.conf 

country=GB ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="your_real_wifi_ssid" scan_ssid=1 psk="your_real_password" key_mgmt=WPA-PSK }


sudo pri-update


Wednesday 3 June 2020

Method For Calculating a 3D Printer Maximum Flow Rate


This note describes the steps taken to test and measure the maximum filament flow rate supported by a 3D printer.

The flow rate depends on a number of factors, including:

  • Hot end heating capability: how quickly can the hot end get heat into the filament as it passes through.
  •  Filament and hot-end differential temperature: How much energy is taken from the hot end when the filament is melted.
  •  Drive capability of the extruder: How quickly can the extruder motor pass filament into the hot end.

Test Overview

The test passes different lengths of filament through the hot end at a set temperature over a fixed 10 second interval.

It is noted when the extruder starts to click / slip, and the extruded filament is weighed and compared against the expected results.


Download the document here: Method for Calculating a 3D Printer Maximum Flow Rate