Шаговый двигатель 28BYJ-48. Прошу помощи в доработке класса

Ну, это я удачно паузу взял. Вам практически всё уже написали.

(все номера строк по самому первому скетчу)

  1. Функция, имя которой совпадает с именем класса является конструктором независимо ни от чего другого, потому, да, это конструктор;
  2. @BOOM написал Вам про private, я тоже считаю его здесь чрезмерным. С задачей недоступности из программы вполне и protected справится. А использование private сужает возможности дальнейшего использования класса, а именно – запрещает классам-наследникам доступ к этим переменным;
  3. @andriano написал про то, что инициализацию железа лучше делать не в конструкторе, а в методе, который вызывается вручную. Согласен. В данном случае никаких проблем нет, но если уж делать так, как делаете Вы, то надо чётко понимать что Вы делаете и где лежат грабли. Надеюсь, Вы понимаете;
  4. @MMM Вам совершенно правильно сказал про константы. Вообще, есть общее правило, “если Вы не собираетесь менять какую-то переменную (или метод не собирается менять свойства класса), не скрывайте этого от компилятора, пусть знает”. Про эти дела я позже отдельно скажу;

Клевета! :slight_smile:

То нет особого смысла делать его классом.

Ну, теперь, что я ещё заметил по мелочи (“крупняк” пока оставим):

  1. в строке №20 moment2 (а в строке №29 – uk, а в строке №80 – arrow2) используются до инициализации. Нет, я понимаю, что Вы используете то, что изначально они нули, но это некрасивая практика – коробит аж. Неужели трудно поставить инициализацию?
  2. За имена переменных типа pin1, pin2, pin3 и т.п. надо бить по рукам. У этих пинов есть вполне осмысленные функции и переменные заслуживают осмысленных названий;
  3. Ваш метод mkstep (как и появившейся позже begin) не изменяет никаких свойств класса. И не собирается изменять! Тогда почему он (метод) не объявлен const? Просто, в силу упомянутого выше правила?
  4. Всё, что там связано с uk и выводом на пины, нуждается в серьёзно сутевом комментарии.

Теперь про “крупняк”. (я согласен со всем, что написали коллеги, но здесь буду использовать Ваш изначальный код без правок, которые они предложили. Эти правки Вы сами внесёте).

Про inline классы и константные свойства

Если в классе все методы inline, как у Вас, то нет никакого смысла иметь константные свойства – они только память отжирают. Все константные свойства можно и нужно вынести в параметры шаблона. Смотрите:

Ваша программа:
class MOTORS
{
  private:
    int pin11, pin22, pin33, pin44;
  public:
    MOTORS(int pin1, int pin2, int pin3, int pin4)
    {
      pinMode(pin1, OUTPUT);
      pinMode(pin2, OUTPUT);
      pinMode(pin3, OUTPUT);
      pinMode(pin4, OUTPUT);
      pin11 = pin1;
      pin22 = pin2;
      pin33 = pin3;
      pin44 = pin4;
    }
    void mkstep(bool arrow)
    {
      static unsigned long moment2;
      while (millis() - moment2 < 2)
      {
      }
      moment2 = millis();
      static byte array1[] = {1, 0, 0, 1};
      static byte array2[] = {1, 1, 0, 0};
      static byte array3[] = {0, 1, 1, 0};
      static byte array4[] = {0, 0, 1, 1};
      static byte uk;
      digitalWrite(pin11, array1[uk]);
      digitalWrite(pin22, array2[uk]);
      digitalWrite(pin33, array3[uk]);
      digitalWrite(pin44, array4[uk]);
      if (arrow == true)
      {
        switch (uk)
        {
          case 0: uk = 3;
            break;
          case 1: uk = 0;
            break;
          case 2: uk = 1;
            break;
          case 3: uk = 2;
            break;
        }
      }
      else
      {
        switch (uk)
        {
          case 0: uk = 1;
            break;
          case 1: uk = 2;
            break;
          case 2: uk = 3;
            break;
          case 3: uk = 0;
            break;
        }
      }
    }
};

// подключение шагового двигателя
#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5

MOTORS Stmt(IN1, IN2, IN3, IN4);

byte arrow2;

void setup()
{

}
void loop()
{
  Stmt.mkstep(arrow2);
}

У меня показывает память программы/данных: 1092/38

А вот

То же самое, но без свойств, через параметры шаблона
template <const uint8_t pin1, const uint8_t pin2, const uint8_t pin3, const uint8_t pin4>
class MOTORS
{
  public:
    MOTORS(void)
    {
      pinMode(pin1, OUTPUT);
      pinMode(pin2, OUTPUT);
      pinMode(pin3, OUTPUT);
      pinMode(pin4, OUTPUT);
    }
    void mkstep(bool arrow)
    {
      static unsigned long moment2;
      while (millis() - moment2 < 2)
      {
      }
      moment2 = millis();
      static byte array1[] = {1, 0, 0, 1};
      static byte array2[] = {1, 1, 0, 0};
      static byte array3[] = {0, 1, 1, 0};
      static byte array4[] = {0, 0, 1, 1};
      static byte uk;
      digitalWrite(pin1, array1[uk]);
      digitalWrite(pin2, array2[uk]);
      digitalWrite(pin3, array3[uk]);
      digitalWrite(pin4, array4[uk]);
      if (arrow == true)
      {
        switch (uk)
        {
          case 0: uk = 3;
            break;
          case 1: uk = 0;
            break;
          case 2: uk = 1;
            break;
          case 3: uk = 2;
            break;
        }
      }
      else
      {
        switch (uk)
        {
          case 0: uk = 1;
            break;
          case 1: uk = 2;
            break;
          case 2: uk = 3;
            break;
          case 3: uk = 0;
            break;
        }
      }
    }
};

// подключение шагового двигателя
#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5

MOTORS<IN1, IN2, IN3, IN4> Stmt;

byte arrow2;

void setup()
{

}
void loop()
{
  Stmt.mkstep(arrow2);
 }

У меня показывает память программы/данных: 1038/30

Как видите, мы сэкономили и то, и другое.

Конечно, это правило (как и любое другое) надо применять с умом.

Про Ваши массивы array1-4

(это уже не про класс, правда)

Зачем они память жрут? Давайте посмотрим на строки №№29-32. В них Вы всегда двум пинам выставляете HIGH и двум пинам – LOW. При этом, в зависимости от uk имеем:

uk pin1 pin2 pin3 pin4
0 1 1 0 0
1 0 1 1 0
2 0 0 1 1
3 1 0 0 1

Легко заметить, что:
pin1 получает значение HIGH при uk == 0 или 3
pin2 – при uk < 2
pin3 – при uk == 1 или 2
pin4 – при uk > 1

Ну, и кто нам мешает так и написать в строках №№29-32

digitalWrite(pin11, uk==0 || uk==3);
digitalWrite(pin22, uk < 2);
digitalWrite(pin33, uk==1 || uk==2);
digitalWrite(pin44, uk > 1);

И массивы не нужны вовсе.

Это при Ваших значениях uk. А если бы Вы сделали их такими, чтобы просто за каждый пин отвечал свой бит в uk, было бы ещё проще.

6 лайков