Help identifying parameter in code

Long story short I am attempting to slightly modify an existing sketch to add in a stepper motor function. I am reasonably new to arduino coding, and this sketch I am messing with is way above my skill level. This sketch operates a homemade metal detector, and I want to add in a section that will energize a stepper motor upon the metal detector reaching a certain threshold. While operating the metal detector there are a couple variables in the serial monitor that correlate to the strength of feedback from the metal detector, but I cannot for the life of me figure out what those values represent in the sketch itself. My other idea was to trigger the stepper motor off of an LED cycle instead, as the onboard LED of my R3 uno flashes every time the buzzer in my circuit "clicks". But I am at a loss as to which values I should tie an "if" statement to in order to energize the stepper when necessary. This was a bit long-winded, but I tried to articulate my problem the best I could. A solid ~75% of this sketch is greek to me so im working with the limited knowledge I have. I have identified and initialized the stepper in the sketch, but am at a loss as to how to actually tie its function into this sketch. See attached sketch. Thank you in advance.

//Metal detector based on pulse delay in LR circuit
//Connect a coil beween pin 10 and pin 8,
//a 100 Ohm resistor between pin 8 and ground,
//a speaker in series with a 10muF capacitor between pin 12 and ground,
//a reset-button between A0 and ground.
//Reference coil: 60 turns, diameter 6cm, AWG26 (0.4mm) wire. L~300muH, R~2Ohm
//
//R. Oldeman Oct 11 2020, CC BY-NC-SA 4.0 licence

#define debug true

//some parameters
#define sensitivity  5000 //threshold as a fraction of reference      
#define aimtime    160000 //aim for measurement every 160k cycles (=10ms) 
#define LEDpulselen 16000 //length of the LED pulse in clock cycles
#define cycles         40 //number of clock cycles reserved for calculations
#define printfrac      50 //fraction of measurements printed when in debug mode

//pin definitions - cannot change freely!
#define pulsepin 10 //must be pin 10 - TIMER1B output
#define probepin  8 //must be pin 8  - input capture pin
#define LEDpin   13 //if changed also need to update the direct-port writing
#define soundpin 12 //if changed also need to update the direct-port writing
#define resetpin A0 //can be changed freely 

//global variables - shared between main loop and measurement function
long int imeas = 0; //counts the number of measurements performed
int absdiff;       //absolute value of difference wrt reference
long int phase = 0; //tracks integral of absdiff
long int phasemax; //value at which the phase counter turns over
int LEDcycles = 0; //number of cycles that the LED pin stays high
int LEDcycle = 0;  //cycle index of the LED pulse

//
#include <Stepper.h>
const int stepsPerRevolution = 2048;  // number of steps per revolution
Stepper myStepper(32, 2, 4, 3, 5); // initialize stepper on pins 2 through 5
//

void setup() {
  noInterrupts(); //disable all inerrupts to avoid glitches

  if (debug)Serial.begin(9600);

  pinMode(pulsepin, OUTPUT);
  digitalWrite(pulsepin, LOW);
  pinMode(probepin, INPUT);
  pinMode(LEDpin, OUTPUT);
  digitalWrite(LEDpin, LOW);
  pinMode(soundpin, OUTPUT);
  digitalWrite(soundpin, LOW);
  pinMode(resetpin, INPUT_PULLUP);

  //
  myStepper.setSpeed(750); // set speed of motor to 750 rpm
  //

  //setup timer1 to FASTPWM on pin 10
  TCCR1A = 0B00100011;
  TCCR1B = 0B00011001;
}

//perform measurement of delay of the trailing edge
long int meas(int period, int minlen, int maxlen, int steplen, int nloop) {
  long int sum = 0;
  int nmiss = 0;
  OCR1A = period;      //set the period
  TIFR1 |= 0B00000001; //clear the timer overflow bit
  for (int iloop = 0; iloop < nloop; iloop++) {
    for (int len = minlen; len < maxlen; len += steplen) {
      OCR1B = len;                       //set the pulselength
      while ((TIFR1 & 0B00000001) == 0); //wait for timer overflow
      TIFR1 |= 0B00000001;               //clear the timer overflow bit
      while (TCNT1 < (period - cycles)); //wait till pulse is almost finished
      if ( (TIFR1 & 0B00100000) != 0) {  //check if trailing edge has been detected
        sum += (ICR1 - len);
        TIFR1 |= 0B00100000;             //clear the input capture flag
      } else {
        nmiss++;
      }
      //update phase
      phase += absdiff;
      //blink and click when phase rolls through
      if (phase > phasemax) {
        phase -= phasemax;
        LEDcycle = LEDcycles;
        PORTB = (PORTB | 0B00100000); //switch on LED
        PORTB = (PORTB ^ 0B00010000); //invert sound pin - click!
      }
      //switch off LED when it's been on long enough
      if (LEDcycle > 0) {
        LEDcycle--;
        if (LEDcycle == 0)PORTB = (PORTB & (!0B00100000));
      }
    }
  }
  if (nmiss > 0)sum = 0; //invalidate the result if there have been missing pulses
  return sum;
}

//flash LED with error code indefinitely if there's been an error
void go_error(byte errorcode) {
  if (debug) {
    Serial.print("ERROR ");
    Serial.print(errorcode);
    if (errorcode == 1)Serial.println(": No pulse on probe pin - check connections");
    if (errorcode == 2)Serial.println(": Delay too short - try more windings");
    if (errorcode == 3)Serial.println(": Delay too long - try fewer windings");
    if (errorcode == 4)Serial.println(": No robust pulse on pulselength scan - check coil resistance");
  }
  //enable in interrupts to use delay() and flash to indicate error code
  interrupts();
  while (true) {
    for (byte i = 0; i < errorcode; i++) {
      digitalWrite(LEDpin, HIGH);
      delay(100);
      digitalWrite(LEDpin, LOW);
      delay(100);
    }
    delay(500);
  }
}


void loop() {

  //perform initial robust measurement of average delay time
  long int tau = meas(16000, 8000, 8001, 1, 16) / 16;
  if (debug)Serial.print("delay in clock cycles:");
  if (debug)Serial.println(tau);
  if (debug)Serial.print("estimated coil inductance in muH:");
  if (debug)Serial.println(1.44 * tau * 100.0 / (16.0));

  if (tau == 0) go_error(1);         // no pulse
  if (tau < 5)  go_error(2);         // too short
  if (tau > 800)go_error(3);         // too long

  //choose pulsing parmeters based on measured delay time
  int minlen = 3 * tau;
  int maxlen = 5 * tau;
  int period = maxlen + 2 * tau + cycles;
  LEDcycles = LEDpulselen / period + 1;

  // repeat loop or speed up loop to approach aimed duration of measurement
  int steplen = 1;
  int nloop = 1;
  float tottime = float(period) * (maxlen - minlen);
  if (tottime > aimtime * (3.0 / 2.0)) steplen = round(tottime / aimtime);
  if (tottime < aimtime * (2.0 / 3.0)) nloop = round(aimtime / tottime);

  if (debug)Serial.print(" minlen: ");
  if (debug)Serial.print(minlen);
  if (debug)Serial.print(" maxlen: ");
  if (debug)Serial.print(maxlen);
  if (debug)Serial.print(" steplen: ");
  if (debug)Serial.print(steplen);
  if (debug)Serial.print(" period: ");
  if (debug)Serial.print(period);
  if (debug)Serial.print(" nloop: ");
  if (debug)Serial.print(nloop);
  if (debug)Serial.print(" LEDcycles: ");
  if (debug)Serial.println(LEDcycles);

  //perform a scan from minlen to maxlen
  long int minval = 1000000000;
  for (int len = minlen; len < maxlen; len += steplen) {
    long int val = meas(period, len, len + 1, 1, nloop);
    minval = min(val, minval);
    if (debug)Serial.print("len,val:");
    if (debug)Serial.print(len);
    if (debug)Serial.print(" ");
    if (debug)Serial.println(val);
  }
  if (minval == 0)go_error(4);

  //determine the reference value
  long int ref = meas(period, minlen, maxlen, steplen, nloop);

  //threshold and phasemax
  int threshold = ref / sensitivity;
  phasemax = 16000000 / period * threshold; //aim for 1Hz at threshold
  if (debug)Serial.print("reference, threshold, phasemax: ");
  if (debug)Serial.print(ref);
  if (debug)Serial.print(" ");
  if (debug)Serial.print(threshold);
  if (debug)Serial.print(" ");
  if (debug)Serial.println(phasemax);

  long int sum = 0;
  long int sumsq = 0;
  while (true) {
    long int val = meas(period, minlen, maxlen, steplen, nloop);

    //check if reset of reference value is requested
    if (digitalRead(resetpin) == LOW) ref = val;

    int diff = val - ref;
    absdiff = abs(diff);
    if (absdiff < threshold) {
      phase = 0;             //reset the phase
      if (diff > 0)ref += 1; //absorb slow drifts
      if (diff < 0)ref -= 1;
    }

    if (debug) {
      sum += diff;
      sumsq += long(diff) * long(diff);
      if (imeas % printfrac == 0) {
        float mean = float(sum) / printfrac;
        float rms = sqrt( (float(sumsq) / printfrac) - pow(mean, 2.0) );
        Serial.print(imeas);
        Serial.print(" val ref diff phase ");
        Serial.print(val);
        Serial.print(" ");
        Serial.print(ref);
        Serial.print(" ");
        Serial.print(diff);
        Serial.print(" ");
        Serial.print(mean);
        Serial.print(" ");
        Serial.print(rms);
        Serial.println("");
        sum = 0; sumsq = 0;
      }
    }
    imeas++;
  }
}

hi, welcome to the forum.

Please post a link to wherever the original code was found.

Did the original function for you without excitement?

Please post your current effort using code tags after formatting it… here's one way:

In the IDE use the "Autoformat" tool on your code.

Then select the entire sketch and use the "Copy for Forum".

Come back here and paste what you just copied.

So the code will be much easier and more inviting to scrutinize.

The formatting provides major hints about the structure. As well, it can often help you (or us) find errors.

TIA

a7

I laughed when I saw 'long story short' and a wall of text. They're just going to ask you to edit your post and use code tags for your code. So you might as well do that while you wait.

EDIT: See... :smiley:

2 Likes

Thanks I appreciate that, and yes in its current (unmodified) form the code works well, save for the need to tweak the sensitivity slightly per my application. I will try to reformat the code and come back.

While I go back and format the sketch, this is the link to where I got the code.

And I laughed when I saw the detector being used on the crotchal area of some blue jeans…

Cool project, though. Might have to try that.

a7

1 Like

I reposted the code in the (hopefully) correct format

Right first time.

Now to keep "us" happy, don't edit that, anything new shoukd get its own new posting here on this thread, and usually shoukd include all the code, so we don't have to refigure it ourselves.

editting the first post in the manner you did was perfectly fine.

Now we can read your wall of text and start trying to help.

Are you saying the posted text is the Instructabke code?

Perhaps you will post your attempt to modify it if it is.

a7

1 Like

And we can't figure out how you are going to carry around a stepper motor, controller board and large battery, while you are out metal detecting.

1 Like

Ill expand. This is for a "because it sounded fun" personal project. I created a metal detecting system around an rc car that I can drive around to locate metal objects. The stepper motor comes into play as part of a marking system that dispenses a small object to mark the approximate location of said metallic object. My goal in this is to have the stepper motor energize and make its rotation upon the metal detection system reaching a certain threshold of intensity. My stepper functions singularly with its own code, as does the metal detector, but I cannot figure out how to "marry" the two together.

Have you a particular stepper motor, control board and power supply sorted yet?

Have you made any experiments with just that hardware, that is stand alone not involving any metal detector stuff in the way?

a7

Yes, the posted code is from the instructable site, but it does include the limited changes I have added in the form of defining/initializing the stepper motor. The 2 sections I added in are sectioned off using comment lines so I could easily find them. example:

//
added stepper text here
//

Currently everything is sourced, wired, and assembled (see picture in above comment). Im using an R3 uno kit.

OK if we talking marriage, you gonna have to trot out both the bride and groom.

That is both working sketches...

And it won't hurt at all to supply some dets about the stepper stuff.

Very nice idea!

a7


/*
  Stepper Motor Control - one revolution

  This program drives a unipolar or bipolar stepper motor.
  The motor is attached to digital pins 8 - 11 of the Arduino.

  The motor should revolve one revolution in one direction, then
  one revolution in the other direction.


  Created 11 Mar. 2007
  Modified 30 Nov. 2009
  by Tom Igoe

*/

#include <Stepper.h>

const int stepsPerRevolution = 2048;  // number of steps per revolution


// initialize the stepper library on pins 2 through 5:
Stepper myStepper(32, 2, 4, 3, 5);

void setup() {
  myStepper.setSpeed(750); // set speed of motor to 750 rpm
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution / 2); // rotate stepper motor 1/2 turn.
  delay(500);
}

There is not much to look at for the stepper sketch. Its just a basic 1/2 turn command.

THX. I have a hot date, so I gotta jet.

I could hope that by the time I look again you'll be out looking for zippers or whatever.

a7

Guess not. I didn't drive home from the beach, if you get my drift, and just noe I can't make heads nor tails of how the detector informs you of the presence or absence of metal.

It looks like yuo added the stepper stuff OK. Use these functions where you want the motion:

void oneStepCCW() {
  myStepper.step(-stepsPerRevolution / 2); // rotate stepper motor 1/2 turn.
  delay(500);
}

void oneStepCW() {
  myStepper.step(stepsPerRevolution / 2); // rotate stepper motor 1/2 turn.
  delay(500);
}

It occurs to me that you will may need the stepper to go backwars? Or is the mechanical concept that repeated 1/2 turns are what you need?

So either way, you need to take the first step when the detection goes over some threshold, and note that you did (set a flag) and reset that flag only when it falls under another, different (lower!) threshold to avoid the thing dithering if the value sticks at the threshold (google hysteresis for fun).

So you get one movment on the stepper each time the higher threshold is surpassed.

Where to test the threshold, and what variable would even serve as a proxy, is I suppose the crux of your qeustion, so sorry to be of little help.

I'll have fun reading this later… :expressionless:

a7

Well after a short hiatus I've been messing around with this some more but haven't had much luck. I tried to simplify the issue by just using a button to activate the stepper motor, but even that isn't working for me. This is the code in it's current form:

//Metal detector based on pulse delay in LR circuit
//Connect a coil beween pin 10 and pin 8,
//a 100 Ohm resistor between pin 8 and ground,
//a speaker in series with a 10muF capacitor between pin 12 and ground,
//a reset-button between A0 and ground.
//Reference coil: 60 turns, diameter 6cm, AWG26 (0.4mm) wire. L~300muH, R~2Ohm
//
//R. Oldeman Oct 11 2020, CC BY-NC-SA 4.0 licence

#define debug true

//some parameters
#define sensitivity  5000 //threshold as a fraction of reference      
#define aimtime    160000 //aim for measurement every 160k cycles (=10ms) 
#define LEDpulselen 16000 //length of the LED pulse in clock cycles
#define cycles         40 //number of clock cycles reserved for calculations
#define printfrac      50 //fraction of measurements printed when in debug mode

//pin definitions - cannot change freely!
#define pulsepin 10 //must be pin 10 - TIMER1B output
#define probepin  8 //must be pin 8  - input capture pin
#define LEDpin   13 //if changed also need to update the direct-port writing
#define soundpin 12 //if changed also need to update the direct-port writing
#define resetpin A0 //can be changed freely 

//global variables - shared between main loop and measurement function
long int imeas = 0; //counts the number of measurements performed
int absdiff;       //absolute value of difference wrt reference
long int phase = 0; //tracks integral of absdiff
long int phasemax; //value at which the phase counter turns over
int LEDcycles = 0; //number of cycles that the LED pin stays high
int LEDcycle = 0;  //cycle index of the LED pulse

//
const int buttonPin = 13; // itendify button on pin 13
int buttonState = 0; // button normally low
#include <Stepper.h> // stepper library
const int stepsPerRevolution = 2048;  // number of steps per revolution
Stepper myStepper(32, 2, 4, 3, 5); // identify stepper on pins 2 through 5
//

void setup() {
  noInterrupts(); //disable all inerrupts to avoid glitches

  if (debug)Serial.begin(9600);

  pinMode(pulsepin, OUTPUT);
  digitalWrite(pulsepin, LOW);
  pinMode(probepin, INPUT);
  pinMode(LEDpin, OUTPUT);
  digitalWrite(LEDpin, LOW);
  pinMode(soundpin, OUTPUT);
  digitalWrite(soundpin, LOW);
  pinMode(resetpin, INPUT_PULLUP);

  //
  pinMode(buttonPin, INPUT); // initialize button as input
  myStepper.setSpeed(750); // set speed of motor to 750 rpm
  //

  //setup timer1 to FASTPWM on pin 10
  TCCR1A = 0B00100011;
  TCCR1B = 0B00011001;
}

//perform measurement of delay of the trailing edge
long int meas(int period, int minlen, int maxlen, int steplen, int nloop) {
  long int sum = 0;
  int nmiss = 0;
  OCR1A = period;      //set the period
  TIFR1 |= 0B00000001; //clear the timer overflow bit
  for (int iloop = 0; iloop < nloop; iloop++) {
    for (int len = minlen; len < maxlen; len += steplen) {
      OCR1B = len;                       //set the pulselength
      while ((TIFR1 & 0B00000001) == 0); //wait for timer overflow
      TIFR1 |= 0B00000001;               //clear the timer overflow bit
      while (TCNT1 < (period - cycles)); //wait till pulse is almost finished
      if ( (TIFR1 & 0B00100000) != 0) {  //check if trailing edge has been detected
        sum += (ICR1 - len);
        TIFR1 |= 0B00100000;             //clear the input capture flag
      } else {
        nmiss++;
      }
      //update phase
      phase += absdiff;
      //blink and click when phase rolls through
      if (phase > phasemax) {
        phase -= phasemax;
        LEDcycle = LEDcycles;
        PORTB = (PORTB | 0B00100000); //switch on LED
        PORTB = (PORTB ^ 0B00010000); //invert sound pin - click!
      }
      //switch off LED when it's been on long enough
      if (LEDcycle > 0) {
        LEDcycle--;
        if (LEDcycle == 0)PORTB = (PORTB & (!0B00100000));
      }
    }
  }
  if (nmiss > 0)sum = 0; //invalidate the result if there have been missing pulses
  return sum;
}

//flash LED with error code indefinitely if there's been an error
void go_error(byte errorcode) {
  if (debug) {
    Serial.print("ERROR ");
    Serial.print(errorcode);
    if (errorcode == 1)Serial.println(": No pulse on probe pin - check connections");
    if (errorcode == 2)Serial.println(": Delay too short - try more windings");
    if (errorcode == 3)Serial.println(": Delay too long - try fewer windings");
    if (errorcode == 4)Serial.println(": No robust pulse on pulselength scan - check coil resistance");
  }
  //enable in interrupts to use delay() and flash to indicate error code
  interrupts();
  while (true) {
    for (byte i = 0; i < errorcode; i++) {
      digitalWrite(LEDpin, HIGH);
      delay(100);
      digitalWrite(LEDpin, LOW);
      delay(100);
    }
    delay(500);
  }
}


void loop() {

  //perform initial robust measurement of average delay time
  long int tau = meas(16000, 8000, 8001, 1, 16) / 16;
  if (debug)Serial.print("delay in clock cycles:");
  if (debug)Serial.println(tau);
  if (debug)Serial.print("estimated coil inductance in muH:");
  if (debug)Serial.println(1.44 * tau * 100.0 / (16.0));

  if (tau == 0) go_error(1);         // no pulse
  if (tau < 5)  go_error(2);         // too short
  if (tau > 800)go_error(3);         // too long

  //choose pulsing parmeters based on measured delay time
  int minlen = 3 * tau;
  int maxlen = 5 * tau;
  int period = maxlen + 2 * tau + cycles;
  LEDcycles = LEDpulselen / period + 1;

  // repeat loop or speed up loop to approach aimed duration of measurement
  int steplen = 1;
  int nloop = 1;
  float tottime = float(period) * (maxlen - minlen);
  if (tottime > aimtime * (3.0 / 2.0)) steplen = round(tottime / aimtime);
  if (tottime < aimtime * (2.0 / 3.0)) nloop = round(aimtime / tottime);

  if (debug)Serial.print(" minlen: ");
  if (debug)Serial.print(minlen);
  if (debug)Serial.print(" maxlen: ");
  if (debug)Serial.print(maxlen);
  if (debug)Serial.print(" steplen: ");
  if (debug)Serial.print(steplen);
  if (debug)Serial.print(" period: ");
  if (debug)Serial.print(period);
  if (debug)Serial.print(" nloop: ");
  if (debug)Serial.print(nloop);
  if (debug)Serial.print(" LEDcycles: ");
  if (debug)Serial.println(LEDcycles);

  //perform a scan from minlen to maxlen
  long int minval = 1000000000;
  for (int len = minlen; len < maxlen; len += steplen) {
    long int val = meas(period, len, len + 1, 1, nloop);
    minval = min(val, minval);
    if (debug)Serial.print("len,val:");
    if (debug)Serial.print(len);
    if (debug)Serial.print(" ");
    if (debug)Serial.println(val);
  }
  if (minval == 0)go_error(4);

  //determine the reference value
  long int ref = meas(period, minlen, maxlen, steplen, nloop);

  //threshold and phasemax
  int threshold = ref / sensitivity;
  phasemax = 16000000 / period * threshold; //aim for 1Hz at threshold
  if (debug)Serial.print("reference, threshold, phasemax: ");
  if (debug)Serial.print(ref);
  if (debug)Serial.print(" ");
  if (debug)Serial.print(threshold);
  if (debug)Serial.print(" ");
  if (debug)Serial.println(phasemax);

  long int sum = 0;
  long int sumsq = 0;
  while (true) {
    long int val = meas(period, minlen, maxlen, steplen, nloop);

    //check if reset of reference value is requested
    if (digitalRead(resetpin) == LOW) ref = val;

    int diff = val - ref;
    absdiff = abs(diff);
    if (absdiff < threshold) {
      phase = 0;             //reset the phase
      if (diff > 0)ref += 1; //absorb slow drifts
      if (diff < 0)ref -= 1;
    }

    if (debug) {
      sum += diff;
      sumsq += long(diff) * long(diff);
      if (imeas % printfrac == 0) {
        float mean = float(sum) / printfrac;
        float rms = sqrt( (float(sumsq) / printfrac) - pow(mean, 2.0) );
        Serial.print(imeas);
        Serial.print(" val ref diff phase ");
        Serial.print(val);
        Serial.print(" ");
        Serial.print(ref);
        Serial.print(" ");
        Serial.print(diff);
        Serial.print(" ");
        Serial.print(mean);
        Serial.print(" ");
        Serial.print(rms);
        Serial.println("");
        sum = 0; sumsq = 0;
      }
    }
    imeas++;
  }

}

I'm Trying to insert a basic button command, but no matter where I insert this piece of code, the main one ceases to function.



  buttonState = digitalRead(buttonPin); // Read state of button
  if (buttonState == HIGH) // if button is pressed
  {
    Serial.println("counterclockwise");
    myStepper.step(-stepsPerRevolution / 2); // rotate stepper motor 1/2 turn.
  }

I'm at a loss as to how to get this to work, and am wondering if the nature of this program itself doesn't work with any other added functions. As I mentioned before I'm pretty new to arduino programming so this sketch for the metal detector is way out of my league. Any help is appreciated :+1:

OK, using the functions from #16 above see if you can use an example sketch from the IDE or one you hunt down with them.

If you find or write a program that uses a pushbutton to alternately turn on and off an LED (get that to work), then right where you turn on and off the LED add oneStepCW() where you turn on the LED and oneStepCCW() where you turn off the LED.

So you can alternately move the motor CCW, then back CW press by press.

It's a trivial program, and srsly if you can't do that yet, or figure it out, you should drop any more serious undertaking, slow your roll and learn up a bit so you can.

I've looked until I can't and don't see the obvious place to just put some stepper motor stuff into the original.

Perhaps the author of the original would be interested in he;ping if you ask nice and describe very carefully exactly what you are trying to do.

Modifying a sketch you didn't write is hard. The less organized and clear the original, the harder.

I can say this about my own, older code, which I sometimes wonder about, who the f wrote this crap and how did she think I was supposed to understand it? :wink:

I'm at the beach looking at this through a tiny window, but my advice would be the same no matter what.

I'm stuck on the idea that if the metal detection goes above a high threshold you wanna make a half move up, and when it falls below a low threshold a half move down.

If I don't got part that right, describe it in the same manner what you want to do and when.

a7

Thanks for the reply. So in post #17, the shorter section of code posted at the end of the post is the piece of code that needs to be added to the main metal detecting code. I've already extracted that from a working program I made in which I can activate the stepper by pressing a button. The other parts of that code (where I establish and call out the various components at the head of the program and in voidSetup) have already been added to the main code (which is why they're not present in that small snippet). To clarify, my original idea was to have the stepper activated upon the metal detector reaching a certain threshold (when the detected metal is close enough to the coil). But at this point, in the interest of just getting it to work, I have settled with just trying to get the stepper motor to function by pushing the button (independent, and not relying on the metal detector signal whatsoever). But I've tried inserting that "if" statement for the button/stepper into like 20 different places with no luck. no matter where I try to nest it, the main code stops functioning properly. I'm beginning to think this code is created in a way that will not accept another function without compromising functionality.

Change or make the pinMode() of your button to INPUT_PULLUP.

Wire your button from the input pin to ground. Nothing else needs be on the input pin but the button.

Change the sense of when the motor should turn from a comparison to HIGH to a comparison with LOW.

So LOW is when you press the button.

So changed, that code can be can be be put literally anywhere in the loop() function, and if you don't press the button, the original metal detector should run.

Set that aside. That is take out the if statement that will run the motor when you press the button.

Try placing

    Serial.println("                Maybe this gets regular attention!");

at various places in the code. You may see it once in a long time. You may see it dozens of times or even hundreds of times a second.

The original metal detection should not be broken by this experiment, which experiments will have to serve as I seem to get a certain kind of headache looking into the original code, and short of building the thing myself, it does not appear easy to run any kind of simulation of the process it follows.

The stepper function, when you do press the button to move the motor, will run the motor and as far as I can tell block, that is stay right there until the motion is done. This will screw up the metal detection, but not forever.

Sry I know this may not help much, it does seems that the code was not written "properly", that is to say with any consideration on mind that someone might like to add a simple additional capability like you trying.

And this kind of tinkering is more like particle physics or biology than maths or logic or programming. Really not the way to go, but it could might let you find a place or two that is plausible, and try them out for whether you cab]n kludge thus up w/o understanding the flow.

I still think you should do everything I to,d you in my previous advices, including contacting the author. Just be gentle and don't start off by calling the code tots crap. :expressionless:

If you succeed, you get to call yourself a hacker, but not a programmer. :wink:

a7