/// \method pulse_width([value]) /// Get or set the pulse width in milliseconds. STATIC mp_obj_t pyb_servo_pulse_width(mp_uint_t n_args, const mp_obj_t *args) { pyb_servo_obj_t *self = args[0]; if (n_args == 1) { // get pulse width, in us return mp_obj_new_int(10 * self->pulse_cur); } else { // set pulse width, in us self->pulse_dest = mp_obj_get_int(args[1]) / 10; self->time_left = 0; servo_timer_irq_callback(); return mp_const_none; } }
// Interrupt dispatch void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &TIM3_Handle) { USBD_CDC_HAL_TIM_PeriodElapsedCallback(); // Periodically raise a flash IRQ for the flash storage controller if (tim3_counter++ >= 500 / USBD_CDC_POLLING_INTERVAL) { tim3_counter = 0; NVIC->STIR = FLASH_IRQn; } } else if (htim == &TIM5_Handle) { servo_timer_irq_callback(); } }
/// \method speed([speed, time=0]) /// Get or set the speed of a continuous rotation servo. /// /// - `speed` is the speed to move to change to, between -100 and 100. /// - `time` is the number of milliseconds to take to get to the specified speed. STATIC mp_obj_t pyb_servo_speed(mp_uint_t n_args, const mp_obj_t *args) { pyb_servo_obj_t *self = args[0]; if (n_args == 1) { // get speed return mp_obj_new_int((self->pulse_cur - self->pulse_centre) * 100 / self->pulse_speed_100); } else { #if MICROPY_PY_BUILTINS_FLOAT self->pulse_dest = self->pulse_centre + self->pulse_speed_100 * mp_obj_get_float(args[1]) / 100.0; #else self->pulse_dest = self->pulse_centre + self->pulse_speed_100 * mp_obj_get_int(args[1]) / 100; #endif if (n_args == 2) { // set speed immediately self->time_left = 0; } else { // set speed over a given time (given in milli seconds) self->time_left = mp_obj_get_int(args[2]) / 20; self->pulse_accum = 0; } servo_timer_irq_callback(); return mp_const_none; } }
/// \method angle([angle, time=0]) /// Get or set the angle of the servo. /// /// - `angle` is the angle to move to in degrees. /// - `time` is the number of milliseconds to take to get to the specified angle. STATIC mp_obj_t pyb_servo_angle(uint n_args, const mp_obj_t *args) { pyb_servo_obj_t *self = args[0]; if (n_args == 1) { // get angle return mp_obj_new_int((self->pulse_cur - self->pulse_centre) * 90 / self->pulse_angle_90); } else { #if MICROPY_ENABLE_FLOAT self->pulse_dest = self->pulse_centre + self->pulse_angle_90 * mp_obj_get_float(args[1]) / 90.0; #else self->pulse_dest = self->pulse_centre + self->pulse_angle_90 * mp_obj_get_int(args[1]) / 90; #endif if (n_args == 2) { // set angle immediately self->time_left = 0; } else { // set angle over a given time (given in milli seconds) self->time_left = mp_obj_get_int(args[2]) / 20; self->pulse_accum = 0; } servo_timer_irq_callback(); return mp_const_none; } }