Vex motor code help need

hm a7

lot's of new things in this code-version

here is one with serial print and comments

// https://wokwi.com/projects/362524913933364225
// https://forum.arduino.cc/t/vex-motor-code-help-need/1088689

# include <Servo.h>
const byte upLimit_Pin   = 2;
const byte DownLimit_Pin = 3;
const byte StopBtn_Pin   = 4;
const byte servo_Pin     = 7;

const byte upLED_Pin     = 8;
const byte downLED_Pin   = 9;
Servo aServo;

int servoState = 1;
int lastServoState = 1;

boolean upperLimitSwitchPressed = false;
boolean lowerLimitSwitchPressed = false;

int position = 90;
  
void setup(){
  Serial.begin(115200);
  Serial.println("\nhello world.\n");

  pinMode(upLimit_Pin  , INPUT_PULLUP);
  pinMode(DownLimit_Pin, INPUT_PULLUP);
  pinMode(StopBtn_Pin,   INPUT_PULLUP);

  pinMode(upLED_Pin,   OUTPUT);
  pinMode(downLED_Pin, OUTPUT);

  aServo.attach(servo_Pin);
  aServo.write(90);  
}


void loop() {
  // does what the name says
  simulateSwitchPressing(); 
  //if (!digitalRead(upLimit_Pin)) {
  if (upperLimitSwitchPressed) {
    servoState = -1;  // gonna go DOWN now! ");
  }
  
  //if (!digitalRead(DownLimit_Pin)) {
  if (lowerLimitSwitchPressed) {  
    servoState = 1; // gonna UP now. ");
  }

  if (!digitalRead(StopBtn_Pin)) {
    servoState = 0; // gonna stop now. ");
  }

  printStateOnChange();

  // servo and limit LEDs
  static unsigned long lastTwitch;
  if (millis() - lastTwitch < 200) {
    return;
  }  
  lastTwitch = millis();
  // change servopsosition a little bit
  position -= servoState << 2;
  position = constrain(position, 0, 180);
  Serial.print("Servopisition=");
  Serial.println(position);

  if (position == 0) {
    position = 5;
  }

  if (position == 180) {
    position = 175;
  }
  
  digitalWrite(upLED_Pin, position < 25);
  digitalWrite(downLED_Pin, position > 155);
  
  aServo.write(position);
}


void printStateOnChange() {
  // check if variable "servoState" has changed 
  // its value since last call of this function
  if (lastServoState != servoState) {
    Serial.println("Limit switch pressed delay(2000)");
    delay(2000);
    // if it has rEALLY changed its value 
    lastServoState = servoState; // update lastServoState

    if (servoState == -1) {
      Serial.println("going DOWN now.");    
    }

    if (servoState == 1) {
      Serial.println("going UP now!");    
    }

    if (servoState == 0) {
      Serial.println("stopped.");    
    }
  }
}


void simulateSwitchPressing() { 
  if (position < 25) {
    upperLimitSwitchPressed = true;
  }
  else {
    upperLimitSwitchPressed = false;
  }

  if (position > 175) {
    lowerLimitSwitchPressed = true;
  }
  else {
    lowerLimitSwitchPressed = false;
  }
}

best regards Stefan

Please do not use hijack my simulation work to further whatever your goals are.

We are trying to show @jmathew213123 that there is nothing hard about limit switches.

You have needlessly obscured the logic. The hole point was to make the OP actually read, and understand, code she might be able to. Read and understand.

a7

@jmathew213123

In my simulation, you can redefine xprintf() and get a chatty mode going:

//void xprintf(char *) {}

void xprintf(char *msg)
{
  Serial.print(msg);
  delay(77);  // spam reducer only
}

a7

I don't think so

"obscured" logic:

bad coding style using hardcoded numbers instead of selfexplaining constants
make it harder to understand

what is this?

    xprintf("               gonna go DOWN now! ");

what wizardness are you doing here??

  position -= servoState << 2;

huh? how can this ever make a LED switch on / off???

  digitalWrite(8, position < 25);
  digitalWrite(9, position > 155);

So I tested that new code that I made and it actually worked for the most part. When I initially upload the code, the motor starts moving right away before I press the start button. For some reason both the limit switches work correctly as when I press the first limit switch the motor spins counterclockwise and when I press the second limit switch it stops the motor as it should. For some reason the button isn't working. The button may be faulty but it could also be a coding error. If it is a coding error I'm not sure what I did incorrect. I'm think it could be something to do with the debounce stuff I included from the example code @alto777 showed me but I'm not sure.

#include <Servo.h>

Servo servo;

#define BUTTON_PIN 8
#define LIMIT_PIN 7
#define LIMIT_PIN2 6
byte lastButtonState = LOW;
byte lastLimitState = HIGH;
byte lastLimitState2=HIGH;

unsigned long debounceDuration = 50; // millis
unsigned long lastTimeButtonStateChanged = 0;
void setup() {
  servo.attach(9);
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LIMIT_PIN, INPUT_PULLUP);
  pinMode(LIMIT_PIN2, INPUT_PULLUP);

}
void loop() {
  if (millis() - lastTimeButtonStateChanged > debounceDuration) {
    byte buttonState = digitalRead(BUTTON_PIN);
    byte limitState = digitalRead(LIMIT_PIN);
    byte limitState2 = digitalRead(LIMIT_PIN2);
    if (buttonState != lastButtonState && limitState == lastLimitState && limitState2 == lastLimitState2) {
      lastTimeButtonStateChanged = millis();
      lastButtonState = buttonState;
      if (buttonState == HIGH) {
        servo.write(60);
      }
    }

    if (buttonState == lastButtonState && limitState != lastLimitState && limitState2 == lastLimitState2) {
      lastTimeButtonStateChanged = millis();
      lastLimitState = limitState;
      if (limitState == LOW) {
        servo.write(120);
      }
    }

     if (buttonState == lastButtonState && limitState == lastLimitState && limitState2 != lastLimitState2) {
      lastTimeButtonStateChanged = millis();
      lastLimitState2 = limitState2;
      if (limitState2 == LOW) {
        servo.write(60);
        delay(1000);
        servo.write(180);
      }
    }
  }
}```

Did you try a simple sketch that proves the button is working or not working?

You have to adopt an experimenter's or scientific or even just common sense approach to figuring out what is happening and why it isn't what you think.

How is that button wired? Did you ever say what the button is supposed to do?

Why is the button pin mode INPUT? Could it be you've left off a resistor to pull it, either way, or that you've used the wrong sense on the button, HIGH means what, presst or not presst?

Did you not read and trace either simulation to see that debouncing does not need to be part of the solution? The mechanical constraints of the physical system are such debouncing is unnecessary.

a7

@jmathew213123 I have altered your code.

You ended up with three copies of a common debouncing pattern, all running off one timer.

I renamed the timer lastInputCheckTime to better reflect its roll. I removed the extra conditions on the button and limit switch debouncing code. You were saying "see this press only if it is the only thing being pressed", which is not necessary. The two limit switches cannot be "pressed" at the same time. If the button happened to be pressed at the exact (within 50 ms) of either limit switch, so what? The two switches would be handled in the order they were pressed, or if exact, in the order the code says to check. Perhaps moving the button debouncing code to be the last of three would give you comfort as it would then "prioritize" that function.

I also removed all but one call to millis(). I call it once, and stash that as now, and use now anywhere I need the current time. So everyone works off the same clock. You'll see ppl doing that and dignifying it by using currentMillis or something fancy like that.

Read the code:

#include <Servo.h>

Servo servo;

#define BUTTON_PIN 8
#define LIMIT_PIN 7
#define LIMIT_PIN2 6

byte lastButtonState = LOW;
byte lastLimitState = HIGH;
byte lastLimitState2=HIGH;

unsigned long debounceDuration = 50; // millis
unsigned long lastInputCheckTime = 0;

void setup() {
  Serial.begin(115200);
  Serial.println("state toggle blur");

  servo.attach(9);
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LIMIT_PIN, INPUT_PULLUP);
  pinMode(LIMIT_PIN2, INPUT_PULLUP);

}


void loop() {
  static unsigned long now;

  now = millis(); // one millis call for all time

  if (now - lastInputCheckTime > debounceDuration) {
   
    byte buttonState = digitalRead(BUTTON_PIN);
    byte limitState = digitalRead(LIMIT_PIN);
    byte limitState2 = digitalRead(LIMIT_PIN2);

    if (buttonState != lastButtonState) {
      lastButtonState = buttonState;
      if (buttonState == HIGH) {
        Serial.println("sixty");
        servo.write(60);
      }

      lastInputCheckTime = now;
    }

    if (limitState != lastLimitState) {
      lastInputCheckTime = now;
      lastLimitState = limitState;
      if (limitState == LOW) {
        Serial.println("       120");
        servo.write(120);    
      }

      lastInputCheckTime = now;
    }

     if (limitState2 != lastLimitState2) {
      lastInputCheckTime = now;
      lastLimitState2 = limitState2;
      if (limitState2 == LOW) {
        Serial.print("                60... ");
        servo.write(60);
        delay(1000);
        Serial.println(" ...           180");
        servo.write(180);
      }

      lastInputCheckTime = now; // delay kinda messes the hole idea up, but hey.
    }
  }
}

Hi @matthew3302

well done posting a new attempt to code.

indention and curly braces have an important purpose
curly braces { and }

the encapsulate code.
example:
if you code an if-condition

if (myCounter == 119) {
  doSomething();
}

the code "doSomething()"
is only executed if the value of variable with name "myCounter" has the value 119.

Otherwise the code doSomething is not executed.
Your example

does execute all the following up code which is

    byte buttonState = digitalRead(BUTTON_PIN);
    byte limitState = digitalRead(LIMIT_PIN);
    byte limitState2 = digitalRead(LIMIT_PIN2);
    if (buttonState != lastButtonState && limitState == lastLimitState && limitState2 == lastLimitState2) {
      lastTimeButtonStateChanged = millis();
      lastButtonState = buttonState;
      if (buttonState == HIGH) {
        servo.write(60);
      }
  // AND MORE BELOW

only if the if-condition

if (millis() - lastTimeButtonStateChanged > debounceDuration) {

is true

whenever this if-condition is not true all the code is simply
not executed.

best regards Stefan

So I have tried both a7's code and my code without the denouncing stuff and in both instances when I upload the program the motor starts moving clockwise. I have change the button multiple times and have eve tried using a vex button but it does that every time. It doesn't seem to detect the button for some reason. Both the limit switches work just fine so I'm not sure why the button won't I have check all my wiring so I don't think that is the issue. I'm not sure what I'm missing in my code.

#include <Servo.h>

Servo servo;

#define BUTTON_PIN 8
#define LIMIT_PIN 7
#define LIMIT_PIN2 6
byte lastButtonState = LOW;
byte lastLimitState = HIGH;
byte lastLimitState2=HIGH;


void setup() {
  servo.attach(9);
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LIMIT_PIN, INPUT_PULLUP);
  pinMode(LIMIT_PIN2, INPUT_PULLUP);

}
void loop() {
  
    byte buttonState = digitalRead(BUTTON_PIN);
    byte limitState = digitalRead(LIMIT_PIN);
    byte limitState2 = digitalRead(LIMIT_PIN2);
    if (buttonState != lastButtonState && limitState == lastLimitState && limitState2 == lastLimitState2) {
     
      lastButtonState = buttonState;
      if (buttonState == HIGH) {
        servo.write(60);
      }
    }

    if (buttonState == lastButtonState && limitState != lastLimitState && limitState2 == lastLimitState2) {
      
      lastLimitState = limitState;
      if (limitState == LOW) {
        servo.write(120);
      }
    }

     if (buttonState == lastButtonState && limitState == lastLimitState && limitState2 != lastLimitState2) {
  
      lastLimitState2 = limitState2;
      if (limitState2 == LOW) {
        servo.write(60);
        delay(500);
        servo.write(180);
      }
    }
  }

How is this button wired to the Arduino board?

Do you have a pull up (or pull down) resistor in place?

Are you using the correct sense pressed == HIGH (or LOW) for the way the switch is wired and the logic that uses the value that gets digitakRead()?

Have you bothered to try a small sketch that does nothing but test that button for plausible operation?

a7

I have wired the button in what I believe is pull down. I am using a 10k ohm resistor which is wired to the ground pin on the button. When I tested it in the past it gave a low signal when untouched and a high when pressed. I have been wiring it the same way since I start this project.

Dear mathew

what is so hard about reading this tutorial??

Is your button wired this way?

or this way?

or this way?

Each of this way works
with a different code

have you ever analysed one of the WOKWI simulations how the switches were connected in the WOKWI simulations?

What is so hard about looking at the limit-switched how the limit switches are wired and how the code for the limit switches looks like?????

whar differencies do you see between the wiring in the WOKWI-Simulation and your wiring?

what differencies do you see between the button-code in the WOKWI-simulation and your code?

Make a hand drawn schematic how the limit switch is wired
Make a hand drawn schematic how your button is wired

What do you think? How many additional posts do you need until you start carefully analysing and carefully comparing?

Both of my limit switches are wired without any resistors. I use INPUT_PULLUP in my code. The button is wired in a pull down method. I use a 10k ohm resistor and it is wired to ground. I'm not sure how the wiring could be the issues because these have both worked separately before so why wouldn't they work together. Do I need to not use any resistors at all and change the coding of the button. Would using INPUT_PULLUP on the button fix the issue?

Limit Switch wiring

Button wiring

write a small testcode that does nothing more than printing the result of digitalRead() or your button to the serial monitor

We are at post 166. How many additionaly posts do you need to understand that posting a working code does not happen??

Here is

exactly

your code-logic
I just added what each and every arduino-coder does:

I added serial output that makes visible what your code is doing.

How many additional postings do you need to understand that printing to the serial monitor is the best analysing tool that you have??

upload this code-version and open the serial monitor
adjust baudrate to 115200 and then watch and read what gets printed to the serial monitor
Then you will exactly see what your code is doing and why it does not work as you intended.

#include <Servo.h>

Servo servo;

#define BUTTON_PIN 8
#define LIMIT_PIN 7
#define LIMIT_PIN2 6
byte lastButtonState = LOW;
byte lastLimitState = HIGH;
byte lastLimitState2 = HIGH;


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
  servo.attach(9);
  pinMode(BUTTON_PIN, INPUT);
  pinMode(LIMIT_PIN, INPUT_PULLUP);
  pinMode(LIMIT_PIN2, INPUT_PULLUP);
  Serial.println("exiting Setup");
}

void loop() {

  byte buttonState = digitalRead(BUTTON_PIN);
  byte limitState = digitalRead(LIMIT_PIN);
  byte limitState2 = digitalRead(LIMIT_PIN2);
  // if-condition1
  if (buttonState != lastButtonState && limitState == lastLimitState && limitState2 == lastLimitState2) {
    Serial.println("1 if-condition1 is true");

    lastButtonState = buttonState;
    if (buttonState == HIGH) {
      Serial.println("servo.write(60);");
      servo.write(60);
    }
  }

  // if-condition2
  if (buttonState == lastButtonState && limitState != lastLimitState && limitState2 == lastLimitState2) {
    Serial.println("22 if-condition2 is true");

    lastLimitState = limitState;
    if (limitState == LOW) {
      Serial.println("servo.write(120);");
      servo.write(120);
    }
  }

  // if-condition3
  if (buttonState == lastButtonState && limitState == lastLimitState && limitState2 != lastLimitState2) {
    Serial.println("333 if-condition3 is true");

    lastLimitState2 = limitState2;
    if (limitState2 == LOW) {
      Serial.println("servo.write(60);");
      servo.write(60);
      delay(500);
      Serial.println("servo.write(180);");
      servo.write(180);
    }
  }
}

So I think the issue was actually the Arduino pin. When I ran the test code with the button plugged into pin 8 the serial monitor showed it output a constant high signal. When I put it into pin 7 it gave me a low signal when unpressed and a high signal when pressed. I'll now try it in my main program

What can you conclude from this line of code?

Without posting how you wired the button. This sentence is useless.
Without posting your testcode. This sentence is useless.

My system now works. I guess the issue was just that pin. Here is the test code I used.

#define BUTTON_PIN 8

void setup() {
 Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT);


}

void loop() {
  // put your main code here, to run repeatedly:
if (digitalRead(BUTTON_PIN) == LOW){
  Serial.println("low");
}

if (digitalRead(BUTTON_PIN)==HIGH){
  Serial.println("high");

}
}

My next issue is making the button wireless. To do this I think I need to use a transmitter and receiver. I've done a bit of research and I found that there are two different types. 315 hz and 433hz. I think I'll use 433 since it is stronger and the button will be outside the vending machine and the rest will be inside. I'm not sure which one to get however. I watched a video and they used cheaper pair. I looked in the comments of that video and they recommended to use a Superheterodyne Receiver since it is more reliable. However in that video he imported some code using a website called radio head and said it was important part of making it work. I'm not sure what transmitter and receiver to buy or if they will work with this radio head website. Do I even need to use that website.

video I watched

possible transmitter and receiver
option 1
option 2 (not alot of review on this so I'm not sure if I want to go with this)

Post the code you are happy with that now works.

Is the RF thing really the only next step? I ask because you are wading towards deeper waters… I suggest you work on something else and…

Please do not just try to add new functions or hardware or modules until you have played with them in simple circumstances, like coming to a full understanding of example code you had no part in writing.

I wish you the best of success.

a7