Julian Rogers Home Pi cam pan tilt 2 PIi cam with pan and tilt 4

Under Construction

Pi cam software 1

The idea here is that a Python Tkinter script runs on the Pi which involves nine buttons laid out on a 3x3 grid. Pushing a button moves the camera into the corresponding position, up/down (high, centre low) left/right (left, centre, right). The Pi communicates with the Feather by means of GPIO pins. With four pins, 16 different possibilities can be communicated (eg. 1 repesents top right, 9, bottom right etc.) I have used an additional pin to enable the buttons which control the pan and tilt.

On the Feather, the inputs from the Pi are converted into a number and a switch/case control structure selects appropriate values to feed into the servos via the servo library. If the enable input from the Pi is valid, the Feather switches on power to the servos.

There are other ways for the Pi to communicate with the Feather, for example, by serial, however, the GPIO pin method is straightforward, the pins are not needed for anything else. Also I intend to use serial to send data from a number of sensors which will be connected later to the Feather by I2C.

// 16.4.19

// servo control

#include <Servo.h>

Servo pan;

Servo tilt;


const int lpan = 65;

const int cpan = 95;

const int rpan = 115;

const int utilt = 80;

const int ctilt = 65;

const int dtilt = 35;

bool pt = false;    // pan-tilt valid

int num;


void setup() {  

  pan.attach(9);

  tilt.attach(5);

  

  pinMode(13, INPUT);   // represents 8

  pinMode(12, INPUT);   // represents 4

  pinMode(11, INPUT);   // represents 2

  pinMode(10, INPUT);   // represents 1

  pinMode(6, INPUT);    // enable

  pinMode(15, OUTPUT);      // A1 repurposed! Switches power to servos

  digitalWrite(15, HIGH);

  

  Serial.begin(9600);

  pan.write(cpan);

  tilt.write(ctilt);

  delay(1000);

}


void loop() {

  pt = digitalRead(6);

  if(pt == true){

    digitalWrite(15, HIGH);  // switch on servos

    num = digitalRead(13) * 8 + digitalRead(12) * 4 + digitalRead(11) * 2 + digitalRead(10);

    //Serial.println(num);  //check it's working as it should

    

    switch(num){

      case 1:

        tilt.write(utilt);

        pan.write(lpan);

        break;

      case 2:

        tilt.write(utilt);

        pan.write(cpan);

        break;

      case 3:

        tilt.write(utilt);

        pan.write(rpan);

        break;

      case 4:

        tilt.write(ctilt);

        pan.write(lpan);

        break;

      case 5:

        tilt.write(ctilt);

        pan.write(cpan);

        break;

      case 6:

        tilt.write(ctilt);

        pan.write(rpan);

        break;

      case 7:

        tilt.write(dtilt);

        pan.write(lpan);

        break;

      case 8:

        tilt.write(dtilt);

        pan.write(cpan);

        break;

      case 9:

        tilt.write(dtilt);

        pan.write(rpan);

        break;

     }

      

  }

  

  if(pt == false){

    digitalWrite(15, LOW); // cut power to servos

  }

  

}


Here is the Feather sketch:

# GUI to control RPI GPIO for servos on Feather

# 16.4.19

# by Julian Rogers

# servo_super4b


from tkinter import *   #GUI


import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setwarnings(False)


GPIO.setup(7, GPIO.OUT)     #to pin 5   enable

GPIO.setup(12, GPIO.OUT)    #to pin 13  represents 8

GPIO.setup(16, GPIO.OUT)    #to pin 12  represents 4

GPIO.setup(20, GPIO.OUT)    #to pin 11  represents 2

GPIO.setup(21, GPIO.OUT)    #to pin 10  represents 1

GPIO.output(21, False)

GPIO.output(20, False)

GPIO.output(16, False)

GPIO.output(12, False)

GPIO.output(7, False)


import datetime

import time


# create the root window

root = Tk()


# modify the window

root.title("***")

root.geometry("200x170")

root.configure(bg = "gray")


# create a frame

app = Frame(root)

app.configure(bg = "gray")

app.grid()


title_lab = Label(app, text = " Camera pan/tilt", font = ("Arial Bold", 16), fg = "maroon", bg = "gray")

title_lab.grid(row = 1, column = 1, columnspan = 8)


blank_lab = Label(app, bg = "gray")

blank_lab.grid(row = 2, column = 1, sticky = "w")


def all_off():

    GPIO.output(21, False)

    GPIO.output(20, False)

    GPIO.output(16, False)

    GPIO.output(12, False)

    #GPIO.output(7, False)


def release():

    all_off()

    sys_1_but.config(bg = "light blue")

    sys_2_but.config(bg = "light blue")

    sys_3_but.config(bg = "light blue")

    sys_4_but.config(bg = "light blue")

    sys_5_but.config(bg = "light blue")

    sys_6_but.config(bg = "light blue")

    sys_7_but.config(bg = "light blue")

    sys_8_but.config(bg = "light blue")

    sys_9_but.config(bg = "light blue")


    sys_1_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_1_but.grid(row = 3, column = 1, sticky = "w")


def on_off_1():

    but_col = sys_1_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(21, True)

    else:

        but_col = "light blue"

        GPIO.output(21, False)


    sys_1_but.config(bg = but_col)


sys_1_but.config(command = on_off_1)



sys_2_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_2_but.grid(row = 3, column = 2, sticky = "w")


def on_off_2():

    but_col = sys_2_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(20, True)

    else:

        but_col = "light blue"

        GPIO.output(20, False)


    sys_2_but.config(bg = but_col)


sys_2_but.config(command = on_off_2)


sys_3_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_3_but.grid(row = 3, column = 3, sticky = "w")


def on_off_3():

    but_col = sys_3_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(20, True)

        GPIO.output(21, True)

    else:

        but_col = "light blue"

        GPIO.output(20, False)

        GPIO.output(21, False)


    sys_3_but.config(bg = but_col)


sys_3_but.config(command = on_off_3)


sys_4_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_4_but.grid(row = 4, column = 1, sticky = "w")


def on_off_4():

    but_col = sys_4_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(16, True)

    else:

        but_col = "light blue"

        GPIO.output(16, False)


    sys_4_but.config(bg = but_col)


sys_4_but.config(command = on_off_4)


sys_5_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_5_but.grid(row = 4, column = 2, sticky = "w")


def on_off_5():

    but_col = sys_5_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(21, True)

        GPIO.output(16, True)

    else:

        but_col = "light blue"

        GPIO.output(21, False)

        GPIO.output(16, False)


    sys_5_but.config(bg = but_col)



sys_5_but.config(command = on_off_5)


sys_6_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_6_but.grid(row = 4, column = 3, sticky = "w")


def on_off_6():

    but_col = sys_6_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(20, True)

        GPIO.output(16, True)

    else:

        but_col = "light blue"

        GPIO.output(20, False)

        GPIO.output(16, False)


    sys_6_but.config(bg = but_col)


sys_6_but.config(command = on_off_6)


sys_7_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_7_but.grid(row = 5, column = 1, sticky = "w")


def on_off_7():

    but_col = sys_7_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(16, True)

        GPIO.output(20, True)

        GPIO.output(21, True)

        

    else:

        but_col = "light blue"

        GPIO.output(21, False)

        GPIO.output(20, False)

        GPIO.output(16, False)


    sys_7_but.config(bg = but_col)


sys_7_but.config(command = on_off_7)


sys_8_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_8_but.grid(row = 5, column = 2, sticky = "w")


def on_off_8():

    but_col = sys_8_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(12, True)

    else:

        but_col = "light blue"

        GPIO.output(12, False)


    sys_8_but.config(bg = but_col)


sys_8_but.config(command = on_off_8)


sys_9_but = Button(app, text = "X", font = ("Arial", 16), fg = "light blue", bg = "light blue")

sys_9_but.grid(row = 5, column = 3, sticky = "w")


def on_off_9():

    but_col = sys_9_but.config('bg')[-1]

    release()

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(21, True)

        GPIO.output(12, True)

    else:

        but_col = "light blue"

        GPIO.output(21, False)

        GPIO.output(12, False)


    sys_9_but.config(bg = but_col)


sys_9_but.config(command = on_off_9)


space_lab = Label(app, text = "X", font = ("Arial", 5), fg = "gray", bg = "gray")

space_lab.grid(row = 4, column = 4)


enable_but = Button(app, text = "En", font = ("Arial", 16), fg = "maroon", bg = "light blue")

enable_but.grid(row = 4, column = 5)


def on_off_en():

    release()

    but_col = enable_but.config('bg')[-1]

    

    if but_col == "light blue":

        but_col = "yellow"

        GPIO.output(7, True)

    else:

        but_col = "light blue"

        GPIO.output(7, False)


    enable_but.config(bg = but_col)


enable_but.config(command = on_off_en)


# calls a function after given time

def after(self, ms, func = None, *args):

    """call function after a given time"""


# updates screen every 10 seconds

def task():

    all_off()

    root.after(10000, task)


# calls the screen update every 10 seconds

root.after(10000, task)


#---------------------------------------------------------------------------------------

# kick off the window's event-loop

root.mainloop()






This is the Pi program:

The programs for the Feather and Pi follow. The next page includes details of how to view the camera images and a few screen shots.