Hi everyone,
I am very new to this forum, and this is my first post. I've recently begun a very unique project, so bear with me. I have two pushbuttons and I will attach one to each of the soles of my shoes. I want these buttons to trigger movement on a servo motor that is near my video game controller. What I want to happen is when I am walking, only one button will be pressed, triggering the servo to push a button, moving my in-game character. When I am stopped, both buttons will be pressed, which will trigger the servo to release the button. Simple enough, but there is a complication. When you walk, there is an instance when both feet are touching the ground, which would stop my character, and that's not what I want. I've tried to work around it, but I can't figure it out. What happens is when both buttons are pressed, it will wait a little while, and then move the servo backward with no way to trigger it again. Thanks for the help in advance!
const int leftButtonPin = 2; //buttons
const int rightButtonPin = 3;
const int servoLeft = 5; //servo
const int servoRight = 5;
int left = 0; //variables for reading the states of the buttons
int right = 0;
int Step = true; //should the servo move if a button is pressed? (true if yes)
int leftStep = true; //varibles for left and right buttons
int rightStep = true;
int stopped = false; //varible for if I am stopped
int conjoinedState = false; //variables for reading current and previous states of both buttons
int conjoinedStateLast = false;
#include <Servo.h> //includes the servo libraries
Servo myservo; //names the servo
int pos = 0; //servo position (0 to 180 degrees)
void setup() {
myservo.attach(5); //pin 5 is the servo pin
pinMode(leftButtonPin, INPUT); //buttons are inputs
pinMode(rightButtonPin, INPUT);
pinMode(servoLeft, OUTPUT); //servo is output
pinMode(servoRight, OUTPUT);
Serial.begin(9600); //starts the serial monitor
}
void loop(){
left = digitalRead(leftButtonPin); //determines the states of the buttons
right = digitalRead(rightButtonPin);
if (left == right) {
if (right == HIGH) { //if both buttons are pressed
conjoinedState = true; //both buttons are pressed
} else { //if not
conjoinedState = false; //both buttons are not pressed
}
} else { //if only one button is pressed
conjoinedState = false; //the buttons are not both pressed
}
if (right != left) { // if one button is pressed
if (right == HIGH) { //if right button is pressed
if (Step == true) { //if the servo should move
if (rightStep == true) { //if I am stepping with my right foot
myservo.write(120); //servo goes to 120 degrees
delay(30); //wait 15ms
Serial.print("Right: "); //print the varible on the serial monitor
Serial.println(right);
rightStep = false; // I am not stepping with my right foot
leftStep = true; // I am stepping with my left foot
Step = false; //servo should no longer move
}
}
}
if(left == HIGH) { //same thing as above, just left foot instead
if (Step == true) {
if (leftStep == true) {
myservo.write(120);
delay(30);
Serial.print("Left: ");
Serial.println(left);
rightStep = true;
leftStep = false;
Step = false;
}
}
}
if (left != right and stopped == true) { // if only one button is pressed and I am stopped
Step = true; //servo should move for a step
stopped = false; //I am not stopped
rightStep = true; //resets both feet
leftStep = true;
delay(30);
}
} else { //if both buttons are the same state
delay(500); //wait
if (conjoinedState == true) { //if still both pressed
delay(500); //wait some more
if (conjoinedState == true) { // if still both pressed
myservo.write(100); //servo goes to 100 degrees
delay(15);
Serial.print("Right: "); //prints variables
Serial.println(right);
Serial.print("Left :");
Serial.println(left);
int stopped = true; //I am stopped
}
}
}
}
After you check the states of the buttons I think you need to check for both being pressed first before you deal with individual presses. And when you first detect both being pressed you should start a millis() timer so you can ignore the fact that both are pressed unless they stay pressed for a minimum time.
I suspect the logic of the system would be easier to think about if you focus on buttons being released when a foot is lifted rather than being pressed when a foot is put down. Pressed is the normal state. released is the unusual state.
Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Robin2:
After you check the states of the buttons I think you need to check for both being pressed first before you deal with individual presses. And when you first detect both being pressed you should start a millis() timer so you can ignore the fact that both are pressed unless they stay pressed for a minimum time.
I suspect the logic of the system would be easier to think about if you focus on buttons being released when a foot is lifted rather than being pressed when a foot is put down. Pressed is the normal state. released is the unusual state.
...R
Thanks for the help, but I am also rather new to arduino, could you explain how a millis() timer would work in my project?
Sshu03:
Thanks for the help, but I am also rather new to arduino, could you explain how a millis() timer would work in my project?
Assume you have a variable the keeps track of how many buttons are pressed. Then something like this pseudo code
if (numButtonsPressed == 2) {
if prevNumButtonsPressed < 2) { // the number pressed has just changed
twoButtonsStartTime = millis();
}
if (millis() - twoButtonsStartTime >= millisForOneStep) {
// two feet were on the ground longer than the period of a normal step
}
else {
// assume that a step is in progress - perhaps do nothing
}
}
prevNumButtonsPressed = numButtonsPressed;
Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Robin2:
Assume you have a variable the keeps track of how many buttons are pressed. Then something like this pseudo code
if (numButtonsPressed == 2) {
if prevNumButtonsPressed < 2) { // the number pressed has just changed
twoButtonsStartTime = millis();
}
if (millis() - twoButtonsStartTime >= millisForOneStep) {
// two feet were on the ground longer than the period of a normal step
}
else {
// assume that a step is in progress - perhaps do nothing
}
}
prevNumButtonsPressed = numButtonsPressed;
...R
THANK YOU! THIS WORKS! Here's the final code!
const int leftButtonPin = 2; //buttons
const int rightButtonPin = 3;
int buttonsPressed = 0;
int prevButtonsPressed = 0;
int twoButtonsStartTime = 0;
int millisForOneStep = 500;
int servoLeft = 5; //servo
int servoRight = 5;
int left = 0; //variables for reading button states
int right = 0;
#include <Servo.h>
Servo myservo;
int pos = 0;
void setup() {
myservo.attach(5);
pinMode(leftButtonPin, INPUT);
pinMode(rightButtonPin, INPUT);
pinMode(servoLeft, OUTPUT);
pinMode(servoRight, OUTPUT);
Serial.begin(9600);
}
void loop() {
Serial.print("Amount :");
Serial.print(buttonsPressed);
left = digitalRead(leftButtonPin);
right = digitalRead(rightButtonPin);
if (left == HIGH and right == HIGH) {
buttonsPressed = 2;
} else {
if (left == HIGH and right == LOW){
buttonsPressed = 1;
} else {
if (left == LOW and right == HIGH){
buttonsPressed = 1;
} else {
buttonsPressed = 0;
}
}
}
if (buttonsPressed== 2) {
if (prevButtonsPressed < 2) { // the number pressed has just changed
twoButtonsStartTime = millis();
}
if (millis() - twoButtonsStartTime >= millisForOneStep) {
myservo.write(100);
}
else {
myservo.write(120);
}
}
prevButtonsPressed = buttonsPressed;
}
I realized I, like always, REALLY over complicated this. I can't thank you all enough for the countless headaches you've saved me.