Сервопривод не двигается, если я отсоединяю его ПОСЛЕ записи

Так что это немного странно, и я ничего не понимаю. По сути, я просто играю со своим сервоприводом. Я написал небольшую программу, которую можно найти по этой ссылке: https://pastebin.pl/view/8e9c9573 (Примечание: Это три файла, я оставил там несколько комментариев, а функция idk — это мое последнее средство, пытающееся отделить себя от loop, я действительно не знаю :/ ) .

Поэтому я запускаю controller.Setup() в функции setup, а затем в цикле просто перемещаю его на 180 и отсоединяю, после чего сталкиваюсь с бесконечным петля. Примечание. Я знаю, что это не очень хороший код, но сейчас меня это не волнует.

Проблема в том, что когда я добавляю вызов для отсоединения (строка 22), предыдущий ход не выполняется! Я думаю, что схожу с ума, потому что, как только я удаляю строку и перекомпилирую, она на самом деле перемещается.

Я попытался снять блокировку (Controller::m_Attached), но она все еще не работает. Пожалуйста, дайте мне знать, если я чего-то не заметил, но я действительно не понимаю.

Примечания:

  • Я использую arduino-cli, вот мой не очень идеальный Makefile: https://pastebin .pl/view/daa852ff
  • Я использую библиотеку Servo: https://www.arduino.cc/reference/en/libraries/ серво/
  • Я использую Arduino Uno

ИЗМЕНИТЬ: Кто-то сказал мне опубликовать код в вопросе, так что вот:

//Main.ino
#include <Servo.h>
#include "Controller.h"

Controller controller(3);


void idk();

void setup() {
    Serial.begin(9600);
    controller.Setup();
}

void loop() {
    idk();
    while(true);
}

void idk() {
    controller.Move(180);
    controller.Unlock();
}



// Controller.h
#pragma once
#include <Servo.h>

class Controller
{
public:
    Controller(int servoPin) 
        : m_ServoPin(servoPin), m_Attached(false) {}

    void Setup();
    void Move(int angle);

    void Lock();
    void Unlock();

private:
    Servo m_Servo;
    bool m_Attached;
    const int m_ServoPin = 3;
};


// Controller.ino
#include "Controller.h"

void Controller::Setup()
{
    m_Servo.attach(m_ServoPin);
    m_Attached = true;
    Serial.print("[CONTROLLER] Attached Servo\n");
}

void Controller::Move(int angle)
{
    if (m_Attached)
        m_Servo.write(angle);
}

void Controller::Lock() {
    m_Servo.attach(m_ServoPin);
    m_Attached = true;
}

void Controller::Unlock() {
    m_Servo.detach();
    m_Attached = false;
}

, 👍3

Обсуждение

функция detach (), вероятно, останавливает вывод данных от вывода сигнала управления сервоприводом ... вы отключаете сигнал управления через несколько микросекунд после его включения, поэтому он никогда не генерируется ... кроме того, сервопривод требует, чтобы сигнал был присутствовать во все времена, @jsotola

@jsotola Большое спасибо. Когда я добавляю задержку между вызовами функций, она работает. Вы должны сделать это ответом, чтобы я мог его принять., @stfn


2 ответа


Лучший ответ:

3

Функция detach(), вероятно, не позволяет выводу данных выводить сигнал управления сервоприводом.

Ваш код отключает управляющий сигнал через несколько микросекунд после его включения.

Сигнал управления никогда не генерируется.

Кроме того, сервопривод требует постоянного присутствия сигнала, чтобы он сохранял свое положение.

Когда ваша программа включает в себя события реального мира, вы должны думать о временных рамках событий и о временных рамках работающей программы.

Представьте, что программа может выполнить 100 000 циклов, прежде чем сервопривод завершит движение.

,

2

Операции присоединения и отсоединения выполняют лишь функцию инициализации или деинициализации переменных в функциях библиотеки сервоприводов и могут перемещать сервопривод в центральное положение.

Функция должна знать, какой вывод использовать для управления сервоприводом. После того, как сервопривод подключен, при выполнении команды servo.write он отправит импульс на штифт. Вы можете сделать это сами

    int servopin=8;
    pinMode (servopin, OUTPUT);
    digitalWrite(sevopin,LOW);  // убеждается, что импульса еще нет
    
      // больше кода
    digitalWrite(servopin,HIGH);
    delayMicroseconds(1500);      // 1500 установит сервопривод в положение
    digitalWrite(servopin,LOW);    // среднее положение
    delay(19);    // дает время для хода, может быть разблокирующим кодом

Это можно повторять для обеспечения непрерывного импульса. В ситуациях, когда нагрузка отсутствует или минимальна, сервопривод может не двигаться, если импульсы прекратятся. Если повторять импульсы без задержки, некоторые из них будут проигнорированы. Если, скажем, вы увеличиваете микросекундную задержку для разгона сервопривода и пропускаете задержку после импульса, вы обнаружите, что он перескакивает на несколько шагов. Это также актуально, если вы используете servoWrite без паузы.

После отсоединения функция библиотеки сервопривода не будет знать, какой контакт использует сервопривод.

,

attach() не просто инициализирует переменную: он запускает непрерывный поток импульсов с частотой 50 Гц. А write() не отправляет ни одного импульса: он изменяет ширину всех последующих импульсов потока. Эти импульсы управляются прерываниями, поэтому вам не нужно беспокоиться о синхронизации программы., @Edgar Bonet