4

I am programming an Arduino. In the same .ino file as setup() and loop() I have defined the following:

void setup()
{
  // setup code
}

enum class CYCLE { TypeA, TypeB };

String cycleToString (CYCLE cycle) {
  if (cycle == CYCLE::TypeA) {
    return "TypeA";
  }
  else if (cycle == CYCLE::TypeB) {
    return "TypeB";
  }
  return "Undefined";
}

void loop()
{
  // loop code
}

But on compiling it gives the error:

sketch_v1:37:22: error: 'CYCLE' was not declared in this scope
 String cycleToString (CYCLE cycle) {
                      ^
/Users/.../sketch_v1.ino: In function 'String cycleToString(CYCLE)':
sketch_v1:37:31: error: 'String cycleToString(CYCLE)' redeclared as different kind of symbol
 String cycleToString (CYCLE cycle) {
                                  ^
/Users/.../sketch_v1.ino:37:8: note: previous declaration 'String cycleToString'
 String cycleToString (CYCLE cycle) {
        ^

Note that the enum class is fine and works as intended but if I try to add the function relying on the CYCLE type it then errors.

AJP
  • 181
  • 2
  • 9

4 Answers4

13

This is a known bug of Arduino builder, if you have functions before structs, classes or enums in sketch.

The sketch:

void foo() {
}

enum class CYCLE { TypeA, TypeB };

String cycleToString (CYCLE cycle) { if (cycle == CYCLE::TypeA) { return "TypeA"; } else if (cycle == CYCLE::TypeB) { return "TypeB"; } return "Undefined"; }

void setup() { }

void loop() { }

is processed to this .cpp file

#include <Arduino.h>
#line 1 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
#line 1 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"

#line 2 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino" void foo(); #line 7 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino" String cycleToString(CYCLE cycle); #line 17 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino" void setup(); #line 22 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino" void loop(); #line 2 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino" void foo() { }

enum class CYCLE { TypeA, TypeB };

String cycleToString (CYCLE cycle) { if (cycle == CYCLE::TypeA) { return "TypeA"; } else if (cycle == CYCLE::TypeB) { return "TypeB"; } return "Undefined"; }

void setup() { }

void loop() { }

as you can see the forward declarations of functions are before the first function so before the enum.

The workaround for this bug is to follow good practice and declare all the structs, enums and classes before the first function definition.

Juraj
  • 18,264
  • 4
  • 31
  • 49
1

Note this is not an answer, since your code compiles perfectly. (adding a default/empty setup/loop function).

However, I want to give some improvements that cannot fit in a comment:

  1. (optional) Align { and } under each other. Some put the { behind the line, some on a new line; this is mostly preference. But aligning { and } is mostly more clear.
  2. Put each type/enum value on a new line; this makes it easier to add comments above/after it.
  3. Except for trivial cases, never return from a statement, except the last one. In your case the function is quite simple, but still it's better to keep the return only at the end of a function.
  4. Use a switch statement instead of multiple if statements.

So you get:

enum class CYCLE 
{
  TypeA, 
  TypeB 
};

String cycleToString (CYCLE cycle) 
{
  String str;

  switch (cycle)
  {
  case CYCLE::TypeA:
    str = "TypeA";
    break;

  case CYCLE::TypeB:
    str = "TypeB";
    break;

  default:
    str = "Undefined";
    break;
  }

  return str;
}
Michel Keijzers
  • 13,014
  • 7
  • 41
  • 58
-1

It works if you move the enum class to the top, i.e.:

enum class CYCLE { TypeA, TypeB };

void setup()
{
  // setup code
}

String cycleToString (CYCLE cycle) {
  if (cycle == CYCLE::TypeA) {
    return "TypeA";
  }
  else if (cycle == CYCLE::TypeB) {
    return "TypeB";
  }
  return "Undefined";
}

void loop()
{
  // loop code
}
AJP
  • 181
  • 2
  • 9
-1

I found workaround on Arduino forums: Put your enums in separate file (I use enums.hpp), and include it from the main sketch file (.ino) like #include "enums.hpp".