Pan multi cameras with LCD push buttons

Hello guys

I’m posting a simple demo sketch of the cheap lcd 16/2 display shield with push buttons, that I want to use with a Mega2650 for my project.

What I want to do is move 4 pan servos “don’t need tilt” that are attached to my house cameras.
I want to move each camera’s servo using only the lcd buttons on the shield if that’s possible.

The buttons are “select”, “left”, “up”, “down” and “right”, or when Serial.print respectively they are 724, 482, 308, 131, 0 When pressed.

My thought was to use the “select button” and “Switch Case”.
Create renewing counter that represented each “Case” in the “Switch” the Camera Servo .
From there I would write an “if statement” inside each case statement for manual push button servo movement using left and right button.

I know I can write a counter that repeats based on the Select button Push but I can’t for the life of me figure out how to relate the counter numbers output to the “Switch case”.

So I’m sure by now your aware I’m still a beginner or I would already know this answer.

Just looking for some suggestions, examples or it just can’t be done newbie, no wonder you can’t figure it out!
Thanks in advance.

/*

  Mark Bramwell, July 2010

  This program will test the LCD panel and the buttons.When you push the button on the shield,
  the screen will show the corresponding one.
 
  Connection: Plug the LCD Keypad to the UNO(or other controllers)

*/
#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);           // select the pins used on the LCD panel

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;

#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

int read_LCD_buttons(){               // read the buttons
    adc_key_in = analogRead(0);       // read the value from the sensor 

    // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
    // we add approx 50 to those values and check to see if we are close
    // We make this the 1st option for speed reasons since it will be the most likely result

    if (adc_key_in > 1000) return btnNONE; 

    // For V1.1 us this threshold
    if (adc_key_in < 50)   return btnRIGHT;  
    if (adc_key_in < 250)  return btnUP; 
    if (adc_key_in < 450)  return btnDOWN; 
    if (adc_key_in < 650)  return btnLEFT; 
    if (adc_key_in < 850)  return btnSELECT;  


    return btnNONE;                // when all others fail, return this.
}

void setup(){
   lcd.begin(16, 2);               // start the library
   lcd.setCursor(0,0);             // set the LCD cursor   position 
   lcd.print("Push the buttons");  // print a simple message on the LCD
   Serial.begin (9600);
}
 
void loop(){
   lcd.setCursor(9,1);             // move cursor to second line "1" and 9 spaces over
   lcd.print(millis()/1000);       // display seconds elapsed since power-up

   lcd.setCursor(0,1);             // move to the begining of the second line
   lcd_key = read_LCD_buttons();   // read the buttons

   switch (lcd_key){               // depending on which button was pushed, we perform an action

       case btnRIGHT:{             //  push button "RIGHT" and show the word on the screen
            lcd.print("RIGHT ");
            break;
       }
       case btnLEFT:{
             lcd.print("LEFT   "); //  push button "LEFT" and show the word on the screen
             break;
       }    
       case btnUP:{
             lcd.print("UP    ");  //  push button "UP" and show the word on the screen
             break;
       }
       case btnDOWN:{
             lcd.print("DOWN  ");  //  push button "DOWN" and show the word on the screen
             break;
       }
       case btnSELECT:{
             lcd.print("SELECT");  //  push button "SELECT" and show the word on the screen
             break;
       }
       case btnNONE:{
             lcd.print("NONE  ");  //  No action  will show "None" on the screen
             break;
       }
   }
}

LCD_With_Pushbuttons_test.ino (3.3 KB)

The buttons are "select", "left", "up", "down" and "right", or when Serial.print respectively they are 724, 482, 308, 131, 0 When pressed.

You could use the up and down buttons to change the index into the servo array, incrementing or decrementing the index, depending on which button is pressed.

You could use the left and right buttons then to increase and decrease the servo position.

Hello Paul
Thank you for responding.
Let me show you what I have so far so maybe you can point me to the error of my ways.
I know it’s easier help when you can see what I’m trying to accomplish.

I’m certain someone with better coding skills could simplify and clean up my mess, however it is working up to the point of panning the servo left or right.
I’m able to select the “case:” but I have not figured out what I’m doing wrong with the panning the servo.
I’m trying to convert the analogRead value of left-483 button and right-0 button to move the servos.
So far the servo just stay’s centered.
Any suggestions on converting the button press into a usable variable?

/* Used example by Mark Bramwell for lcd and buttons that I can atribute some code to.
This is to control 5 servos attached to my home cameras using only the push buttons
mounted on the lcd display shield. For my project this is only “Pan” but tilt could be added easy.
Buttons when read centered/pressed are these values for me: 31/0, 144/131, 329/308, 504/482, 850/741.
your values for buttons will be diffrent im sure.
*/
#include <LiquidCrystal.h>
#include <Servo.h>

LiquidCrystal lcd(28, 29, 24, 25, 26, 27);
Servo myservo1; // create servo object to control a servo
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;
Servo myservo6;
int pos1 = 85; // variable to store the servo’s starting position
int pos2 = 85; // more servo’s can be added
int pos3 = 85;
int pos4 = 85;
int pos5 = 85;
int pos6 = 85;
int leftPressed = 50; // variables used to keep left/right button states
int rightPressed = 51;
const int outputPin2 = 44; // tells the Arduino the location of the signal cable to the servo
const int outputPin3 = 45;
const int outputPin4 = 46;
const int outputPin5 = 5; // tells the Arduino the location of the signal cable to the servo
const int outputPin6 = 6;
const int outputPin7 = 7;
const int maxDeg = 175; // limits the maximum range of the servo’s movement to 175
const int minDeg = 5; // limits the minimum range of the servo’s movement to 5
const int movement = 2; // distance to move servo

const int buttonPin = A0; // the pin that all the pushbuttons are attached to, the diffrence between them are the values
int buttonPushCounter = 0; // stored number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button

void setup() {
lcd.begin(16, 2); // start the library
lcd.setCursor(0, 0); // set the LCD cursor position
lcd.print(“Camera,Pan”);
pinMode(buttonPin, INPUT);
myservo1.attach(outputPin2); // attaches the servo’s output location
myservo2.attach(outputPin3);
myservo3.attach(outputPin4);
myservo4.attach(outputPin5);
myservo5.attach(outputPin6);
myservo6.attach(outputPin7);
Serial.begin(9600);
}

void loop() {
const int buttonval = analogRead(buttonPin); // read the pushbutton input pin:
if (buttonval == 724) {
(buttonState = HIGH);
}
else {
(buttonState = LOW);
}
const int leftpin = analogRead(buttonPin);
const int rightpin = analogRead(buttonPin);

if (leftpin == 482) {
(leftPressed );
}
// else {
// (leftPressed = LOW);
//}
if (rightpin == 0) {
(rightPressed = HIGH);
}
else {
(rightPressed = LOW);
}

if (lastButtonState != buttonState) {
if (buttonState == HIGH) {
delay(100);
Serial.println(“OFF”);
}
else {
delay(50);
Serial.println(“ON”);
buttonPushCounter++;
delay(50);
Serial.print(buttonPushCounter);
Serial.println(" times");
}
}
lastButtonState = buttonState;
if (buttonPushCounter == 1 && buttonPushCounter != 0) {
delay (10);
}
if (buttonPushCounter > 1 && buttonPushCounter < 5) {
delay (10);
}
if (buttonPushCounter >= 5 && buttonPushCounter < 6) {
delay (10);
}
if (buttonPushCounter > 5) { //sixth button press, the counter is reset to 0
buttonPushCounter = 0;
}
switch (buttonPushCounter) {
case 1:
if (leftPressed ) {
if (pos1 < maxDeg)
pos1 += movement;
myservo1.write(pos1);
}
if (rightPressed ) {
if (pos1 > minDeg)
pos1 -= movement;
myservo1.write(pos1);
}
break;
case 2:
delay (100);
break;
case 3:
delay (100);
break;
case 4:
delay (100);
break;
case 5:
delay (100);
break;
}
}

New_camera_servo_W_LCD.ino (3.75 KB)

Servo myservo1;  // create servo object to control a servo
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;
Servo myservo6;

An array of Servo objects would certainly be useful.

int pos1 = 85;    // variable to store the servo's starting position
int pos2 = 85;    // more servo's can be added
int pos3 = 85;
int pos4 = 85;
int pos5 = 85;
int pos6 = 85;

An array of servo positions would certainly be useful.

const int outputPin2 = 44; // tells the Arduino the location of the signal cable to the servo
const int outputPin3 = 45;
const int outputPin4 = 46;
const int outputPin5 = 5; // tells the Arduino the location of the signal cable to the servo
const int outputPin6 = 6;
const int outputPin7 = 7;

An array of pin numbers would certainly be useful.

But, if you are not going to use arrays, USE THE SAME DAMNED NUMBERING SCHEME FOR ALL THREE SETS!

 if (buttonPushCounter == 1 && buttonPushCounter != 0) {

If it equals 1, how the hell can it not be not equal to 0?

if (buttonPushCounter >= 5 && buttonPushCounter < 6) {

Just how many values are there that are greater than or equal to 5 and less than 6?

Just why are you delaying based on the number of times a switch was pressed?

Just why does the number of times a switch was pressed have ANY bearing on which servo to move or how far to move it?

Use an array of Servo objects, and array of servo positions, and an array of servo pins (with a MUCH better name that your set of pin numbers). Create a servoNumber variable that you increment or decrement when one of the two appropriate switches is pressed.

When one of the other two appropriate switches is pressed, increment or decrement the value in servoPos[servoNumber] and write that value to Servo[servoNumber].

Hello Paul

Again Thanks for responding

I CLEARLY need to find and attend a class to understand coding much better than I do.

Attached is my current sketch which actually works just like I wanted with the exception of the last case. It display’s “No Cam6” instead of “No Cam”. I don’t understand why it leaves the number 6.
I took to heart everything you suggested.
The Array is a great answer and know it would be much better but I’m not comfortable as yet in writing one. Many frustration for me so far. Maybe after I find some more advanced lessons that will be a better option for me.
I actually began this sketch with a copy of Mark Bramwell’s sketch that simply counted up and I didn’t clean it up to just what I needed.
I cleaned up the pin scheme but what I presented before was me playing with different arrangements of pins and not cleaned up.

Just how many values are there that are greater than or equal to 5 and less than 6?
Correct! previous sketch cleaned up.
Just why are you delaying based on the number of times a switch was pressed?
Correct! previous sketch cleaned up.
Just why does the number of times a switch was pressed have ANY bearing on which servo to move or how far to move it?

If you look at my current sketch you can see in “my minds” method for using a single input (A0) for all 5 button outputs.
The counter for select sets which case is being addressed. The left and right counters increment the servo by one degree at a time, remembers that position and the delays help slow the servo action so there is minimal jerking movement or debounce.
The lcd is showing which camera is addressed and the degrees of movement.

Someone like yourself could have written this simpler, cleaner and certainly in much less time and frustration.
So I will go sit down, learn how to write an array that works and clean this up even more.
Thank you sincerely for your help and guidance.
Rodney

New_camera_servo_W_LCD.ino (9.44 KB)