Left something out?

I have ben running this sketch flawlessly for a week and decided to introduce a potentiometer and hall effect sensor over the weekend and now I have a gremlin somewhere.

When I run the void dblros(); code block every 80 or so button pushes the code will screw up, the table will slide in but on the way out it will stop and grind like it hit the end of the rail then stop and run the last line of code to move the table back out again so I get an in/out/out action and miss the in for some reason along with the grinding stop.

I can reset it by powering on and off to home the slider table again and then it works fine for another 80 or so button pushes and then does it again, have I not kept track of something I should have with the new sensors? It looks right to me but that isn’t saying a whole lot. lol

#include <SPI.h>
#include <Wire.h>
#include <Stepper.h>
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "Adafruit_STMPE610.h"

// Default values for Adafruit shield v2.
#define STMPE_CS 8
#define TFT_DC 9
#define TFT_CS 10

Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

// Assign human-readable names to some common 16-bit color values:
#define   BLACK   0x0000
#define   BLUE    0x001F
#define   RED     0xF800
#define   GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

Stepper tableSlider = Stepper(200, 5, 6);  //table slider pin 5 and 6
Stepper subsRotate = Stepper(200, 3, 4);  //substrate rotate pin 8 and 9

const int gluemac = 7;           // pin to actuate glue machine relay
const int button = 2;            // pin button is on
int val = 0;                     // current button state
int old_val = 0;
int state = 0;
unsigned long time = 0;
unsigned long debounce = 15;

int speedKnob = A1;         //variable speed for double rosette
int sensorValue = 0;        //store pot value

int positionSensor = A0;        //hall effect home pin
int homeVal = 0;

// Rotations 0,2 = portrait  : 0->USB=right,upper : 2->USB=left,lower
// Rotations 1,3 = landscape : 1->USB=left,upper  : 3->USB=right,lower
byte rotation = 1; //(0->3)
const byte _numBtns = 2;

Adafruit_GFX_Button btn[_numBtns];
int btnColor[8] = {RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW, WHITE, BLACK};

TS_Point p;
int x, y;

void invertBtn (byte btnHit) {
  btn[btnHit].drawButton(true);
  delay(300);
  // normal
  btn[btnHit].drawButton(false);
}

void tableHome() {
  homeVal = digitalRead(positionSensor);
  tableSlider.setSpeed(1000);
  while (homeVal == HIGH) {
    tableSlider.step(100);           //home table to sensor
    homeVal = digitalRead(positionSensor);
  }
}

void single() {
  Serial.println("Single function called.");

  tableSlider.step(7000);           //slide table in
  Serial.println("clockwise");

  digitalWrite(gluemac, LOW);      //turn glue machine on
  Serial.println("relay_on");
  delay(300);

  subsRotate.step(800);           //rotate 1 time
  Serial.println("rotate");

  digitalWrite(gluemac, HIGH);       //turn glue off
  Serial.println("relayoff");

  subsRotate.step(300);           //rotate a little more glue dropping
  Serial.println("rotate");
  delay(300);

  tableSlider.step(-7000);             // slide table out
  Serial.println("counterclockwise");
  state = 0;                           //turn everything off
}


void dblros()
{
  Serial.println("Double function called.");

  tableSlider.step(8800);           //slide table in
  Serial.println("clockwise");

  digitalWrite(gluemac, LOW);      //turn glue machine on
  Serial.println("relay_on");
  delay(300);

  subsRotate.step(800);           //rotate 1 time
  Serial.println("rotate");

  digitalWrite(gluemac, HIGH);       //turn glue off
  Serial.println("relayoff");
 

  tableSlider.step(-8800);             // slide table out
  Serial.println("counterclockwise");
  sensorValue = analogRead(speedKnob) * 10;
  delay(sensorValue);

  tableSlider.step(11000);             // slide table in
  Serial.println("clockwise");

  digitalWrite(gluemac, LOW);      //turn glue machine on
  Serial.println("relay_on");
  delay(300);

  subsRotate.step(800);           //rotate 1 time
  Serial.println("rotate");

  digitalWrite(gluemac, HIGH);       //turn glue off
  Serial.println("relayoff");

  subsRotate.step(200);           //rotate a little more glue dropping
  Serial.println("rotate");
  delay(300);


  tableSlider.step(-11000);             // slide table out
  Serial.println("counterclockwise");
  state = 0;                           //turn everything off

}
void setup() {
  pinMode(button, INPUT_PULLUP);
  pinMode(gluemac, OUTPUT);
  digitalWrite(gluemac, HIGH);       //relay is active low
  pinMode(positionSensor, INPUT_PULLUP);
  tableHome();

  tableSlider.setSpeed(3000);  //  table slide
  subsRotate.setSpeed(100);   //substrate rotate

  Serial.begin(9600);
  tft.begin();
  ts.begin();
  if (!ts.begin()) {
    Serial.println("Couldn't start touchscreen controller");
    while (1);
  }
  tft.setRotation(rotation);
  tft.fillScreen(BLUE);
  // x coordinate of 100 doesn't seem right, but it works.
  btn[0].initButton( &tft, 100, 60, 150, 50, BLACK, btnColor[0], BLACK, "1 INCH", 2 );
  btn[0].drawButton(false);
  btn[1].initButton( &tft, 100, 130, 150, 50, BLACK, btnColor[1], BLACK, "DOUBLE", 2 );
  btn[1].drawButton(false);
}

void loop() {
  if (!ts.bufferEmpty()) {
    p = ts.getPoint();
    switch (rotation) {
      case 0:
        x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
        y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
        break;
      case 1:
        // p.x, p.y reversed //
        x = map(p.y, TS_MINY, TS_MAXY, 0, tft.width());
        y = map(p.x, TS_MAXX, TS_MINX, 0, tft.height());
        break;
      case 2:
        x = map(p.x, TS_MAXX, TS_MINX, 0, tft.width());
        y = map(p.y, TS_MAXY, TS_MINY, 0, tft.height());
        break;
      case 3:
        // p.x, p.y reversed //
        x = map(p.y, TS_MAXY, TS_MINY, 0, tft.width());
        y = map(p.x, TS_MINX, TS_MAXX, 0, tft.height());
        break;
    }

    while (ts.touched()) {
      if (btn[0].contains(x, y)) {
        Serial.println("Button 1 hit.");
        invertBtn(0);
      }
      if (btn[1].contains(x, y)) {
        Serial.println("Button 2 hit.");
        invertBtn(1);
      }
    }
  }

  homeVal = digitalRead(positionSensor);
  if (btn[0].contains(x, y) && homeVal == HIGH) {
    tableSlider.step(1000);
  }
  else if (btn[1].contains(x, y) && homeVal == LOW ) {
    tableSlider.step(-4000);           //home table to double rosette
  }

  val = digitalRead(button);    //read input value and store it
  Serial.print("val = "); Serial.println(val); Serial.print("old_val = "); Serial.println(old_val);
  if (val == LOW && old_val == HIGH && millis() - time > debounce ) {     //check if there was a transition
    Serial.print("state = "); Serial.println(state);
    state = 1 - state;
    time = millis();      //button debounce
  }
  old_val = val;          //store old value
  if (state == 1 && btn[0].contains(x, y)) {
    single();
  }
  else if (state == 1 && btn[1].contains(x, y)) {
    dblros();
  }
}

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read.

It looks like you have a decent amount of debug output on Serial. Can you run it with Serial Monitor running to get a better idea of just where the problem occurs. Is it possible the problem is caused by the Arduino resetting? If this is hard to determine from your current code you can add a Serial print in setup to indicate when the program starts.

Can you post the version of the sketch before you added the code for the potentiometer and hall effect sensor. A diff of the two might make it easier for us to spot a problem with the new code.

Could it be a variable overflowing? I haven't looked, but if something's incrementing on button press, could it be that its data type's too small?

pert: Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read.

It looks like you have a decent amount of debug output on Serial. Can you run it with Serial Monitor running to get a better idea of just where the problem occurs. Is it possible the problem is caused by the Arduino resetting? If this is hard to determine from your current code you can add a Serial print in setup to indicate when the program starts.

Can you post the version of the sketch before you added the code for the potentiometer and hall effect sensor. A diff of the two might make it easier for us to spot a problem with the new code.

The code is auto formatted, I put the whole sketch in because when I think it's one thing it ends up being something else that I'm not knowledgeable enough to know about. I'm going to remove the POT and use a simple delay and see if that is where my problem occurs. I have a feeling that is the culprit but I'm not sure why it would be.

ardy_guy: Could it be a variable overflowing? I haven't looked, but if something's incrementing on button press, could it be that its data type's too small?

I was thinking I wasn't keeping track of something I should be but when you are just starting out you just don't know enough to know, but i'm getting closer.

ribbonman: The code is auto formatted

No it's not. The indentation is completely screwed up through most of loop(), in fact the final closing bracket isn't even in the first column, that should make it obvious there is a problem. Makes it extremely hard to read. I had to copy it to the Arduino IDE just to format it. It would be much easier for you to do this before posting than every person who reads this thread having to format it for you.

I removed the POT and still had problems with the stepper losing steps so I changed the microstep controller to a better one and for the time being the stepper doesn’t seem to be losing any steps.

@ardy-guy I did have the problem with the POT being turned down to make the pause interval to quick the steps would mess up on the change of direction so I have made a note not to turn it that far.

Today the sketch was running fine for most of the day and then it started running the sketch without a button press intermittently, I wasn’t near the machine and it just started running and would do that every so often, I’m guessing I’m getting some type of interference although I’m in the dark about what it could be.

Today the sketch was running fine for most of the day and then it started running the sketch without a button press intermittently, I wasn't near the machine and it just started running and would do that every so often, I'm guessing I'm getting some type of interference although I'm in the dark about what it could be.

Your button debounce routine uses lockout, and does not protect against noise, only against switch bounce on a press. You might be better to use a debounce routine which calls for a stable reading for a period of time. Here's some code to try. Non blocking versions can be written, but for a manual button press it may not be an issue.

val = digitalRead(button);    //read input value and store it
if (val == LOW && old_val == HIGH)//check if there was a transition
{
  delay(50);//adjust debounce delay as required
  val = digitalRead(button);//take another reading
  if (val == LOW)//stable reading
  {
    state = 1 - state;//register button press
  }
}
old_val = val;          //store old value
if (state == 1 && btn[0].contains(x, y)) {
  single();
}
else if (state == 1 && btn[1].contains(x, y)) {
  dblros();
}

Thanks CattleDog, I had been using delay for the button code until last week and was reading how I should use mills instead of delay so I changed it.

I haven't had any issues with noise until today so I'm unsure where it would have come from, so many nuances to take into consideration.

I will try it in the morning and see how it reacts.

Just an update, the code cattledog offered did the trick, I ran all day without and random starts. One by one the gremlins get worked out.