Using an Arduino with a stepper motor and relay to digitize 16mm film

Hello. I'm not a "newbie" to using an Arduino, but I've definitely taken on more than my programming skills are capable of with this project and I can use some help. I've modified an old 16mm film projector with a stepper motor. Using my Arduino Uno with the stepper, I'm able to make the projector advance the film one frame at a time... and as this is happening, the film gate is activating a micro-switch that, when closed, trips a DSLR camera that's shooting macro into the projector's modified optics. The results so far have been pretty good, but I'm concerned about causing damage to the film gate with the "trip wire" I've attached to it. This method also seems a little clunky.

I'm trying to program the Arduino so that on every single rotation of the stepper, a relay will close and thus trip the camera's shutter. I'm using very simple code for the rotation of the stepper; it rotates once, pauses for 1 second, then rotates again, etc. I want the relay to close when the stepper motor pauses during that 1 second delay.

I tried combining the sketch for the stepper motor control with a simply relay sketch, but I keep getting compiling errors with suggesting that I may want to use "delay" rather than "relay" in my code.

Here is the simple stepper control sketch I'm using. I found it online, but it works for what I need.

int x;
void setup() {
pinMode(9,OUTPUT); // set Pin9 as PUL
pinMode(8,OUTPUT); // set Pin8 as DIR
}
void loop() {
digitalWrite(8,HIGH); // set high level direction
for(x = 0; x < 400; x++) // repeat 400 times a revolution when setting 400 on driver
{
digitalWrite(9,HIGH); // Output high
delayMicroseconds(500); // set rotate speed
digitalWrite(9,LOW); // Output low
delayMicroseconds(500); // set rotate speed
}
delay(1000); //pause 1 second
digitalWrite(8,HIGH); // set high level direction
for(x = 0; x < 400; x++)
{
digitalWrite(9,HIGH);
delayMicroseconds(500);
digitalWrite(9,LOW);
delayMicroseconds(500);
}
delay(1000);
}

Thanks for taking a look. Hope someone can help.

Aaron

Hi @juanbanzai ,
Welcome to the forum..

A relay is typically just wired to a digital pin..
Relays can be either low or high triggered, depends on what you buy..
you need another pinMode(relayPin,OUTPUT); in your setup..
then depending on relay digitalWrite it high or low to activate before your 1 second sit and spin then deactivate it with another digitalWrite..

let's say pin 12, high activated relay..

int x;
void setup() {
pinMode(9,OUTPUT); // set Pin9 as PUL
pinMode(8,OUTPUT); // set Pin8 as DIR
pinMode(12, OUTPUT);
}
void loop() {
digitalWrite(8,HIGH); // set high level direction
for(x = 0; x < 400; x++) // repeat 400 times a revolution when setting 400 on driver
{
digitalWrite(9,HIGH); // Output high
delayMicroseconds(500); // set rotate speed
digitalWrite(9,LOW); // Output low
delayMicroseconds(500); // set rotate speed
}
//relay on
digitalWrite(12, HIGH);
delay(1000); //pause 1 second
//relay off
digitalWrite(12, LOW);
digitalWrite(8,HIGH); // set high level direction
for(x = 0; x < 400; x++)
{
digitalWrite(9,HIGH);
delayMicroseconds(500);
digitalWrite(9,LOW);
delayMicroseconds(500);
}
delay(1000);
}

happy coding.. ~q

What current is the relay switching? What voltage? Pease post schematics for the relay part of the build. My fear is that a mechanical relay will worn out. Electronical switching would have a much, much longer life.

And relays are slow, and they bounce. As Railroader suggests an electronic switch would be much better.

Thanks very much for the replies... and I realized after I sent my initial post that I didn't say anything about the relay. Sorry about that.

I'm attaching a picture of the relay I'd like to use. I purchased a large quantity of this particular model because I used them in an amateur radio project for remotely switching antennas at the back of my property. I know there's a concern of them failing over time, but I've had 6 of them sitting in a PVC box through 4 winters and not a single one has given me problems as of yet (knock on wood).

For this application, the relay is powered off the 5v on the Arduino, and for testing purposes, I'm using the 3.3v pin on the Arduino to turn an LED on and off from the relay. I found a simply relay "on/off" sketch just to make some tests and to get me started on determining what I want to accomplish.

I wholeheartedly agree that the mechanical switch is a better idea, but the projector I've modified is an older model that unfortunately doesn't have a lot of room to mount the trip wire I've been using to activate the microswitch. There's a few bends in the trip wire to get over and around the inside of the projector's cast aluminum case, and I spent hours trying to come up with a design that would work effortlessly. However, with the combination of the film gate, the projector's rotating shutter, and the case... the trip wire always seems to rub against the case which causes a slight binding in the rotation of the shutter. Even if the stepper motor is able to handle this bit of additional torque, I'd like to be able to eliminate it completely.

The speed of the relay in activating the shutter release on the camera isn't that big of a deal. I can set the delay of rotation on the stepper to anything I want to allow for the relay to close. In fact, the slower the operation, the better. The one particular film I'm building this contraption for is on nitrate stock and has begun to decompose. Winding it through the projector slowly and methodically might be the best option to ensure the film isn't damaged.

Thank you again for the assistance.

Aaron

here's the project simmed..
UnoRelay

have fun.. ~q

Thank you so much for the sketch and the warm welcome to the forum. I loaded the sketch into my Arduino and ran some tests with the stepper and relay connected together. It is so close to what I want to accomplish... and I've been playing with the code to try and modify it to better suit my needs. However, every attempt to make it work has been met with odd behavior from the stepper. My lack of detailed coding skills is clearly showing.

Currently, the stepper makes one 360 deg rotation, then stops. When it stops, the relay closes... which is perfect! However, the relay remains closed during the 1 second delay that holds the stepper motor in place. When the relay opens, the motor rotates a second time. Then, the stepper rotates again. If this scenario were to take place inside the film projector, the stepper motor would advance the film by TWO frame (one per rotation) rather than just one, and only allow for the camera to snap a single frame and miss the other.

Is it possible to allow for the relay to quickly go high/low without effecting the rotation of the motor? I may be way off base, but it seems like the stepper is waiting for the relay to open before it rotates. So basically every time the stepper makes one rotation, the relay has to close, then quickly open.

Here is a link to a short video of what I'm seeing: Arduino Uno vs stepper motor and relay - YouTube

Thank you again for your assistance.

Aaron

can't you just take some delay from the 1 second, like this..

int x;
void setup() {
  pinMode(9, OUTPUT); // set Pin9 as PUL
  pinMode(8, OUTPUT); // set Pin8 as DIR
  pinMode(12, OUTPUT);
}
void loop() {
  digitalWrite(8, HIGH); // set high level direction
  for (x = 0; x < 400; x++) // repeat 400 times a revolution when setting 400 on driver
  {
    digitalWrite(9, HIGH); // Output high
    delayMicroseconds(500); // set rotate speed
    digitalWrite(9, LOW); // Output low
    delayMicroseconds(500); // set rotate speed
  }
  //relay on
  digitalWrite(12, HIGH);
  delay(100);
  //relay off
  digitalWrite(12, LOW);
  delay(900); //pause 1 second
  digitalWrite(8, HIGH); // set high level direction
  for (x = 0; x < 400; x++)
  {
    digitalWrite(9, HIGH);
    delayMicroseconds(500);
    digitalWrite(9, LOW);
    delayMicroseconds(500);
  }
  delay(1000);
}

curious..
there's 2 1 second delays in the loop..
should we activate relay on each stop or just first??

~q

and two times rotating the stepper. Wouldn't it enough to do the rotation of the stepper once in the loop?

In this case I would prefer to accelerate and decelerate the stepper when moving. It would certainly be less damaging for the film if the stepper did not immediately start at full speed. This can be easily done with a stepper library - e.g. my MobaTools which can be installed via the library manager.

I would say activate the relay on each stop. I just uploaded the new sketch and the relay high/low is perfect. The DSLR shutter trips just as it should.

I'm going to try and increase the delay for the motor's rotation to give the camera more than enough time to snap a frame and save the photo, but if it can take a picture on every single rotation of the motor, I'll be in business.

Thank you!

like this??

int x;
void setup() {
  pinMode(9, OUTPUT); // set Pin9 as PUL
  pinMode(8, OUTPUT); // set Pin8 as DIR
  pinMode(12, OUTPUT);
}
void loop() {
  digitalWrite(8, HIGH); // set high level direction
  for (x = 0; x < 400; x++) // repeat 400 times a revolution when setting 400 on driver
  {
    digitalWrite(9, HIGH); // Output high
    delayMicroseconds(500); // set rotate speed
    digitalWrite(9, LOW); // Output low
    delayMicroseconds(500); // set rotate speed
  }
  delay(900); //pause 1 second
  digitalWrite(8, HIGH); // set high level direction
  for (x = 0; x < 400; x++)
  {
    digitalWrite(9, HIGH);
    delayMicroseconds(500);
    digitalWrite(9, LOW);
    delayMicroseconds(500);
  }
  //relay on
  digitalWrite(12, HIGH);
  delay(100);
  //relay off
  digitalWrite(12, LOW);
  delay(900);
}

Let me know if it's moving to fast, can play with the MobaTools for you if you'd like..

have fun.. ~q

Here is a version with MobaTols and accelerating/decelerating the stepper:

#include <MobaTools.h>
const byte dirPin = 8;
const byte pulPin = 9;
const byte relPin = 12;
const int stepsPerRev = 400;
MoToStepper filmStepper( stepsPerRev, STEPDIR ); // create stepper object with 400 steps/rev using a Step/dir driver

void setup() {
    filmStepper.attach( pulPin, dirPin  ); // assign dir/pul pins to the stepper object.
    filmStepper.setSpeedSteps( 10000, 100 ); // set speed to 1000 steps/sec, and ramp up/down within 100 steps

    pinMode(relPin , OUTPUT);
}
void loop() {
    filmStepper.doSteps( stepsPerRev ); // do one revolution
    while ( filmStepper.moving() ); // wait until stepper stops

    digitalWrite(relPin, HIGH); // rel on
    delay(100);
    digitalWrite(relPin, LOW);   //relay off
    delay(900); //pause 1 second
}
1 Like

Oh my gosh! It's absolutely perfect!!

Just sitting on my bench, it appears that this configuration will do exactly what I need. Thank you so much for your help. I'm going to thoroughly study the sketch in order to thoroughly understand what it's doing, but tonight comes the "hard part" of mounting everything into the modified case of the projector. I'll post the results of the project when it's completely assembled since I'm sure this will benefit others who are trying to digitize and preserve old film.

Thank you again. I'm am very grateful for your kindness.

Aaron

1 Like

I'd like to post a follow up and to freely admit that I made one of the biggest engineering gaffs possible.

I managed to successfully fabricate a heavy-duty aluminum L-bracket to mount the stepper motor and ITS mounting bracket to the projector. In its original design, the projector was driven by a motor that had a pully connected to another pulley by a 1/4" wide rubber belt. This, in turn, was driving the projector's shutter by another rubber belt.

I'm sure, by now, you may have figured out my mistake. The pully on the stepper motor is approximately a 1 1/2" in diameter as is the pulley driven by the 1/4" wide rubber belt. However, the projector's shutter is approximately 4" in diameter. So when reality kicked in, I sat there in utter disbelief that I didn't take into consideration that the smaller pulleys would have to rotate 3 times in order for the shutter to go around once; thus allowing for the film gate to grab the film and advance it by one frame. The good news is that the relay activation tripped the camera's shutter every time.;

So I guess my question is whether or not I can modify the sketch to successfully compensate for the size differences between pulleys or if I should abandon the idea of trying to dial in one frame of the film at a time using the Arduino to control the stepper motor. As I said in my first post, I've seen DIY film telecine units that simply operate the projector at a very slow speed with a mechanical switch being tripped by the projector's film gate. I tried this method and it worked OK but not without some issues. To me, it just seems very inefficient and clunky.

I know the stepper motor will do exactly what I want, but I have no clue as to whether or not the code can be modified to take into consideration the size of the pulleys and how many turns will be needed to make the shutter rotate 360 degrees. If I may get very technical about it, the stepper has to rotate 3 full turns and some change in order for the shutter to rotate once... and of course, when this rotation is complete, the relay has to close.

I hope this makes sense what I'm describing.

Thank you again.

Aaron

Here you can do as much steps as you want and as is necessary to advance the film one picture ahead. It does not have to be one revolution. Or did I not understand your issue?

No... that's it exactly. In my original request for assistance, I assumed that one revolution of the stepper motor would work perfectly with what I was trying to accomplish. Reality set it when I got everything installed in the projector and ran the sketch.

So I need three rotations... pause... close relay... open relay... resume rotation.

How would I indicate something more precise like three full rotations PLUS a few additional steps I haven't calculated yet? In other words, the stepper needs to rotate just slightly PAST three full rotations in order for the projector's shutter wheel to rotate once.

Aaron

Calculate the steps needed which obviously should be a little bit more than 1200 steps ( 3 rotations are 1200 steps with 400 stepPerRev ) . Insert this number of steps as parameter to the doSteps method.

...
const int stepsPerRev = 400;
const int stepsPerPicture = 1250;   / whatever you need
MoToStepper filmStepper( stepsPerRev, STEPDIR ); // create stepper object with 400 steps/rev using a Step/dir driver
....
    filmStepper.doSteps( stepsPerPicture ); // advance one picture
...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.