Загрузка данных
ARDUINO IDE:
#include <Servo.h>
Servo myServo;
const int trigPin = 9, echoPin = 10;
const int motorPin = 3; // Пин для обычного моторчика
bool motorState = false;
void setup() {
Serial.begin(9600);
myServo.attach(11);
pinMode(motorPin, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
// Измерение расстояния датчиком
digitalWrite(trigPin, LOW); delayMicroseconds(2);
digitalWrite(trigPin, HIGH); delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
int distance = duration * 0.034 / 2;
Serial.println(distance); // Отправка в Python
delay(100);
// Чтение команд из Python приложения
if (Serial.available() > 0) {
char val = Serial.read();
if (val == '1') myServo.write(90); // Поворот руля
if (val == '0') myServo.write(0); // Прямо
if (val == 'M') { // Вкл/Выкл мотор пропеллера
motorState = !motorState;
digitalWrite(motorPin, motorState ? HIGH : LOW);
}
}
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------PYTHON:
import tkinter as tk
from tkinter import messagebox
import serial
from PIL import Image, ImageTk
# --- НАСТРОЙКА И ПОДКЛЮЧЕНИЕ К ARDUINO ---
# Замените 'COM3' на порт вашей платы Arduino (в Linux/macOS это будет '/dev/ttyUSB0')
try:
ser = serial.Serial('COM3', 9600, timeout=0.1)
except Exception as e:
ser = None
print(f"Предупреждение: Arduino не найдена на COM3. Работа в демо-режиме. Ошибка: {e}")
# Функция отправки команд на Arduino
def send_command(cmd):
if ser and ser.is_open:
ser.write(cmd.encode())
else:
print(f"[Демо-режим] Отправлена команда: {cmd}")
# Функция постоянного обновления данных от датчика
def update_data():
if ser and ser.is_open and ser.in_waiting > 0:
try:
# Читаем строку из COM-порта, декодируем и убираем лишние пробелы
dist = ser.readline().decode('utf-8').strip()
if dist.isdigit(): # Проверяем, что пришли именно цифры
lbl_dist.config(text=f"Дистанция: {dist} см")
except Exception:
pass
# Запускаем эту же функцию снова через каждые 100 миллисекунд
root.after(100, update_data)
# --- СОЗДАНИЕ ИНТЕРФЕЙСА ПРИЛОЖЕНИЯ ---
root = tk.Tk()
root.title("Drone Control Panel")
root.geometry("400x500")
root.configure(bg="#f0f0f0")
# =========================================================================
# МЕСТО ДЛЯ ДОБАВЛЕНИЯ ФОТО ДРОНА
# Положите картинку 'drone.png' (или .jpg) в ту же папку, где лежит этот скрипт!
# =========================================================================
try:
# Открываем изображение и уменьшаем его до размеров 250x180 пикселей
img = Image.open('drone.png').resize((250, 180))
photo = ImageTk.PhotoImage(img)
lbl_img = tk.Label(root, image=photo, bg="#f0f0f0")
lbl_img.pack(pady=15)
except Exception:
# Если картинки нет, покажется эта красная надпись
lbl_no_img = tk.Label(
root,
text="[ Положите фото 'drone.png' в папку с проектом ]",
fg="red",
bg="#f0f0f0",
font=("Arial", 10, "italic")
)
lbl_no_img.pack(pady=20)
# =========================================================================
# Виджет вывода расстояния от ультразвукового датчика
lbl_dist = tk.Label(root, text="Дистанция: -- см", font=("Arial", 18, "bold"), bg="#f0f0f0", fg="#333333")
lbl_dist.pack(pady=15)
# --- КНОПКИ УПРАВЛЕНИЯ ---
# Кнопка 1: Поворот сервопривода (Руль вправо)
btn_servo_on = tk.Button(
root, text="Повернуть серво (Команда 1)",
bg="#2ecc71", fg="white", font=("Arial", 11, "bold"),
command=lambda: send_command('1'), height=2
)
btn_servo_on.pack(fill='x', padx=40, pady=5)
# Кнопка 2: Возврат сервопривода (Руль прямо)
btn_servo_off = tk.Button(
root, text="Вернуть серво (Команда 0)",
bg="#e74c3c", fg="white", font=("Arial", 11, "bold"),
command=lambda: send_command('0'), height=2
)
btn_servo_off.pack(fill='x', padx=40, pady=5)
# Кнопка 3: Включение / Выключение обычного моторчика (Пропеллер)
btn_motor = tk.Button(
root, text="Вкл / Выкл Мотор (Команда M)",
bg="#3498db", fg="white", font=("Arial", 11, "bold"),
command=lambda: send_command('M'), height=2
)
btn_motor.pack(fill='x', padx=40, pady=20)
# Запуск цикла опроса Arduino и работы интерфейса
update_data()
root.mainloop()