Automating the Darkroom Part 4: The Software

All of the software was developed using the Arduino development environment (IDE). This is a free set of tools available at Arduino. The board is connected via a USB cable and is powered from it as well. The tools take care of compiling and linking and then download the SW to the board. All of the hardware already has pre-written libraries to control it available either built-in or at different places on the web. All of the lamp, servo, and LED control is built-in to the IDE. The LCD display and touchscreen is available from the vendor Adafruit. This was crucial and made the SW able to be completed over a week of part time work (evenings and weekends).

Below are examples of some of the SW. I am happy to share all of it with anyone who is interested.

Controlling the LCD and Touchscreen

The LCD library allows one to issue simple print commands and control the orientation, color and size of the text. One can also draw lines and boxes. The user interface consists entirely of text and boxes and was made to be simple to display and use. I started with the premise of  dividing the screen in to a matrix of squares. Some squares might be joined to provide more room to display more information. The display is 320 pixels wide and 240 pixels high. It seems reasonable that a 2.8" display could divide well into 80x80 pixel squares. Given this is a touch screen the squares have to big enough for my fingers. This worked out to be a good choice I have not regretted yet. This gives a matrix of 4x3 squares which in essence become labeled buttons.

The touchscreen library provides a simple interface that can detect a touch and give the location of the touch in x/y coordinates to a pixel resolution. I define BOXSIZE as my 80 pixels. The code below gets a touch point and then scales the result to each box and makes a single value by multiplying the x coordinate by 10 and adding it to the y coordinate.

 TS_Point p = ts.getPoint();
      Press = (p.y / BOXSIZE) + p.x / BOXSIZE * 10; 
      click();
      while (ts.touched());
The boxes are the located and encoded as follows
03  02  01  00
13  12  11  10
23  22  21  20
These feed into a switch statement that then decides on the behavior for each location pressed. Each page has its own function containing a switch statement. The Next key returns from the function which then allows the next page function to run.
while (1) //call menus sequentially. Next key forces exit from each menu function invoking the next.
  {
    Manual();
    Split_Auto();
    Develop();
    Flash();
  }
}
It was all meant to keep it very simple. Given four levels of menus I have considered a hierarchy approach with one top menu to select the four menus. It doesn't seem worth it yet.

Controlling the Servo

The servo in of itself is simple you just make a call with the desired angle (i).
 filterservo.write(i);
Unfortunately the servo is very fast. Too fast for the large filter wheel. So I wrote some code to slow it down. It works by moving small increments waiting and then moving again until the desired position is reached.  You still call it with the desired angle (171 degrees in this example).
      slow_servo(171);
But it is something else inside. The 'for' loop reads the current angle and then adds (or subtracts) one degree and moves the motor, then waits a small time (SERVOSLEW) before adding (or subtracting) another degree and moving again. The 'for' loop ends once the desired angle has been reached. There are two loops, one to increase the angle and one to decrease the angle.
if (filterservo.read() < angle)
  {
    for (i = filterservo.read(); i <= angle; i++)
    {
      filterservo.write(i);
      delay(SERVOSLEW);
    }
    return;
  }
  if (filterservo.read() > angle)
    for (i = filterservo.read(); i >= angle; i--)
    {
      filterservo.write(i);
      delay(SERVOSLEW);
    }

Testing the Exposure Timings

The easiest way I found to test the timings for the exposures was to use an audio editing program on my iPad. I left it recording in a quiet room and then initiated an exposure run with the relay connected. Since the relay makes a sound on opening and closing I can measure the time using the editing cursor. Below is an example. In this case I am testing 3 1/2 stops which we think of as 11 seconds. In reality it is 11.313 seconds (2 to the power of 3.5). You can see in the trace the relay closing at the start (I trimmed out the audio prior to that event). Next are a series of blips that are the second metronome sounds from the speaker on the board. Finally is the relay opening sound. The cursor sits at the center of the relay opening sound and shows 11.32 seconds which is very close to desired 11.313 seconds. The timing in the Arduino software is in millisecond resolution. 
Example of Audio File used for Timer Testing

Comments

This comment has been removed by the author.