Go Down

Topic: using External Interrupts for limit switch (Read 515 times) previous topic - next topic

tdurand29

Hello,

I'm currently trying to make a gluing machine using stepper motors and a lead screw to move a plunger used to press on a tube of glue. I want to put a limit switch at the end of the lead screw that will be triggered when the glue is empty. I am using interrupts to code the limit switch, because I wasn't this to take priority once it is pressed to prevent breaking something. But I'm running into a problem. When the limit switch is triggered it is suppose to stop any motion further and retract the plunger a few rotations. But when the limit switch is pressed it stops the motion but doesn't retract and it locks up everything and nothing else can be done until the restart button is pressed. I'm just wondering what I can do to make the limit switch work and retract.

Thank you!

Thomas

Code: [Select]
//Testing Buttons with LCD and New Motors
#include <Stepper.h>
#include <LiquidCrystal.h>

//setting up led
int greenLed = 52;
int redLed = 50;

// Setting up int for the control buttons
int glueButton = 53;
int pulseButton = 51;
int upButton = 49;
int downButton = 47;
int emptyLimitSwitch = 2;

// Setting up int for glueing motor
int in1Pin = 6;
int in2Pin = 5;
int in3Pin = 4;
int in4Pin = 3;
const int stepsPerRev = 200;
Stepper glueStepper (stepsPerRev, in1Pin, in2Pin, in3Pin, in4Pin);

// Setting up Constants for LCD
const int rs = 7, en = 8, d4 = 9, d5 = 10, d6 = 11, d7 = 12;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  //Activating LCD letting the arduino know the LCD is 16 characters x 2 Rows
  lcd.begin(16, 2);

  //Activating stepper and setting pin mode
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);

  pinMode(glueButton, INPUT_PULLUP);
  pinMode(pulseButton, INPUT_PULLUP);
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(emptyLimitSwitch, INPUT_PULLUP);

  pinMode(greenLed, OUTPUT);
  pinMode(redLed, OUTPUT);
  digitalWrite(greenLed, HIGH); //turning on green led

  attachInterrupt(digitalPinToInterrupt(emptyLimitSwitch), empty, LOW);
}

void loop() {
  //reading pot values and assinging value to a name, mapping the pots to chosen range
  int pulseValue = analogRead(A0);
  int pulseStep = map(pulseValue, 0, 1023, 0, 500);
  int glueStepValue = analogRead(A1);
  int glueStep = map(glueStepValue, 0, 1023, 0, 1000);
  int glueRpmValue = analogRead(A2);
  int glueRpm = map(glueRpmValue, 0, 1023, 0, 201);
  int rpmValue = analogRead(A3);
  int rpm = map(rpmValue, 0, 1023, 0, 5);

  //printing the pot values to the lcd screen and moving cursor and printing blanks to refresh the screen
  lcd.print("P=");
  lcd.setCursor(2, 0),
                lcd.print("   ");
  lcd.setCursor(2, 0);
  lcd.print(pulseStep);
  lcd.setCursor(6, 0);
  lcd.print("Gstp=");
  lcd.setCursor(11, 0),
                lcd.print("    ");
  lcd.setCursor(11, 0),
                lcd.print(glueStep);
  lcd.setCursor(0, 1);
  lcd.print("Grpm=");
  lcd.setCursor(5, 1),
                lcd.print("   ");
  lcd.setCursor(5, 1),
                lcd.print(glueRpm);
  lcd.setCursor(8, 1);
  lcd.print("RPM=");
  lcd.setCursor(12, 1),
                lcd.print("   ");
  lcd.setCursor(12, 1),
                lcd.print(rpm);
  lcd.setCursor(0, 0);

  //reading button values
  int glueButtonValue = digitalRead(glueButton);
  int pulseButtonValue = digitalRead(pulseButton);
  int upButtonValue = digitalRead(upButton);
  int downButtonValue = digitalRead(downButton);
  int emptyLimitSwitchValue = digitalRead(emptyLimitSwitch);

  //button code
  if (glueButtonValue == LOW)
  {
    glueStepper.setSpeed(glueRpm);
    glueStepper.step(-1500 - glueStep);

    glueStepper.step(800);
    delay(250);
  }

  if (pulseButtonValue == LOW)
  {
    glueStepper.setSpeed(glueRpm);
    glueStepper.step (-pulseStep);

  }

  if (upButtonValue == LOW)
  {
    glueStepper.setSpeed(275);
    glueStepper.step(500);
  }

  if (downButtonValue == LOW)
  {
    glueStepper.setSpeed(275);
    glueStepper.step(-500);
  }
  if (emptyLimitSwitchValue == LOW)
  {
    glueStepper.setSpeed(250);
    glueStepper.step(1000);
  }
}
void empty() {
  int emptyLimitSwitchValue = digitalRead(emptyLimitSwitch);

  if (emptyLimitSwitchValue == LOW) {
    glueStepper.setSpeed(200);
    glueStepper.step(5000);
  }
}

jimmer

#1
Oct 20, 2018, 03:03 am Last Edit: Oct 20, 2018, 03:04 am by jimmer
Have you tried triggering on CHANGE instead ?  You are testing again for LOW anyway so ....

I've not triggered on LOW so I don't know how that works in terms of time delays or whatever, maybe it's triggering continuously??

Delta_G

Quote
I am using interrupts to code the limit switch, because I wasn't this to take priority
You may be mistaken on the proper use of interrupt then.  Interrupts have nothing to do with priority of tasks.  You can write the code to give the limit switch total priority and never touch an interrupt.  Interrupts are for things that might happen so fast that even a microprocessor can miss them.  That's unlikely with your gluing machine. 

remember, an interrupt can't tell another function to stop running.  If you really want the limit switch to be able to stop the process where it is, then the whole process needs to be written non-blocking so you can keep the limit switch read in a tight loop.  Without doing that, then even with an interrupt all you could do would be to set a variable and react to it from the main code.  Even with that, if the code is blocking you'll have to wait until it is done to check the variable.  So the interrupt gains you nothing. 

You need to rewrite this as a state machine and get rid of the delay calls.  Once you do that, then you can possibly have something on your limit switch that can be responsive.  Until then, no interrupt is going to help. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Go Up