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-
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')[-
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')[-
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')[-
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')[-
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')[-
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')[-
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')[-
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')[-
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')[-
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')[-
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-
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.