Function inside the "void setup" doesn't work

Dear forum members,

I need some help with the code I put together for controlling a variable capacitor’s movements. The capacitor is part of a magnetic loop antenna, of which you can adjust the resonant frequency by changing the capacitance. The capacitor is rotated by a stepper motor that is driven by an A4988 module, which itself is controlled by an Arduino Nano.

Basically, what it does is as you turn the capacitor clockwise/counterclockwise, fast or slow; an OLED screen shows the current position (between 0 and 2400). There are 4 buttons that are assigned to rotation (CW-slow, CCW-slow, CW-fast, CCW-fast) and a 5th that is a “function” button (for future development). There’s also a micro switch near the variable capacitor. These are all connected to the digital pins, which stay “HIGH” unless the buttons are depressed (pls. see the attached schematic).

The problem is that a function I put in the code doesn’t seem to work. It’s the “ZEROING” function that I call inside the “Void Setup”. Every time the circuit is powered on, the capacitor has to rotate until it hits and closes the microswitch, causing the D2 to go “LOW”. This normally stops the capacitor at its minimum capacitance value and also zeroes the step count so we get a reference point for adjusting the antenna the same way every time we use it.

I tried different things to understand why the “ZEROING” doesn’t work but couldn’t succeed. In my opinion, it’s not a mechanical problem because when I check the connection, I see that the D2 is always HIGH and goes LOW when I manually close the microswitch. The four buttons work as intended and turn the capacitor. The display correctly shows the step count.

I suspect that it’s a mistake a did when putting the code together. Speaking of the code, probably it’s very crude and can be improved but I’m limited by my narrow knowledge.

I would be glad if you can help me correct this issue. This is my first post, I hope I posted it in the correct sub-forum.

The code is below. My IDE is 1.8.7. The Nano is one with ATmega168.







#include <SPI.h>
#include <Wire.h>

//-------------------------------------------
// required for the OLED screen
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
// Define proper RST_PIN if required.
#define RST_PIN 4

SSD1306AsciiAvrI2c oled;

//--------------------------------------------
#define DISTANCE 1    // step-unit

int maxSteps = 2400;   // max steps of the stepper motor, if a gearbox is used, steps x gearbox ratio.
int currentPosition = 0;
int sTEPP = 1;        // real steps counter
int StepCounter = 0;  // to make the stepper one step a time, used in conjunction with DISTANCE
int Stepping = false; // initial condition of this has to be false, don't touch
int speedDelay = 2000;// delay in sec or microsec, motor speed will slow down if too short (100 microsec etc) or too long (4000 milisec etc)
int MemPos01 = 1200;  // Step number/position for min SWR at XXX frequency // for future development
int enaPin = 12;      // A4988 enable pin - power to STEPPER if LOW
int microPin1 = 13;   // A4988 microstepping MS1 pin for 1/2 stepping (HLL for 1/2, LHL for 1/4,
int microPin2 = 10;   // A4988 microstepping MS3 pin (I needed only MS1 and MS3, anything besides 1/2 stepping lacks torque anyway)
int stepPin = 9;      // A4988 step pin
int dirPin = 8;       // A4988 dir pin
int butPinCCW = 7;     // counterclockwise turn button (fast) // when looked from the stepper's end
int butPinCW = 6;    //   clockwise turn button (fast)
int butPinfineCCW = 5; // counterclockwise turn button (slow)
int butPinfineCW = 4; //   clockwise turn button (slow)
int butPinFunc = 3;   // Function button
int ZeroSwitch = 2;   // Capacitor zeroing microswitch
int Measure = A0;     // RF intensity measurement, analog input pin (not used, for semi-auto tuning version in the future)


//------------------------------------------------------------------------

void setup() {

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0
  // Call oled.setI2cClock(400000);

  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  // pinMode(11, OUTPUT); // this pin is reserved for future use
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7, INPUT);
  pinMode(6, INPUT);
  pinMode(5, INPUT);
  pinMode(4, INPUT);
  pinMode(3, INPUT);
  pinMode(2, INPUT);
  pinMode(A0, INPUT);
  // Serial.begin (9600);
  digitalWrite(stepPin, LOW);
  digitalWrite(dirPin, LOW);
  digitalWrite(microPin1, HIGH);

  ZEROING ();


}
//------------------------------


// This is to display the current position of the capacitor with respect to point 0 (max. capacitance)

void stepWRITE() {
  oled.setFont(Verdana_digits_24);
  oled.clear();
  oled.set2X();
  oled.print(currentPosition);
  //delayMicroseconds (1000);
}
//------------------------------
// This is to bring the capacitor to starting position (max. capacitance) on every start
// if too fast, it will close down the switch earlier

void ZEROING() {

  if (digitalRead(ZeroSwitch) == HIGH && Stepping == false)
  {
    Stepping = true;
  }

  while (Stepping == true && digitalRead(ZeroSwitch) == HIGH)
  {

    digitalWrite(enaPin, LOW);
    digitalWrite(dirPin, HIGH);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(speedDelay);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(speedDelay);

    StepCounter = StepCounter + 1;
    currentPosition = currentPosition + sTEPP;
    // .println (currentPosition);
  }
  if (digitalRead(ZeroSwitch) == LOW) {
    StepCounter = 0;
    currentPosition = 0;
    // Serial.println (currentPosition)
    digitalWrite(enaPin, HIGH);
    stepWRITE();
    Stepping = false;

  }

}

// Main loop, this is to turn the capacitor CW and CCW within the max-min points
//------------------------------

void loop() {
  {

    if (digitalRead(butPinCW) == LOW && Stepping == false)
    {
      //digitalWrite(dirPin, LOW);
      Stepping = true;
    }
    if (digitalRead(butPinCCW) == LOW && Stepping == false)
    {
      //digitalWrite(dirPin, HIGH);
      Stepping = true;
    }

    if (digitalRead(butPinfineCW) == LOW && Stepping == false)
    {
      //digitalWrite(dirPin, LOW);
      Stepping = true;
    }

    if (digitalRead(butPinfineCCW) == LOW && Stepping == false)
    {
      //digitalWrite(dirPin, HIGH);
      Stepping = true;
    }

    while (Stepping == true && digitalRead(butPinCW) == LOW)
    {
      if (currentPosition > 0)
      {
        digitalWrite(dirPin, HIGH);
        digitalWrite(enaPin, LOW);
        // digitalWrite(2, HIGH);  MS1
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(speedDelay);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(speedDelay);
        StepCounter = StepCounter + 1;
        currentPosition = currentPosition - sTEPP;
        //   stepWRITE();


        //  digitalWrite (2, LOW); MS1
      }
      else {
        // .println("Capacitor Maxi");
        oled.clear();
        oled.setFont(Callibri14);
        oled.set2X();
        oled.setCursor(0, 0);
        oled.print("CAPACITOR");
        oled.setCursor(0, 8);
        oled.print("MINIMUM");
      }
    }

    while (Stepping == true && digitalRead(butPinCCW) == LOW)
    {
      if (currentPosition < maxSteps)
      {
        digitalWrite(enaPin, LOW);
        digitalWrite(dirPin, LOW);
        //   digitalWrite(2, HIGH); MS1
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(speedDelay);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(speedDelay);

        StepCounter = StepCounter + 1;
        currentPosition = currentPosition + sTEPP;
        // .println (currentPosition);
        //    stepWRITE();


        // digitalWrite (2, LOW);  MS1
      }
      else {
        // .println("Capacitor Mini");
        oled.clear();
        oled.setFont(Callibri14);
        oled.set2X();
        oled.setCursor(0, 0);
        oled.print("CAPACITOR");
        oled.setCursor(0, 16);
        oled.print("MAXIMUM");
      }
    }

    while (Stepping == true && digitalRead(butPinfineCW) == LOW)
    {
      if (currentPosition > 0)
      {
        digitalWrite(enaPin, LOW);
        digitalWrite(dirPin, HIGH);
        //  digitalWrite(3, HIGH);
        digitalWrite(stepPin, HIGH);
        delay(50);
        digitalWrite(stepPin, LOW);
        delay(50);

        StepCounter = StepCounter + 1;
        currentPosition = currentPosition - sTEPP;
        // .println (currentPosition);
        stepWRITE();
        //  digitalWrite (3, LOW);  MS3
      }
      else {
        // .println("Capacitor Maxi");
        oled.clear();
        oled.setFont(Callibri14);
        oled.set2X();
        oled.setCursor(0, 0);
        oled.println("CAPACITOR"); // print idi bunlar sonradan ln ekledim !!!!!
        oled.setCursor(0, 8);
        oled.println("MINIMUM");
      }
    }
    stepWRITE();

    while (Stepping == true && digitalRead(butPinfineCCW) == LOW)
    {
      if (currentPosition < maxSteps)
      {

        digitalWrite(enaPin, LOW);
        //   digitalWrite(3, HIGH);
        digitalWrite(dirPin, LOW);
        digitalWrite(stepPin, HIGH);
        delay(50);
        digitalWrite(stepPin, LOW);
        delay(50);

        StepCounter = StepCounter + 1;
        currentPosition = currentPosition + sTEPP;
        // .println (currentPosition);
        stepWRITE();

        // digitalWrite (3, LOW);  MS3
      }
      else {
        // .println("Capacitor Mini");
        oled.clear();
        oled.setFont(Callibri14);
        oled.set2X();
        oled.setCursor(0, 0);
        oled.println("CAPACITOR");
        oled.setCursor(0, 16);
        oled.println("MINIMUM");
      }
    }

    if (StepCounter == DISTANCE)
    {
      StepCounter = 0;
      Stepping = false;
    }
    digitalWrite(enaPin, HIGH);
  }

}

Can you write to the LCD at all? Perhaps add a line in setup to print something like ....starting up

What exactly happens when you turn the power on, does the capacitor not turn at all, turn but stops before reaching the microswitch, turns past the microswitch, or turns and properly stops at the microswitch but then does not zero the counter?

You might want to put a delay between the while loop that steps the motor and the subsequent if statement that resets the counter, in case the switch contact is bouncing.

Hello thank you for your reply. Yes, the screen shows "0" 1-2 seconds after power-on and then correctly updates the number of steps if the buttons are pushed and the capacitor rotated.

Hello, thank you for your reply. The capacitor doesn't move at all after the circuit is powered on. After 1-2 seconds the screen shows "0" and then everything works as intended. It's like the ZEROING function doesn't exist at all.

Thank you also for the advice, I'll add a small delay.

Do you have pullup or pulldown resistors on the inputs to keep them in a known state at all times ?

Reading your code would be easier if you used the names that you have given the pins instead of the anonymous pin numbers

Microswitches normally have 3 pins: "Normally Open", "Normally Closed" and "Common". Which did you connect? Your diagram only shows 2 pins on this switch. I think you should have used NO and C.

I notice that you don't set microPin2 (10) as an OUTPUT. But then you don't write to it, either.

Here is how I would write the code:

#include <Wire.h>

//-------------------------------------------
// required for the OLED screen
#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

SSD1306AsciiAvrI2c oled;

long int CurrentPosition = 0;

const int MaxSteps = 2400;   // max steps of the stepper motor, if a gearbox is used, steps x gearbox ratio.
const int speedDelay = 2000; // delay in microseconds, motor speed will slow down if too short (100 microsec etc) or too long (4000 microsec etc)
const int MemPos01 = 1200;   // Step number/position for min SWR at XXX frequency // for future development

// Pins
const int microPin1 = 13;    // A4988 microstepping MS1 pin for 1/2 stepping (HLL for 1/2, LHL for 1/4,
const int enaPin = 12;       // A4988 enable pin - power to STEPPER if LOW
const int RESERVED_PIN = 11; // Reserved for future use
const int microPin2 = 10;    // A4988 microstepping MS3 pin (I needed only MS1 and MS3, anything besides 1/2 stepping lacks torque anyway)
const int stepPin = 9;       // A4988 step pin
const int dirPin = 8;        // A4988 dir pin
const int butPinCCW = 7;     // counterclockwise turn button (fast) // when looked from the stepper's end
const int butPinCW = 6;      //   clockwise turn button (fast)
const int butPinfineCCW = 5; // counterclockwise turn button (slow)
const int butPinfineCW = 4;  //   clockwise turn button (slow)
const int butPinFunc = 3;    // Function button
const int ZeroSwitch = 2;    // Capacitor zeroing microswitch
const int Measure = A0;      // RF intensity measurement, analog input pin (not used, for semi-auto tuning version in the future)
// A1 through A3 available.  A4 and A5 are the Wire pins (on an UNO, Nano, Mini)

// Define some constants for direction of motion.  CCW is toward the home switch.
const bool CW = true;
const bool CCW = false;

//------------------------------------------------------------------------

void setup()
{
  oled.begin(&Adafruit128x64, I2C_ADDRESS);

  // Call oled.setI2cClock(400000);

  pinMode(microPin1, OUTPUT);
  pinMode(enaPin, OUTPUT);
  pinMode(microPin2, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(butPinCCW, INPUT);
  pinMode(butPinCW, INPUT);
  pinMode(butPinfineCCW, INPUT);
  pinMode(butPinfineCW, INPUT);
  pinMode(butPinFunc, INPUT);
  pinMode(ZeroSwitch, INPUT);
  // pinMode(A0, INPUT);  // Only use pinMode() for digitalRead()/digitalWrite(), not analogRead().
  // Serial.begin (9600);
  digitalWrite(stepPin, LOW);
  digitalWrite(dirPin, LOW);
  digitalWrite(microPin1, HIGH);

  ZEROING ();
}

// This is to display the current position of the capacitor with respect to point 0 (max. capacitance)
void ShowPosition()
{
  oled.setFont(Verdana_digits_24);
  oled.clear();  // Doing this for each step will cause flicker.
  oled.set2X();
  oled.print(CurrentPosition);
  // Serial.println (CurrentPosition);
}

void Step(bool direction)
{
  // Set dirPin HIGH for CW and LOW for CCW
  digitalWrite(dirPin, direction ? HIGH : LOW);

  // Take one step
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(speedDelay);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(speedDelay);

  // Count that one step
  if (direction)
    CurrentPosition++;  // CW
  else
    CurrentPosition--;  // CCW
}

//------------------------------
// This is to bring the capacitor to starting position (max. capacitance) on every start
// if too fast, it will close down the switch earlier
void ZEROING()
{
  // Enable movement
  digitalWrite(enaPin, LOW);

  // If already pressing the switch, back off.
  while (digitalRead(ZeroSwitch) == LOW)
  {
    Step(CW); // move away from the home switch
  }

  // Move until pressing the switch
  while (digitalRead(ZeroSwitch) == HIGH)
  {
    Step(CCW); // move toward the home switch
  }

  // We have closed the Home switch
  CurrentPosition = 0;

  // Disable motion
  digitalWrite(enaPin, HIGH);
  ShowPosition();
}

// Main loop, this is to turn the capacitor CW and CCW within the max-min points
void loop()
{
  // Move if any of the buttons are pressed
  digitalWrite(enaPin, LOW);  // Enable Motion

  while (digitalRead(butPinCW) == LOW && CurrentPosition < MaxSteps)
  {
    Step(CW);
    ShowPosition();
  }

  while (digitalRead(butPinfineCW) == LOW && CurrentPosition < MaxSteps)
  {
    Step(CW);
    ShowPosition();
    delay(250);  // Limit to four steps per second
  }

  while (digitalRead(butPinCCW) == LOW && CurrentPosition > 0)
  {
    Step(CCW);
    ShowPosition();
  }

  while (digitalRead(butPinfineCCW) == LOW && CurrentPosition > 0)
  {
    Step(CCW);
    ShowPosition();
    delay(250);  // Limit to four steps per second
  }

  digitalWrite(enaPin, HIGH);  // Disable Motion

  if (CurrentPosition >= MaxSteps)
  {
    // We have reached the maximum position (Minimum Capacitance)
    // Serial.println("Capacitor Minimum");
    oled.clear();
    oled.setFont(Callibri14);
    oled.set2X();
    oled.setCursor(0, 0);
    oled.print("CAPACITOR");
    oled.setCursor(0, 8);
    oled.print("MINIMUM");
  }

  if (CurrentPosition <= 0)
  {
    // We have reached the minimum position (Maximum Capacitance)
    // Serial.println("Capacitor Maximum");
    oled.clear();
    oled.setFont(Callibri14);
    oled.set2X();
    oled.setCursor(0, 0);
    oled.print("CAPACITOR");
    oled.setCursor(0, 16);
    oled.print("MAXIMUM");
  }
}

Hi, thank you for your reply. Yes, there are pulldown resistors on the inputs. I can see that the voltage goes from 5V to 0V when the buttons are depressed and vice versa.

Hello Paul, thank you for your reply. The connection should be fine, the voltage on the assigend pin remains as 5V, then goes down to 0V as intended when the capacitor hits the switch.

Hi John, thank you very very much for your suggestions. It,s very kind of you to take the time to alter the program. I will try your version tonight and will write again.

Those are pull-up resistors, they pull the pin up to 5V unless the switch is pressed. Pull-down resistors would be between the pin and ground, with the switch between the pin and 5V. The pin would be pulled down to ground unless the switch is pressed.

It is safer to use pull-up than pull-down because there is less risk of accidentally causing a short circuit from 5V to ground.

Most Arduino have internal pull-up resistors so that you often do not need to add external resistors. Enable them with pinMode(pin, INPUT_PULLUP).

@PaulRB, thank you for the info Paul.

@johnwasser , Dear John, I just tried your version but it seems like it needs some change. At the start, the capacitor rotated in the good direction but didn't stop after closing the switch. The display didn't show anything. I'll keep working on to understand why. Thanks again.

@johnwasser's code will not display anything until the end of the ZEROING() function. It sounds like the code is stuck in the CW while-loop in ZEROING(). That could mean that the zero switch is not being actuated or not being detected.

When the motor is running and appears to be closing the switch but does not stop, does the voltage from the switch change? If you push the switch with your finger when the motor is running, does it change then?