Program for coil winder, buttons work normal first time but do nothing the second time pressed. Arduino UNO

Hi. I made a coil winder with a x axis stepper motor turning a ball screw linear stage to move a wire guide left and right. The Y axis is a motor that spins a bobbin on its shaft. The X moves the wire back and forth while the Y axis spins the bobbin. The X axis homes when powered up as it should. The buttons, buttonPin and buttonPin2, work as they should but one time only. After that the buttons do nothing when pushed. I have set the layers to low numbers for quick testing. There are no errors when verifying. I’m not sure if I’m over looking something or maybe I have somehow messed up my Arduino UNO. Any help would be appreciated.


// Coil Winder Sketch 39 AWG, 150 winds per layer. 1:10 ratio, 1:1:10 ratio.


//Define pin connections & motor's steps per revolution
const int stepPinX = 2; // motor X step pin
const int dirPinX = 3; // motor X direction pin
const int enableX = 4; // motor X enable pin
const int stepPinY = 5; // motor Y step pin
const int dirPinY = 6; // motor Y direction pin
const int enableY = 7; // motor Y enable pin
const int buttonPin = 8; // pin connected to the buttonPin switch
const int homeSwitch = 9; // Pin connected to Home Switch to ground
const int buttonPin2 = 10; // pin connected to the buttonPin2 switch
const int stepsPerRevolution = 200; //number of steps per revolution in motorloop


//creates  variable integers for layers
     
      int turnsPerLayer = 15; //Change this number for the number of turns in layer
      int Layers = 0;         //Total layers                       
      int LayersTotal = 5;    //Total layers for coil one in 1:10 ratio
      int LayersTotal2 = 10;  //Total layers for coil ten in 1:10 ratio                
      
void setup() 
{ 
  
// Declare pins 

    pinMode(stepPinX, OUTPUT);
    pinMode(dirPinX, OUTPUT);
    pinMode(stepPinY, OUTPUT);
    pinMode(dirPinY, OUTPUT);
    pinMode(enableX, OUTPUT);
    pinMode(enableY, OUTPUT);
    pinMode(buttonPin, INPUT_PULLUP);
    pinMode(homeSwitch, INPUT_PULLUP);
    pinMode(buttonPin2, INPUT_PULLUP);
     
// Start Homing procedure of X axis Stepper Motor at startup

  while (digitalRead(homeSwitch) == LOW) // Do this until the switch is not activated   
    {  
      digitalWrite(dirPinX, LOW);      // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(stepPinX, HIGH);
      delay(.2);                       // Delay to slow down speed of Stepper
      digitalWrite(stepPinX, LOW);
      delay(.2);   
    }

  while (digitalRead(homeSwitch) == HIGH) // Do this until the switch is activated
    { 
      digitalWrite(dirPinX, HIGH); 
      digitalWrite(stepPinX, HIGH);
      delay(2);                       // More delay to slow even more while moving away from switch
      digitalWrite(stepPinX, LOW);
      delay(2);
    }
  
}

void loop() 
{
      ButtonloopA();  // Call function
}


void ButtonloopA()    //Function called to pause winding
{                              
    if (digitalRead(buttonPin) == LOW) // check if the pushbutton is pressed. If it is, the buttonState is LOW 
      { 
        MotorloopA();    // call function after button is pressed
      }
    else if (digitalRead(buttonPin2) == LOW) // check if the pushbutton2 is pressed. If it is, the buttonState is LOW 
      {
        MotorMainLoopA();  // call function after button is pressed
      }   
    else 
      {
        ButtonloopA();   // call ButtonloopA function loop until a button is pressed
      }
}

void MotorloopA()     //Function called to wind layer right to left
{                
      digitalWrite(dirPinX, HIGH);      // Set motor X direction clockwise                    
      digitalWrite(dirPinY, LOW);       // Set motor Y direction clockwise
      for(; Layers < LayersTotal;) // Count layers and stop at LayersTotal amount
        {
          
          for(int stepTurns = 0; stepTurns < turnsPerLayer; stepTurns++) //Count winds per layer and calls MotorloopA to switch direction at turnsPerLayer amount
              {
                for(int x = 0; x < stepsPerRevolution; x++) // Spin motor Y one rotation
                   {
                      TurnRatio();    //Call function
                   }
                
              }
            Layers++;             //Adds 1 to Layers count
            MotorloopB();        //call function pause loop waiting for button push
        }
    ButtonloopA();      //call function pause loop waiting for button push
}
void ButtonloopB()      //Function called to pause winding
{                              
    if (digitalRead(buttonPin) == LOW) // check if the pushbutton is pressed. If it is, the buttonState is LOW 
      { 
        MotorloopB();    // call function after button is pressed
      }
    else if (digitalRead(buttonPin2) == LOW) 
      {
        MotorMainLoopB();  // call function after button is pressed
      }   
    else 
      {
        ButtonloopB();   // call function loop until button is pressed
      }
}
void MotorloopB()       //Function called to wind layer left to right
{  
      digitalWrite(dirPinX, LOW);   // Set motor X direction clockwise
      for(; Layers < LayersTotal;) // Count layers and stop at LayersTotal amount
        {
          
          for(int stepTurns = 0; stepTurns < turnsPerLayer; stepTurns++) //Count winds per layer and calls MotorloopA to switch direction at turnsPerLayer amount
              {
                for(int x = 0; x < stepsPerRevolution; x++) // Spin motor Y one rotation
                   {
                      TurnRatio();    //Call function
                   }
                
              }
  
          Layers++;             //Adds 1 to Layers count
          MotorloopA();       //Call function to wind right to left
        }
      ButtonloopB();      //call function pause loop waiting for button push
}
void MotorMainLoopA()  //Function called to wind ten coil in 1:10 right to left
{     
      digitalWrite(dirPinX, HIGH);      // Set motor X direction clockwise
      for(; Layers < LayersTotal2;) // Count layers and stop at LayersTotal amount
        {
          
          for(int stepTurns = 0; stepTurns < turnsPerLayer; stepTurns++) //Count winds per layer and calls MotorloopA to switch direction at turnsPerLayer amount
              {
                for(int x = 0; x < stepsPerRevolution; x++) // Spin motor Y one rotation
                   {
                      TurnRatio();    //Call function
                   }
                
              }
          Layers++;             //Adds 1 to Layers count
          MotorMainLoopB();    //call function pause loop waiting for button push
        }
      ButtonloopA();      //call function pause loop waiting for button push
}
  
void MotorMainLoopB()         //Function called to wind coil ten in 1:10 left to right
{   
      digitalWrite(dirPinX, LOW);   // Set motor X direction clockwise
      for(; Layers < LayersTotal2;) // Count layers and stop at LayersTotal amount
        {
          
          for(int stepTurns = 0; stepTurns < turnsPerLayer; stepTurns++) //Count winds per layer and calls MotorloopA to switch direction at turnsPerLayer amount
              {
                for(int x = 0; x < stepsPerRevolution; x++) // Spin motor Y one rotation
                   {
                      TurnRatio();    //Call function
                   }
                
              }
          Layers++;             //Adds 1 to Layers count
          MotorMainLoopA();    //call function pause loop waiting for button push
        } 
      ButtonloopB();        //call function pause loop waiting for button push
}
void StepMotorX()
{
      digitalWrite(stepPinX, HIGH);  //One step X motor
      delayMicroseconds(100);
      digitalWrite(stepPinX, LOW);
      delayMicroseconds(100);
}
void StepMotorY()
{
      digitalWrite(stepPinY, HIGH);  //One step Y motor
      delayMicroseconds(100);
      digitalWrite(stepPinY, LOW);
      delayMicroseconds(100); 
}
void TurnRatio()
{
      StepMotorX();   //One X step

      StepMotorY();   //to three Y steps
      StepMotorY();
      StepMotorY();

      StepMotorX();   //One X step
      
      StepMotorY();   //to three Y steps
      StepMotorY();
      StepMotorY();  
      
      StepMotorX();   //One X step

       
      StepMotorY();   //to two Y steps
      StepMotorY();
      
}

void ButtonloopB()  //Function called to pause winding
{
  if (digitalRead(buttonPin) == LOW)  // check if the pushbutton is pressed. If it is, the buttonState is LOW
  {
    MotorloopB();  // call function after button is pressed
  } else if (digitalRead(buttonPin2) == LOW) {
    MotorMainLoopB();  // call function after button is pressed
  } else {
    ButtonloopB();  // call function loop until button is pressed
  }
}

I can't say it' related to your issue but both Buttonloops can invoke recursion.  Recursion has its uses but one must be very careful about it.  I'd start with rewriting the functions to be non-recursive.

Kudos for code and a schematic in your first post.

What is the sequence of operation? What function do button1 and button2 have? I assume a limit switches for the X motor? How are your buttons wired? How is the homeswitch wired? Limit (home) switches are usually on (make) until home (break)... so for your INPUT_PULLUP switches, that is LOW (motor moves) until HIGH (motor stops).

Which state is which direction?

Sequence

First, the homing of the X axis works fine no problem. The wire guide moves to the right till it trips the homeSwitch, changes direction moving to the left at a much slower speed, stops when the homeSwitch un-trips, and calls the function ButtonloopA().

ButtonloopA() loops until buttonPin or buttonPin2 is pushed.

Buttonpin calls the function MotorloopA() which moves the wire guide to the left while the Y axis rotates 15 times then calls function MotorloopB(). MotorloopB moves the wire guide to the right while the Y axis rotates 15 times then calls function MotorloopA(). Each time the X axis changes direction is considered a layer. When LayersTotal = 5 the function ButtonloopB() is called and winding is paused. At this point the buttonPin button can be pushed again and nothing will happen but buttonPin2 can be pushed and function MotorMainLoopA() is called and winding resumes. The main difference between buttonPin and buttonPin2 is buttonPin is LayersTotal = 5 and buttonPin2 is LayersTotal2 = 10. The functions called are different names but the results are the same moving the wire guide back and forth while spinning the Y axis and winding the coil.

The buttons are simple connected to ground. Push for LOW.

You don't seem to appreciate the problem @dougp points out which is recursion. It is not useful here and is in fact just plain a Bad Thing.

"Keep checking buttonPin and buttonPin2 until one of them does something."

void ButtonloopB()
{
  while (1) {
    if (digitalRead(buttonPin) == LOW) {
      MotorloopB();
      break;
    }

    if (digitalRead(buttonPin2) == LOW) {
      MotorMainLoopB();
      break;
    }
  }

  return;
}

I think that amounts to the same thing and is free of recursion.

You have to fix any function that calls itself.

a7

I was just reading the link @dougp posted about recursion and trying to understand how that could cause me problems. I see that it could be problematic but not necessarily.
I see your example completely removes the calling of the function from within itself. I will also look into your example to understand it.

OK, IC.

The simple way of looking at it is that when you call a function, things get allocated to handling the fact that you did. These things are freed up when the function returns.

If you call a function from within itself each call means an additional allocation of resources. If there is not return from the function, eventually the resources each successive call needs amount to more than is available - here the problem is a use of memory called the stack. When you run out of that, bad things happen.

In proper use of recursion, eventually something causes all the calls to return, one hopes before anything went wrong, and all the resources are recovered.

I can't recall seeing a use of recursion beyond the academic in the context of the kind of prgoramming we do on microprocessors.

FWIW an algorithm expressed in terms of recursion can always be written without using it.

a7

Your code is too complicated. Simplify it to this:

  1. X motor "homes"
  2. Y spool motor steps forward three times for every one step of the X (lateral) motor.
  3. When lateral motor X hits an edge, it changes direction
  4. You either want 5, 10 or 15 changes of direction... keep track of layers.
// Coil Winder Sketch 39 AWG, 150 winds per layer. 1:10 ratio, 1:1:10 ratio.

//Define pin connections & motor's steps per revolution
const int stepPinX = 2; // motor X step pin
const int dirPinX = 3; // motor X direction pin
const int enableX = 4; // motor X enable pin

const int stepPinY = 5; // motor Y step pin
const int dirPinY = 6; // motor Y direction pin
const int enableY = 7; // motor Y enable pin

const int buttonPin1 = 8; // pin connected to the buttonPin1 switch
const int homeSwitch = 9; // Pin connected to Home Switch to ground
const int buttonPin2 = 10; // pin connected to the buttonPin2 switch
const int stepsPerRevolution = 200; //number of steps per revolution in motorloop

int Layers; // a layer should be a change of direction

void setup() {
  Serial.begin(115200);
  // Declare pins
  pinMode(stepPinX, OUTPUT);
  pinMode(dirPinX, OUTPUT);
  pinMode(stepPinY, OUTPUT);
  pinMode(dirPinY, OUTPUT);
  pinMode(enableX, OUTPUT);
  pinMode(enableY, OUTPUT);
  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(homeSwitch, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);

  Serial.println("Homing (press HOME limit button)");
  home(); // move X toward home switch
}

void loop() {
  if (!digitalRead(buttonPin1) || !digitalRead(buttonPin2)) {
    delay(200); // debounce the limit switches
    digitalWrite(dirPinX, !digitalRead(dirPinX)); // make direction opposite of previous direction
    Serial.print("DIR:");
    Serial.print(digitalRead(dirPinX));
    Serial.print(" LAYER: ");
    Serial.println(++Layers);
  }
  for (int i = 0; i < 3; i++) // counting...
    StepMotorY(); // three Y steps
  StepMotorX(); // one X xtep
}

void StepMotorX() {
  digitalWrite(stepPinX, HIGH);  //One step X motor
  delay(2);
  digitalWrite(stepPinX, LOW);
  delay(2);
}

void StepMotorY() {
  digitalWrite(stepPinY, HIGH);  //One step Y motor
  delay(2);
  digitalWrite(stepPinY, LOW);
  delay(2);
}

void home() {
  // Start Homing procedure of X axis Stepper Motor at startup
  digitalWrite(dirPinX, LOW);      // (HIGH = anti-clockwise / LOW = clockwise) WHICH IS LEFT/RIGHT?
  while (digitalRead(homeSwitch) == HIGH) // Do this until the switch is not activated
  {
    digitalWrite(stepPinX, HIGH);
    delay(2);                       // Delay to slow down speed of Stepper
    digitalWrite(stepPinX, LOW);
    delay(2);
  }
  Serial.println("press appropriate limit switch - B1 or B2");
}
diagram.json for wokwi.com
{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-nano", "id": "nano", "top": 4.8, "left": -0.5, "attrs": {} },
    {
      "type": "wokwi-pushbutton-6mm",
      "id": "btn1",
      "top": -31,
      "left": 0,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-pushbutton-6mm",
      "id": "btn2",
      "top": -59.8,
      "left": 0,
      "attrs": { "color": "yellow" }
    },
    {
      "type": "wokwi-pushbutton-6mm",
      "id": "btn3",
      "top": -88.6,
      "left": 0,
      "attrs": { "color": "green" }
    },
    { "type": "wokwi-a4988", "id": "drv1", "top": -91.2, "left": 139.2, "attrs": {} },
    { "type": "wokwi-a4988", "id": "drv2", "top": -235.2, "left": 139.2, "attrs": {} },
    { "type": "wokwi-vcc", "id": "vcc1", "top": -296.84, "left": 192, "attrs": {} },
    { "type": "wokwi-gnd", "id": "gnd1", "top": -9.6, "left": 191.4, "attrs": {} },
    {
      "type": "wokwi-stepper-motor",
      "id": "stepper1",
      "top": -307.21,
      "left": 214.62,
      "attrs": { "size": "8", "arrow": "white" }
    },
    {
      "type": "wokwi-stepper-motor",
      "id": "stepper2",
      "top": -172.81,
      "left": 214.62,
      "attrs": { "size": "8", "arrow": "white" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo1",
      "top": -86.4,
      "left": -19.2,
      "attrs": { "text": "B1" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo2",
      "top": -57.6,
      "left": -48,
      "attrs": { "text": "home" }
    },
    {
      "type": "wokwi-text",
      "id": "legendservo3",
      "top": -28.8,
      "left": -19.2,
      "attrs": { "text": "B2" }
    }
  ],
  "connections": [
    [ "nano:GND.2", "btn1:2.r", "black", [ "v0" ] ],
    [ "nano:GND.2", "btn2:2.r", "black", [ "v0" ] ],
    [ "nano:GND.2", "btn3:2.r", "black", [ "v0" ] ],
    [ "nano:10", "btn1:1.r", "green", [ "v0" ] ],
    [ "nano:9", "btn2:1.r", "green", [ "v0" ] ],
    [ "nano:8", "btn3:1.r", "green", [ "v0" ] ],
    [ "nano:2", "drv1:STEP", "green", [ "v0" ] ],
    [ "nano:3", "drv1:DIR", "green", [ "v0" ] ],
    [ "nano:4", "drv1:ENABLE", "green", [ "v0" ] ],
    [ "drv1:SLEEP", "drv1:RESET", "green", [ "h-9.6", "v-9.6", "h-9.6" ] ],
    [ "nano:5", "drv2:STEP", "green", [ "v0" ] ],
    [ "nano:6", "drv2:DIR", "green", [ "v0" ] ],
    [ "nano:7", "drv2:ENABLE", "green", [ "v0" ] ],
    [ "drv2:SLEEP", "drv2:RESET", "green", [ "h-9.6", "v-9.6" ] ],
    [ "vcc1:VCC", "drv2:VMOT", "red", [ "v0" ] ],
    [ "vcc1:VCC", "drv2:VDD", "red", [ "v0" ] ],
    [ "gnd1:GND", "drv1:GND.1", "black", [ "v0" ] ],
    [ "gnd1:GND", "drv1:GND.2", "black", [ "v0" ] ],
    [ "gnd1:GND", "drv2:GND.1", "black", [ "v0" ] ],
    [ "gnd1:GND", "drv2:GND.2", "black", [ "v0" ] ],
    [ "vcc1:VCC", "drv1:VMOT", "red", [ "v0" ] ],
    [ "vcc1:VCC", "drv1:VDD", "red", [ "v0" ] ],
    [ "drv2:2B", "stepper1:A+", "green", [ "h0" ] ],
    [ "drv2:2A", "stepper1:A-", "green", [ "h0" ] ],
    [ "drv2:1A", "stepper1:B-", "green", [ "h0" ] ],
    [ "drv2:1B", "stepper1:B+", "green", [ "h0" ] ],
    [ "drv1:2B", "stepper2:A+", "green", [ "h0" ] ],
    [ "drv1:1A", "stepper2:B-", "green", [ "h0" ] ],
    [ "drv1:1B", "stepper2:B+", "green", [ "h0" ] ],
    [ "drv1:2A", "stepper2:A-", "green", [ "h0" ] ]
  ],
  "dependencies": {}
}

@alto777, I tried replacing my code with the non recursion code and while it does work, the program still has the same problem. The first button push calls a function and starts winding correctly but when the program pauses again, the second push of the same button does nothing.

// Coil Winder Sketch 39 AWG, 150 winds per layer. 1:10 ratio, 1:1:10 ratio.


//Define pin connections & motor's steps per revolution
const int stepPinX = 2; // motor X step pin
const int dirPinX = 3; // motor X direction pin
const int enableX = 4; // motor X enable pin
const int stepPinY = 5; // motor Y step pin
const int dirPinY = 6; // motor Y direction pin
const int enableY = 7; // motor Y enable pin
const int buttonPin = 8; // pin connected to the buttonPin switch
const int homeSwitch = 9; // Pin connected to Home Switch to ground
const int buttonPin2 = 10; // pin connected to the buttonPin2 switch
const int stepsPerRevolution = 200; //number of steps per revolution in motorloop


//creates  variable integers for layers
     
      int turnsPerLayer = 15; //Change this number for the number of turns in layer
      int Layers = 0;         //Total layers                       
      int LayersTotal = 5;    //Total layers for coil one in 1:10 ratio
      int LayersTotal2 = 10;  //Total layers for coil ten in 1:10 ratio                
      
void setup() 
{ 
  
// Declare pins 

    pinMode(stepPinX, OUTPUT);
    pinMode(dirPinX, OUTPUT);
    pinMode(stepPinY, OUTPUT);
    pinMode(dirPinY, OUTPUT);
    pinMode(enableX, OUTPUT);
    pinMode(enableY, OUTPUT);
    pinMode(buttonPin, INPUT_PULLUP);
    pinMode(homeSwitch, INPUT_PULLUP);
    pinMode(buttonPin2, INPUT_PULLUP);
     
// Start Homing procedure of X axis Stepper Motor at startup

  while (digitalRead(homeSwitch) == LOW) // Do this until the switch is not activated   
    {  
      digitalWrite(dirPinX, LOW);      // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(stepPinX, HIGH);
      delay(.2);                       // Delay to slow down speed of Stepper
      digitalWrite(stepPinX, LOW);
      delay(.2);   
    }

  while (digitalRead(homeSwitch) == HIGH) // Do this until the switch is activated
    { 
      digitalWrite(dirPinX, HIGH); 
      digitalWrite(stepPinX, HIGH);
      delay(2);                       // More delay to slow even more while moving away from switch
      digitalWrite(stepPinX, LOW);
      delay(2);
    }
  
}

void loop() 
{
      ButtonloopA();  // Call function
}


void ButtonloopA()
{
  while (1) {
    if (digitalRead(buttonPin) == LOW) {
      MotorloopA();
      break;
    }

    if (digitalRead(buttonPin2) == LOW) {
      MotorMainLoopA();
      break;
    }
  }

  return;
}

void MotorloopA()     //Function called to wind layer right to left
{                
      digitalWrite(dirPinX, HIGH);      // Set motor X direction clockwise                    
      digitalWrite(dirPinY, LOW);       // Set motor Y direction clockwise
      for(; Layers < LayersTotal;) // Count layers and stop at LayersTotal amount
        {
          
          for(int stepTurns = 0; stepTurns < turnsPerLayer; stepTurns++) //Count winds per layer and calls MotorloopA to switch direction at turnsPerLayer amount
              {
                for(int x = 0; x < stepsPerRevolution; x++) // Spin motor Y one rotation
                   {
                      TurnRatio();    //Call function
                   }
                
              }
            Layers++;             //Adds 1 to Layers count
            MotorloopB();        //call function pause loop waiting for button push
        }
    ButtonloopA();      //call function pause loop waiting for button push
}
void ButtonloopB()
{
  while (1) {
    if (digitalRead(buttonPin) == LOW) {
      MotorloopB();
      break;
    }

    if (digitalRead(buttonPin2) == LOW) {
      MotorMainLoopB();
      break;
    }
  }

  return;
}
void MotorloopB()       //Function called to wind layer left to right
{  
      digitalWrite(dirPinX, LOW);   // Set motor X direction clockwise
      for(; Layers < LayersTotal;) // Count layers and stop at LayersTotal amount
        {
          
          for(int stepTurns = 0; stepTurns < turnsPerLayer; stepTurns++) //Count winds per layer and calls MotorloopA to switch direction at turnsPerLayer amount
              {
                for(int x = 0; x < stepsPerRevolution; x++) // Spin motor Y one rotation
                   {
                      TurnRatio();    //Call function
                   }
                
              }
  
          Layers++;             //Adds 1 to Layers count
          MotorloopA();       //Call function to wind right to left
        }
      ButtonloopB();      //call function pause loop waiting for button push
}
void MotorMainLoopA()  //Function called to wind ten coil in 1:10 right to left
{     
      digitalWrite(dirPinX, HIGH);      // Set motor X direction clockwise
      for(; Layers < LayersTotal2;) // Count layers and stop at LayersTotal amount
        {
          
          for(int stepTurns = 0; stepTurns < turnsPerLayer; stepTurns++) //Count winds per layer and calls MotorloopA to switch direction at turnsPerLayer amount
              {
                for(int x = 0; x < stepsPerRevolution; x++) // Spin motor Y one rotation
                   {
                      TurnRatio();    //Call function
                   }
                
              }
          Layers++;             //Adds 1 to Layers count
          MotorMainLoopB();    //call function pause loop waiting for button push
        }
      ButtonloopA();      //call function pause loop waiting for button push
}
  
void MotorMainLoopB()         //Function called to wind coil ten in 1:10 left to right
{   
      digitalWrite(dirPinX, LOW);   // Set motor X direction clockwise
      for(; Layers < LayersTotal2;) // Count layers and stop at LayersTotal amount
        {
          
          for(int stepTurns = 0; stepTurns < turnsPerLayer; stepTurns++) //Count winds per layer and calls MotorloopA to switch direction at turnsPerLayer amount
              {
                for(int x = 0; x < stepsPerRevolution; x++) // Spin motor Y one rotation
                   {
                      TurnRatio();    //Call function
                   }
                
              }
          Layers++;             //Adds 1 to Layers count
          MotorMainLoopA();    //call function pause loop waiting for button push
        } 
      ButtonloopB();        //call function pause loop waiting for button push
}
void StepMotorX()
{
      digitalWrite(stepPinX, HIGH);  //One step X motor
      delayMicroseconds(100);
      digitalWrite(stepPinX, LOW);
      delayMicroseconds(100);
}
void StepMotorY()
{
      digitalWrite(stepPinY, HIGH);  //One step Y motor
      delayMicroseconds(100);
      digitalWrite(stepPinY, LOW);
      delayMicroseconds(100); 
}
void TurnRatio()
{
      StepMotorX();   //One X step

      StepMotorY();   //to three Y steps
      StepMotorY();
      StepMotorY();

      StepMotorX();   //One X step
      
      StepMotorY();   //to three Y steps
      StepMotorY();
      StepMotorY();  
      
      StepMotorX();   //One X step

       
      StepMotorY();   //to two Y steps
      StepMotorY();
      
}

@xfpd It seems the homing is not operating correctly with your code. The stepper motor just makes a hum but does not move. I am studying this more.

All I got at the moment is to suggest to you to add

  Serial.begin(115200);

to the setup() function, and add Serial.print() and println() statements to check the values of key variables and confirm that they are properly informing flow through your code.

Your spare description makes it sound like you are getting stuck somewhere.

You might be able to place a small delay on the loop to cut down on the output of such statements. Also it's fairly easy to make printing happen only when a variable has a new value rather than every time.

a7

Thanks. I will do this.

When you connect your wires according to the sketch, both will work.

I supplied the simulation setup for you to see and adjust as needed. (in the same post)

look this over

// Coil Winder Sketch 39 AWG, 150 winds per layer. 1:10 ratio, 1:1:10 ratio.

// motor pins
const int stepPinX    = 2;
const int dirPinX     = 3;
const int enableX     = 4;

const int stepPinY    = 5;
const int dirPinY     = 6;
const int enableY     = 7;

const int PinButStart = 8;
const int PinButStop  = 10;
const int PinHome     = 9;

// constants
const int StepsPerRev = 200; 
const int XyRatio     = 10;
const int MaxLayer    = 5;
const int MaxX        = 100;

// variables
int  yStepCnt;
int  xStepCnt;
int  nLayer;

enum { CW = LOW, CCW = HIGH };
int dirX;

bool run;

char s [90];

// -----------------------------------------------------------------------------
void
step (
    int  PinStep,
    int  PinDir,
    int  dir )
{
    digitalWrite (PinDir, dir);

    digitalWrite (PinStep, HIGH);
    delay        (1);
    digitalWrite (PinStep, LOW);
    delay        (1);
}

// -----------------------------------------------------------------------------
void home ()
{
    Serial.println ("home");
    while (digitalRead (PinHome) == HIGH)
        step (stepPinX, dirPinX, CW);
    Serial.println (" home - done");
}

// -----------------------------------------------------------------------------
void loop ()
{
    if (run) {
        step (stepPinY, dirPinY, CW);           // turn bobin
        yStepCnt++;

        if (! (yStepCnt % XyRatio))  {          // advance X
            step (stepPinX, dirPinX, dirX);
            xStepCnt++;

            if (! (xStepCnt % MaxX))  {         // change direction
                if (MaxLayer <= ++nLayer)  {
                    run = false;                // done
                    Serial.println (" loop: done");
                }

                dirX = CW == dirX ? CCW : CW;
            }
        }

        sprintf (s, " layer %d, yStepCnt %4d, xStepCnt %4d, dir %s",
                nLayer, yStepCnt, xStepCnt, dirX == CW ? "CW" : "CCW");
        Serial.println (s);
    }

    if (digitalRead (PinButStart) == LOW)  {
        run      = true;
    }
    else if (digitalRead (PinButStop) == LOW)
        run = false;
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (115200);

    pinMode (stepPinX,   OUTPUT);
    pinMode (dirPinX,    OUTPUT);
    pinMode (stepPinY,   OUTPUT);

    pinMode (dirPinY,    OUTPUT);
    pinMode (enableX,    OUTPUT);
    pinMode (enableY,    OUTPUT);

    digitalWrite (enableX, HIGH);
    digitalWrite (enableY, HIGH);

    pinMode (PinButStart, INPUT_PULLUP);
    pinMode (PinButStop,  INPUT_PULLUP);
    pinMode (PinHome,     INPUT_PULLUP);

    sprintf (s, "  %6d StepsPerRev", StepsPerRev);
    Serial.println (s);
    sprintf (s, "  %6d XyRatio", XyRatio);
    Serial.println (s);
    sprintf (s, "  %6d MaxLayer", MaxLayer);
    Serial.println (s);
    sprintf (s, "  %6d MaxX", MaxX);
    Serial.println (s);

    home ();
}

@alto777 The Debug Serial.print works well. The answer to my button problem was in the Motorloop() functions. Once the variable 'Layers' is no longer '< LayersTotal' it would skip all the motor functions and go back to the Buttonloop() function. So as long as the button was pushed it would loop from Motorloop() to Buttonloop() over and over.
The solution is

if (digitalRead(buttonPin) == LOW) {
      Layers = 0;
      MotorloopA();
      break;
    }

That reset the variable 'Layers' back to '0' after each of the buttons is pushed allowing the motor functions to be called.

Thanks

@xfpd It seems I had wired the home switch opposite of my schematic. I moved a wire on the home switch from connector 1 to 2 and the program works. The code will need some tweaking to do exactly what I need but I like the way it is written. I will be studying this more.
Thanks

1 Like

@gcjr I will be looking over this code too. So many different ways to program to get the same results. Lots to learn.
Thanks

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