import time
import RPi.GPIO as GPIO
from unihiker import GUI
import Adafruit_DHT
import pygame
from threading import Thread

# 初始化GUI
gui = GUI()

# 引脚定义
DHT_PIN = 10          # 温湿度传感器
BUZZER_PIN = 11       # 蜂鸣器
RGB_RED = 12          # RGB红灯
RGB_GREEN = 13        # RGB绿灯
RGB_BLUE = 14         # RGB蓝灯
GRAY_LEFT = 15        # 左侧灰度传感器
GRAY_RIGHT = 16       # 右侧灰度传感器
IR_LEFT = 17          # 左侧红外避障
IR_RIGHT = 18         # 右侧红外避障
MOTOR_A1 = 19         # 电机A正极
MOTOR_A2 = 20         # 电机A负极
MOTOR_B1 = 21         # 电机B正极
MOTOR_B2 = 22         # 电机B负极

# 初始化GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUZZER_PIN, GPIO.OUT)
GPIO.setup(RGB_RED, GPIO.OUT)
GPIO.setup(RGB_GREEN, GPIO.OUT)
GPIO.setup(RGB_BLUE, GPIO.OUT)
GPIO.setup(GRAY_LEFT, GPIO.IN)
GPIO.setup(GRAY_RIGHT, GPIO.IN)
GPIO.setup(IR_LEFT, GPIO.IN)
GPIO.setup(IR_RIGHT, GPIO.IN)
GPIO.setup(MOTOR_A1, GPIO.OUT)
GPIO.setup(MOTOR_A2, GPIO.OUT)
GPIO.setup(MOTOR_B1, GPIO.OUT)
GPIO.setup(MOTOR_B2, GPIO.OUT)

# 初始化PWM
pwm_red = GPIO.PWM(RGB_RED, 1000)
pwm_green = GPIO.PWM(RGB_GREEN, 1000)
pwm_blue = GPIO.PWM(RGB_BLUE, 1000)
pwm_red.start(0)
pwm_green.start(0)
pwm_blue.start(0)

# 初始化蜂鸣器
buzzer = GPIO.PWM(BUZZER_PIN, 440)
buzzer.start(0)

# 初始化DHT11传感器
dht_sensor = Adafruit_DHT.DHT11

# 初始化pygame音频
pygame.mixer.init()
try:
   sound = pygame.mixer.Sound("alert.wav")  # 准备一个音频文件
except:
   print("未找到音频文件")

# 电机控制函数
def motor_control(a1, a2, b1, b2):
   GPIO.output(MOTOR_A1, a1)
   GPIO.output(MOTOR_A2, a2)
   GPIO.output(MOTOR_B1, b1)
   GPIO.output(MOTOR_B2, b2)

def forward():
   motor_control(1, 0, 1, 0)

def backward():
   motor_control(0, 1, 0, 1)

def left():
   motor_control(0, 1, 1, 0)

def right():
   motor_control(1, 0, 0, 1)

def stop():
   motor_control(0, 0, 0, 0)

# RGB灯控制
def set_rgb(r, g, b):
   pwm_red.ChangeDutyCycle(r)
   pwm_green.ChangeDutyCycle(g)
   pwm_blue.ChangeDutyCycle(b)

# 蜂鸣器控制
def beep(freq=440, duration=0.1):
   buzzer.ChangeFrequency(freq)
   buzzer.ChangeDutyCycle(50)
   time.sleep(duration)
   buzzer.ChangeDutyCycle(0)

# 播放声音
def play_sound():
   try:
       sound.play()
   except:
       beep(880, 0.5)

# 读取环境数据
def read_environment():
   humidity, temperature = Adafruit_DHT.read_retry(dht_sensor, DHT_PIN)
   return temperature, humidity

# 自动避障模式
def avoid_obstacle_mode():
   set_rgb(0, 0, 100)  # 蓝色表示避障模式
   while True:
       left_ir = GPIO.input(IR_LEFT)
       right_ir = GPIO.input(IR_RIGHT)
       
       if not left_ir and not right_ir:  # 前方无障碍
           forward()
       elif not left_ir and right_ir:    # 右侧有障碍
           left()
           time.sleep(0.5)
       elif left_ir and not right_ir:    # 左侧有障碍
           right()
           time.sleep(0.5)
       else:                             # 前方有障碍
           backward()
           time.sleep(0.5)
           right()
           time.sleep(1)
       
       time.sleep(0.1)

# 巡线模式
def line_follow_mode():
   set_rgb(0, 100, 0)  # 绿色表示巡线模式
   while True:
       left_gray = GPIO.input(GRAY_LEFT)
       right_gray = GPIO.input(GRAY_RIGHT)
       
       if not left_gray and not right_gray:  # 在线条上
           forward()
       elif not left_gray and right_gray:    # 偏右
           left()
       elif left_gray and not right_gray:    # 偏左
           right()
       else:                                 # 丢失线条
           stop()
           beep()
           time.sleep(0.5)
       
       time.sleep(0.1)

# 显示环境数据
def display_environment():
   while True:
       temp, humi = read_environment()
       gui.clear()  # 清空屏幕
       gui.draw_text(f"温度: {temp}°C", x=120, y=50, font_size=20)
       gui.draw_text(f"湿度: {humi}%", x=120, y=80, font_size=20)
       time.sleep(2)

# 主控制函数
def main():
   # 创建UI按钮
   btn_avoid = gui.add_button(x=50, y=150, text="避障模式", onclick=lambda: start_mode(avoid_obstacle_mode))
   btn_line = gui.add_button(x=150, y=150, text="巡线模式", onclick=lambda: start_mode(line_follow_mode))
   btn_stop = gui.add_button(x=100, y=200, text="停止", onclick=stop)
   btn_sound = gui.add_button(x=100, y=250, text="播放声音", onclick=play_sound)
   
   # 显示初始信息
   gui.draw_text("智能机器人小车", x=120, y=20, font_size=24)
   
   # 启动环境数据显示线程
   env_thread = Thread(target=display_environment)
   env_thread.daemon = True
   env_thread.start()
   
   # 初始灯光效果
   for i in range(3):
       set_rgb(100, 0, 0)
       time.sleep(0.2)
       set_rgb(0, 100, 0)
       time.sleep(0.2)
       set_rgb(0, 0, 100)
       time.sleep(0.2)
   set_rgb(0, 0, 0)

def start_mode(mode_func):
   mode_thread = Thread(target=mode_func)
   mode_thread.daemon = True
   mode_thread.start()

if __name__ == "__main__":
   try:
       main()
       while True:
           time.sleep(1)
   except KeyboardInterrupt:
       stop()
       GPIO.cleanup()

