Arduino не может скомпилировать переменную с именем SP: «Ожидаемый») перед »(« токен ») - PullRequest
0 голосов
/ 04 февраля 2020

Я работаю над прямой и обратной моделью kinemati c для проекта и не могу исправить эту ошибку. Я очень плохо знаком с классами в C ++ и использовал их только в python в прошлом, поэтому извините, если это глупая проблема.

Ниже приведен фрагмент моего кода, который содержит все, что мне кажется дай ошибку. Строка, показывающая ошибку, помечена, я понятия не имею, что происходит, и я не могу ее исправить.

#include <Servo.h>


class Leg{
  public:
    //The class's variables that all functions for this class can use
    int PositionX; 
    int PositionY;

    Servo Shoulder();
    Servo Elbow();

    Leg(int SP, int EP){ //-----------This line has the error!
      // This is the constructor function
      const int ShoulderPin = SP;
      const int ElbowPin = EP;
      PositionX = 0
      PositionY = 0

      Shoulder.attach(ShoulderPin);
      Elbow.attach(ElbowPin);
    }

    void GoTo(float DemandS, float DemandE) {
      // Sends this Leg to a certain position (could make this return a True when it is done)
      // Inputs are in degrees (chould change)
      Shoulder.write(DemandS);
      Elbow.write(DemandE);
    }
};

Я пытался: дать функции конструктора тип переменной (void), Перемещение конструктора из блока кода с помощью Leg :: Leg (.... {. Повсюду проверяется наличие любых незакрытых скобок. Их нет. Закомментирую библиотеку Servo и все ее применения.

I ' я действительно оценил бы любую помощь, поскольку я чувствую, что я перепробовал все и, должно быть, что-то упустил где-то, обдумывая делать это без классов, но это будет очень раздражающим. Большое спасибо:)

Ответы [ 3 ]

2 голосов
/ 04 февраля 2020

Эти две строки:

Servo Shoulder();
Servo Elbow();

, вероятно, должны быть:

Servo Shoulder;
Servo Elbow;

т.е. создание экземпляров объектов типа Servo вместо объявления функций, которые не принимают параметры и вернуть объект Servo.

И из комментариев выясняется, что вам не следует использовать SP в качестве имени здесь:

Leg(int SP, int EP)

, так что используйте что-то более похожее на:

Leg(int this_is_for_this, int and_this_is_for_this_other_thing)

или используйте верблюжий случай или что-то общее в вашем коде, но будьте описательными.

0 голосов
/ 05 февраля 2020

Вы столкнулись с макросом препроцессора , и вам придется изменить имя переменной. sp должно быть безопасным для использования.

Не используйте ALLCAPS для имен переменных. По соглашению ALLCAPS зарезервирован для констант, и в первые дни C единственный способ получить константу был с помощью макроса препроцессора, представляющего литерал. Если вы будете следовать соглашению, шансы на то, что один из ваших идентификаторов столкнется с макросом и будут заменены, значительно уменьшатся.

TL; DR Version

Где-то в одном из заголовочных файлов библиотеки Arduinio есть в конечном итоге, что-то вроде

#define SP ((*(volatile unsigned int *)0xNN)

, которое принимает NN, число, представляющее смещение регистра SP, и превращает его в нечто, что программа C или C ++ может использовать проще. Это сделано для того, чтобы вы могли посмотреть на текущий указатель стека, если хотите (возможно, для отладки).

#defines - простая текстовая подстановка. Когда SP найден, он заменяется ((*(volatile unsigned int *)0xNN). Таким образом,

Leg(int SP, int EP)

преобразуется после того, как вы видите его в

Leg(int ((*(volatile unsigned int *)0xNN), int EP)

до того, как компилятор его видит. Компилятор не может разобрать этот беспорядок, поэтому вы получаете сообщение об ошибке, которое не соответствует написанному вами коду. Получается много веселья.

Это звучит как кошмар, и может быть, но иногда макросы являются лучшим инструментом для работы. Подробнее о макросах и о том, как их использовать, не попадая в более распространенные ловушки: Почему макросы препроцессора являются злыми и каковы альтернативы? ?

Самое простое, что вы можете сделать, это придерживаться соглашения и никогда не использовать идентификаторы ALLCAPS, кроме случаев определения макроса. Если вы используете sp вместо SP, вы, вероятно, в безопасности.

Копая вывод препроцессора какого-то старого кода Arduino, я нахожу

#define SP _SFR_IO16(0x3D)

Что приводит к

#define _SFR_IO16(io_addr) _MMIO_WORD((io_addr) + __SFR_OFFSET)

и

#define _MMIO_WORD(mem_addr) (*(volatile uint16_t *)(mem_addr))

Так что мое первоначальное предположение немного сбилось, но результат тот же.

0 голосов
/ 05 февраля 2020

спасибо всем, вы пришли к решению! Использование решения mm о замене SP и EP на foo и bar соответственно работало. Я не уверен, являются ли foo и bar специальными переменными в c ++ или потому, что SP имеет другие значения для компилятора, как предположил user4581301.

Спасибо всем за помощь! -Leon

...