Stalled - several things at the same time

I am making an apparatus to convert 8mm cine films into a digital form. Its all been done before but its new to me. It involes taking a still photograph of every single frame of the cine film, I am aiming for 3 frames per second. Then other PC based software is used to turn these into a movi.

I will use a heavily modified old projector to transport the film through the gate. The original motor will be replaced with a DC motor driven via an H bridge and the lamp will be relaced by an 8 watt COB LED. A still camera is mounted outside the projector and is focused on the film gate. The whole lot will be controlled by an arduino.

A small magnet is fitted to the shutter blade within the projector which passes a hall sensor every time a new frame of cine film is ready in the gate.

I will use a PC based program to take the pictures. This part is a bit hairy. The pic is taken by clicking a button on the GUI. I have modified a mouse to take the signal from the arduino every time the hall sensor senses the magnet. (so the mouse acts like a left click). So before starting the process I have to position the mouse arrow so that it is over the "button".

The COB LED gets very hot if it is permanently on, even with a big heatsink. So I intend to switch it on only when needed. The power to the LED is also a PWM feed so that I can adjust the exposure.

The PC program seems to need a 15mS pulse to start taking the photo so my sequence is:-

magnet detected
send 15mS pulse to the mouse and turn on LED
wait another 15mS while the picture is taken
wait another 15mS for good measure
switch off LED
wait for the next magnet detection

The arduino will eventually control the motor as well but at the moment I am working only on the Capture (Trigger pulse) and the control of the LED (strobe pulse)

I have dabbled in arduino stuff before but to be honest, I have made too big a jump this time. The milli stuff is doing my head in. I have started using serial.Print to try and debug but my brain is not big enough to process the evidence that I am seeing.
I can see that the capPin is HIGH when needed but I see no response from the strobe.

My code

const byte ledPwmPin = 6;
const int potPin = A0;
const int capPin = 13;
const int hallPin = 2;

int output;
int ledValue;
unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
unsigned long startTrigger;
unsigned long endTrigger;
unsigned long endStrobe;
const unsigned long triggerPulseDuration = 15;  //the value is a number of milliseconds
const unsigned long strobeOnDuration = 45;  //the value is a number of milliseconds
volatile byte val = LOW;
volatile byte valCap = HIGH;

void setup() 
{
  Serial.begin(115200);  //start Serial in case we need to print debugging info
  startMillis = millis();  //initial start time
  pinMode(ledPwmPin, OUTPUT);
  pinMode(capPin, OUTPUT);
  pinMode(hallPin, INPUT);
  pinMode(potPin, INPUT);
}

void loop()
{
  currentMillis = millis();

  startTriggerPulseAndStrobe();
  endTriggerPulse();
  stopStrobe();

}



void startTriggerPulseAndStrobe()
{
  val = digitalRead(hallPin);
   Serial.print("val = ");
   Serial.println(val);

  if (currentMillis - startMillis >= triggerPulseDuration && val == LOW)
  {
    digitalWrite(capPin, HIGH);
    valCap = digitalRead(capPin);
       Serial.print("valCap = ");
   Serial.println(valCap);
    startTrigger = millis();
    
    //Reading from potentiometer
    output = analogRead(potPin);
    //Mapping the Values between 0 to 255
    //from 0 -255 using the analogwrite funtion
    ledValue = map(output, 0, 1023, 0, 255);
    analogWrite(ledPwmPin, ledValue);
  }
}



void endTriggerPulse()
{
  endTrigger = millis();
  if (endTrigger - startTrigger >= triggerPulseDuration)  //test whether the triggerPulseDuration has elapsed
  {
    digitalWrite(capPin, LOW);
  }
}


void stopStrobe()
{
  endStrobe = millis();
  if (endStrobe - startMillis  >= strobeOnDuration)
  {
    analogWrite(ledPwmPin, 0);
  }
}

Can someone give me some pointer on what I am doing wrong with the millis, probably many things?
Also
I suspect that the trigger pulse is being sent multiple times during the relatively long period that the magnet passes the hall sensor. I need to prevent this.

Many thanks in anticipation

Use of startMillis looks odd. You set it in Setup, so it's close to zero and never touch it again. But you check it in several places to see if it's time to do something.

Have you mixed up startMillis and startTrigger?

Think of the problem more as a state machine. You are either waiting for the hall sensor, generating the pulse, or waiting after the pulse is done

const byte ledPwmPin = 6;
const int potPin = A0;
const int capPin = 13;
const int hallPin = 2;

unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long triggerPulseDuration = 15;  //the value is a number of milliseconds
const unsigned long strobeOnDuration = 45;  //the value is a number of milliseconds

enum { WAITING, PULSE_ON, PULSE_DELAY };
int state;

void setup()
{
  Serial.begin(115200);  //start Serial in case we need to print debugging info
  startMillis = millis();  //initial start time
  pinMode(ledPwmPin, OUTPUT);
  pinMode(capPin, OUTPUT);
  pinMode(hallPin, INPUT);
  pinMode(potPin, INPUT);
  state = WAITING;
}

void loop()
{
  int output;
  int ledValue;

  currentMillis = millis();

  switch (state) {
    case WAITING:   // waiting for hall sensor
      if ( digitalRead(hallPin) == LOW ) {
        Serial.println("triggered");
        digitalWrite(capPin, HIGH);
        startMillis = currentMillis;
        state = PULSE_ON;
      }

      break;

    case PULSE_ON:  // waiting for pulse duration to expire

      if (currentMillis - startMillis >= triggerPulseDuration) {
        Serial.println("Pulse OFF");
        digitalWrite(capPin, LOW);
        startMillis = currentMillis;
        state = PULSE_DELAY;
      }

      //Reading from potentiometer
      output = analogRead(potPin);
      //Mapping the Values between 0 to 255
      //from 0 -255 using the analogwrite funtion
      ledValue = map(output, 0, 1023, 0, 255);
      analogWrite(ledPwmPin, ledValue);

      break;

    case PULSE_DELAY:

      if (currentMillis - startMillis >= strobeOnDuration) {
        Serial.println("reset");
        digitalWrite(ledPwmPin, LOW);
        state = WAITING;

      }
      break;
  }
}

Thanks for the help, I finally got most of it working. The hall sensor and the PWM for the big LED are working fine now. As suggested, my millis were all wrong.

The problem now is making the arduino activate the left mouse button. My last attempt was misguided, I had a pin attached to one of the 3 contacts on the left click micro switch. I had decided that all it needed was 5v to make it click. It sort of worked but not well. It messed up my laptop. After a test I had to do lots of random clickes around the GUI to eventually get it to behave normally.

Next I got another mouse that has only 2 contacts on the left switch. It would have been nice if one of these was to ground and the other to 5v, that would make sense to me, but no. One has 5v on it (but does not ping through to the 5V pin on the USB connector). The other is not conected to 5V or ground.

All that is needed is for these two contacts to be shorted together while the cursor is hovered over the "snapshot" button on the GUI.

How can I do this with an Arduino?

I could do it with a mechanical relay but I worry about the thousands, maybe millions of cycles it will have to do.

Is there a better way?

Any help very much appreciated.

I have ordered an Arduino micro which I understand can be set up to "be" a mouse, also a solid state relay that may be of use.

There must be a way!

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