Servos dancing without me hitting a button

I am very new and this is my first project outside silly exercises and the intro kit book, so take it easy on me.

I am trying to make 4 servos dance when (and only when) I hit 1 on my 16 key touchpad (as a precursor to using these elements to turn my garden hoses on and off... baby steps here). They are supposed to dance once each, then stop until a button is pushed again.

However, when I upload the code below, the servos dance without any buttons being pushed. Furthermore, they continue dancing in sequence on a loop despite my loop ending with converting my variable lastPush to a non-1 number. I cannot determine what I am doing wrong. I barely understand libraries yet, and I am using 2 of them, so I suspect the issue lies there somehow. I am sure there are a number of other unnecessary or incorrect things I am doing as a result, so if you see something, feel free to mention it.

Thank you for any help you can give. I am really enjoying this hobby so far.

#include <Keypad.h>
//four rows
const byte ROWS = 4;
//four columns
const byte COLS = 4;
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
//connect to the row pinouts of the keypad
byte rowPins[ROWS] = {13, 12, 9, 8};
//connect to the column pinouts of the keypad
byte colPins[COLS] = {7, 4, 3, 2};
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

#include <Servo.h>
Servo servoA;
Servo servoB;
Servo servoC;
Servo servoD;

int angleA = 0; // the angle of the servo A
int angleB = 0;// the angle of the servo B
int angleC = 0; // the angle of the servo C
int angleD = 0; // the angle of the servo D
char lastPush = 17; // the last button pushed. I am using 17 as the parking spot for no button pushed

void setup(){
Serial.begin(9600); // these lines set up the serial readout on the computer
servoA.attach(11);
servoB.attach(10);
servoC.attach(6);
servoD.attach(5);

} 
void loop(){
char customKey = customKeypad.getKey();
if (customKey){Serial.println(customKey);} // show button presses in serial readout
if (customKey){lastPush = (customKey);} // establish the last button pushed semi-permanently
if (customKey){Serial.println(lastPush);} // show lastPush in serial

if (lastPush = 1)
{servoA.write(90);
delay(250);
servoA.write(45);
delay(250);
servoA.write(135);
delay(250);
servoA.write(0);
delay(1000);

servoB.write(90);
delay(250);
servoB.write(45);
delay(250);
servoB.write(135);
delay(250);
servoB.write(0);
delay(1000);

servoC.write(90);
delay(250);
servoC.write(45);
delay(250);
servoC.write(135);
delay(250);
servoC.write(0);
delay(1000);

servoD.write(90);
delay(250);
servoD.write(45);
delay(250);
servoD.write(135);
delay(250);
servoD.write(0);

lastPush = 17;
Serial.println(lastPush);}
}

Twitching servos is usually due to an inadequate power supply, like trying to use the 5V Arduino output.

Since that can actually damage the Arduino, use a separate power supply, 5 to 6V, 1 Ampere per small (e.g. SG-90) servo. A 4xAA battery pack can power two small servos. Don't forget to connect all the grounds.

should be ==

good luck.. ~q

I really appreciate this reply. I WAS using the 5v from the Arduino to power the servos, and I will fix that using the diagram you supplied.

To be clear, though, my original issue was that they are doing the PROGRAMMED DANCE without me hitting a button (upon booting up), and continuing to do it for more than one loop

progress, thank you! with the "==", it now doesn't automatically do the dance when I turn it on, however, now it won't do the dance at all even if I push "1." I can tell from the serial monitor that I am hitting 1, and that is changing my int lastPush to 1, so why isn't that triggering the servo program?

my guess, the keypad returns the ascii value for the character 1, which is decimal 49..
or wrap your 1 in '1'.. :slight_smile:

~q

I've been wondering why it was adding +48 to all my button presses! That's why I switched from lastPush being an int to being a char (also because the 16 button pad has *, #, A, B, C, and D). Should I switch back to int, embrace the ascii, and go with "if lastPush == 49"?

lol, that worked. I hate it, because I don't think in ASCII, but it worked :slight_smile:

yes or check for the character by using single quotes if (lastPush == '1')
~q

1 Like

qubits, you rule, and this forum rules. I had just been saying that everything on the internet is terrible, but I didn't know about this little pocket of excellence.

2 Likes

I changed it back to a char and went with your suggested: if (lastPush == "1") and now nothing happens even if I push 1. the ascii workaround worked though!

double quotes means a string, single quotes is single char..
should be '1'
~q

You do now, because that is a good thing.

I'll get there :nerd_face:

1 Like

That did the trick, thanks again!

1 Like

OK, one last question(updated code below). Why am I not getting a "17" printed to serial once the dance is over, due to my command Serial.println(lastPush);?

instead I am just getting an empty line in the serial readout.

#include <Keypad.h>
//four rows
const byte ROWS = 4;
//four columns
const byte COLS = 4;
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
//connect to the row pinouts of the keypad
byte rowPins[ROWS] = {13, 12, 9, 8};
//connect to the column pinouts of the keypad
byte colPins[COLS] = {7, 4, 3, 2};
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

#include <Servo.h>
Servo servoA;
Servo servoB;
Servo servoC;
Servo servoD;

int angleA = 0; // the angle of the servo A
int angleB = 0;// the angle of the servo B
int angleC = 0; // the angle of the servo C
int angleD = 0; // the angle of the servo D
char lastPush = 17; // the last button pushed. I am using 17 as the parking spot for no button pushed

void setup(){
Serial.begin(9600); // these lines set up the serial readout on the computer
servoA.attach(11);
servoB.attach(10);
servoC.attach(6);
servoD.attach(5);

} 
void loop(){
char customKey = customKeypad.getKey();
if (customKey){Serial.println(customKey);} // show button presses in serial readout
if (customKey){lastPush = (customKey);} // establish the last button pushed semi-permanently
if (customKey){Serial.println(lastPush);} // show lastPush in serial

if (lastPush == '1')
{servoA.write(90);
delay(250);
servoA.write(45);
delay(250);
servoA.write(135);
delay(250);
servoA.write(0);
delay(1000);

servoB.write(90);
delay(250);
servoB.write(45);
delay(250);
servoB.write(135);
delay(250);
servoB.write(0);
delay(1000);

servoC.write(90);
delay(250);
servoC.write(45);
delay(250);
servoC.write(135);
delay(250);
servoC.write(0);
delay(1000);

servoD.write(90);
delay(250);
servoD.write(45);
delay(250);
servoD.write(135);
delay(250);
servoD.write(0);
delay(1000);

lastPush = 17;
Serial.println(lastPush);}
}

[EDIT] DISREGARD... I got it wrong.

This conditional statement... [quote="potzertommy82, post:16, topic:1386313"] `if (lastPush == '1')` [/quote]

... leads to this...

So the ASCII equivalent of "17" decimal is "XON"

DEC OCT HEX BIN        SYMB HTML        DESCRIPTION
17	021	11	00010001	DC1	&#17;	 	Device Control One (XON)

sorry went to bed before i saw this..
ascii 17 is a non printable char..
if you want to see the 17 try Serial.println(lastPush, DEC);
This will print the decimal value for the character stored in lastPush..

~q

Interesting...short nap I guess? The forum shows your post #18 as having been posted 15m ago for me.

lol, i was replying to post #16, 9hr old..
slept for about 6hr, if im lucky..
~q