#![no_std]
#![no_main]
use esp32_hal::{
clock::ClockControl,
delay::Ets,
gpio::{IO, Pins},
pac::Peripherals,
prelude::*,
timer::TimerGroup,
Rtc,
};
const SERVO_PIN: usize = 17; // Предположим, что сервопривод подключен к GPIO17
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take().unwrap();
let system = peripherals.DPORT.split();
let clocks = ClockControl::max(system.clock_control).freeze();
let mut rtc = Rtc::new(peripherals.RTC);
rtc.swd.disable();
rtc.rwdtn.disable();
let timer_group0 = TimerGroup::new(peripherals.TIMG0, &clocks);
let mut wdt0 = timer_group0.wdt;
wdt0.disable();
let pins = Pins::new(peripherals.GPIO, peripherals.IO_MUX);
let mut servo_pin = pins.gpio17.into_push_pull_output();
loop {
move_servo(&mut servo_pin, 0); // повернуть в крайнюю левую позицию
Ets::delay_ms(1000);
move_servo(&mut servo_pin, 90); // повернуть в среднее положение
Ets::delay_ms(1000);
move_servo(&mut servo_pin, 180); // повернуть в крайнюю правую позицию
Ets::delay_ms(1000);
}
}
// Функция перемещения сервопривода в определенное положение
fn move_servo(pin: &mut impl OutputPin, position: u16) {
// Приведение позиции к диапазону широтно-импульсной модуляции (PWM)
let duty = map(position, 0, 180, 500, 2500); // от 500 до 2500 микросекунд
pwm_output(pin, duty as f32 / 1000.0); // конвертация в миллисекунды
}
// Линейная функция преобразования угла в ширину импульса
fn map(value: u16, in_min: u16, in_max: u16, out_min: u16, out_max: u16) -> u16 {
((value - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min
}
// Генерация PWM сигнала с указанной длительностью
fn pwm_output(pin: &mut impl OutputPin, duty_cycle: f32) {
use std::thread::sleep;
use std::time::Duration;
let period = Duration::from_secs_f32(duty_cycle); // Длительность активного периода (HIGH)
let pause = Duration::from_millis(20); // Длительность неактивного периода (LOW)
pin.set_high().unwrap(); // Активный период
sleep(period);
pin.set_low().unwrap(); // Неактивный период
sleep(pause);
}