🎛️
Integrating Display and Controls
Learn how to combine everything - add a display to show status and a button to start/stop tracking!
State Management
Your tracking system needs to remember its current state - is it tracking or stopped? We use variables to track this!
Tracking State:
# State variables
tracking_active = False # Is tracking on or off?
face_detected = False # Is a face currently detected?
servo_angle = 90 # Current servo position
# States your system can be in:
# 1. Stopped - not tracking, waiting for button press
# 2. Tracking - actively following face
# 3. No Face - tracking active but no face detected
Button to Start/Stop Tracking
Add a button that toggles tracking on and off. When pressed, it changes the tracking state!
Button Control Code:
import RPi.GPIO as GPIO
import time
# Set up button
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Tracking state
tracking_active = False
last_button_state = GPIO.HIGH
def check_button():
"""Check if button was pressed (toggle tracking)"""
global tracking_active, last_button_state
current_state = GPIO.input(2)
# Detect button press (transition from HIGH to LOW)
if last_button_state == GPIO.HIGH and current_state == GPIO.LOW:
tracking_active = not tracking_active # Toggle state
print(f"Tracking: {'ON' if tracking_active else 'OFF'}")
time.sleep(0.3) # Debounce
last_button_state = current_state
return tracking_active
# Use in main loop
try:
while True:
is_tracking = check_button()
if is_tracking:
print("Tracking is active!")
# Do tracking here
else:
print("Tracking stopped - waiting...")
time.sleep(0.1)
except KeyboardInterrupt:
GPIO.cleanup()
Displaying Status on Screen
Use an LCD display to show the current status - is tracking on? Is a face detected? What's the servo angle?
Status Display Code:
from RPLCD.i2c import CharLCD
import time
# Initialize LCD
lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1,
cols=16, rows=2, dotsize=8)
def update_display(tracking_active, face_detected, servo_angle):
"""Update LCD with current status"""
lcd.clear()
# First line: Tracking status
if tracking_active:
status = "Tracking: ON"
else:
status = "Tracking: OFF"
lcd.write_string(status)
# Second line: Face and angle info
lcd.cursor_pos = (1, 0)
if face_detected:
lcd.write_string(f"Face: YES {int(servo_angle)}°")
else:
lcd.write_string("Face: NO")
# Use in main loop
try:
while True:
# Get current state
tracking = check_button()
face_found = detect_face() # Your face detection function
angle = get_servo_angle() # Your servo angle function
# Update display
update_display(tracking, face_found, angle)
time.sleep(0.5) # Update display every 0.5 seconds
except KeyboardInterrupt:
lcd.clear()
lcd.write_string("Stopped")
time.sleep(2)
lcd.clear()
Project: Full Control Interface
Let's combine everything - face detection, servo tracking, display, and button control!
Materials Needed:
- Raspberry Pi
- Raspberry Pi Camera Module
- Servo motor (for pan/tilt)
- 16x2 LCD Display (I2C)
- Push button
- Jumper wires
- Breadboard
Complete Integrated System Code:
import cv2
import RPi.GPIO as GPIO
from RPLCD.i2c import CharLCD
import time
# ===== SETUP =====
# Face detection
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# Servo motor
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
servo_pwm = GPIO.PWM(18, 50)
servo_pwm.start(0)
# Button
GPIO.setup(2, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# LCD Display
lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1,
cols=16, rows=2, dotsize=8)
# Camera
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
# ===== STATE VARIABLES =====
tracking_active = False
current_servo_angle = 90
last_button_state = GPIO.HIGH
last_display_update = 0
# ===== FUNCTIONS =====
def set_servo_angle(angle):
"""Move servo to angle"""
global current_servo_angle
duty = 2 + (angle / 180) * 10
servo_pwm.ChangeDutyCycle(duty)
time.sleep(0.1)
servo_pwm.ChangeDutyCycle(0)
current_servo_angle = angle
def check_button():
"""Check button and toggle tracking"""
global tracking_active, last_button_state
current_state = GPIO.input(2)
if last_button_state == GPIO.HIGH and current_state == GPIO.LOW:
tracking_active = not tracking_active
time.sleep(0.3) # Debounce
last_button_state = current_state
return tracking_active
def update_display(tracking, face_detected, angle):
"""Update LCD display"""
lcd.clear()
# Line 1: Status
if tracking:
lcd.write_string("Tracking: ON")
else:
lcd.write_string("Tracking: OFF")
# Line 2: Face info
lcd.cursor_pos = (1, 0)
if face_detected:
lcd.write_string(f"Face:YES {int(angle)}°")
else:
lcd.write_string("Face: NO")
def calculate_servo_angle(face_x, frame_width):
"""Convert face X to servo angle"""
angle = (face_x / frame_width) * 180
return max(0, min(180, angle))
# ===== MAIN LOOP =====
print("System started! Press button to toggle tracking.")
lcd.write_string("Press button")
time.sleep(2)
try:
while True:
# Check button
is_tracking = check_button()
if is_tracking:
# Read camera frame
ret, frame = cap.read()
if ret:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
if len(faces) > 0:
# Face detected - track it
x, y, w, h = faces[0]
face_center_x = x + w // 2
# Calculate target angle
target_angle = calculate_servo_angle(face_center_x, 320)
# Smooth movement
angle_diff = target_angle - current_servo_angle
if abs(angle_diff) > 2:
step = 5 if angle_diff > 0 else -5
new_angle = current_servo_angle + step
new_angle = max(0, min(180, new_angle))
set_servo_angle(new_angle)
# Update display
update_display(True, True, current_servo_angle)
else:
# No face detected
update_display(True, False, current_servo_angle)
else:
# Tracking stopped
update_display(False, False, current_servo_angle)
time.sleep(0.1)
except KeyboardInterrupt:
cap.release()
servo_pwm.stop()
lcd.clear()
lcd.write_string("Stopped")
time.sleep(2)
lcd.clear()
GPIO.cleanup()
print("System stopped!")
Understanding the Complete System:
- Button Control: Press button to start/stop tracking
- Face Detection: Continuously detects faces when tracking is active
- Servo Tracking: Moves servo to follow detected face
- Status Display: Shows tracking status, face detection, and servo angle
- State Management: System remembers if tracking is on/off
Summary
You've learned:
- ✅ State management tracks system status (tracking on/off)
- ✅ Button can toggle tracking on and off
- ✅ LCD display shows current system status
- ✅ All components work together in one system
- ✅ Display updates in real-time to show what's happening
- ✅ Button provides user control over the system
🎉 Almost There! You've integrated all the components! In the final lesson, you'll assemble everything into the complete human-tracking fan project.
🎮 Try It: Practice Integration!
Practice combining components. Try these challenges:
📝 Challenge 1: State Toggle
Write code that toggles a state variable when button is pressed:
📝 Challenge 2: Status Display
Write a function that displays status on LCD:
💡 Tip: Remember to update the display regularly (every 0.5-1 second), and always clear the display before writing new content!
🎯 Activity: Full Control Interface
What You'll Build:
Create a complete control interface with display and button for your tracking system!
Step-by-Step Instructions:
- Connect Components: Wire button, LCD, servo, and camera
- Write Button Function: Create function to toggle tracking state
- Write Display Function: Create function to update LCD status
- Integrate Everything: Combine all components in main loop
- Test: Press button to start/stop, watch display update
- Refine: Adjust display update frequency and button debounce
Display Information:
- ✅ Line 1: "Tracking: ON" or "Tracking: OFF"
- ✅ Line 2: "Face: YES 90°" or "Face: NO"
- ✅ Updates every 0.5-1 second
- ✅ Shows current servo angle when face detected
🏆 Bonus Challenge: Can you add a second button that resets the servo to center position (90 degrees)?
💪 Practice Challenges
Challenge 1: Enhanced Display
Add more information to the display:
- Show frame count or detection rate
- Show time since tracking started
- Show number of faces detected
Challenge 2: Multiple Buttons
Add a second button for different functions:
- Button 1: Start/Stop tracking
- Button 2: Reset servo to center
Challenge 3: Status LED
Add an LED that indicates system status:
- Green LED: Tracking active, face detected
- Yellow LED: Tracking active, no face
- Red LED: Tracking stopped