22 Apr

Drawing machine (vPiP)

We’ve decided to take a break from the Wireless RGB Pixels project and revisit the hanging v plotter.

We are looking at making the various parts of the system independent services that talk over MQTT. This allows us to change the various bits of the system in a modular fashion.

Starting with the communication between the current Python vPiP scripts and the hardware. This will be a c/c++ binary that subscribes to the MQTT broker and listens for messages that it should pass to the hardware. The existing Python scripts will publish the relevant plotter data to the MQTT broker. This allows us to potentially control many drawing machines at the same time. It should also make the task of adding a GUI or app a bit easier. The GUI or app will publish messages to the machines and subscribe to messages that they can act on.

As a side note, if you have been following this project, you may have seen (or experienced) the glitchy stepper motor problem recently. This was due to the duplication of python processes and has been fixed in the existing version. Get the latest code from github.

08 Jan

Wireless RGB Pixels – Prototype PCB (v1.2)

The prototype PCB for the wireless RGB pixel is at v1.2.

Front of v1.2 PCB pinout (top) and back of PCB showing NRF module (bottom)

This version fixes a mistake I made with the power pins (I misread the data sheet) and does away with the RC pin multiplexing simplfying and standardizing the SPI comms with the NRF24L01. This also means there is no serial debug output from the ATtiny.

Initial radio range tests with the test firmware are disappointing. Comms was spotty and random. I experimented with the various power levels and have tried removing some of the PCB material and re-orienting the NRF module at an angle to see if that made any difference but it didn’t appear to.

Cropped PCB material near NRF PCB antenna on left, NRF soldered at an angle on back of PCB on right.

Cheap amplified NRF modules from ebay actually reduced the range compared to a standard PCB antenna version.

It will be interesting to compare the non Arduino-IDE based firmware with the test code in terms of radio range and comms reliability. I will update when available.

19 Apr

Hanging V plotters at the Arts University Bournemouth – Part 2

After a lot of faffing, things breaking and some head scratching, the machines are all working as anticipated and we’re almost ready to start doing some drawings!

This post shows the result of running some calibration tests and some test drawings.


The Pylargraph machine is finally plotting a graph of tweets for the chosen disaster related keywords. For some reason the code had defaulted to scaling all tweets to a height of 1mm. This produced straight lines which wasn’t very interesting. Now its producing interesting line graphs.


Then we have a vPiP machine rendering a Vulcan bomber. The grid is the result of a test program that we use to check the machine is properly calibrated and will be drawing things where we think it should.


And the large format landscape vPiP machine drawing a vector of the exploded view of the Gondola (the thing that holds the pen) that this machine uses. Again, the grid is drawn by a test program.

21 Mar

Installing and configuring Pycupi

There has been some interest in Pycupi from the wider community so I figured an install/configuration guide might be handy.

IMG_7041 (2)

Tank Girl – v-plotter CMY (3 pass) Pycupi spiral arc render A2 Stabilo Point 88 Fineliner

First off this guide assumes you are using a configured Raspberry Pi that is running a recent version of Raspbian Jessie.


Python should already be installed along with PySerial. However we still need the Pillow library for image processing.

From the command line run:

pip install Pillow

If that completes without error you can move on to the install.


From the command line (and somewhere in your home directory) run

git clone https://github.com/brianinnes/pycupi.git

That will get Pycupi. Inside the Pycupi directory you will find an Arduino/Stepper directory which contains the firmware for the Eggbot/Spherebot/Polargraph controller. A Python directory which contains the core Pycupi program and test scripts. A testImages folder that contains a few images. And a wikiResources dir which contains stuff that lives on the wiki.

cd into the Pycupi/Python directory and run

python test1.py

which will probably throw an error complaining about the serial port. Thats ok, we needed to run this to have Pycupi create the default config. The default config lives in your users dir (/home/some_user/.polargraph/config.cfg). You will need to edit a few settings to match your machine before you can do any drawing.

Note: A semi-colon denotes a comment in the config file. Any line starting with a semi-colon will be ignored.

Under the [Polargraph] section, configure the following (any settings not mentioned here, which are present in the config should be left as default):

  • pensize – not currently implemented – will be ignored.
  • machinewidth – This should be set to the distance in mm between your pulleys.
  • machineheight – The physical height of you machine measured in mm from the centre of your pulleys.
  • mmperrev – The circumference of your pulleys (in mm) or how much chord or chain (in mm) is played out for each whole revolution of a pulley.
  • setsperrev – The number of steps your motors make in each whole revolution.
  • stepmultiplier – The step multiplier applied by your stepper drivers (Pycupi firmware defaults this to 8).
  • serialport – The serial port your stepper control board is attached to (/dev/ttyUSB0 on a RaspberryPi connected to the ‘Arduino Nano dual stepper board v2.1’).
  • motoraccel – A time value in seconds that determines how long it takes the motors to accelerate to their fastest speed.
  • motormaxspeed – The maximum speed the motors are allowed to move in mm/sec (needs confirmation).
  • penup & pendown – not currently implemented. Configuration angles for servo are set in the firmware.
  • homex – The home position in the (horizontal) x axis, measured in mm from the top left pulley. This position can be anywhere you like. Suggested value would be in the middle of your machine.
  • homey – The home position in the (vertical) y axis, measured in mm from the centre line of the pulleys (imaging a line drawn between the centre of the pulleys, homey will be some distance below this). This position can be anywhere you like. Suggested value would be 120mm down from the centre line, but will be dependant on your machine.

For a graphical representation of machine size measurements, see this post.

Under the [Paper] section you can define your paper size and its position.

An example A3 page would be as follows:

  • size = A3 – The name of the paper size.
  • width = 297 – Width in mm.
  • height = 420 – Height in mm.
  • posx = 175 – The position (in mm) from the left edge of your machine to the left edge of the paper.
  • posy = 240 – The position (in mm) from the top edge (centre line) of your machine to the top edge of the paper.
  • margin = 20 – A margin (in mm) around the edge of the paper where the machine will not draw (usually where you tape the paper to the machine). The specified margin will be applied on all sides of the page.
  • pixels = 3000 – The resolution for this paper in pixels.
  • rotate = false – If false the image is not rotated. If true the image will be rotated.

Under the screen section:

  • screenX = 5000 – The resolution the plot simulations will be. When generating simulations (bitmap images of a plot), you can specify a higher resolution that your final plot so you can see more detail to spot potential issues before running a plot.
  • showImage = false – not currently implemented.
  • saveImage = false – not currently implemented.

Now when you run

python test1.py

the machine should spring into life and draw a rectangle filled with smaller rectangles.

13 Mar

Pycupi v-plotter control software

MakeBmth held its regular monthly meeting at Eagle Labs Bournemouth on Thursday 10th March 2016. We plan to meet there once a month (the second regular monthly meeting will be held at the Uni or under the new Hilton Hotel – check the meetup group or forum for details).


We spent the evening learning about Brians Python port/rewrite of Gocupi, called Pycupi.

Pycupi (and Gocupi) is a cut down firmware that implements a command queue, stepper motor and servo control functions. Along with a control application written in Python (or ‘Go’ in Gocupis case). The who thing is meant to be run on a Raspberry Pi (though you could in theory run it on any computer).


Pycupi does the image processing on the Raspberry Pi and can (currently) generate simulations (jpeg images) of the expected output or it can plot that using a suitable stepper controller. The firmware in the Pycupi github repository is currently configured to work with my Eggbot/Polargraph electronics.


We learned about the multiple co-ordinate systems that are working together to produce a drawing.

Native: The co-ordinate system that works in motor steps.

System: The co-ordinate system that Pycupi maps to the native co-ordinates.

Image: The drawing co-ordinates which defines the drawing area.

We looked at how the native co-ordinates are not Polar (Angle and distance) but is a position triangulated based on the length of the two motor strings or chains. To calculate the position we need to know the machine width and how many mm of string or chain each step of the motor represents and finally a we need a reference or starting point (home).


A bit of trigonometry gives us the lengths of the strings/chains for a given position.


We looked at the different renderers currently avilalbe in Pycupi.

Spiral Arc: Renders an image using tiny spirals of varying size & density and the whole thing plots in on an Arc path from a corner (Defaults to top left (NW)).

renderSpiralArc(filename, x, y, image_width, pixel_size, drawing_object)

  • filename = the image to render (jpg/png/bmp)
  • x = the horizontal position of the top left of the image (bottom left if rotated)
  • y = the vertical position of the top left of the image (bottom left if rotated)
  • image_width = how many pixels wide the render should be
  • pixel_size = how big (in pixels) the spiral elements will be (bigger = less detail)
  • drawing_object = the python object you created to represent the machine

Norwegian Spiral: Renders an image using amplitude modulation along a spiral path from the centre of the image.

renderNorwegianSpiral(filename, x, y,image_width, density, maximum_density,pixel_size, drawing_object)

  • filename = the image to render (jpg/png/bmp)
  • x = the horizontal position of the top left of the image (bottom left if rotated)
  • y = the vertical position of the top left of the image (bottom left if rotated)
  • image_width = how many pixels wide the render should be
  • density = how densely packed the pixels will be
  • maximum_density = pixels will never be more densely packed than this (Need clarification on how these relate)
  • pixel_size = how big (in pixels) the spiral elements will be (bigger = less detail)
  • drawing_object = the python object you created to represent the machine

SVG: Draws vector images. Currently implements paths but not stroke or fill. Will cope with most elements of the SVG specification so it will happily draw curved paths.

renderSVG(filename, x, y, image_width, p)

  • filename = the vector image to render (svg)
  • x = the horizontal position of the top left of the image (bottom left if rotated)
  • y = the vertical position of the top left of the image (bottom left if rotated)
  • image_width = how many pixels wide the render should be
  • drawing_object = the python object you created to represent the machine


A Kandinsky part way through rendering with multiple colour separations.


The machine on the left is running Pycupi and has an example vector plot bottom right. The vector on the machine on the right was plotted with the Polargraph.co.uk software.


29 Feb


MakeBmth has manged to get 3 Polargraphs working! (Technically 2 v-plotters running the Polargraph.co.uk software and 1 running a Gocupi/Python mashup)


The one on the left is running the Gocupi firmware and is being run with Pycupi a Python port/rewrite of the Gocupi ‘Go‘ control software.

The other two are running the Polargraph.co.uk  a1_server firmware variant modified to run on our electronics.

The one in the middle is running with Pylargraph which is a Python script to control the original firmware with the intention of plotting or graphing the result of a regular twitter search.

The other is running with the Polargraph.co.uk control software.

The various 3d printed parts are our own designs or modified versions of existing designs.

My own designs are available on github and thingiverse but not everything is finished.

18 Sep

Polargraph Los Dios Muertos

All the cool kids dig the Mexican Day of the Dead festival make up these days… and what with Halloween just around the corner this seemed apt.


If I remember rightly, this was plotted with grid size 12, sample size 18, pixel scaling @ 1 and the usual 0.35mm pen tip for a 0.4mm Stabilo Point 88. This took over 24hrs!

The original image can be found here

15 Sep

Polargraph Einstein

The latest plot from the Polargraph. Tweaked the pixel scaling here (0.98), but I think it is slightly too much for the chosen grid size as there are gaps between some of the pixels. This was grid size 16, sample size 18 and pen tip size 0.35 on the usual 0.4mm Stabilo.IMG_20150914_212112

Try looking at the picture from a distance or squinting and see how much detail your brain adds to the image!


09 Sep

Polargraph prints

Some more recent prints from the Polargraph. This is still running with the original PCB. I haven’t yet updated the software to account for the pin out changes on v2.1.


I’ve seen the Bruce Lee picture plotted on other Polargraphs and it comes out really well, so wanted to see how it compares when plotted on my Polargraph. This was plotted with grid size @ 18 and sample area @ 20 with a Stabilo Point 88 Fineliner 0.4mm with pen tip size set to 0.35mm in software.


Sir Terry Pratchett plotted from a colour photo with grid size @ 12, sample area @ 18 and the same pen and pen tip size as above.

The new gondola design seems to be working really well now.


New Gondola design plotting Albert Einstein.


All three points of force are acting (more or less) around the centre of the pen. Two of the arms require support when printed and were rough when they came of the printer and even after cleaning up they would get stuck from time to time which cause glitches in the plot. The parts were assembled and spun on a drill and manually manipulated for a while and with the addition of some silicone grease they seem to work well now.

The removable pen holder thread dimensions are still wrong. I need to get my 3d printer running again so I can test any changes I make. In the mean time I turned the pen holder down on a lathe and it is currently a press fit, which seems to work really well. I’m tempted to get rid of the thread and redesign both parts to be press fit. That would make them quicker and easier to print.

This design also uses a lot less plastic than my previous version and also allows visibility of the pen tip so you can see exactly what is being plotted. Previously I had to wait a while for the gondola to move on to see if the pen was plotting correctly.

One additional part I need to design is the pen depth setting tool. The idea of the removable pen holder was that I could load it into a jig, drop in a pen which would then correctly set the depth of the pen in the pen holder. Tighten the screw and fit to gondola! That would allow me to do quick pen changes which would be handy if I ever get round to trying plots with multiple colours.


01 Dec

Persistence of Vision workshop

Everyone managed to get their PoV kits working. There was some pretty impressive soldering going on considering most hadn’t attempted surface mount before!

We will be running the PoV workshop again at some point next year.