Go Down

Topic: Stepper Moves, IR Flashes, Repeat... How? (Read 1 time) previous topic - next topic

IntelliTom

Hi Ian

Thanks for taking the time to help.  I have been playing with this all day ;)

A friend helped me and I got this working in a different way:

Code: [Select]
#include <AFMotor.h>
int IRledPin =  12;    // LED connected to digital pin 12
const int ButtonPin = 2;
AF_Stepper motor(200, 1);
int ButtonState = 0;

// This procedure sends a 38KHz pulse to the IRledPin
// for a certain # of microseconds. We'll use this whenever we need to send codes
void pulseIR(long microsecs) {
  // we'll count down from the number of microseconds we are told to wait

  cli();  // this turns off any background interrupts

  while (microsecs > 0) {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
   delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working
   digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
   delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working

   // so 26 microseconds altogether
   microsecs -= 26;
  }

  sei();  // this turns them back on
}

void SendNikonCode() {
  Serial.println("Fire Camera!");
  pulseIR(2080);
  delay(27);
  pulseIR(440);
  delayMicroseconds(1500);
  pulseIR(460);
  delayMicroseconds(3440);
  pulseIR(480);

  delay(65); // wait 65 milliseconds before sending it again

  pulseIR(2000);
  delay(27);
  pulseIR(440);
  delayMicroseconds(1500);
  pulseIR(460);
  delayMicroseconds(3440);
  pulseIR(480);

  delay(55);
}

void RotateTT() {
  Serial.println("6 Double coil steps");
  motor.step(6, FORWARD, DOUBLE);
}

// setup() is called first, then loop() is repeatedly called until power is switched off.
// We're doing everything in setup(), so loop() can be empty.

void setup()   {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Start!");
  pinMode(ButtonPin, INPUT);
  pinMode(IRledPin, OUTPUT);
  motor.setSpeed(5);
  for (int i = 0; i < 5; i++) {
  if (ButtonState == LOW) {
     SendNikonCode();
     delay(1000);
     RotateTT();
     delay(1000);
  }
  else {
  digitalWrite(IRledPin, LOW);
  }
}
}
void loop()
{
  // All done. Loop here, doing nothing.
}


Though your method works too and seems cleaner.  However, the next step is as you suggested, a button to start the process.  I can't seem to work out the right code.  You can see in the example above what I have tried and it just acts like the button is not there.  i.e it cycles through the 2 functions for the amount specified, then stops.  I tried to add a button start to your code also and the same happens

Code: [Select]
#include <AFMotor.h>
int IRledPin =  12;    // LED connected to digital pin 12
AF_Stepper motor(200, 1);
int NumberOfPictures = 5;  // How many pictures should we take?
int CountVariable = 0;  // I'll use this to keep a tab on how many pictures we've taken so far.
const int ButtonPin = 2;
int ButtonState = 0;

void setup()   {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Start!"); 
  pinMode(IRledPin, OUTPUT);
  motor.setSpeed(5);
}

void loop() {
  if (ButtonState == LOW) {
  if (CountVariable == NumberOfPictures) return; // Stop now as CountVariable indicates that we have taken the correct NumberOfPictures

RotateTT();
delay(1000); // wait half a second for good measure
SendNikonCode();
delay(1000); // wait half a second for good measure
CountVariable ++; // increment the count variable so it is actually counting :)
}  // at this point it will go to the top of the loop at the void loop() line and start again.
}

// This procedure sends a 38KHz pulse to the IRledPin
// for a certain # of microseconds. We'll use this whenever we need to send codes
void pulseIR(long microsecs) {
  // we'll count down from the number of microseconds we are told to wait

  cli();  // this turns off any background interrupts

  while (microsecs > 0) {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
   delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working
   digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
   delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working

   // so 26 microseconds altogether
   microsecs -= 26;
  }

  sei();  // this turns them back on
}

void SendNikonCode() {
  Serial.println("Fire Camera!");
  pulseIR(2080);
  delay(27);
  pulseIR(440);
  delayMicroseconds(1500);
  pulseIR(460);
  delayMicroseconds(3440);
  pulseIR(480);

  delay(65); // wait 65 milliseconds before sending it again

  pulseIR(2000);
  delay(27);
  pulseIR(440);
  delayMicroseconds(1500);
  pulseIR(460);
  delayMicroseconds(3440);
  pulseIR(480);
 
  delay(55);
}


void RotateTT() {
  Serial.println("6 Double coil steps");
  motor.step(6, FORWARD, DOUBLE);
}


I would love to know what I'm doing wrong  :smiley-eek:

IntelliTom

ok I am a step closer.

Code: [Select]
#include <AFMotor.h>
int IRledPin =  12;    // LED connected to digital pin 12
AF_Stepper motor(200, 1);
int NumberOfPictures = 5;  // How many pictures should we take?
int CountVariable = 0;  // I'll use this to keep a tab on how many pictures we've taken so far.
const int ButtonPin = 2;
int ButtonState = HIGH;

void setup()   {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Start!"); 
  pinMode(IRledPin, OUTPUT);
  motor.setSpeed(5);
}

void loop() {
  if (ButtonState == LOW) {
    Serial.println("Button Pressed");
    if (CountVariable == NumberOfPictures) return; // Stop now as CountVariable indicates that we have taken the correct NumberOfPictures
 
  RotateTT();
  delay(1000); // wait half a second for good measure
  SendNikonCode();
  delay(1000); // wait half a second for good measure
  CountVariable ++; // increment the count variable so it is actually counting :)
    }  // at this point it will go to the top of the loop at the void loop() line and start again.
  }

// This procedure sends a 38KHz pulse to the IRledPin
// for a certain # of microseconds. We'll use this whenever we need to send codes
void pulseIR(long microsecs) {
  // we'll count down from the number of microseconds we are told to wait

  cli();  // this turns off any background interrupts

  while (microsecs > 0) {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
   delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working
   digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
   delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working

   // so 26 microseconds altogether
   microsecs -= 26;
  }

  sei();  // this turns them back on
}

void SendNikonCode() {
  Serial.println("Fire Camera!");
  pulseIR(2080);
  delay(27);
  pulseIR(440);
  delayMicroseconds(1500);
  pulseIR(460);
  delayMicroseconds(3440);
  pulseIR(480);

  delay(65); // wait 65 milliseconds before sending it again

  pulseIR(2000);
  delay(27);
  pulseIR(440);
  delayMicroseconds(1500);
  pulseIR(460);
  delayMicroseconds(3440);
  pulseIR(480);
 
  delay(55);
}


void RotateTT() {
  Serial.println("6 Double coil steps");
  motor.step(6, FORWARD, DOUBLE);
}


I changed the 'int ButtonState = 0;' to 'int ButtonState = HIGH;' and now I have it where in the serial monitor it prints 'Start!' and pauses.  But pressing the button does not do anything.  I've double checked the wiring and tested the button with a separate sketch.  My pin numbers are correct.

:smiley-sweat:

IanMcRV

#7
Feb 10, 2013, 01:21 am Last Edit: Feb 10, 2013, 01:23 am by IanMcRV Reason: 1
Hi Tom,

You need to set the pinMode to INPUT_PULLUP because otherwise you will get problems when using things like a stepper motor or a servo.

See if this works, all I'm doing here is first setting the counter to the max so nothing happens in the loop and then when the user presses the button it resets the counter to 0 so that the loop begins the processing.
Gets rid of enclosing everything in an if statement:

Code: [Select]

#include <AFMotor.h>
int IRledPin =  12;    // LED connected to digital pin 12
AF_Stepper motor(200, 1);
int NumberOfPictures = 5;  // How many pictures should we take?
int CountVariable = 5;  // I'll use this to keep a tab on how many pictures we've taken so far. I've set this to 5 already so nothings going to happen until its reset to 0
int ButtonPin = 2; // needn't be a const
// int ButtonState = 0; // don't need this line

void setup()   {
 Serial.begin(9600);           // set up Serial library at 9600 bps
 Serial.println("Start!");  
 pinMode(IRledPin, OUTPUT);
 pinMode(ButtonPin, INPUT_PULLUP); // you hadn't set the pin mode in your example, you need to wire the button between pin 2 and Gnd
 motor.setSpeed(5);
}

// you also need to use digitalRead(ButtonPin) to get the value of the pin.

void loop() {
 if (digitalRead(ButtonPin) == LOW) CountVariable = 0; // the magic line, if the button is pressed then the count is set to 0 so it all begins.
 if (CountVariable == NumberOfPictures) return; // Stop now as CountVariable indicates that we have taken the correct NumberOfPictures

RotateTT();
delay(1000); // 1000 milliseconds = 1 second
SendNikonCode();
delay(1000); // 1000 milliseconds = 1 second
CountVariable ++; // increment the count variable so it is actually counting :)
}  // at this point it will go to the top of the loop at the void loop() line and start again.

// everything below this is nicely hidden away :)

// This procedure sends a 38KHz pulse to the IRledPin
// for a certain # of microseconds. We'll use this whenever we need to send codes
void pulseIR(long microsecs) {
 // we'll count down from the number of microseconds we are told to wait

 cli();  // this turns off any background interrupts

 while (microsecs > 0) {
   // 38 kHz is about 13 microseconds high and 13 microseconds low
  digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
  delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working
  digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
  delayMicroseconds(10);         // hang out for 10 microseconds, you can also change this to 9 if its not working

  // so 26 microseconds altogether
  microsecs -= 26;
 }

 sei();  // this turns them back on
}

void SendNikonCode() {
 Serial.println("Fire Camera!");
 pulseIR(2080);
 delay(27);
 pulseIR(440);
 delayMicroseconds(1500);
 pulseIR(460);
 delayMicroseconds(3440);
 pulseIR(480);

 delay(65); // wait 65 milliseconds before sending it again

 pulseIR(2000);
 delay(27);
 pulseIR(440);
 delayMicroseconds(1500);
 pulseIR(460);
 delayMicroseconds(3440);
 pulseIR(480);
 
 delay(55);
}


void RotateTT() {
 Serial.println("6 Double coil steps");
 motor.step(6, FORWARD, DOUBLE);
}

IntelliTom

Thanks Ian, but no joy.  This just cycles through the whole thing endlessly.  Doesn't stop at 5, doesn't wait for a button press.

IanMcRV

#9
Feb 10, 2013, 01:43 am Last Edit: Feb 10, 2013, 01:47 am by IanMcRV Reason: 1
Ah, okay,  I was doing it from memory. It's late here. I'll have a go tomorrow and do some testing on my system. Sorry it doesn't work yet but I think we're close!

One thing though. Try using pin 3 for the button instead of pin 2 as pin 2 is the main serial port.

Go Up