Как передать объект Encoder конструктору другого класса
Я пытаюсь создать класс (Arm), который управляет рукой. У рук есть 2 двигателя, каждый с энкодером, поэтому я передаю 4 целых числа для контактов и пытаюсь передать 2 указателя (по одному для каждого объекта энкодера).
файл .ino:
#include "Arm.h"
#include <Encoder.h>
// контакты драйвера двигателя
#define ShoulderUP 7
#define ShoulderDW 8
#define ElbowUP 9
#define ElbowDW 10
#define encoderShoulderPinA 20
#define encoderShoulderPinB 21
#define encoderElbowPinA 22
#define encoderElbowPinB 23
//создаем объекты энкодера
Encoder ElbowEncoder(encoderElbowPinA, encoderElbowPinB);
Encoder ShoulderEncoder(encoderShoulderPinA, encoderShoulderPinB);
//создаем объект рука
Arm Arm1(ShoulderUP, ShoulderDW, ElbowUP, ElbowDW, ElbowEncoder, ShoulderEncoder);
void setup() {
Serial.begin(9600);
}
void loop() {
Arm1.ShoulderMoveTime(1, 255, 1000);
}
файл .h:
#ifndef Arm_h
#define Arm_h
#include <Arduino.h>
#include <Encoder.h>
class Arm {
public:
Arm(int ShoulderUpPin, int ShoulderDownPin, int ElbowUpPin, int ElbowDownPin, Encoder *ElbowEncoder, Encoder *ShoulderEncoder);
//контакты, подключенные к вашему энкодеру:
// Лучшая производительность: оба вывода имеют возможность прерывания
// Хорошая производительность: только первый вывод имеет возможность прерывания
// Низкая производительность: ни один из выводов не имеет возможности прерывания
void ShoulderMoveTime(int dir, int speed, int time);
//dir = 0 означает вверх, dir = 1 означает вниз; скорость между 0-255
void ElbowMoveTime(int dir, int speed, int time);
//dir = 0 означает вверх, dir = 1 означает вниз; скорость между 0-255
//Перемещает руку в заданное положение
void ArmMovePosition(int shoulderPos, int elbowPos);
// калибрует текущее положение руки до нуля
void ZeroArm();
//возвращает положение руки
void getArmPosition();
private:
Encoder *ElbowEncoder;
Encoder *ShoulderEncoder;
int _ShoulderUpPin;
int _ShoulderDownPin;
int _ElbowUpPin;
int _ElbowDownPin;
};
#endif
и файл .cpp:
#include "Arduino.h" #include "Кодировщик.h" #include "Arm.h" Arm::Arm(int ShoulderUpPin, int ShoulderDownPin, int ElbowUpPin, int ElbowDownPin, Encoder *ElbowEncoder, Encoder *ShoulderEncoder) { pinMode(ShoulderUpPin, ВЫХОД); pinMode(ShoulderDownPin, ВЫХОД); pinMode(ElbowUpPin, ВЫХОД); pinMode(ElbowDownPin, ВЫХОД); _ShoulderUpPin = ПлечоВверх; _ShoulderDownPin = ПлечоВнизPin; _ElbowUpPin = ЛокотьВверх; _отвод вниз штифт = отвод вниз штифт; //_ShoulderEncoderPinA = ShoulderEncoderPinA; //_ShoulderEncoderPinB = ShoulderEncoderPinB; //_Отводной кодировщикPinA = Отводной кодировщикPinA; // _КоленоккодировщикPinB = КоленоЭнкодерPinB; кодировщик локтя = *энкодер локтя; Кодировщик Плеча = *Кодировщик Плеча; //ElbowEncoder(_ElbowEncoderPinA, _ElbowEncoderPinB); //ShoulderEncoder(_ShoulderEncoderPinA, _ShoulderEncoderPinB); } void Arm::ShoulderMoveTime(int dir, int speed, int time) { ... } void Arm::ElbowMoveTime(int dir, int speed, int time) { ... } void Arm:: ArmMovePosition (int плечоPos, int локотьPos) { int ShoulderinitialPos = ShoulderEncoder.read(); int ElbowinitialPos = ElbowEncoder.read(); // TODO: я думаю, что это будет перемещать только один сустав за раз //Двигаем плечо----------------------------------------------------------- --------------------------------------- if (shoulderPos > ShoulderinitialPos) { //проверить, в каком направлении должна двигаться рука while (shoulderPos > ShoulderEncoder.read()) { //пока целевое положение больше фактического положения мотора, перемещаем плечо вверх digitalWrite(_ShoulderUpPin, ВЫСОКИЙ); // ЭТО МОЖЕТ БЫТЬ ОБРАТНО } digitalWrite(_ShoulderUpPin, НИЗКИЙ); //остановить движение руки вверх } иначе если (плечоПос < ПлечоначальноеПос) { в то время как (shoulderPos < ShoulderEncoder.read()) { digitalWrite(_ShoulderDownPin, ВЫСОКИЙ); } digitalWrite(_ShoulderDownPin, НИЗКИЙ); } еще { Serial.print("Ошибка: неверная целевая позиция плеча"); } //Двигаем локтем------------------------------------------------------------- --------------------------------------- if (elbowPos > ElbowinitialPos) { // проверяем, в каком направлении должна двигаться рука while (elbowPos > ElbowEncoder.read()) { //пока целевое положение больше фактического положения мотора, двигаем колено вверх digitalWrite(_ElbowUpPin, ВЫСОКИЙ); // ЭТО МОЖЕТ БЫТЬ ОБРАТНО } digitalWrite(_ElbowUpPin, НИЗКИЙ); //остановить движение руки вверх } иначе если (elbowPos < ElbowinitialPos) { в то время как (elbowPos < ElbowEncoder.read()) { digitalWrite(_ElbowDownPin, ВЫСОКИЙ); } digitalWrite(_ElbowDownPin, НИЗКИЙ); } еще { Serial.print("Ошибка: неверная целевая позиция локтя"); } } пустота Arm:: ZeroArm () { ПлечоЭнкодер.write(0); ElbowEncoder.write(0); Serial.println("Рука тарирована"); } пустота Arm::getArmPosition() { Serial.print("Положение плеча: "); Serial.print(ShoulderEncoder.read()); Serial.print("Положение локтя:"); Serial.println(ElbowEncoder.read()); }
К сожалению, возникла проблема с передачей объекта Encoder. Я получаю сообщение об ошибке: "Ошибка компиляции: нет соответствующей функции для вызова 'Arm::Arm(int, int, int, int, Encoder&, Encoder&)'"
Я определенно новичок в программировании, поэтому заранее спасибо за, вероятно, простую проблему.
@EricWeissman, 👍2
Обсуждение1 ответ
Вы прыгаете вперед и назад между указателями и самими объектами. Измените его, чтобы передавать указатели на конструктор руки и последовательно использовать указатели (или передавать ссылку и всегда использовать ее, просто будьте последовательны). Это будет что-то вроде:
// основной код, передать указатель, а не сам объект
Arm Arm1(ShoulderUP, ShoulderDW, ElbowUP, ElbowDW, &ElbowEncoder, &ShoulderEncoder);
// заголовок
public:
Arm(int ShoulderUpPin, int ShoulderDownPin, int ElbowUpPin, int ElbowDownPin, Encoder *ElbowEncoder, Encoder *ShoulderEncoder);
// цена за тысячу показов
Arm::Arm(int ShoulderUpPin, int ShoulderDownPin, int ElbowUpPin, int ElbowDownPin, Encoder *ElbowEncoder, Encoder *ShoulderEncoder) {
pinMode(ShoulderUpPin, OUTPUT);
pinMode(ShoulderDownPin, OUTPUT);
pinMode(ElbowUpPin, OUTPUT);
pinMode(ElbowDownPin, OUTPUT);
_ShoulderUpPin = ShoulderUpPin;
_ShoulderDownPin = ShoulderDownPin;
_ElbowUpPin = ElbowUpPin;
_ElbowDownPin = ElbowDownPin;
this.ElbowEncoder = ElbowEncoder; // использовать это.' чтобы указать частную переменную класса, так как это то же имя, что и переданный параметр.
this.ShoulderEncoder = ShoulderEncoder;
}
И затем внутри вашего класса, поскольку ElbowEncoder является указателем, а не самим кодировщиком, используйте ElbowEncoder->method(), а не ElbowEncoder.method()
Лично я бы немного изменил структуру. Зачем создавать энкодеры на верхнем уровне, если они используются только в классе arm? Создайте их в классе рук внутри:
//в .h
public:
Arm(int ShoulderUpPin, int ShoulderDownPin, int ShoulderEncoderPinA,int ShoulderEncoderPinB,
int ElbowUpPin, int ElbowDownPin, int ElbowEncoderPinA, int ElbowEncoderPinB);
private:
Encoder ShoulderEncoder;
Encoder ElbowEncoder;
// в .cpp
Arm::Arm(int ShoulderUpPin, int ShoulderDownPin, int ShoulderEncoderPinA,int ShoulderEncoderPinB,
int ElbowUpPin, int ElbowDownPin, int ElbowEncoderPinA, int ElbowEncoderPinB) :
ShoulderEncoder(ShoulderEncoderPinA,ShoulderEncoderPinB),
ElbowEncoder(ElbowEncoderPinA,ElbowEncoderPinB) {
// код конструктора
}
Это создаст кодировщики как частные для руки, как только вы вызовете конструктор руки. Особенно удобно, если вы хотите иметь более одной руки.
- Скетч с несколькими классами (.h и .cpp) – как соединить классы
- Передача двумерного массива в функцию
- Как работают массивы?
- Сбой при использовании переменных ссылок в классах
- Возникла проблема с доступом к значениям из указателя
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: "недопустимое использование нестатической функции-члена" при вызове функции из моего собственного класса-метода
- Массив динамического размера в качестве члена класса
Что происходит, когда вы передаете объект Encoder в качестве указателя через
& ElbowEncoder
?, @chrislЯ получаю сообщение "Ошибка компиляции: нет соответствия оператору =" (типы операндов "Кодировщик" и "Кодировщик*")", @EricWeissman
пожалуйста, скопируйте все сообщение об ошибке и вставьте его в свой вопрос ... ** не ** помещайте его в комментарий, как вы только что сделали ... также ** нет изображений текста ** ... отформатируйте текст как код, @jsotola
вы можете использовать ссылку. член и параметр как тип
Encoder
, а в _списке инициализации конструктора_ вы устанавливаете значение члена из значения параметра.MyClass::MyClass(Encoder& _encoder) : encoder(_encoder) {}
, @Juraj