Ну, это я удачно паузу взял. Вам практически всё уже написали.
(все номера строк по самому первому скетчу)
- Функция, имя которой совпадает с именем класса является конструктором независимо ни от чего другого, потому, да, это конструктор;
- @BOOM написал Вам про
private
, я тоже считаю его здесь чрезмерным. С задачей недоступности из программы вполне иprotected
справится. А использованиеprivate
сужает возможности дальнейшего использования класса, а именно – запрещает классам-наследникам доступ к этим переменным; - @andriano написал про то, что инициализацию железа лучше делать не в конструкторе, а в методе, который вызывается вручную. Согласен. В данном случае никаких проблем нет, но если уж делать так, как делаете Вы, то надо чётко понимать что Вы делаете и где лежат грабли. Надеюсь, Вы понимаете;
- @MMM Вам совершенно правильно сказал про константы. Вообще, есть общее правило, “если Вы не собираетесь менять какую-то переменную (или метод не собирается менять свойства класса), не скрывайте этого от компилятора, пусть знает”. Про эти дела я позже отдельно скажу;
То нет особого смысла делать его классом.
Ну, теперь, что я ещё заметил по мелочи (“крупняк” пока оставим):
- в строке №20
moment2
(а в строке №29 –uk
, а в строке №80 –arrow2
) используются до инициализации. Нет, я понимаю, что Вы используете то, что изначально они нули, но это некрасивая практика – коробит аж. Неужели трудно поставить инициализацию? - За имена переменных типа
pin1
,pin2
,pin3
и т.п. надо бить по рукам. У этих пинов есть вполне осмысленные функции и переменные заслуживают осмысленных названий; - Ваш метод
mkstep
(как и появившейся позжеbegin
) не изменяет никаких свойств класса. И не собирается изменять! Тогда почему он (метод) не объявленconst
? Просто, в силу упомянутого выше правила? - Всё, что там связано с
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
, было бы ещё проще.