An LED Skinner-type moth trap

Two or three years ago, I had the idea of producing ‘a better moth trap’ using LEDs. Since then, several hundred people have read that blog post and several readers have made their own traps. One reader has produced a commercial version of an LED moth light and written a scientific paper on its efficacy.

About a year ago, I started work on producing another LED lamp unit designed to either operate either singly or as an array. The idea behind the concept was that a unit of 4 x 3W LEDs; royal blue, emerald green, UV and ice white, could be combined on a single heat-sink that was structured in such a way that one unit (12W) could be used as a bar in front of white sheet, two (24W) could be used in a V-shaped formation on a Skinner-type trap, and that four (48W) could be combined into a square array that could replace a mercury vapour bulb on a Robinson-type trap. Last night, I tried out the Skinner array (24W max). I chose the night based upon the fact that it was the time of year that the Giant Peacock Moth makes its appearance. These spectacular moths are up to 20cm across and are Europe’s largest moth.

IMG_4334IMG_4335

I powered the LEDs from an old laptop ‘brick’ power supply that is well-capable of providing the high currents necessary. I chose to run the LEDs in series rather than in parallel. This has the disadvantage that the different colour LEDs drop different voltages and thus do not all run at the same power. However, it works well enough and the power supply was for free.  As this was the first outing for this particular trap, and I was unsure how the heat-sink would cope, I put two hefty diodes in series with the 15V supply to drop the voltage by about 1V. Running the lamp on the bench I had found that this resulted in running at about half power. However, the lamp is still astonishingly bright and the heat-sink does not even get warm. The diodes used to drop the voltage do warm up a bit, but being 10A diodes they are well able to cope with this, and they get warm rather than hot to the touch. Next time I run the trap, I will do so with only one diode in the supply line (about  14.5V).

It was a warm and cloudy evening. I had not expected much. However, the results were nothing short of astonishing. I had hoped to attract a Giant Peacock Moth. However, instead they came in numbers. At first they flew around and it was hard to tell how many there were. One, then two, then three, then four, then five entered the trap. Two males that had been fluttering in the eaves of the covered terrace, settled quietly on the beams. One settled on the outside of the trap. I began trying to photograph them. While I cannot be sure, there were at least 8 or 9 of these moths and with several in flight around me, possibly as many as 15 or 20. These were not of course the only visitors. There were several hawk moths including a beautiful Elephant Hawk and dozens of smaller moths together with many beetles. Since the object of the evening was the Giant Peacock Moth, I paid little attention to the many other species.

The bottom line to this report is that the V-shaped array works very well with a Skinner trap. I believe the overall philosophy is correct – an LED light source that is rich at the blue end of the spectrum, tuned to the peak absorption of moth (and beetle) photoreceptors. I would add that my entire trap cost about £25 (not including the cost of the power supply). ‘Brick’ power supplies from old laptops are practically free at boot fairs or can even be had from new on eBay at very low prices where the laptops they were designed to be supplied with are now considered defunct.

I am writing a little blog-post on the Peacock Moth – you will soon be able to find it at petermobbs.com.

Advertisements
Posted in Photography and electronics | Tagged , , , , , , | 3 Comments

Macro flash bracket and other macro tools for OM-D users

This blog entry describes several things I have made/used that make flash and macro photography easier for me; a trigger grip/bracket I have made to support two Meike Mk320p flashes, how to use such a setup in conjunction with remote pre-focus shutter buttons and the Keyline art filter to take perfectly (well, hopefully!) focused macro shots. It is specifically aimed at Olympus OM-D users though some of the tricks may be useful more generally. First, a word in praise of the Meike flash unit: it’s small, it’s versatile and it has a reasonable guide number and, above all, it is pretty cheap! Second, a word of explanation for why I have built such a setup. The answer is moderately complex! I sometimes need to take macro shots using flash. I like the technique in which you hold a single flash with a large diffuser in one hand and the camera in the other, or you mount the flash and the diffuser on the top of the camera. However you can’t really beat two flashes with diffusers for good macro lighting, and it is for this reason that both Nikon and Olympus will sell you a twin flash setup for macro. The Nikon and Olympus flashes mount on the lens or optionally on little stands. I have such a setup for my Nikon cameras – the R1C1 unit with the SU800 flash commander. The Olympus unit is also meant to be very good but both are pricey £400 – £600 and I don’t find the Nikon setup easy to hand-hold – it’s heavy and a bit tricky to steer. Since I already had one Meike flash, an extra 55 Euros to add a 2nd gun seemed a much cheaper way to go. However, I needed some kind of frame on which to mount the two flash units. For this, I turned to a newly acquired skill: 3D printing. More of this bracket later.

The OM-D E-M1 Mark 2 is equipped with ‘focus peaking’, and I use it a lot. I far prefer it to the ‘magnify’ option. Peaking shows you when an object is in focus by highlighting pixels on the in focus objects with the colour of your choice. ‘Magnify’, as its name implies, ‘bigs up’ the part of the image of interest so you can better see if it is in focus. I prefer ‘peaking’ because I find it annoying to lose sight of the majority of the field of view for a small selected magnified region. With ‘peaking’ you can see everything *and* see what bits of the image are in focus. Normally, these functions are activated when you turn the focusing ring on the lens. However, they can be allocated to buttons and then you can activate them by pressing say the ‘Fn1’ button. If you press the button, on comes the peaking and with its help you can move the object into focus without having to turn the focus ring. You press the shutter button and with a bit of luck you have a perfectly focused shot. Next shot press the Fn1 button and away you go gain. I love the focus peaking function and I used it all the time. However, a while ago, I came upon this: http://trevinchow.com/blog/2012/10/28/how-to-get-focus-peaking-with-the-olympus-om-d-e-m5/ – a way of adding a kind of ‘focus peaking’ to the old E-M5 Mk1 – back then it didn’t have that function built in. So, I had to try it. Basically, on the E-M1 Mk2 you simply set the Art Filter to ‘Keyline’ (number 11 in the Art Filter menu). As part of its overall effect, the Keyline filter highlights in focus pixels as black.  If you want ‘focus peaking’ to be available all the time without pressing any buttons before taking the shot, Keyline may be the way to go. In use, I set the camera to record a small jpeg and a RAW image. It’s a bit annoying to throw away storage on recording a Keyline image but they can easily be thrown away later and I find that it is worth it. I find it much easier to view the Keyline image on the live view screen than a focus peaking image and you soon realize that the in focus Keyline image ‘snaps’ when you hit exact focus. I have tried to demonstrate this with the photo shown below (forgive me for the fact it is taken with an iPhone – the object here is to demonstrate the effect rather than take wonderful photos!). You can of course go on using ‘focus peaking’ with the bracket – assign it to the Fn1 button and you can reach it from the RHS grip with your thumb. It is somewhat annoying that it seems you have to press that button for every shot – do let me know if there is a trick that lets you have it ON all the time.

You can use this Keyline peaking technique at any time; with or without flash, manual focus, single AF etc. though , unfortunately it does not work with proCapture but then nor does peaking. However, I find it most useful for when you want to take photos at a preset distance. This makes sense when you are using macro flash – your flash guns are set for objects at a certain distance both with respect to their angle and their power. Note that in the picture above the camera is viewing a curved sheet of paper. It is pretty clear (black pixels) what is in focus and what is not even though, the difference in the distance from the lens only change by a mm or two.

OK, so now to the bracket. I have used U-shaped brackets before to mount a camera along with various bits of electronics, for laser rangefinders, cross-beam laser triggers etc. I decided to try 3D printing such a bracket for two Meike flashes. At some point, I will want to add a range-finder laser trigger to this setup, indeed, it is ready to go, but that is another story! Here is a screen shot from Slic3R of the STL file for the bracket.

You will see it has two handles by which to hold the setup. They are oval and I find them pretty comfortable. I separately printed two trigger switch boxes that mount on the handles – one functions to set the camera to pre-focus and the other to fire the shutter.

When pressed, they connect the second and third ring respectively of a 2.5mm jack plug to its barrel. This plug inserts into the remote socket on the right hand side of the E-M1 and allows the buttons to take over the functions of the camera’s own shutter button. It is worth noting that separating the ‘pre-focus’ and ‘shutter’ functions has both advantages and disadvantages. For me the big advantage when doing macro photography is that ‘single AF (sAF) + manual’ is useful because it can, given reasonable light, in combination with the focusing range limiter on the lens barrel of the Olympus 60mm lens, very quickly focus the lens on the object of interest. This is fine if you immediately go from pre-focus to taking the shot without taking your finger off the shutter button. However, sometimes it would be more useful for macro shooting if you could use sAF to do the initial focusing and then remove your finger from the shutter button and use the technique of slightly rocking back and forth while taking photos. If you do this with sAF enabled every press of the shutter button will cause the camera to seek a new focus lock. Not so if you divorce pre-focus from the shutter button – use pre-focus button to get near to the focus you want and then use the shutter button as many times as you like without the camera seeking a new focus lock. The downside is that, for reasons that I do not understand, you have to press the pre-focus button briefly if you want to ‘chimp’ (view) your pictures. The picture of the complete setup shows how the pre-focus and shutter buttons are mounted and other images (above)  show Slic3R screen captures of the STL files for them.

The only other components of the system are the two little stands for the flash guns made from pieces cut from 50 x 25 rectangular 3mm aluminium tube drilled with holes on their bases tapped for 1/4 inch UNC tripod bolts. A 7mm hole on the side of these stands allows 1/4 inch UNC bolts to pass through to hold flash gun clamps (see the pictures). The stands provide a wide range of possibilities for positioning the flash units. Remarkably, this whole thing feels really good in the hand; secure precise and easy to maneuver. The downside is that you need to set the camera up by either holding the whole thing in one hand or by sitting down with it and doing that….but, it was the same with my Nikon R1C1 set up only that was MUCH heavier!

So, how well does it work? To test it, I set up the camera in full manual modem, set the aperture,  placed a 20 Euro note flat on my desk and then gave myself the minimum time to find the preset focus point and hit the shutter button.  I found that using the Keyline filter, I could have perfect focus in much less than a second. I repeated this about 20 times and each time I got nicely focused shots. As described above, one can also use Single AF to get the initial focus and then after letting go of the pre-focus button move the setup a bit to hit precise focus and then press the shutter button without pre-focus. It won’t be everyone’s cup of tea but it works for me!

I printed the bracket in PLA but I will be making the final version in ABS (or possibly  PETG). PLA seems fine but it isn’t good in the heat.

If you find anything here interesting or controversial (!), leave a comment and I’ll get back to you. If there is a demand, I will put the STL files on Thingiverse.

Posted in Photography and electronics | Tagged , , , , , , , , , , , , , , , , | Leave a comment

A bigger, better diy turntable for stereo or product photography.

Sometimes, in order to take stereo photos of larger objects, you need a bigger turntable. Also, a bigger turntable makes it easier to incorporate the lighting on its surface. It is always best to take a stereo pair in such a way that the lighting moves with the object thus preventing confusing changes in the shadows. This very short blog post explains how you can make a stereo turntable from a ‘Lazy-Susan’ bearing – a ‘Lazy-Susan’ being a thing you normally put food on in the centre of the dining table and that allows you turn the turntable to present the food to whomever you want.

The bearing I have used is readily available from Ebay suppliers. It is made in metal, is a high quality product, and comes in a variety of diameters. The one I chose is about 25cm across and supports a turntable about 60cms in diameter. The bearing cost about £15. You will need a bigger bearing for larger turntables. I cut the turntable from chipboard.

Manufacture is pretty simple. You need a piece of chipboard bigger than the circle you plan to cut from it. It is helpful if it is square or rectangular. Take a rule and draw two diagonals from each corner to the other. If the board is rectilinear, the diagonals will cross at the centre. Drill a 2mm hole at this point. Find a strip of wood longer than the radius of the turntable you want to make. Bang a nail trough it at one end – choose a nail the point of which will sit nicely in the 2mm hole – it’s going to be the pivot of a crude beam compass. Drill a hole in the other end of the strip of wood of such a size that you can push a pencil through it. The hole needs to sit at distance from the nail equivalent to the radius of the turntable you want to make. Fix the pencil in place with hot melt glue or tape. Place the point of the nail in the small hole in the chipboard and scribe a circle. An alternative way of doing this is to tape two pencils to long rule if you have one. Then drill a hole just outside the circumference of the circle that is big enough to take the blade of a jig-saw. Very carefully cut out the circle of chipboard. It doesn’t matter if the finished object is perfectly circular or not but it’s  nice if you get as close as possible. You can finish the edge of the turntable with a rasp or sandpaper depending on how good the cut surface you left is. When you are happy, decide which surface is going to be the top and spray it with matte black paint – I guess you could choose white or gray or any other colour but black seemed best to me. Let it dry. Don’t throw the piece of board you cut the circle from away, you are going to need it later!

Take a sheet of tracing paper bigger than the bearing. Mark the centres of the holes in the bearing on the tracing paper. To find the geometric centre of the bearing, join the points you have marked with lines. Carefully position the tracing paper on the back of the chipboard turntable so that the bearing centre sits on the small hole – a light behind the board may aid in this. Now tape the tracing paper down and using a sharp stylus (a nail?) mark the fixing holes for the bearing. Using those marks as a guide, fix the bearing to the board. You will need to put some spacers behind the bearing to hold it away from turntable, otherwise it will bind on the turntable. I used two washers under the bearing at each screw point. To give you some ideas about how to centre the bearing, the photo below shows the bearing screwed to the chipboard rectangle marked with the turntable circumference and the lines to show how the holes in the bearing can be used to find its centre.

lazy2

If you are going to use the turntable for stereo photography, calculate the circumference of the turntable (pi * D). Take that number and divide it by 360. That is the distance the edge of the turntable needs to rotate through to move 1 degree. For my 60cm turntable that is about 0.5cm. Take a piece of the board from which you cut the turntable and select a quadrant or a smaller section that is nice and ‘circular’. Spray it with black paint and using a fine brush, mark it with white 1 or 2 degree index marks. Also, place such marks at intervals on the turntable – I just put four marks at 90 degree intervals. Insert the little plastic feet that come with the bearing into the holes for them in the bearing and put the turntable on a flat surface and give it a spin! You are done!

lazy1

There are plenty of instructions for taking turntable stereo pairs to be found elsewhere on the web. In short, place the object you want to photograph over the turntable’s centre. Set up your lighting on the turntable – I use Nikon’s twin macro flashes on suitable stands. Put you camera on a tripod and take a picture (left-eye image). Turn the turntable clockwise through about 3.5 degrees (you can experiment!) and take the second (right-eye) image. It’s that easy. Of course, the turntable can also be used to take pictures of objects at many angles; they can even be combined into movies and stereo movies.

Posted in Photography and electronics | Tagged , , , , , , , | Leave a comment

More on building a better moth trap

My apologies for the long interval between my last post and this one. I have been battling with a 300 year old French farmhouse and its needs. I was motivated to make this post by the extensive interest in the article I wrote about constructing a better moth trap using LEDs. In particular, two kind emails from Eric Gendle made me think that it was worth encouraging people to persevere with the notion that LEDs are the way to go with respect to moth trapping. Indeed, given that manufacturers have stopped, or are likely to stop, making mercury vapour and other light sources that used to be used in moth traps, it may be the only way to go! The design I published within these pages some months ago has worked quite well for me though I have modified it somewhat, adding an ice white 3W LED to the blue, green and UV ones. The Ice White LED is an experiment – it is rich in blue light but will add to the overall spectrum throughout the visible range. We will see if it increases the traps appeal to moths! It is also the case that the new generation of UV LEDs are somewhat brighter than the one I used before, and I have used one of these in the new lamp. Coincidentally, both Eric and I have used Future Eden as our supplier of choice for LEDs and we both want to say what a superb company it is; high quality LEDs sent quickly and cheaply and, most important, Mickey, the owner has been very helpful to both of us. You can find Future Eden’s shop on Ebay or here: https://futureeden.co.uk/.

First, I think it would be encouraging to show one of the pictures Eric kindly sent me. They indicate that for a very modest outlay, it is possible to do as well, or perhaps even better than much more expensive commercial designs. Eric’s trap consist of three LED light bars and a netting tent with an entry funnel at the top. In the picture shown here, there is a Skinner trap below that has also snared some moths. His system is run from a 12V lead acid battery and incorporates the resistors necessary to limit the current through the LEDs. His trap cost about £15 for the LEDs and resistors, and £20 for a 12amp hour 12v Lead acid battery with which he can run the trap for a whole night. He notes that running his trap in late autumn he attracted “100+ of the epirrita complex of late autumn moths plus 10+ each of Feathered Thorn, December and Mottled Umber and a single Satellite “.

Moth trap 1_11 copy

Now, just a quick note on the latest version of the lamp that I mentioned above. It has four 3W LEDs – blue, green, UV and Ice White. These could be run in series from a car battery without any resistors though, I have not tested this (beware!). However, I have run them in parallel configuration from a Chinese constant current/voltage supply like the one described in my original post. When run from that device, I limit the current to 3 amps at 3.5V (10.5W). I have mounted the LEDs on an aluminium bar and drilled it such that using aluminium right angle the bars can be connected together back-to-back in a V formation or four bars combined in a square configuration. To power the V one would need two constant current/voltage drivers capable of handling at least 5A, or four for the square arrangement. The advantage of a modular configuration is that LEDs are quite directional (usually spreading light within a 120 degree cone) and using more than one allows one to attract moths from a greater area. Unfortunately, I have not had time to build and test several modules run together in a trap. Future Eden can supply better quality drivers than those I have used, to power any arrangement of LEDs.

Here is picture of the new lamp (under test at low current – fiercely bright at 3A!). The aluminium bar (250 x 50 x 8mm) is only just adequate in terms of cooling if the LEDs are run at full power but it is possible, using the constant current driver, to limit the current so that the bar never gets too hot. Obviously, if one does this, one loses some light. A better heat sink would be finned and offer a larger cooling surface but the one shown is adequate particularly given it is cooler at night.

IMG_3542

More recently, Eric has sent me some further details of his trap and the pictures below show it more detail. He says, “The (picture of the) bare frame shows the structure made from 2 of the large polythene buckets usually filled with building plaster, joined top to top and with the sides cut out.”  “The second image shows the lighting arrangement.” I think Eric’s design is very innovative and with a 4 X 3 arrangement of 3W LEDs it is going to generate a lot of light!

DSC_6298 copy

DSC_6299 copy

Finally, here is a picture of 2 of 3 (or the same one 3 times!) Giant peacock Moths that visited the original light and settled on my foot. Another fluttered around the light reflected from my shorts! These chaps are huge! Plenty of other moths were attracted too but on the days the Peacock moths visited, the main visitors were hundred of beetles!

OLYMPUS DIGITAL CAMERA

IMG_3395

So, the bottom line is that you definitely can make a very effective LED moth trap for a very attractive price though, you do need to be prepared to experiment a bit. Always bear in mind that there are good and bad moth days, and that on a bad day it is possible to catch very little or nothing!

Again, many thanks to Eric Gendle for sharing his experiences, pictures and design. Thank you to Mickey of Future Eden for the help he gave both of us.

 

Posted in Photography and electronics | Tagged , , , , , , , , , , | 8 Comments

Control box for a focus rail, and other stepping motor-driven camera moving devices. The program.

With some reluctance, I have decided to upload the Arduino code that I use to drive the new electronics that I use with my focus rail. As I said in the previous post, it can be used with up to five stepping motor-driven devices. Thus, it can be used to move a camera, or a specimen one is photographing, along X, Y and Z axes as well as providing the facility to rotate the camera or specimen around the A & B axes. The control box incorporates 8 outputs (configured as 4 pairs) that can be used to trip the shutters of cameras, prefocus, or operate strobes. The box also has provision for up to 8 analogue inputs. However, these are at the present time, unused. Currently I have only the one focus rail and a turntable with which to test the box. Other bits are in the process of construction. The control box utilises an Arduino Mega, which with its provision for lots of digital outs and analogue ins, provides almost infinite scope for expansion.

The hardware consists of the aforementioned Mega, a 4 line LED display driven by an I2C module via the SDA and SLC pins on the Arduino, EasyDriver boards to drive the stepping motors, a rotary encoder with a push-button switch, and the little optocoupler boards pictured below to trigger the cameras etc. The project is housed in a die-caste aluminium box and all the connections bar those to external switches and jacks are made using DuPont connectors.  I will at some point, if I can find the time, draw up a wiring diagram. However, in many ways, this should not be necessary because the programme contains a list of all the pin connections necessary to make the different circuits work together apart from the SDA and SLC connections mentioned above.

The menu system is scrolled by the rotary encoder and operating the integral push button activates the selected menu item. The  short video below (a new one!) shows this system in operation. I brought the Arduino’s reset pin out to an external pushbutton to make it easy to resent the system should anything go wrong. I added a switch to turn off the power supply to the motors so that one can test the programme without disconnecting them. I also cut a hole in the side of the box to allow me to program (reprogram, reprogram and reprogam again and again!)  the board in situ via its USB socket.

My reluctance in publishing the code is two-fold. Firstly, I do not consider myself in any way to be an Arduino expert – my competence has grown, but I remain a complete novice by comparison to the gurus! Secondly, the code is a work in prgress and likely always will be! I am sure there are lots of errors, however, I have been using it to take pictures so, in practice it works for me. If anyone finds the code at all useful then I will be very happy. However, I do ask that should you pass it on, or use chunks, you acknowledge the source (this blog) so there is a chance that I can keep a handle on the development of the code and put right any errors  etc. Unfortunately, WordPress do not make it that easy to publish your code exactly as one would see it in the Arduino Editor. However, I am hopeful people should be able to cut and past the code presented on this page into an editor – look out for lines that have scrolled, and other formatting errors that have been produced by incorporating the code into these WordPress pages. It looks OK but beware of potential problems. I am thinking of placing the code on Github or elsewhere – news on this another time. There are about 1000 lines altogether.

Before the code here are a few pictures to help explain the components I have used.

img_3018

The box with its four line display. The red button is an external reset. The RHS carries the 4 stereo jack sockets for the outputs to the camera and flashes and also sockets for the as yet  unused sensor inputs. 4-pin aviation sockets are used for connecting the motors. There is a motor power socket and switch on the LHS, and an access hole for a USB plug.

img_3017

The two types of circuit board used inside the box other than the Arduino Mega. The little optocoupler boards are available from China for next to nothing on eBay. The EasyDriver boards are also very cheap. You will need to solder on some header pins to connect the boards to the Mega using DuPont connectors. My box currently contains three EasyDrivers and two quad optocoupler boards.

This short video shows the options currently available from the rotary encoder-based menu.

Here is the program – don’t forget there is a sideways scroll bar at the bottom of the page!

//STEPPER BOX 2 Begun 04/October 2016
// Global variables to have capital letters
//#define ENCODER_OPTIMIZE_INTERUPTS // Use if time overhead is crucial
#include <Encoder.h>
#include <LiquidCrystal_I2C.h>
Encoder myencoder(2, 3); // both of these are interupt pins - gives highest fidelity
int Button_pin = 13;// pin that connects to encoder switch/button
int Upper_limit = 8; // initial max for encoder
int Lower_limit = 1; // initial min for encoder
int Increment = 10; // initial value for multilier re: durations, distance etc
int Direction; // intial direct rail will move 0 = forward
long int Distance;
int Number_photos;
int Delay_1;// Time over which railmovement settles down
int Delay_2;// Exposure time during which rail halts
int Dir_pin = 11; // Set initial pins to those for Z axes
int Drive_pin = 12; // initial pin for Z stepper motion
int Enable_pin = 10; // initial pin to enable Z stepper motor
int Camera_pin = 16;// connected to camera remote socket - camera may need another pin for prefocus - say 15 on same jack socket
int Flash_pin = 17;// connects to flash socket - rename and initialise if using more than one flash - ie Flash_2_pin = 19
int Motor_selected = 3; //start with Z motor selected
int Number_Photos_hold;
int Direction_hold;
int Distance_hold;
int Delay_1_hold;
int Delay_2_hold;
int Delay_shutter_lag = 100; // sets period required to activate camera
byte Reuse_Z_values;
byte Button_flag; // flag for button press
byte Old_button_flag = HIGH; // carry old value of button forward

String Main_Menu_Title = " --MAIN MENU-- ";
// 12345678901234567890
String Option_1 = " Stack ";
String Option_2 = " Jog ";
String Option_3 = " Rotate ";
String Option_4 = " Shoot ";
String Option_5 = " Flash ";
String Option_6 = " Shoot & flash ";
String Option_7 = " Motor - X,Y,Z,A,B ";
String Option_8 = "Distance multiplier ";
String Explain_1 = " (Create Z stack) ";
String Explain_2 = " (Jog back/forward)";
String Explain_3 = " (Control A,B Axes)";
String Explain_4 = " (Fire w/out flash)";
String Explain_5 = " (Fire flash) ";
String Explain_6 = " (Fire and flash) ";
String Explain_7 = " (Select motor) ";
String Explain_8 = "(Click sensitivity)";
LiquidCrystal_I2C lcd(0x3F, 20, 4); // set address for LCD on I2C
void setup()
{
pinMode(10, OUTPUT);// set all motor enable pins as outputs
pinMode(20, OUTPUT);
pinMode(23, OUTPUT);
pinMode(29, OUTPUT);
pinMode(32, OUTPUT);
digitalWrite(10, HIGH); // set all motor enable pins to off = HIGH
digitalWrite(20, HIGH);
digitalWrite(23, HIGH);
digitalWrite(29, HIGH);
digitalWrite(32, HIGH);
pinMode(15, OUTPUT);//configure current flash and camera pins as outputs
pinMode(16, OUTPUT);
pinMode(17, OUTPUT);
pinMode(18, OUTPUT);
// others as one wishes
pinMode (Button_pin, INPUT_PULLUP);
lcd.init();
lcd.clear();
lcd.backlight();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print(" M A D B O F F I N ");
lcd.setCursor(0, 1);
lcd.print(" L A B S ");
lcd.setCursor(0, 2);
lcd.print("Software version 1.3");
lcd.setCursor(0, 3);
lcd.print(" 28th October 2016 ");
delay(4000);
lcd.clear();
}

void loop()

{
lcd.setCursor(0, 0);
lcd.print(Main_Menu_Title);
int k = encode_return(Upper_limit, Lower_limit); // call subroutine with upper and lower limits, k holds value returned from encoder
// Spell out menu options using encoder to select
switch (k) {
case 1:
lcd.setCursor(0, 1);
lcd.print(Option_1);
lcd.setCursor(0, 2);
lcd.print(Explain_1);
break;
case 2:
lcd.setCursor(0, 1);
lcd.print(Option_2);
lcd.setCursor(0, 2);
lcd.print(Explain_2);
break;
case 3:
lcd.setCursor(0, 1);
lcd.print(Option_3);
lcd.setCursor(0, 2);
lcd.print(Explain_3);
break;
case 4:
lcd.setCursor(0, 1);
lcd.print(Option_4);
lcd.setCursor(0, 2);
lcd.print(Explain_4);
break;
case 5:
lcd.setCursor(0, 1);
lcd.print(Option_5);
lcd.setCursor(0, 2);
lcd.print(Explain_5);
break;
case 6:
lcd.setCursor(0, 1);
lcd.print(Option_6);
lcd.setCursor(0, 2);
lcd.print(Explain_6);
break;
case 7:
lcd.setCursor(0, 1);
lcd.print(Option_7);
lcd.setCursor(0, 2);
lcd.print(Explain_7);
break;
case 8:
lcd.setCursor(0, 1);
lcd.print(Option_8);
lcd.setCursor(0, 2);
lcd.print(Explain_8);
break;
default:
;
}
Button_flag = digitalRead(Button_pin);
if (Button_flag != Old_button_flag)
{
Old_button_flag = Button_flag;
delay(100);
}
if (Button_flag == LOW && k == 1)
{
stacker();
}
else if (Button_flag == LOW && k == 2)
{
jogger();
}
else if (Button_flag == LOW && k == 3)
{
rotate();
}
else if (Button_flag == LOW && k == 4)
{
shoot();
}
else if (Button_flag == LOW && k == 5)
{
flash();
}
else if (Button_flag == LOW && k == 6)
{
shoot_flash();
}
else if (Button_flag == LOW && k == 7)
{
select_motor();
}
else if (Button_flag == LOW && k == 8)
{
click_Increment();
}
}

//
// SUBROUTINE encode_return () is sent upper and lower limits and returns encoder_value
//

int encode_return (int Upper_limit, int Lower_limit) {
int new_encoder_value = -999;
int mult_enc;
new_encoder_value = myencoder.read();
new_encoder_value = new_encoder_value / 4; // because each click increases encoder value by 4
// now test to see if limits exceeded
if (new_encoder_value >= Upper_limit) {
new_encoder_value = Upper_limit;
mult_enc = (Upper_limit * 4); //not clear why "if" not blocking code here????? add a 2...take it out or not??!
myencoder.write(mult_enc);
}
if (new_encoder_value <= Lower_limit) { new_encoder_value = Lower_limit; mult_enc = (Lower_limit * 4) + 2; //add 2 to stop "if" blocking code myencoder.write(mult_enc); } return new_encoder_value; } // // SUBROUTINE stacker () creates a stack of photos // void stacker() { Direction = 1; Number_photos = 1; Distance = 0; Delay_1 = 0; Delay_2 = 0; byte Old_button_flag = HIGH; byte Button_flag = HIGH; if (Motor_selected > 3)
{
lcd.clear();
// 01234567890123456789
lcd.setCursor(0,0);
lcd.print("--------------------");
lcd.setCursor(0,1);
lcd.print("Use X, Y or Z motor ");
lcd.setCursor(0,2);
lcd.print("Choose when offered!");
lcd.setCursor(0,3);
lcd.print("--------------------");
delay(1500);
lcd.clear();
select_motor();
}
lcd.clear();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print("--STACKER SUB-MENU--");
//
// do while loop here for direction to run
//
lcd.setCursor(0, 1);
// 12345678901234567890
lcd.print(" (Direction) ");
if (Reuse_Z_values == HIGH)
{
myencoder.write(Direction_hold * 4);
}
do
{
Direction = encode_return(2, 1);
if (Direction == 1)
{
lcd.setCursor(0, 2);
lcd.print(" **Forward** ");
}
if (Direction == 2)
{
lcd.setCursor(0, 2);
lcd.print(" **Reverse** ");
}
Button_flag = digitalRead(Button_pin);
if (Button_flag != Old_button_flag)
{
Old_button_flag = Button_flag;
delay(30);
}
} while (Button_flag == HIGH);
Direction_hold = Direction;
myencoder.write(4); // return to a value of 1 for encoder - divide by four!
delay(200); // inserting this delay ends problems with 'bouncing by' setting number of photos
// 12345678901234567890
// do while loop here for number of photos
Old_button_flag = HIGH;
Button_flag = HIGH;
lcd.setCursor(0, 1);
// 12345678901234567890
lcd.print(" Number of Photos: ");
lcd.setCursor(0, 2);
lcd.print(" ");
if (Reuse_Z_values == HIGH)
{
myencoder.write(Number_Photos_hold * 4);
}
do
{
Number_photos = encode_return(1000, 1);
lcd.setCursor(10, 2);
lcd.print(Number_photos);
lcd.print(" ");
Button_flag = digitalRead(Button_pin);
if (Button_flag != Old_button_flag)
{
Old_button_flag = Button_flag;
delay(30);
}
} while (Button_flag == HIGH);
Number_Photos_hold = Number_photos;
myencoder.write(4); // return to a value of 1 for encoder - divide by four!
delay(200); // inserting this delay ends problems with 'bouncing by' setting distance to run
//
// do while loop here for distance to run
//
lcd.setCursor(0, 1);
// 12345678901234567890
lcd.print(" Distance (um): ");
if (Reuse_Z_values == HIGH)
{
myencoder.write(Distance_hold * 4);
}
do
{
Distance = encode_return(10000, 1); // um could be a problem for longer distances!!
Distance = Distance * Increment;
//lcd.print(" ");
lcd.setCursor(9, 2);
lcd.print(Distance);
lcd.print(" ");
Button_flag = digitalRead(Button_pin);
if (Button_flag != Old_button_flag)
{
Old_button_flag = Button_flag;
delay(30);
}
} while (Button_flag == HIGH);
Distance_hold = Distance / Increment;
myencoder.write(4);
delay(200); // inserting this delay ends problems with 'bouncing by'
// 12345678901234567890
// do while loop here for delay to settle rail

lcd.setCursor(0, 1);
// 12345678901234567890
lcd.print("Delay - settle (ms):");
if (Reuse_Z_values == HIGH)
{
myencoder.write(Delay_1_hold * 4);
}
do
{
Delay_1 = encode_return(9999, 1);
Delay_1 = Delay_1 * Increment;
lcd.setCursor(9, 2);
lcd.print(Delay_1);
lcd.print(" ");
Button_flag = digitalRead(Button_pin);
if (Button_flag != Old_button_flag)
{
Old_button_flag = Button_flag;
delay(30);
}
} while (Button_flag == HIGH);
Delay_1_hold = Delay_1 / Increment;
myencoder.write(4); // return to a value of 1 for encoder - divide by four!
delay(200); // inserting this delay ends problems with 'bouncing by'

// 12345678901234567890
// do while loop here for delay for exposure i.e. after tripping shutter

lcd.setCursor(0, 1);
lcd.print("Delay - expose (ms):");
if (Reuse_Z_values == HIGH)
{
myencoder.write(Delay_2_hold * 4);
}
do
{
Delay_2 = encode_return(9999, 1);
Delay_2 = Delay_2 * Increment;
lcd.setCursor(9, 2);
lcd.print(Delay_2);
lcd.print(" ");
Button_flag = digitalRead(Button_pin);
if (Button_flag != Old_button_flag)
{
Old_button_flag = Button_flag;
delay(30);
}
} while (Button_flag == HIGH);
Delay_2_hold = Delay_2 / Increment;
myencoder.write(4); // return to a value of 1 for encoder - divide by four!
lcd.clear();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print("Photos: ");
lcd.print(Number_photos);
lcd.setCursor(0, 1);
lcd.print("Distance: ");
lcd.print(Distance);
lcd.setCursor(0, 2);
lcd.print("Delay (settle): ");
lcd.print(Delay_1);
lcd.setCursor(0, 3);
lcd.print("Delay (expose): ");
lcd.print(Delay_2);
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("--------------------");
lcd.setCursor(0, 1);
// 12345678901234567890
lcd.print(" ACCEPT VALUES? ");
lcd.setCursor(0, 2);
lcd.print("Press in 2 sec = YES");
lcd.setCursor(0, 3);
lcd.print("--------------------");
Button_flag = HIGH;
for (int i = 0; i <= 1000; i++) {
Button_flag = digitalRead(Button_pin);
delay(20);
if (Button_flag == LOW)
{
break;
}
}
if (Button_flag == LOW)
{
motor_driver();
}
lcd.clear();
lcd.setCursor(0, 0);
// 01234567890123456789
lcd.print("--------------------");
lcd.setCursor(0, 1);
lcd.print(" Finished Z stack! ");
lcd.setCursor(0, 2);
lcd.print("--------------------");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("--------------------");
lcd.setCursor(0, 1);
// 12345678901234567890
lcd.print("REUSE STACK VALUES? ");
lcd.setCursor(0, 2);
lcd.print("Press in 2 sec = YES");
lcd.setCursor(0, 3);
lcd.print("--------------------");
Reuse_Z_values = LOW;
Button_flag = HIGH;
for (int i = 0; i <= 200; i++) {
Button_flag = digitalRead(Button_pin);
delay(20);
if (Button_flag == LOW)
{
Reuse_Z_values = HIGH;
break;
}
}
lcd.clear();
return;
}

//
//
// SUBROUTINE motor_driver () moves the motor via EasyDriver and activates camera to produce a photo stack
//
//

int motor_driver()
{
// This value is crucial for absolute accuracy and needs to be set by moving the rail and seeing how far it actually travels.
float steps_per_micron = 0.78824; //1.25mm is 1600 steps (with 8 microsteps per step) so 0.78125 steps/micron!
long int steps_between_photos;
long int distance_between_photos;
long int total_steps;
int carry_direction;
pinMode(Dir_pin, OUTPUT);
pinMode(Drive_pin, OUTPUT);
pinMode(Camera_pin, OUTPUT);
pinMode(Flash_pin, OUTPUT);
pinMode(Enable_pin, OUTPUT);
digitalWrite(Dir_pin, LOW);
digitalWrite(Drive_pin, LOW);
digitalWrite(Enable_pin, LOW);
distance_between_photos = Distance / (Number_photos - 1);
steps_between_photos = (float)distance_between_photos / steps_per_micron; // check loss of precision!
lcd.clear();
lcd.setCursor(0, 0);
lcd.clear();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print("Caution motor active");
lcd.setCursor(0, 1);
lcd.print("Creating Z stack of:");
lcd.setCursor(9, 2);
lcd.print(Number_photos);
lcd.setCursor(7, 3);
lcd.print("Photos");
delay(1500);

//head off in the right direction!
if (Direction == 2) {
digitalWrite(Dir_pin, LOW);
}
if (Direction == 1) {
digitalWrite(Dir_pin, HIGH);
}
//set Camera_pin high - first photo is where the rail is now
//tell operator taking first photo
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Creating Z stack! ");
lcd.setCursor(0, 1);
// 1234567890123456890
lcd.print("Photo #: 1 ");
lcd.setCursor(0, 2);
lcd.print("In stack of: ");
lcd.print(Number_photos);
digitalWrite(Camera_pin, HIGH);
delay (Delay_shutter_lag);// wait for shutter to open plus a bit - 52ms for Nikon plus a copule of ms before flash
digitalWrite(Flash_pin, HIGH);
delay(10);// trigger flash
digitalWrite(Camera_pin, LOW);
digitalWrite(Flash_pin, LOW);
delay(Delay_2);
for (int x_count_photos = 1; x_count_photos <= Number_photos - 1; x_count_photos++) {
//move rail position by steps_between_photos
//motor speed is set by delays....going slowly to avoid lost steps.....
for (int y_count_steps = 1; y_count_steps <= steps_between_photos; y_count_steps++) {
digitalWrite(Drive_pin, LOW);
delayMicroseconds(200);
digitalWrite(Drive_pin, HIGH);
delayMicroseconds(200);
}
//Tell user which photo is being taken
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Creating Z stack! ");
lcd.setCursor(0, 1);
// 12345678901234567890
lcd.print("Photo #: ");
lcd.print(x_count_photos + 1);
lcd.setCursor(0, 2);
lcd.print("In stack of: ");
lcd.print(Number_photos);
delay(Delay_1); // settle dealy to steady camera and rail
// take the photo and set Flash_pin high with Camera_pin long enough to trigger camera
digitalWrite(Camera_pin, HIGH);
delay (Delay_shutter_lag);// delay for shutter to open - ~1/10th
// Neeeds work here to set delay so flash occurs with correct timing - not relevant if camera triggers flashes
digitalWrite(Flash_pin, HIGH);
delay(10);// long enough pulse to trigger flash
digitalWrite(Camera_pin, LOW);
digitalWrite(Flash_pin, LOW);
delay(Delay_2); // allow for extended exposure times greater than 1 second provided by message delay
}
delay(1000);// so you can see the last value for photo number
//
//Rewind the slider to the starting point by reversing rail_direction and going back total number of steps in stack
//
//Warn that rewind about to take place..
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("--------------------");
lcd.setCursor(0, 1);
// 01234567890123456789
lcd.print(" Caution rewinding! ");
lcd.setCursor(0, 2);
lcd.print("<<<<<<<<<<>>>>>>>>>>");
lcd.setCursor(0, 3);
lcd.print("--------------------");
delay (1500);
carry_direction = Direction;
if (carry_direction == 2) {
digitalWrite(Dir_pin, HIGH);
}
if (carry_direction == 1) {
digitalWrite(Dir_pin, LOW);
}
//digitalWrite(Dir_pin, rail_direction);
total_steps = (Number_photos - 1) * steps_between_photos;
for (int x_count_rewind = 1; x_count_rewind <= total_steps; x_count_rewind ++) { digitalWrite(Drive_pin, LOW); delayMicroseconds(200); digitalWrite(Drive_pin, HIGH); delayMicroseconds(200); } digitalWrite(Enable_pin, HIGH); myencoder.write(4); lcd.clear(); } // /// SUBROUTINE jogger() jogs a motor via encoder // void jogger () { long int j = 0; int i = 0; int old_encoder_value; int step_size = 10; float jog_Increment = 0; Old_button_flag = HIGH; Button_flag = HIGH; if (Motor_selected > 3)
{
lcd.clear();
// 01234567890123456789
lcd.setCursor(0,0);
lcd.print("--------------------");
lcd.setCursor(0,1);
lcd.print("Use X, Y or Z motor ");
lcd.setCursor(0,2);
lcd.print("Choose when offered!");
lcd.setCursor(0,3);
lcd.print("--------------------");
delay(1500);
lcd.clear();
select_motor();
}
pinMode(Dir_pin, OUTPUT);
pinMode(Drive_pin, OUTPUT);
pinMode(Enable_pin, OUTPUT);
digitalWrite(Dir_pin, HIGH);
digitalWrite(Drive_pin, LOW);
digitalWrite(Enable_pin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
// 01234567890123456789
lcd.print(" ---JOG SUB-MENU--- ");
lcd.setCursor(0, 1);
lcd.print(" Ready to move! ");
lcd.setCursor(0, 2);
lcd.print("Jog Increment (um): ");
jog_Increment = float(Increment) * float(step_size) * 0.78824;
lcd.setCursor(0, 3);
lcd.print(" ");
lcd.print(int(jog_Increment));
// 12345678901234567890
step_size = step_size * Increment; // scale step_size with value from Increment subroutine
old_encoder_value = myencoder.read();
do
{
j = myencoder.read();
if (j > old_encoder_value)
{
i = 1;
do {// not at all clear why a for loop will not work...but it doesn't!
digitalWrite(Dir_pin, HIGH);
digitalWrite(Drive_pin, HIGH);
delayMicroseconds(600);
digitalWrite(Drive_pin, LOW);
delayMicroseconds(600);
i = i + 1;
} while (i <= step_size);
}
if (j < old_encoder_value)
{
i = 1;
do {
digitalWrite(Dir_pin, LOW);
digitalWrite(Drive_pin, HIGH);
delayMicroseconds(600);
digitalWrite(Drive_pin, LOW);
delayMicroseconds(600);
i = i + 1;
} while (i <= step_size);
}
old_encoder_value = myencoder.read();
Button_flag = digitalRead(Button_pin);
if (Old_button_flag != Button_flag)
{
Old_button_flag = Button_flag;
delay(70);
}
} while (Button_flag == HIGH);
lcd.clear();
digitalWrite(Enable_pin, HIGH);
myencoder.write(4);
}

//
// SUBROUTINE rotate () rotates a rotary axis motor
//

void rotate () {
//probably needs to check that a rotary axis motor has been selected in the 'select motor' subroutine
//and then gets instructions re: clockwise or anticlockwise and the number of degrees (limits?)
int turn_clock = 0;
int turn_clock_old = 0;
if (Motor_selected <= 3) { lcd.clear(); // 01234567890123456789 lcd.setCursor(0,0); lcd.print("--------------------"); lcd.setCursor(0,1); lcd.print(" Use A or B motor "); lcd.setCursor(0,2); lcd.print("Choose when offered!"); lcd.setCursor(0,3); lcd.print("--------------------"); delay(1500); lcd.clear(); select_motor(); } Old_button_flag = HIGH; Button_flag = HIGH; pinMode (Dir_pin, OUTPUT); pinMode(Drive_pin, OUTPUT); pinMode(Enable_pin, OUTPUT); digitalWrite(Enable_pin, LOW); // been problem when I defined enable pin as output????? lcd.clear(); lcd.setCursor(0, 0); lcd.print("--ROTATE SUB-MENU---"); // 12345678901234567890 lcd.setCursor(0, 1); lcd.print("Jog step 0.22 degree"); lcd.setCursor(0, 2); lcd.print("Degrees of rotation:"); lcd.setCursor(0, 3); myencoder.write(0); // cahnged to zero -ok?? do { turn_clock = myencoder.read(); turn_clock = turn_clock / 4; if (turn_clock > turn_clock_old) {
digitalWrite(Dir_pin, LOW);
digitalWrite(Drive_pin , HIGH);
delayMicroseconds(900);
digitalWrite(Drive_pin, LOW);
delayMicroseconds(900);
}
else if (turn_clock < turn_clock_old) {
digitalWrite(Dir_pin, HIGH);
digitalWrite(Drive_pin, HIGH);
delayMicroseconds(900);
digitalWrite(Drive_pin, LOW);
delayMicroseconds(900);
}
turn_clock_old = turn_clock;
lcd.setCursor(8, 3);
lcd.print(float(turn_clock) * 0.225);
lcd.print(" ");
Button_flag = digitalRead(Button_pin);
if (Old_button_flag != Button_flag)
{
delay(100);
Button_flag = digitalRead(Button_pin);
Old_button_flag = Button_flag;
}
} while (Button_flag == HIGH);
myencoder.write(4);
lcd.clear();
digitalWrite(Enable_pin, HIGH);
}

//
// SUBROUTINE shoot () takes a picture without flash, just fires shutter on press of rotary encoder knob
//

void shoot () {
// just fires shutter on press of rotary encoder knob
int k;
int j;
byte Old_button_flag = HIGH;
byte Button_flag = HIGH;
lcd.clear();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print("---SHOOT SUB-MENU---");
lcd.setCursor(0, 1);
lcd.print("Click to take photo!");
// 12345678901234567890
// need to get clockwise or anticlockwise and degrees
while (Button_flag == HIGH)
{
Button_flag = digitalRead(Button_pin);
if (Old_button_flag != Button_flag)
{
delay(30);
Button_flag = digitalRead(Button_pin);
Old_button_flag = Button_flag;
}
if (Button_flag == LOW)
{
digitalWrite(Camera_pin, HIGH);
delay(Delay_shutter_lag);// no need for lag here
digitalWrite(Camera_pin, LOW);
delay(Delay_2);
// 1234567890123456789
lcd.setCursor(0, 2);
lcd.print(" Photo taken! ");
delay(500);
lcd.clear();
return;
}
}
}

//
// SUBROUTINE flash () just fires the flashes on press of rotary encoder knob
//

void flash () {
// just fires flashes on press of rotary encoder knob
int k;
int j;
byte Old_button_flag = HIGH;
byte Button_flag = HIGH;
lcd.clear();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print("---FLASH SUB-MENU---");
lcd.setCursor(0, 1);
lcd.print("Click to fire flash ");
// 12345678901234567890
// need to get clockwise or anticlockwise and degrees
while (Button_flag == HIGH)
{
Button_flag = digitalRead(Button_pin);
if (Old_button_flag != Button_flag)
{
delay(30);
Button_flag = digitalRead(Button_pin);
Old_button_flag = Button_flag;
}
if (Button_flag == LOW)
{
digitalWrite(Flash_pin, HIGH);
delay(10);
digitalWrite(Flash_pin, LOW);
delay(Delay_2);
// 1234567890123456789
lcd.setCursor(0, 2);
lcd.print(" Flash fired! ");
delay(500);
lcd.clear();
return;
}
}
}

//
// SUBROUTINE shoot_flash () just takes a single picture with flash on press of rotary encoder knob
// this and the routines shoot() & shoot_flash() could all be choices within one subroutine??
//

void shoot_flash () {
// just fires flashes on press of rotary encoder knob
int k;
int j;
byte Old_button_flag = HIGH;
byte Button_flag = HIGH;
lcd.clear();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print("SHOOT&FLASH SUB-MENU");
lcd.setCursor(0, 1);
lcd.print("Click = flash photo ");
// 12345678901234567890
// need to get clockwise or anticlockwise and degrees
while (Button_flag == HIGH)
{
Button_flag = digitalRead(Button_pin);
if (Old_button_flag != Button_flag)
{
delay(30);
Button_flag = digitalRead(Button_pin);
Old_button_flag = Button_flag;
}
if (Button_flag == LOW)
{
digitalWrite(Camera_pin, HIGH);
delay(Delay_shutter_lag);
digitalWrite(Flash_pin, HIGH);
delay(10);
digitalWrite(Camera_pin, LOW);
digitalWrite(Flash_pin, LOW);
delay(Delay_2);
// 1234567890123456789
lcd.setCursor(0, 2);
lcd.print(" Flash photo taken!");
delay(500);
lcd.clear();
return;
}
}
}

//
// SUBROUTINE select_motor() allows choice of which motor to control
//

int select_motor () {
char motor = 'Z';
Old_button_flag = HIGH;
Button_flag = HIGH;
myencoder.write(12);
lcd.clear();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print("---MOTOR SUB-MENU---");
// 12345678901234567890
lcd.setCursor(0, 1);
lcd.print(" A, B for rotations!");
lcd.setCursor(0, 2);
lcd.print("Current motor: ");
lcd.print(motor);
while (Button_flag == HIGH)
{
Motor_selected = encode_return(5, 1);
switch (Motor_selected) {
case 1:
motor = 'X';
break;
case 2:
motor = 'Y';
break;
case 3:
motor = 'Z';
break;
case 4:
motor = 'A';
break;
case 5:
motor = 'B';
break;
default:
;
}
lcd.setCursor(0, 2);
lcd.print(" Current motor: ");
lcd.print(motor);
Button_flag = digitalRead(Button_pin);
if (Old_button_flag != Button_flag)
{
Old_button_flag = Button_flag;
delay(70);
}
}
switch (motor) { //set pins up for the motor selected
case 'X':
Enable_pin = 20;
Dir_pin = 21;
Drive_pin = 22;
break;
case 'Y':
Enable_pin = 23;
Dir_pin = 24;
Drive_pin = 25;
break;
case 'Z': // reset these to 26, 27, 28 when rewiring done!
Enable_pin = 10;
Dir_pin = 11;
Drive_pin = 12;
break;
case 'A':
Enable_pin = 29;
Dir_pin = 30;
Drive_pin = 31;
break;
case 'B':
Enable_pin = 32;
Dir_pin = 33;
Drive_pin = 34;
break;
default:
;
}
myencoder.write(4);
//return; //Motor_selected......no need to return this variable it's global
}

//
// SUBROUTINE click_Increment() adjusts the 'sensitivity' of the rotary encoder making
// it easier to dial up big numbers
//

int click_Increment() {
byte Old_button_flag = HIGH;
byte Button_flag = HIGH;
myencoder.write(40);
lcd.clear();
lcd.setCursor(0, 0);
// 12345678901234567890
lcd.print("-CLICK INC SUB-MENU-");
lcd.setCursor(0, 1);
lcd.print(" For each encoder ");
lcd.setCursor(0, 2);
lcd.print(" click inc will be: ");
// 12345678901234567890
while (Button_flag == HIGH)
{
Increment = encode_return(50, 1);
lcd.setCursor(9, 3);
lcd.print(Increment);
// 1234567890
lcd.print(" ");
Button_flag = digitalRead(Button_pin);
if (Old_button_flag != Button_flag)
{
delay(100);
Button_flag = digitalRead(Button_pin);
Old_button_flag = Button_flag;
}
if (Button_flag == LOW)
{
lcd.clear();
myencoder.write(4); // return encoder value to 1
return Increment;
}
}
}

Posted in Photography and electronics | Tagged , , , , , , , | 26 Comments

New control box for a focus rail with many other options

I have now completed the new control box for the focus rail that I described how to build in a post I made a year or two ago. Actually, the new control box is capable of a great deal more than controlling a focus rail. The current version is set up to control three motors so that the X, Y and Z position of the camera/object can be set in 3D space. Thus, the control box can be used for both Z stacking and stitching images. Further, the number of motors can easily be expanded to 5 allowing control of rotation in 2 planes with the object of making macro stereo photographs. The box includes 8 opto-coupled outputs arranged to allow the triggering of 4 cameras/flashes (only 4 because 2 outputs are used per camera to activate pre-focus and the shutter). Unused at the moment, but already incorporated, are 8 analogue/digital  inputs that could either be used to trigger motor movements, or allow cameras and flashes to respond to external events, or one or more could be used to stop the motors when a limit is reached.

img_2951

Rotary encoder controlled camera mover controller with the focus rail described in an earlier post

The menu system is driven by a rotary encoder and incorporates a ‘click sensitivity’ option that allows the encoder to increase any variable by between 1 and X for each rotational click. The use of the encoder provides for a much more responsive and versatile interface than a button pad. There is a switch to turn off power to the motors that is useful both when testing, to prevent heating of the motor, and also as an emergency stop! An LED indicates when the motor is active and there is an external button to reset the microprocessor. I have used an Arduino Mega 2560 because it is significantly more capable than an Uno. Further expansion would not be a problem bar finding room in the control box and having the abilities of a spider where routing the wiring is concerned. EasyDriver boards (http://www.schmalzhaus.com/EasyDriver/) control the motors and commercially available opto-coupler boards are used for the flash and camera output control signals. In theory, the design  could easily be used to control a pan and tilt system for hyper-resolution photography and/or virtual 3D. The programming leans heavily on an interrupt-based encoder library that enables the encoder to be read while the sketch is busy doing other things (see http://www.pjrc.com/teensy/td_libs_Encoder.html). The current sketch is about  600 lines including comments etc.

The approximate cost of all the hardware, assuming a Mega clone such as a Funduino is employed, is about £35. Because all the components are available as finished boards, the only difficult things are the point-to-point wiring between them, and between the boards and the sockets etc. Mostly, the wiring can be done using Dupont  jumper cables.

The little video of the prototype below shows the bare bones of the project in action. The mechanics of the X&Y axes have yet to be constructed – they could simply be repeats of the design I published earlier but my intention is to motorize an old microscope mechanical stage and incorporate on it a rotary table rather like the one I also described in a previous post. When I am happy with the code, I will publish the sketch that will control the mechanical gubbins. Meantime, it functions very well as an alternative to the push-button control box that I made for my focus rail.

By way of cheering up those, including myself, that make stupid mistakes, the reason the control box is shown powered from both a USB input and an external power supply, is because I blew the Arduino’s external psu circuitry by connecting its 5V output to the 5V output on an EasyDriver!

Posted in electronics, Photography and electronics | Tagged , , , , , , , , , , , , , , | 13 Comments

How to take ‘bad macro’ photos

I was somewhat reluctant to do a blog post about the process of taking pictures. Whenever I read anything about this on internet forums, there is lots of flaming and trolling. However, I want to start out by freely admitting that I take ‘bad macro’ pictures. My definition of ‘bad macro’ goes something like this – most people carry lots of gear out into the wild and often take stunningly beautiful shots of the animals and plants they encounter. While I sometimes do the same, apart from taking the stunning photos that is (!),  generally I am interested in seeing things and my camera acts as both an eye capable of resolving what mine cannot, and a kind of nature notebook that I can take home as a record of what was about and where, and that I can use to identify an insect or plant that I don’t immediately recognise. I carry a camera with a macro lens and nothing else….no tripod, no monopod, no flash, just a lens hood and a plastic bag to protect the camera if it starts to rain.

dsc_4522_hf

Shooting dragonflies is fun. They often have beautiful colours and they return to same perch making it much easier to photograph them.

It seems to me that there are three ways to take macro photos in the wild. The one I describe above requires only a camera and lens and thus can only make use of natural light. The method has quite a few advantages, choose a light camera and the right lens and you can walk all day taking photos that look natural. It is easier to be stealthy with a lightweight setup. Indeed, while I can understand how on a cool and still morning or evening you might be able to use a tripod to get pin sharp pictures by natural light, I find it vanishingly unlikely you’d find many butterflies or other insects that would sit still long enough for you to get set up. Adding a flash will provide for more light and allow you take photos where natural light would not but adds significantly to the weight you need to carry around, and reduces your mobility. Plus, most insects are gone once the flash fires. Add enough flash power and put an ND8 filer on the front of your lens, and daylight can be rendered almost superfluous (though not completely irrelevant – the subject of another post). The built in flash on your camera is not usually terribly useful for  macro flash, it’s in the wrong place, and most often one adds either a ring flash or a pair of dedicated macro flash guns. More of such setups another time.

OLYMPUS DIGITAL CAMERA

A Clouded Yellow butterfly. Sometimes you can get really close and rattle off several shots.

I have two cameras and macro lenses, an aging Nikon D7000 with a wonderfully sharp Nikon 105mm macro lens with vibration reduction, and an Olympus OM-D EM-1 with a great macro lens, the Olympus 60mm macro. The Olympus body has built in 3-axis stabilisation. Now for a truly controversial statement – the Nikon setup is nowhere near as good as the Olympus one! Why? First, the Nikon is way too heavy for my liking. The Nikon and lens weigh in at 1571g; the Olympus at 601g. While I think the Nikon 105mm is sharper than the Olympus 60mm, there really isn’t that much in it for ‘bad macro’. Secondly, I find the focus-peaking system available in the electronic viewfinder (EVF) of the Olympus to be a fantastic boon. As soon as you hit perfect focus, the white peaking pixels light up and in a trice, I can see the antenna and eyes of my subject are in focus. Really important if you wear varifocal glasses as I need to! However, the single most important factor is simply weight and manoeuvrability, and on that front, the Olympus micro 4/3rds wins hands down. Indeed, so taken am I with it that I intend to invest in an E-M1 Mk 2.

img_2933

The size and weight differences between a D SLR and a micro 4/3rds are quite marked. The former weighs 2.5 times as much as the latter!

So, a few words on my ‘bad technique’.  Outdoors there are three things that move; the wind blows everything around, the thing you want to photograph may (will) move or fly away, and you, the photographer, shake and wobble around. While the latter may not be obvious when you take a picture of a landscape, it becomes very obvious when you are trying to take photos around 1:1 magnification and the object has tiny feature that will betray your slightest movements as blur. Unless you are photographing plants, where it is possible to clamp the stem, or even use a light tent to shade them from the wind, there is generally almost nothing you can do about the first two sources of movement described above other than aim for a reasonably high shutter speed, which helps a bit with movement in the plane of focus, but not at all if the movement takes the object out of focus. A small aperture will provide a bit more depth of field (DoF) but will add blur through diffraction if the lens is stopped down too far. The best solution by far is to work on a still day! A still, sunny day before the heat comes on is the best time for ‘bad macro’ shots of insects.  Not only do the things like butterflies move more slowly when they are cool, but also you stay cool – getting up and down from your knees, or lying on the ground and getting up again, maybe a hundred times in a day when its 37oC is a recipe for heatstroke. The other thing that I find helps a great deal is good camera holding technique. A good macro photo doesn’t generally result from adopting a position that is much higher than the object you are trying to photograph. So, usually it is best to crouch, kneel or lie down to get on the right level. On one knee you can rest an elbow on one knee and tuck the other one into your side, focus,  – hold your breath and rock slightly to get perfect focus and then hit the shutter button.  Continuous shooting with a tiny rocking motion can also be used though you then have later to sort out which frame represents the perfect shot and it can be a pain to do this if you go for many frames per second. I reserve lying down for things that are likely to fly off pretty much as soon as I adopt that position – much better suited to plants than butterflies etc. If you do adopt lying down then propping your elbows on the ground will give you a lot of stability. Standing up, keeping your elbows tucked in is essential. The image stabiliser is your friend and I have it on at all times. On a bright day, when shooting insects, I usually choose an ASA that allows me to shoot at a 500th with an aperture of f8 to f16 – about 500ASA in bright sunlight. At that setting, noise is tolerable though if conditions get dimmer, I sometimes have to shoot at higher ASAs. However, the DoF will always be a small number of millimetres and it is this that means a great deal of attention to camera holding technique is necessary. With insects and other small creatures, always aim to have the eyes in focus – it always looks best.

There is ‘cheat’ that can be useful if you need a little more stability and you walk with a pole. Hold the camera as shown below, you can slide your hand down the stick to get to the right height, rock forward or backwards to get a bit closer or further away and in focus. It can really help and is far quicker than messing with a tripod or a monopod, and sticks are to be found everywhere for free!. If in doubt always hit the shutter button….the worst photo is the one you didn’t quite take.

img_2942

Sorry about the socks! Down on one knee, one elbow pushed against the knee, the other tucked in. The right hand holds the camera against the stick with a lttle downward force applied to the pole.

My only other tips for ‘bad macro’ involve knowing your prey. Many people do not realise that insects are creatures of habit. Butterflies have ‘leks’ and often return to the same spot at a particular time of day, flying off and returning to the exact same spot many times. As an example, a Red Admiral we named ‘Red’ returned to more or less the same spot in our garden every evening at around 6pm for a month! Dragonflies will perch on the same twig over-and-over again. So, if at first you don’t succeed, try just waiting for your prey to return. On a bright day, shadowing an insect will often cause it to move away so get used to walking such that your shadow doesn’t pass over them. Move slowly and without sudden movement. I am convinced that once your body fills the field of view of an insect’s eye, you can get very close because you no longer cause sudden changes from say full sunlight to shadowed. Mating insects often give up caring about most other things and butterflies chasing one another are often quite easy to shoot when they alight. And yes, you are right, surely there is an advantage to using a flash but, it isn’t absolutely necessary, and taking ‘bad macro’ pictures is surprisingly satisfying – sometimes, they even look quite good!

 

Posted in Photography and electronics | Tagged , , , , , , , , , , , , , , , , , | Leave a comment