simple logic question

Say I have an led and 2 switches plugged into the arduino.

What general logic / series of control structure would I use in order to carry out the following operations:

  1. Do nothing until the first switch is thrown

  2. Once the switch is thrown, have led carry out a pre-programmed pattern of flashes, but only once

  3. After the pre-programmed pattern finishes, turn the led on until the second switch is thrown

  4. After the second switch is thrown, shut off the LED and then do nothing until arduino is reset

  1. Do nothing until the first switch is thrown

Who will throw the switch?

  1. Once the switch is thrown, have led carry out a pre-programmed pattern of flashes, but only once

Who throws the switches? yes, only once what?

  1. After the pre-programmed pattern finishes, turn the led on until the second switch is thrown

Wait if the led turns on how do you flash the led with no power?
You need to get rid of the person who throws the switches, you will end wasting money buying new ones.

  1. After the second switch is thrown, shut off the LED and then do nothing until arduino is reset

I really want to know who is throwing the switches.

Logic questions with logic answers, it's better to use the right words to describe what you
are and want to do.

:smiley:

Google "state machine" for one approach.

@jremington I looked into it, but being a novice programmer that looks a little over my head. are you implying a switch case could be used here? and if so, how?

@Domino60 This is a hypothetical situation to describe a more complex program. I have a robot vehicle with a starting switch and an end-stop switch. I want the vehicle to start when I push one button, run through a pre-programmed path once, and then go straight until the end stop is triggered. I figured If I simplified the situation it might be easier for people to give answers, but apparently not . I fully understand how to code the motions of the robot, i just don't understand the logic i might need to get the switches to trigger these actions.

Ah, that does seem much less complex than the examples google had to offer. I asume you would cary that out with a switch case function?

Thanks! now, time to get coding :open_mouth: ...

Domino60:
Logic questions with logic answers, it's better to use the right words to describe what you
are and want to do.

The questions were perfectly framed for readers on this forum, and it's your answers which are crap.

Delta_G:
State machine isn't hard.

.... and are well worth getting your mind round sooner rather than later.

Forum member Nick Gammon has this to say on the matter.

Hello James,

1st let me say +1 to using a state machine. It lets your code have operating modes. :slight_smile:

If you store your 2 switch states as bits in a byte, the resulting value tells you both switches.

Say switch 1 is bit 0 and switch 2 is bit 1.
value 0, both switches are 0.
value 1, switch 1 is thrown and switch 2 is open.
value 2, switch 1 is open and switch 2 is closed.
value 3, both switches are closed.

One thing to be aware of is contact switch bounce. When the contacts are very close there will be sparks crossing the gap for maybe 2 millis or more. If all you do is read the pin quickly a single press or release will look like many press and release events.
You can salt your code with a delay everywhere pin state change is detected but the delay can also throw off other timing. For something one-thing-at-a-time simple that's not a problem but keep in mind not to try making the sketch do more than one thing at a time which sorry, will make for a pretty lame robot.

When you're ready, there is a no-delays way around that where each switch gets monitored and the switch state is not always the pin state. You can still pack switch states into a single variable to check them all at once.

With the states as bits you can use bit logic commands to operate on any or all of them at once. Using an unsigned long you can evaluate up to 32 states at once as opposed to

if ((sw1 == 1) && (sw2 == 0 ) && (sw3 == ....... etc etc etc constructs.

Keep it in mind while working on your robot project.

Domino60:
I really want to know who is throwing the switches.

Really?

Logic questions with logic answers, it's better to use the right words to describe what you
are and want to do.

REALLY?

This is actually one of the better formulated questions I've seen on here, with a quite clear description of what is being requested. Why do you have to be an unhelpful smart-ass in the first response?

Domino60:
:smiley:

I am not amused.

james_d:
I figured If I simplified the situation it might be easier for people to give answers,

Which is very appreciated but left you open to stupid trolling with a stupid troll punchline.

You need to get rid of the person who throws the switches, you will end wasting money buying new ones.

Because the word "throw" can be taken an obviously wrong way......

GoForSmoke:
Because the word "throw" can be taken an obviously wrong way......

Except that "throw" actually is one of the correct slang terms for operating a switch. It's "funny" on the same level as "Is your refrigerator running? Then you better go catch it!"

It would be amusing if Domino's post actually had useful information in it, but it doesn't. He was just being an ass for no reason. Even when I'm being a smart-ass about something, I at least try to include something that could be a useful hint.

The big knife switches for high current electricity, not everyone wanted to hold the handle when contact was made. It is a throw motion even if you do keep a hand on the handle by "throw the lever" definitions.

I enjoy a bit of clowning but like you said, it wasn't to help anyone so I call it trolling.

Well guys I've been tinkering for a while and I cant seem to get anything to work. When I upload The code below, the arduino doesn't wait for an input from the switch, and just goes through the programmed path section of the code and then immediately stops, not waiting for the limit switch.

Here's my code:

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myStepper = AFMS.getStepper(200, 1);

Adafruit_DCMotor *myMotor = AFMS.getMotor(3);    // And connect a DC motor to port M1

int startswitchPin = 4;     // switch is connected to pin 2
int sval;     // variable for reading the pin status

int limitswitchPin = 6;    // switch is connected to pin 5
int lval;      // variable for reading the pin status

boolean firstrun = false;

void setup() {

  pinMode(startswitchPin, INPUT);
  pinMode(limitswitchPin, INPUT);
  
  AFMS.begin();   // create with the default frequency 1.6KHz
  //AFMS.begin(1000);     // OR with a different frequency, say 1KHz
  myStepper->setSpeed(40);       // set default stepper motor speed to 100 rpm 
}

void loop() {

  static int state = 0; // initial state is 1, the "idle" state.

  switch(state)
  {
    
    case 0:     //check initial starting switch
      sval=digitalRead(startswitchPin);     // read input value and store it in val
      
      if (sval == HIGH) {                       // check if the button is pressed and it isnt second run
        state = 1;
      }
      else; {}
        
      break;
    
    case 1:   //preprograped pattern to travel inbetween cans
      
      delay(500);  // Wait .5 seconds
    
      myMotor->run(FORWARD);    //turn on motor, forwards  
    
      uint8_t i;    // initiate a value to increment 
    
      for (i=0; i<200; i++) {    // code to ramp up motor speed   
        myMotor->setSpeed(i);  
        delay(2);              // Wait .2 second
      }    
      delay(500);
   
      myMotor->setSpeed(200);
      myMotor->run(FORWARD);
    
      delay(500);
      myStepper->step(20, FORWARD, DOUBLE);     // runs stepper motor 10 degrees forward
    
      delay(500);
      myStepper->step(40, BACKWARD, DOUBLE);    // runs stepper motor 10 degrees backward
  
      delay(500);
      myStepper->step(20, FORWARD, DOUBLE);    // runs stepper motor 10 degrees FORWARD
    
      delay(2000);
      myStepper->step(20, BACKWARD, DOUBLE);   // runs stepper motor 10 degrees BACKWARD
    
      delay(500);
      myStepper->step(40, FORWARD, DOUBLE);    // runs stepper motor 10 degrees forward
  
      delay(500);
      myStepper->step(20, BACKWARD, DOUBLE);   // runs stepper motor 10 degrees backward
    
      delay(500);
      for (i=200; i!=100; i--) {    // code to ramp down motor speed   
        myMotor->setSpeed(i);  
        delay(2);              // Wait .2 second
      }
      delay(10);
      state = 2;  // advance to next state

      break;
     
    case 2:    // run motor at a slow rate until limit switch is triggered
      myMotor->run(FORWARD);
      myMotor->setSpeed(100);   // set dc motor speed to at a much slower rate
      
      delay(10);
      
      lval=digitalRead(limitswitchPin);    // read input value and store it in lval
      
      if (lval == LOW) {     // check if limit switch is pressed
        state = 3;     // advance to next state
      }
      
      break;
   
    case 3:   // stop the motor completely and wait 1000 seconds until looping back to the start (this is           the only way i could figure out to end the code completely)
      myMotor->run(RELEASE);
      delay(1000000);
      state = 0;    
      break;
  }
}

Is your switch wired to be normally HIGH or normally LOW?