Help with code needed...

Hi everyone.
I am new both to this forum and programming.

I have been building a clock

and rather than wind up the weights by hand every 3 days I have employed a stepper motor, sprocket and chain which is driven by an Arduino uno. The Arduino is activated by 2 hall effect sensors in each of the bottom corners and as a safe guard stopped by 2 read switches in each of the top (sort of top) corners. Each of the weight boxes carry a magnet. The system only requires 1of the hall effect sensors to be triggered. The stepper motor is connect to the main drum via a magnetic clutch. This is necessary as the clock will not function if directly connected so it needs to be able to free wheel.

I have had the program written which appears below.

The system logic is as follows.

  1. Magnet needs to hover over Hall effect sensors for 10 sec before triggering Arduino.
  2. Circuit excites magnetic clutch.
  3. System power to motor for 10 seconds then wait for 5 seconds so clock can recover( its a long story if you know anything about clocks).repeat another 2 times
  4. cut power.

So far so good except for the magnetic clutch which exhibits backlash after the power is cut. It is turned back around 1/2 by the 16kgs that is resisting with a clunk. This is what i want to eliminate.
I think i need to de-energize the clutch after cutting power to the motor to stop this.

Any suggestions would be appreciated. I have attached a wiring diagram.

//john's comment

int dirpin = 3;
int steppin = 4;
int enable = 5;

int clutch_pin = 2;

int bottomLeft_pin = 8;
int bottomRight_pin = 9;

int Direction;
int Delay;
int tableRows = 13;

int MoveDelay = 1000; //Micro seconds
int MoveSteps = 2000;
int MoveDirection = 0;
int LiftStages = 3;

//LOW FUNCTION
void moveStepper (int Delay, long int steps, int Direction) {
int i;
if (Direction == 0) {
digitalWrite(dirpin, HIGH); // Set the direction.
}
else {
digitalWrite(dirpin, LOW); // Set the direction.
}
for (i = 0; i < steps; i++) // Iterate for 4000 microsteps.
{
digitalWrite(steppin, LOW); // This LOW to HIGH change is what creates the
delayMicroseconds(Delay);
digitalWrite(steppin, HIGH);
delayMicroseconds(Delay); // This delay time is close to top speed for this
} // particular motor. Any faster the motor stalls.
digitalWrite(dirpin, LOW); // Change direction.
}

void setup() {
Serial.begin(9600);
Serial.setTimeout(500);

// Setup the pins
pinMode(clutch_pin, OUTPUT); //set the clutch pin to be an output
digitalWrite(clutch_pin, LOW); //intitalise the clutch pin to be low (Disabled)

pinMode(dirpin, OUTPUT); // Set up the stepper pins
pinMode(steppin, OUTPUT);
pinMode(enable, OUTPUT);

digitalWrite(enable, HIGH); //intitalise the clutch pin to be High (Disabled)

pinMode(bottomLeft_pin, INPUT); // Assign the pin to read the bottom switch
pinMode(bottomRight_pin, INPUT); // Assign the pin to read the bottom switch

}
void loop()
{
// Main Program

if (digitalRead(bottomLeft_pin) == HIGH && digitalRead(bottomRight_pin) == HIGH ) // not at bottom either hall effect sensor will trigger
{ delay(10000); //Wait 10 seconds
}
else
{
for (int stage =0; stage < LiftStages; stage ++) // go up in stages
{
digitalWrite(clutch_pin, HIGH);
digitalWrite(enable, LOW);

moveStepper (MoveDelay, MoveSteps, MoveDirection);

digitalWrite(clutch_pin, LOW);
digitalWrite(enable, HIGH);

delay(5000);
}

}
}

An interesting project. You call it "backlash". Maybe it should be called remanence. The clutch is not demagnitized totally when current is removed. Try and apply a thin, none magnetic material like plastic, thick paper, between the magnet and the iron in the clutch. That will help although it decreases the force of the clutch a little bit. Applying a zener diode of some 15 volts in serie with the free wheel diod will fasten the release of the clutch. Just check that the voltage of the power supply plus the zener voltage does not exceed the max voltage of the transistor powering the magnet in the clutch. I can't tell if this last suggestion is a solution. The first suggestion is.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom.. :slight_smile:

Hi,
Did you get any answers on facebook?

Tom... :slight_smile:

void moveStepper (int Delay, long int steps, int Direction) {
  int i;
  if (Direction == 0) {
    digitalWrite(dirpin, HIGH); // Set the direction.
  }
  else {
    digitalWrite(dirpin, LOW); // Set the direction.
  }
  for (i = 0; i < steps; i++) // Iterate for 4000 microsteps.

Suppose that you call this function to step 40000 times. Will it actually step that number of times? Will it actually quit after the right number of steps?

The loop index can NOT be a different type than the number of times to iterate.

The comment on the last line in the snippet is nonsense.

Thanks for the code.....now where does it go? and another question.

int MoveDelay = 1000; //Micro seconds I know this is how long the motor runs
int MoveSteps = 2000; I know if I halve this value then it runs twice as fast
int MoveDirection = 0; Direction obviously...
int LiftStages = 3; How many times it will repeat.

I noticed that the rest between each cycle needs to be longer but I don't know how to control this.
Can i put a line in between move delay and move steps?

thanks Dean.

Can i put a line in between move delay and move steps?

You have our permission to do that.

permission accepted.
What would that line be......
Dean.

1964deano:
permission accepted.
What would that line be......
Dean.

That depends on what you want the line to do.

The lines you were asking about control how many times things happen, but they do not make the things happen. Other code does that. It appears that that is where you want to add a delay before the next (set of) thing(s) happen(s).

Have you tried a short delay between disabling the motor and engaging the clutch?
Wouldn't a sprag clutch (overrunning clutch) and DC motor be much simpler and more efficient?

After watching the video again, looks to me like when the motor and clutch are released, the weights are spinning the drum backwards until the escapement pawl catches it with a CLUNK. May not be a simple, easy fix. :frowning:

When I wind my clocks, I pull the chain until the weight is near the top, then I ease the chain back up until the weight rests on the internal mechanism.
If I were to simple release the chain, it would end with a similar clunk to your clock.

Maybe you need to wind it up to the top, then reverse a bit so the mechanism can 'catch' the weight before you remove power to your motor and clutch.

PaulS:
That depends on what you want the line to do.

The lines you were asking about control how many times things happen, but they do not make the things happen. Other code does that. It appears that that is where you want to add a delay before the next (set of) thing(s) happen(s).

Thanks Paul. That is what I need. I need a longer pause as you said. So where is the line and how can that be made either longer or shorter. ?

Dean

outsider:
Have you tried a short delay between disabling the motor and engaging the clutch?
Wouldn't a spring clutch (overrunning clutch) and DC motor be much simpler and more efficient?

After watching the video again, looks to me like when the motor and clutch are released, the weights are spinning the drum backwards until the escapement pawl catches it with a CLUNK. May not be a simple, easy fix. :frowning:

Yes that's right the weights are pulling down and rotating drum until the ratchets prevent them from doing so.
Have you tried a short delay between disabling the motor and engaging the clutch.
Don't know how to do that.Any helpful code based suggestions I can try?.
cheers

Dean.

TomGeorge:
Hi,
Did you get any answers on facebook?

Tom... :slight_smile:

No Haven't got any here either.
It's a shame really since there "seems" to be knowledgeably people around.

Dean.

With the help from John who wrote the original script here is a solution. We have made a variable that can adjusted to make the delay longer between winding events. Further we have got the stepper motor to reverse at the end of each winding event to ease the weight back onto the ratchets to stop the clunk.
Haven't tried that yet but can't wait to see what happens.
Dean.

/john's comment

int dirpin = 3;
int steppin = 4;
int enable = 5;
 
int clutch_pin = 2;
 
int bottomLeft_pin = 8;
int bottomRight_pin = 9;
 
int Direction;
int Delay;
int tableRows = 13;
 
int MoveDelay = 1000;     //Micro seconds half this value to double speed
long int MoveSteps = 2000;//number of steps so how long it runs for
int MoveDirection = 0;
int RevDirection = 1;
long int RevSteps = 200;  // winds motor back to stop clunking try 100
int RevDelay = 2000;     //Micro seconds length of time stepper goes in reverse
int LiftStages = 1;     // was 20
int DelayBetweenStages = 5000;   // increase to allow clock to recover from having gear train unweighted
int InitialDelay = 10000; //time to set up.
 
 
 
 
//LOW FUNCTION
void moveStepper (int Delay, long int steps, int Direction) {
  long int i;
  if (Direction == 0) {
    digitalWrite(dirpin, HIGH); // Set the direction.
  }
  else {
    digitalWrite(dirpin, LOW); // Set the direction.
  }
  for (i = 0; i < steps; i++) // Main move loop
  {
    digitalWrite(steppin, LOW); // This LOW to HIGH change is what creates the
    delayMicroseconds(Delay);
    digitalWrite(steppin, HIGH);
    delayMicroseconds(Delay);
  }
  digitalWrite(dirpin, LOW); // Change direction.
}
 
 
 
void setup() {
  Serial.begin(9600);
  Serial.setTimeout(500);
 
  // Setup the pins
    pinMode(clutch_pin, OUTPUT);  //set the clutch pin to be an output
    digitalWrite(clutch_pin, LOW);  //intitalise the clutch pin to be low (Disabled)
 
   
    pinMode(dirpin, OUTPUT); // Set up the stepper pins
    pinMode(steppin, OUTPUT);
    pinMode(enable, OUTPUT);
 
    digitalWrite(enable, HIGH);  //intitalise the clutch pin to be High (Disabled)
 
    pinMode(bottomLeft_pin, INPUT); // Assign the pin to read the bottom switch
    pinMode(bottomRight_pin, INPUT); // Assign the pin to read the bottom switch
   
}
void loop()
{
// Main Program
 
  if (digitalRead(bottomLeft_pin) == HIGH  && digitalRead(bottomRight_pin) == HIGH )  // not at bottom either hall effect sensor will trigger
    { delay(InitialDelay); //Wait 10 seconds
    }
    else
    {
      for (int stage =0; stage < LiftStages; stage ++) // go up in stages
      {
        digitalWrite(clutch_pin, HIGH);
        digitalWrite(enable, LOW);
  
        moveStepper (MoveDelay, MoveSteps, MoveDirection); //move up a stage
        moveStepper (RevDelay, RevSteps, RevDirection); //Back off a little at top of move to engage ratchet teeth.
 
        digitalWrite(clutch_pin, LOW);
        digitalWrite(enable, HIGH);
 
        delay(DelayBetweenStages);
      }
   
    }
}