Tinkercad 编写 Arduino C++ 代码时出现无用的错误
Unhelpful errors in Tinkercad writing Arduino c++ code
抱歉,如果我的某些来源看起来真的很糟糕。这是我第一次尝试编写 Arduino 代码和 C++。我通常呆在 c# 的舒适区。
我在 Tinkercad 电路上尝试 运行 我的源代码时遇到以下错误。 Tinkercad 吐出错误的方式对学习来说很糟糕。任何能够指出我的错误的人都会非常有帮助。
错误
- 2:23: error: use of enum 'LedActionTypes' without previous
declaration
- 4:23: error: use of enum 'SignalTypes' without previous declaration
- 4:64: error: use of enum 'SignalDirections' without previous declaration
- 5:23: error: use of enum 'SignalTypes' without previous declaration
- 5:64: error: use of enum 'SignalDirections' without previous declaration
- 5:103: error: use of enum 'DigitalSignalValues' without previous declaration
- 8:16: error: variable or field 'AddAction' declared void
- 8:16: error: 'LedAction' was not declared in this scope
我的源代码
/* Enums */
enum SignalTypes
{
General = 0,
Analog = 1,
Digital = 2,
};
enum SignalDirections
{
Inbound = 0x0,
Outbound = 0x1,
};
enum DigitalSignalValues
{
Low = 0x0,
High = 0x1,
};
enum LedActionTypes
{
None = 0,
ChangeBrightness = 1,
};
/* LED Action object */
class LedAction {
// Functions
void Constructor(enum LedActionTypes action, int intensity, int delay)
{
// Check for valid intensity value
if (intensity < 0)
intensity = 0;
if (intensity > 255)
intensity = 255;
Intensity = intensity;
Finished = false;
Action = action;
CompleteOn = millis() + delay;
}
public:
// Properties
boolean Finished;
enum LedActionTypes Action = None;
int Intensity = 0;
unsigned long CompleteOn = 0;
// Constructor
LedAction()
{
Constructor(Action, Intensity, 0);
}
LedAction(enum LedActionTypes action)
{
Constructor(action, Intensity, 0);
}
LedAction(enum LedActionTypes action, int intensity, int delay)
{
Constructor(action, intensity, delay);
}
// Methods
void Loop() {
if (Finished) { return; }
unsigned long currentTimeStamp = millis();
if (CompleteOn >= currentTimeStamp)
{
//Process the action
Finished = true;
}
}
};
/* LED object */
class Led {
// Functions
void Constructor(enum SignalTypes signalType, byte pbPin, enum SignalDirections signalDirection, int intensity)
{
// Check for valid intensity value
if (intensity < 0)
intensity = 0;
if (intensity > 255)
intensity = 255;
Intensity = intensity;
Constructor(SignalType, PBPin, SignalDirection, DigitalSignalValue);
}
void Constructor(enum SignalTypes signalType, byte pbPin, enum SignalDirections signalDirection, enum DigitalSignalValues signalValue)
{
SignalType = signalType;
PBPin = pbPin;
SignalDirection = signalDirection;
DigitalSignalValue = signalValue;
}
public:
// Properties
byte PBPin;
int Intensity;
enum DigitalSignalValues DigitalSignalValue;
enum SignalTypes SignalType = Analog;
enum SignalDirections SignalDirection = Outbound;
LedAction Actions[20]{ LedAction(None) };
// Constructor
Led()
{
Constructor(SignalType, 0, SignalDirection, 0);
}
Led(byte pbPin, enum SignalDirections signalDirection, int intensity)
{
Constructor(SignalType, pbPin, signalDirection, intensity);
}
Led(byte pbPin, enum SignalDirections signalDirection, enum DigitalSignalValues signalValue)
{
Constructor(SignalType, pbPin, signalDirection, signalValue);
}
Led(enum SignalTypes signalType, byte pbPin, enum SignalDirections signalDirection, int intensity)
{
Constructor(signalType, pbPin, signalDirection, intensity);
}
Led(enum SignalTypes signalType, byte pbPin, enum SignalDirections signalDirection, enum DigitalSignalValues signalValue)
{
Constructor(signalType, pbPin, signalDirection, signalValue);
}
// Methods
void Setup()
{
switch (SignalType)
{
case Analog:
analogWrite(PBPin, Intensity);
break;
case Digital:
digitalWrite(PBPin, Intensity);
pinMode(PBPin, SignalDirection);
break;
}
}
void Loop()
{
int n;
// Loop through all actions and find unfinished ones then fire them off
for ( n=0 ; n<20 ; ++n )
{
if (!Actions[n].Finished)
{
Actions[n].Loop();
if (Actions[n].Finished)
{
//Action was just flagged ready to process
switch (Actions[n].Action)
{
case ChangeBrightness:
digitalWrite(PBPin, Actions[n].Intensity);
break;
}
}
}
}
}
void AddAction(LedAction action)
{
int n;
// Loop through all actions and find an unfinished one then reuse it
for (n = 0; n < 20; ++n)
{
if (!Actions[n].Finished)
{
action.Finished = false;
Actions[n] = action;
break;
}
}
}
void ClearAllActions()
{
int n;
// Loop through all actions and mark all as finished
for (n = 0; n < 20; ++n)
{
if (!Actions[n].Finished)
{
Actions[n].Finished = true;
}
}
}
};
有关 Tinkercad Circuits 的代码示例可在...
https://www.tinkercad.com/things/gmGeFVKOA3e-adrunio-test/editel
进入页面后,单击 "Simulate" 播放按钮(左下方),然后单击顶部的 "Start Simulation" 按钮。您应该会看到与我看到的相同的错误。
好的,所以我想我找到了答案...
在与 Tinkercad 和那里的强大支持团队进行了几次对话后,我被告知他们使用旧版本的 Arduino 来编译他们的代码。好吧,我正在编写的所有代码和我正在编写的 IDE 都是基于所有内容的最新版本。我认为这是我的问题开始发生的地方。
目前,当尝试在 Tinkercad 使用的当前版本中编译以下代码时,出现了相应的错误...
enum TestEnum
{
OptOne = 1,
OptTwo = 2
};
class TestClass {
private:
void InitilizeClass(enum TestEnum te)
{ }
public:
TestClass(enum TestEnum te)
{ }
};
void setup()
{ }
void loop()
{ }
如您所见,我正在尝试在我的 class 中创建一个名为 InitializeClass()
的函数,它将我的枚举作为参数。编译器不喜欢这一点,由于某种原因,错误突出显示以及返回的错误太可怕了,什么也没告诉我!
但是,如果我将 class 更改为仅在构造函数本身中使用枚举,那么编译似乎没有错误。
enum TestEnum
{
OptOne = 1,
OptTwo = 2
};
class TestClass {
private:
void InitilizeClass()
{ }
public:
TestClass(enum TestEnum te)
{ }
};
void setup()
{ }
void loop()
{ }
问题
我想创建一个 class,它的重复代码尽可能少,这通常是我尝试编写代码的一般方式。如果我必须输入相同的代码两次...开始考虑将其变成一个函数。这样 a) 代码更少,b) 如果您需要更改逻辑,您可以在一个地方而不是多个地方更改它。所以我开始通常让我的 classes 看起来像这样...
enum TestEnum
{
OptOne = 1,
OptTwo = 2
};
class TestClass {
private:
void InitilizeClass(enum TestEnum te, int n, int t)
{
if (n < 0)
n = 0;
if (n > 255)
n = 255;
TE = te;
N = n;
T = t;
}
public:
enum TestEnum TE = OptOne;
int N = 0;
int T = 0;
TestClass(enum TestEnum te)
{ InitilizeClass(te, 0, 0); }
TestClass(enum TestEnum te, int n)
{ InitilizeClass(te, n, 0); }
TestClass(enum TestEnum te, int n, int t)
{ InitilizeClass(te, n, t); }
};
void setup()
{ }
void loop()
{ }
这在 VS IDE (c++) 以及最新的 Arduino IDE 中工作得很好。但是,由于 Tinkercad 使用的是旧的 Arduino 编译器,因此它适合我在私有 class 函数中使用枚举。 (更新:刚刚发现这发生在任何 class 函数中!不仅仅是私有函数。)
解决方案
所以一直以来,在编写我的 Arduino 项目时,我一直在用 c# 的心态思考,而我本应该更像 c++ 一样思考。好吧,在我的辩护中,我毕竟是一个彻头彻尾的 c# 人。我更喜欢 C++。几乎在所有方面都很好。显然也有例外。我最近发现,虽然 c# 不允许,但 c++ 确实允许您重载 class 构造函数!这改变了我用 C++ 编写 classes 的方式。现在没有理由让私有 class 函数初始化 class。所以我可以像下面这样...
enum TestEnum
{
OptOne = 1,
OptTwo = 2
};
class TestClass {
public:
enum TestEnum TE = OptOne;
int N = 0;
int T = 0;
TestClass(enum TestEnum te)
{ TestClass(te, 0, 0); }
TestClass(enum TestEnum te, int n)
{ TestClass(te, n, 0); }
TestClass(enum TestEnum te, int n, int t)
{ TestClass(te, n, t); }
};
void setup()
{ }
void loop()
{ }
我的朋友们在旧的 Arduino 编译器中编译得很好。它还为其他代码节省了一些 space(这些 ATTiny 芯片并不大,所以较小的程序总是赢!)。
抱歉,如果我的某些来源看起来真的很糟糕。这是我第一次尝试编写 Arduino 代码和 C++。我通常呆在 c# 的舒适区。
我在 Tinkercad 电路上尝试 运行 我的源代码时遇到以下错误。 Tinkercad 吐出错误的方式对学习来说很糟糕。任何能够指出我的错误的人都会非常有帮助。
错误
- 2:23: error: use of enum 'LedActionTypes' without previous
declaration
- 4:23: error: use of enum 'SignalTypes' without previous declaration
- 4:64: error: use of enum 'SignalDirections' without previous declaration
- 5:23: error: use of enum 'SignalTypes' without previous declaration
- 5:64: error: use of enum 'SignalDirections' without previous declaration
- 5:103: error: use of enum 'DigitalSignalValues' without previous declaration
- 8:16: error: variable or field 'AddAction' declared void
- 8:16: error: 'LedAction' was not declared in this scope
我的源代码
/* Enums */
enum SignalTypes
{
General = 0,
Analog = 1,
Digital = 2,
};
enum SignalDirections
{
Inbound = 0x0,
Outbound = 0x1,
};
enum DigitalSignalValues
{
Low = 0x0,
High = 0x1,
};
enum LedActionTypes
{
None = 0,
ChangeBrightness = 1,
};
/* LED Action object */
class LedAction {
// Functions
void Constructor(enum LedActionTypes action, int intensity, int delay)
{
// Check for valid intensity value
if (intensity < 0)
intensity = 0;
if (intensity > 255)
intensity = 255;
Intensity = intensity;
Finished = false;
Action = action;
CompleteOn = millis() + delay;
}
public:
// Properties
boolean Finished;
enum LedActionTypes Action = None;
int Intensity = 0;
unsigned long CompleteOn = 0;
// Constructor
LedAction()
{
Constructor(Action, Intensity, 0);
}
LedAction(enum LedActionTypes action)
{
Constructor(action, Intensity, 0);
}
LedAction(enum LedActionTypes action, int intensity, int delay)
{
Constructor(action, intensity, delay);
}
// Methods
void Loop() {
if (Finished) { return; }
unsigned long currentTimeStamp = millis();
if (CompleteOn >= currentTimeStamp)
{
//Process the action
Finished = true;
}
}
};
/* LED object */
class Led {
// Functions
void Constructor(enum SignalTypes signalType, byte pbPin, enum SignalDirections signalDirection, int intensity)
{
// Check for valid intensity value
if (intensity < 0)
intensity = 0;
if (intensity > 255)
intensity = 255;
Intensity = intensity;
Constructor(SignalType, PBPin, SignalDirection, DigitalSignalValue);
}
void Constructor(enum SignalTypes signalType, byte pbPin, enum SignalDirections signalDirection, enum DigitalSignalValues signalValue)
{
SignalType = signalType;
PBPin = pbPin;
SignalDirection = signalDirection;
DigitalSignalValue = signalValue;
}
public:
// Properties
byte PBPin;
int Intensity;
enum DigitalSignalValues DigitalSignalValue;
enum SignalTypes SignalType = Analog;
enum SignalDirections SignalDirection = Outbound;
LedAction Actions[20]{ LedAction(None) };
// Constructor
Led()
{
Constructor(SignalType, 0, SignalDirection, 0);
}
Led(byte pbPin, enum SignalDirections signalDirection, int intensity)
{
Constructor(SignalType, pbPin, signalDirection, intensity);
}
Led(byte pbPin, enum SignalDirections signalDirection, enum DigitalSignalValues signalValue)
{
Constructor(SignalType, pbPin, signalDirection, signalValue);
}
Led(enum SignalTypes signalType, byte pbPin, enum SignalDirections signalDirection, int intensity)
{
Constructor(signalType, pbPin, signalDirection, intensity);
}
Led(enum SignalTypes signalType, byte pbPin, enum SignalDirections signalDirection, enum DigitalSignalValues signalValue)
{
Constructor(signalType, pbPin, signalDirection, signalValue);
}
// Methods
void Setup()
{
switch (SignalType)
{
case Analog:
analogWrite(PBPin, Intensity);
break;
case Digital:
digitalWrite(PBPin, Intensity);
pinMode(PBPin, SignalDirection);
break;
}
}
void Loop()
{
int n;
// Loop through all actions and find unfinished ones then fire them off
for ( n=0 ; n<20 ; ++n )
{
if (!Actions[n].Finished)
{
Actions[n].Loop();
if (Actions[n].Finished)
{
//Action was just flagged ready to process
switch (Actions[n].Action)
{
case ChangeBrightness:
digitalWrite(PBPin, Actions[n].Intensity);
break;
}
}
}
}
}
void AddAction(LedAction action)
{
int n;
// Loop through all actions and find an unfinished one then reuse it
for (n = 0; n < 20; ++n)
{
if (!Actions[n].Finished)
{
action.Finished = false;
Actions[n] = action;
break;
}
}
}
void ClearAllActions()
{
int n;
// Loop through all actions and mark all as finished
for (n = 0; n < 20; ++n)
{
if (!Actions[n].Finished)
{
Actions[n].Finished = true;
}
}
}
};
有关 Tinkercad Circuits 的代码示例可在... https://www.tinkercad.com/things/gmGeFVKOA3e-adrunio-test/editel
进入页面后,单击 "Simulate" 播放按钮(左下方),然后单击顶部的 "Start Simulation" 按钮。您应该会看到与我看到的相同的错误。
好的,所以我想我找到了答案...
在与 Tinkercad 和那里的强大支持团队进行了几次对话后,我被告知他们使用旧版本的 Arduino 来编译他们的代码。好吧,我正在编写的所有代码和我正在编写的 IDE 都是基于所有内容的最新版本。我认为这是我的问题开始发生的地方。
目前,当尝试在 Tinkercad 使用的当前版本中编译以下代码时,出现了相应的错误...
enum TestEnum
{
OptOne = 1,
OptTwo = 2
};
class TestClass {
private:
void InitilizeClass(enum TestEnum te)
{ }
public:
TestClass(enum TestEnum te)
{ }
};
void setup()
{ }
void loop()
{ }
如您所见,我正在尝试在我的 class 中创建一个名为 InitializeClass()
的函数,它将我的枚举作为参数。编译器不喜欢这一点,由于某种原因,错误突出显示以及返回的错误太可怕了,什么也没告诉我!
但是,如果我将 class 更改为仅在构造函数本身中使用枚举,那么编译似乎没有错误。
enum TestEnum
{
OptOne = 1,
OptTwo = 2
};
class TestClass {
private:
void InitilizeClass()
{ }
public:
TestClass(enum TestEnum te)
{ }
};
void setup()
{ }
void loop()
{ }
问题
我想创建一个 class,它的重复代码尽可能少,这通常是我尝试编写代码的一般方式。如果我必须输入相同的代码两次...开始考虑将其变成一个函数。这样 a) 代码更少,b) 如果您需要更改逻辑,您可以在一个地方而不是多个地方更改它。所以我开始通常让我的 classes 看起来像这样...
enum TestEnum
{
OptOne = 1,
OptTwo = 2
};
class TestClass {
private:
void InitilizeClass(enum TestEnum te, int n, int t)
{
if (n < 0)
n = 0;
if (n > 255)
n = 255;
TE = te;
N = n;
T = t;
}
public:
enum TestEnum TE = OptOne;
int N = 0;
int T = 0;
TestClass(enum TestEnum te)
{ InitilizeClass(te, 0, 0); }
TestClass(enum TestEnum te, int n)
{ InitilizeClass(te, n, 0); }
TestClass(enum TestEnum te, int n, int t)
{ InitilizeClass(te, n, t); }
};
void setup()
{ }
void loop()
{ }
这在 VS IDE (c++) 以及最新的 Arduino IDE 中工作得很好。但是,由于 Tinkercad 使用的是旧的 Arduino 编译器,因此它适合我在私有 class 函数中使用枚举。 (更新:刚刚发现这发生在任何 class 函数中!不仅仅是私有函数。)
解决方案
所以一直以来,在编写我的 Arduino 项目时,我一直在用 c# 的心态思考,而我本应该更像 c++ 一样思考。好吧,在我的辩护中,我毕竟是一个彻头彻尾的 c# 人。我更喜欢 C++。几乎在所有方面都很好。显然也有例外。我最近发现,虽然 c# 不允许,但 c++ 确实允许您重载 class 构造函数!这改变了我用 C++ 编写 classes 的方式。现在没有理由让私有 class 函数初始化 class。所以我可以像下面这样...
enum TestEnum
{
OptOne = 1,
OptTwo = 2
};
class TestClass {
public:
enum TestEnum TE = OptOne;
int N = 0;
int T = 0;
TestClass(enum TestEnum te)
{ TestClass(te, 0, 0); }
TestClass(enum TestEnum te, int n)
{ TestClass(te, n, 0); }
TestClass(enum TestEnum te, int n, int t)
{ TestClass(te, n, t); }
};
void setup()
{ }
void loop()
{ }
我的朋友们在旧的 Arduino 编译器中编译得很好。它还为其他代码节省了一些 space(这些 ATTiny 芯片并不大,所以较小的程序总是赢!)。