Friday, 13 June 2014

Lights, camera, action ...

I have been using the excellent OctoPrint by Gina Häußge to control two of my Mendel90 printers with a Raspberry Pi for a while now. I prefer the convenience of using an Ethernet connection rather than USB. It means I can control a machine from any PC in the house rather than having to dedicate a laptop that had to be close to a machine. Here are the details of my set up: -

Mounting

There are several places a Raspberry PI can be mounted but I chose to place it on top of the PSU so that the wiring was kept short and didn't need to pass though any of the frame elements or need any new holes drilling. I.e. all the electronics are together in one bay.


I made a tray that supports the PCB all the way round and has a couple of pillars with M2.5 nut traps to screw it down. It shares the screws with the bottom of the Melzi, replacing the spacers, which are moved to the top.

raspberry_pi_assembly:
Vitamins:
  2 Nyloc nut M2.5
  2 M2.5 pan screw x 12mm
  1 Raspberry PI model B
  2 Washer M2.5 x 5.9mm x 0.5mm

Printed:
  1 rpi_bracket.stl
When it comes to mounting the camera there are again lots of possibilities. I contemplated something like this:http://www.shapedo.com/danielbull/raspberry_pi_camera_mount_for_the_nop_head_mendel90_3d_printer but I went for a straight on view from the back by printing a bar that spans the stays and clamps to the Dibond.


This gives a view orthogonal and centred with the bed so the only degree of freedom the camera needs is vertical tilt.


The bar can be clamped at any height. Lower gives a better view of the nozzle when it it close to the bed but tall objects soon go out of the field of view. Obviously a longer flat cable is needed to connect the camera to the RPI than the one supplied with it. They are readily available on eBay.

I also attached a 300 lumen LED light strip to the bar which gives enough light for the camera, even in a dark room. Having the light behind the camera avoids any glare from the glass. The particular strip I used is a SPS125 from Sanken Power Systems. I bought them several years ago and I don't think they are commonly available. However, the design is easily customisable by adding a new description to scad/vitamins/light_strips.scad. The clamps should then morph to suit.

The bar is printed in two unequal halves and the shorter one (red) slides into the longer one. The seam marks where the camera should be placed for alignment with the bed and the overlap length is such that both halves are the same height in total, so printing them together allows better cooling without needing excessive slowdown.

raspberry_pi_camera_assembly:
Vitamins:
  2 M2 cap screw x 12mm
  2 M3 cap screw x 10mm
  7 M3 cap screw x 16mm
  2 Nyloc nut M2
  9 Nyloc nut M3
  1 Raspberry PI camera
  1 Sanken SPS125 light strip
  2 Washer M2 x 5mm x 0.3mm
  9 Washer M3 x 7mm x 0.5mm

Printed:
  1 rpi_camera_bar_stl.stl
  1 rpi_camera_back.stl
  1 rpi_camera_focus_ring.stl
  1 rpi_camera_front.stl
  2 rpi_light_clamp.stl
By default the RPI camera is focused at infinity and the lens is locked in place. It is possible to break the seal though and focus it very close indeed giving a microscopic view. For this application it only needs tweaking a little to focus at the middle of the bed. I designed a little focus wheel that can be glued onto the end of the lens carrier to make it easier to turn.

When I ran the camera with the default settings in OctoPrint it streamed data at about 16Mbits / second and used 40% of the RPI's CPU time. It worked fine printing from SD card but slowed down the comms when printing over USB. On a suggestion by Gina I added the usestills option to scripts/webcamDeamon, i.e.
camera_raspi_options="-fps 10 -x 640 -y 480 -usestills"
That reduced the data rate to 3Mbps and the CPU load to 5%. It also had the side effect of vastly increasing the field of view. Here is a time-lapse captured by OctoPrint before I made the change. Notice the reduced field of view compared to the picture above.



Nothing on my WinXP machine would play the mpg files produced by OctoPrint, so I downloaded VLC Media Player. I found that is also able to record the OctoPrint video stream on the host PC. This video clip was recorded during the same build as the time-lapse above.



On another Mendel90 that I only use to print ABS parts, and hence don't fit the fan duct, I use a Logitech C270 USB webcam mounted in front of the machine, which gives a view like this: -


For this machine I mounted the same light strip just behind the gantry on brackets that hang over the top of the stays in the same way as the spool holders.


light_strip_assembly:
Vitamins:
  2 M3 cap screw x 10mm
  2 Nyloc nut M3
  1 Sanken SPS125 light strip
  2 Washer M3 x 7mm x 0.5mm

Printed:
  1 light_strip_bracket_left.stl
  1 light_strip_bracket_right.stl
I prefer the  RPI camera at the back solution but it does have the disadvantage that it looks out into the room rather than at the wall behind the machine.

Wiring

I power the RPI with the 5V standby rail of the ATX PSU and use one of the GPIO lines to turn the rest of the PSU on and off and another to turn the light on and off.

One thing I don't like about the RPI is the use of a micro USB connector for the power. A lot of micro USB leads have two much resistance to have enough voltage left at the RPI end. When you buy them there no indication of resistance but I managed to get some that where about 1.6Ω! To get around that I simply cut the wire off close to the plug and soldered to what was left.

The 5V volt supply comes from the purple wire of the ATX power supply. It looks blue on the photo below, but that is the camera lying! For a solid ground referenced to the logic on the Melzi I run a stout wire to the top terminal of the X limit switch. This ensures any voltage drop or noise in the ground wire between the PSU and the Melzi does not affect the USB comms and I find them rock solid in this configuration.


The remaining connections are the green PS_ON of the power supply goes to the drain of a small SMT MOSFET mounted on the back of the vero board and the negative lead of the light strip goes to the drain of a larger MOSFET. The positive lead of the light strip goes to the FAN+ terminal on the Melzi.

To make the vero circuit I started by cutting the tracks in a few places and drilling out some holes to provide strain relief for the flying leads.


I wanted the board to mount vertically but I didn't have a right angle connector to hand. Since I only need a few pins from one row I surface mounted a through hole straight connector.

Here it is with the MOSFETs and wires added: -

The small MOSFET is a 2N7002L and the larger one is a PHT8N06LT, but almost any logic drive N-channel enhancement mode MOSFETs should work. Neither gets fully turned on at 3V but both easily pass the current required, which is only milliamps for the PS_ON signal and about half an Amp for the lights.

On another machine I just soldered the MOSFETS to the connector and used heatshrink sleeving for strain relief for the flying leads on the drains. Much quicker but a bit fragile.

Software

OctoPrint

There are two ways to get OctoPrint onto a Raspberry Pi. You can start with a Raspbian image such as this one and then add OctoPrint by following these instructions or you can get an image for the RPI with OctoPrint already installed (called OctoPi) from here. The first method needs more steps and gets you the latest version. The second method is simpler but it takes me several hours to download, unzip and copy the image onto the SD card, so the first method can be quicker if you already have Raspbian installed.

When the RPI is booted you should be able to connect to it with SSH client like Putty or Tera Term. The default host name is octopi, username: pi, password: raspberry. If your DHCP server does not register the host name with DNS then you can find its IP address with a free application called Advanced IP Scanner found here. A good tutorial can be found here.

The first thing I do when connected is run :-
sudo raspi-config
to expand the file system, set the time zone and change the host name, etc.

VNC

In order to be able to update the firmware I install the Arduino IDE and to run that I need a remote desktop so I installed TightVNC following the guide here.

Arduino IDE

I install Arduino 1.0.1with:
sudo apt-get install arduino
I then get a copy of Marlin from Github with:
git clone git://github.com/nophead/Marlin.git
I then move the Melzi board support package to the Arduino IDE installation with:
cd Marlin
sudo mv Marlin/Melzi /usr/share/arduino/hardware


The Arduino IDE is a bit slow and clunky running on a RPI over VNC but it does work. A lighter weight alternative is a package called ino that can compile and download Arduino applications from the command line. It still needs the Arduino IDE installation but avoids the need for VNC.

Installation should be as simple as:
sudo pip install ino
But that installs an out of date version that does not scan the hardware directory for additional board support packages, and so does not support Melzi. Instead I install it from source:
git clone git://github.com/amperka/ino.git
cd ino
sudo pip install -r requirements.txt
sudo make install
If make install complains python2 does not exist then do:
sudo ln -s /usr/bin/python2.7 /usr/bin/python2
Ino expects the source code to be in a directory called src whereas the IDE puts it in a directory with the same name as the sketch. A simple workaround is to make a symbolic link in the directory above with:
ln -s Marlin src
rm -rf src/Gen7 src/Sanguino
(The other BSP packages have to be removed from the src directory because otherwise ino tries to build them and fails).

The firmware can then be built and downloaded with:
ino build -m atmega1284 && ino upload -p /dev/ttyUSB0 -m atmega1284

GPIO

To control the RPI's GPIO pins I followed the instructions here: https://projects.drogon.net/raspberry-pi/wiringpi/download-and-install/. This boiled down to:
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build
Then I extended the systems actions section of ~/.octoprint/config.yaml with the following:
  - action: printer on
    command: gpio mode 5 out; gpio mode 6 out; gpio write 6 1
    name: Printer On
  - action: printer off
    command: gpio write 6 0
    confirm: You are about to turn the printer off.
    name: Printer Off
  - action: light on
    command: gpio mode 5 out; gpio write 5 1
    name: Light On
  - action: light off
    command: gpio write 5 0
    name: Light Off
After a reboot the printers PSU and the light can be turned on and off from the OctoPrint system menu. Obviously the light will only come on if the PSU is on.

Files

I added a new Python script that makes the STL files and BOM files for a list of accessory assemblies:
accessories dibond|sturdy|mendel
The STL files can be found here: github.com/nophead/Mendel90/tree/master/dibond/stls/accessories and the parts lists here: github.com/nophead/Mendel90/tree/master/dibond/bom/accessories. I also generated the files for sturdy and mendel variants but I haven't tested those myself.

26 comments:

  1. Awesome work. Any chance you will be offering the various bits and pieces as an add-on option to those ordering new Mendel90's?

    ReplyDelete
    Replies
    1. Offering the printed parts and fasteners would be no problem. I might make a small PCB to replace the veroboard and offer the transistors and connectors. Not sure I want to buy and sell the RPI, etc.

      I also need to find a more available light strip.

      Delete
  2. Nice to see my Raspberry Pi model was helpful, were the dimensions on it ok?
    I love your blog by the way, your evidence based approach has often helped me in my own 3D printing adventures.

    ReplyDelete
    Replies
    1. Yes I think the dimensions are OK although I only used it to make an STL representation of the board. I didn't base the case dimensions on it.

      I think the version I used was actually a derivative of yours with "edits by Philip McGaw" but I can no longer find it on-line. The closest I can find is https://github.com/rmd6502/openscad/blob/master/R-Pi.scad but that seems to be a further derivative.

      Delete
    2. I have re uploaded it - http://skippy.org.uk/openscad-raspberry-pi-model/

      I will be adding the A+ and B+ dimensions to it as well.

      Delete
  3. Nice tutorial. Can you tell me where to get one of the Sanken SPS125? Regards

    ReplyDelete
    Replies
    1. I don't think they are available for retail. I bought them three years ago when I worked for a major customer of Sanken's and knew the Sales Manager.

      Delete
    2. What about this unit: http://www.amazon.co.uk/dp/B017NOAQZ4

      It consumes 18W. I seem to remember you (Nophead) once saying that there wasn't a lot of current to spare on the +12V rails of the PSU. Did I imagine that? Is there 1.5A to spare?

      Delete
    3. I measured 16A worst case. That is with a J-Head, some heater cartridges take a lot more. The PSU 12V rail is rated 18A, although exactly the same PSU (ACE500BR) was rated for 20A when we first started buying them.

      Delete
  4. Great work! I might use your fixation system for the cam and light since my actual fixation is not that great.
    What lenght did you need for the camera flat cable?

    ReplyDelete
    Replies
    1. 50 cm but 40cm would be better if you can get one.

      Delete
  5. Looking at the rpi_camera_bar.stl file, there are two ridges on each of the two clamp pieces, (the ones which don't carry any part the connecting bar). The corresponding connecting bar pieces have two rectangular holes with a chamfer at one end but these will not accommodate the ridge on the clamping piece which will keep the two parts apart. Please can you explain the assembly of the connecting bar? All this may seem obvious once I come to put nuts and bolts in place but at the moment I am struggling to visualise how the bar will clamp to the dibond sheet as the middle of the ridge seems to get in the way. Thank you, Alan

    ReplyDelete
    Replies
    1. The ridge locates in the slot and forms a pivot at the back of the clamp so it has a pincer action

      Delete
    2. The confusion might be due to this bug: http://forums.reprap.org/read.php?292,372794,372794#msg-372794. I will fix it on GitHub soon.

      Delete
  6. Sorry - I should have written "..there is ONE ridge on each of the two clamping pieces...". So if I understand it correctly, the middle of the ridge does not locate into anything (as there is no slot for it to go into). It is this middle section which forms the fulcrum. As said - it will probably make more sense once I get my screws in place!
    Thanks for the reply.

    ReplyDelete
    Replies
    1. The two clamping pieces don't mate with each other. They mate with the slots in the bottom of the part fused to the end of the bars.

      In the OpenScad files the clamps are a separate module so you can attach other things to the frame with them. For example I plan to make a holder for an SD card extension.

      Delete
  7. Aha! I have just downloaded the revised STLs from GITHUB and all my questions are now answered - my comments above related to the earlier set of STLs as discussed in the RepRap forum here: http://forums.reprap.org/read.php?292,372794
    All fine and dandy, Hey ho and thanks again,
    Alan

    ReplyDelete
  8. If you want to use a single command to turn on or off you can use this:
    - name: I/O Heat Chamber
        action: onoffheat
        command: if [ $( gpio read 2 ) -eq 0 ]; then gpio write 2 1; else gpio write 2 0; fi

    ReplyDelete
  9. Anyone has shared a bracket.stl for the newest Raspberry B+?

    ReplyDelete
  10. Hi, could I ask you confirm what was then changed with the wiring left at the dummy load after the green PS_ON wire was removed. It looks like I could be having stability issues on the PS_ON line as the PSU will randomly turn on, and currently I don't believe it is the state changing on the GPIO pin, and am looking more towards interference due to wiring, although everything looks ok. May even look at replacing the 2N7002L if can't find anything else.

    ReplyDelete
    Replies
    1. I just cut the green wire at the resistor and left the black connected, so the dummy load still functions as before.

      Before the GPIO is defined as an output it floats, so could come on, although mine doesn't. You could add a pull down resistor between the gate and the source pins to keep it off.

      Delete
  11. Hi nophead. Im saving up to buy a mendel90 from you soon. Just want to point out that you can Power the rpi from the gpio. The only problem is that you bypass a fuse. But you dont have to use the usb port. // Peter

    ReplyDelete
    Replies
    1. Yes I have done exactly that on some of my machines. Regarding buying a kit: please contact me via email.

      Delete
  12. Hi nophead,

    So if I read this correctly, you are using USB comms between the RPi and the Melzi? I thought I read somewhere (perhaps Octoprint Google+) that you have connected these via serial? Any chance of a pointer to this if you think it benefits. I'm finally assembling my next Mendel 90 (bought some parts from you before you stopped) and trying to incorporate all the ideas I heard from the outset.

    ReplyDelete
    Replies
    1. On one of my machines I do have a direct serial connection between the expansion port on the Melzi and the GPIO serial port on the RPi, /dev/ttyAMA0.

      I used a 2K2 / 3K3 potential divider to reduce the 5V Melzi TX to 3V for the RPi and a 1K in the Melzi RX line to limit the current when it is powered down.

      On the RPi you have to prevent it using the serial port for boot messages and login.

      The main benefit is it is connectionless so OctoPrint doesn't notice the Melzi being switched on and off. It also frees up a USB port on the RPi for a WIFI adapter as that machine also has USB camera. At 115Kb it is a bit faster than USB at 250Kb. I think with later Raspbian I would be able to go to 250Kb but I haven't tried that yet.

      I still need to connect the USB to update the firmware. It would need a new bootstrap to be able to do it via the serial port.

      Delete