Сервопривод через пользовательскую библиотеку не работает должным образом

Я немного новичок в Arduino, но не в программировании или электронике в целом. Я работаю над библиотекой, которая будет более подробно описана позже, но у меня возникли проблемы с тем, чтобы основы работали должным образом.

Следующий код обеспечивает желаемое поведение, если сервопривод подключен к контакту 3:

#include <Servo.h>

Servo myServo;

void setup() {
  myServo.attach(3);
}

void loop() {
  myServo.write(1);
  delay(1000);
  myServo.write(45);
  delay(1000);
  myServo.write(90);
  delay(1000);
  myServo.write(135);
  delay(1000);
  myServo.write(180);
  delay(1000);
}

Однако, когда я пытаюсь реализовать подобную функциональность в своей собственной библиотеке, сервопривод блокируется и просто как-то скрежещет. Вот заголовочный файл:

#ifndef MotorControl_h
#define MotorControl_h

#include "Arduino.h"
#include "Servo.h"

class MotorControl
{
  public:
    MotorControl(int north, int south, int west, int east);
    void setNorth(int value);
    void setSouth(int value);
    void setWest(int value);
    void setEast(int value);
    int getNorth();
    int getSouth();
    int getWest();
    int getEast();
  private:
    Servo _north;
    Servo _south;
    Servo _west;
    Servo _east;
    int _northVal;
    int _southVal;
    int _westVal;
    int _eastVal;
};

#endif

А вот файл .cpp:

#include "Arduino.h"
#include "MotorControl.h"
#include "Servo.h"

MotorControl::MotorControl(int north, int south, int west, int east)
{
  _north.attach(north);
  _south.attach(south);
  _west.attach(west);
  _east.attach(east);
  _northVal = 0;
  _southVal = 0;
  _westVal = 0;
  _eastVal = 0;
}

void MotorControl::setNorth(int value)
{
  _north.write(value);
  _northVal = value;
}

void MotorControl::setSouth(int value)
{
  _south.write(value);
  _southVal = value;
}

void MotorControl::setWest(int value)
{
  _west.write(value);
  _westVal = value;
}

void MotorControl::setEast(int value)
{
  _east.write(value);
  _eastVal = value;
}

int MotorControl::getNorth()
{
   return _northVal;
}

int MotorControl::getSouth()
{
  return _southVal;
}

int MotorControl::getWest()
{
  return _westVal;
}

int MotorControl::getEast()
{
  return _eastVal;
}

И наконец, код, использующий указанную выше библиотеку, который должен производить то же поведение, что и код выше, но не делает этого:

#include <MotorControl.h>

MotorControl mc(3, 5, 6, 9);

void setup() {}

void loop() {
  mc.setNorth(1); 
  delay(1000);
  mc.setNorth(45);
  delay(1000);
  mc.setNorth(90);
  delay(1000);
  mc.setNorth(135);
  delay(1000);
  mc.setNorth(180);
  delay(1000);
}

Не знаю, что еще добавить... это работает на Uno R3.

Редактировать: Это интересно. Я попробовал код из этого примера: Как инициализировать объект сервопривода в моей собственной библиотеке? что работает просто отлично. Я все еще не уверен, что вижу, что я делаю здесь неправильно. Я вижу различия между моим кодом и примером, но не то, как они вызывают проблемы.

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

, 👍3


2 ответа


1

В C++, когда объект объявляется как член другого объекта, метод конструктора внутреннего объекта должен быть вызван явно (см. конструкторы и списки инициализаторов членов).

В вашем коде свойства типа Servo могут быть созданы в заголовке конструктора MotorControl:

MotorControl::MotorControl(int north, int south, int west, int east)             
    : _north(), _south(), _west(), _east()                                       
{                                                                                
  _north.attach(north);                                                          
  _south.attach(south);                                                          
  _west.attach(west);                                                            
  _east.attach(east);                                                            
  _northVal = 0;                                                                 
  _southVal = 0;                                                                 
  _westVal = 0;                                                                  
  _eastVal = 0;                                                                  
}
,

0

Когда вы создаете свой экземпляр в глобальной области видимости, вы не можете контролировать, когда именно будет вызван конструктор. Если он будет вызван до запуска init(), то ваши строки присоединения не сработают. У вас должен быть метод begin в вашем классе, который обрабатывает присоединение сервоприводов, и вызывайте этот метод из настройки.

,