Функция управления сервоприводами

Я пытаюсь управлять 6 сервоприводами, пока пишу простой код. Я думаю, что вызов функции еще не корректен, и я думаю, что переменные (pos_n, open_n, servo_1) в цикле for не вставляются, а вместо этого просто вставляется строка.

Думаю, я проделал долгий путь, чтобы код не стал громоздким.

Какие изменения заставляют работать эту функцию, чтобы вызовы openValve(1) и openValve(2); работает для обоих сервоприводов?

#include <Servo.h>
const int buttonPin = 2;
int buttonState = 0;

Servo servo_1;
const int pos_1 = 0;
const int open_1 = 105;
const int clos_1 = 10;
//Servo servo_2;
//const int pos_2 = 0;
//const int open_2 = 104;
//const int clos_2 = 9;

String servo_n, pos, pos_n, servo, openServo, open_n;

void setup() {
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);
  servo_1.attach(11);
}

void loop() {
  openValve(1); // call the function
  while (true);
}

void openValve(n) {
  int n = 3;
  pos = "pos_";
  pos_n = (pos + n);
  Serial.println(pos_n);

  servo = "servo_";
  servo_n = servo + n;
  Serial.println(servo_n);

  openServo = "open_";
  open_n = openServo + n;
  Serial.println(open_n);

  // DONT USE STRING BUT THE VARIABLE CONTENTS ??
  for (pos_n = pos_n; pos_n <= open_n; pos_n += 1) {
    servo_n.write(open_n);
    delay(10);
  }
}

, 👍1

Обсуждение

Если вы пытаетесь написать «экономичный» код, то использование объекта String не сделает его «экономичным». Второе, что я заметил, это то, что код не компилируется. Первая ошибка: «Ошибка: ‘n’ не был объявлен в этой области. Я не думаю, что это правильный синтаксис: «void openValve(n) {». СОВЕТ: «n» — это проблема. Пожалуйста, исправьте синтаксические ошибки, затем отредактируйте свой вопрос, чтобы показать нам код, который компилируется., @VE7JRO

переменные в цикле не вставляются во что?, @jsotola

@ VE7JRO, не могли бы вы подсказать, что мне следует использовать вместо объекта String?, @Ludo

@Ludo: простые строки C, то есть массивы char., @Edgar Bonet


1 ответ


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

1

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

Вы пытаетесь составить строку и использовать ее в качестве имени переменной. Это не работает. Строка — это всего лишь переменная/экземпляр типа/класса String. У него не может быть методов класса Servo. Кроме того, параметры функции имеют свой собственный тип. Вы не можете указать значение другого типа для этого параметра. Servo.write() принимает целочисленное значение. Он не может использовать строковое значение. Таким образом, код внутри цикла for бессмыслен и не компилируется. Я бы посоветовал сделать несколько руководств по C++ из Интернета, которые объясняют, как работают переменные в C++.

Вместо этого вам придется использовать несколько переменных типа Servo, по одной для каждого используемого вами серводвигателя. Эти переменные являются экземплярами класса Servo, который реализует все функции, связанные с сервоприводом (например, запись). Каждый двигатель получает свой собственный вывод на Arduino. Вы можете поместить эти объекты Servo в массив, чтобы их можно было индексировать целым числом. Например, вы можете определить следующую переменную в глобальной области видимости:

#define N_SERVOS 6
Servo servos[N_SERVOS];

Это создает массив типа Servo с 6 элементами. Каждый элемент представляет собой один независимый сервообъект. (Обратите внимание, что я использовал определение, чтобы легко изменить количество подключенных сервоприводов при изменении кода). Вы можете получить доступ к отдельному сервообъекту, проиндексировав его:

servos[3].write(pos);

Это запишет новую позицию в сервопривод 4 (4, потому что индексы массива начинаются с 0). Теперь нам нужно прикрепить каждый объект Servo к одному контакту Arduino. Я бы создал дополнительный массив, содержащий соответствующие номера контактов, также в глобальном масштабе:

int servo_pin[N_SERVOS] = {6, 7, 8, 9, 10, 11};

Здесь я использовал контакты с 6 по 11, но вы можете изменить их по своему усмотрению. Затем в функции setup() мы перебираем элементы сервопривода и соответствующие номера контактов и прикрепляем объекты сервопривода к контактам:

for(int i=0;i<N_SERVOS;i++){
    servo[i].attach(servo_pin[i]);
}

Теперь вы можете переписать свою функцию openValve() в соответствии с этим. Я не понимаю, что вы хотели, чтобы сервопривод делал в цикле for, поэтому я оставлю это вам. Сначала нужно исправить синтаксис при объявлении функции. Вы не указали тип параметра n. Это должно выглядеть так:

void openValve(int n){

И тогда вам не следует объявлять новую переменную с тем же именем, поэтому удалите строку int n=3;. Затем вы можете удалить все странные объединения строк. Затем вам нужно исправить цикл for (как я уже писал, я оставлю это вам, так как вы не объяснили, что на самом деле должен делать сервопривод). И, наконец, вам нужно переписать строку записи сервопривода, как описано выше:

servo[n].write(new_pos);

Обратите внимание, что new_pos здесь просто заполнитель, для любых значений, которые вам нужно записать в сервопривод (как уже было сказано, я не понимаю, что именно вы хотите, чтобы сервопривод делал) .


что мне тогда использовать вместо объекта String?

Класс String из среды Arduino может привести к проблемам с памятью (точнее, к фрагментации памяти). Вы можете прочитать сообщение в блоге Маженко о строках Arduino для получения дополнительных объяснений.

Вместо этого следует использовать массивы char, также известные как C-String. Вы создаете буфер фиксированной длины, достаточно большой, чтобы вместить самый большой блок данных, который вам нужно обработать. Допустим, вам нужно максимум 30 символов. Каждая C-строка заканчивается нулем ('\0'). Этот ноль также требует места в буфере. Таким образом, фактический размер буфера равен 31.

char string_buffer[31];

Вы даже можете напрямую инициализировать его строковым значением:

char string_buffer[31]="Teststring";

Вы можете использовать sprintf(), чтобы поместить отформатированную строку в буфер. Например, строка с числом:

sprintf(string_buffer, "Number: %d", 50);

поместит строку "Число: 50" в буфер и завершит ее нулем.

,

Я немного застрял, думая, как PHP-код со вставкой «переменных»: p Спасибо за ваш подробный ответ!, @Ludo

@Ludo Если вы считаете, что мой ответ правильный, вы можете отметить его как правильный. Тогда другие увидят, что это действительно решило вашу проблему., @chrisl