4

Given the following enums

enum RelayState { RELAY_OFF = HIGH, RELAY_ON = LOW };
enum class CrossingZoneState: uint8_t {
    CROSSINGZONE_CLEAR = 0, // no train in crossing area, also initialized state
    CROSSINGZONE_OCCUPIED = 1, // train detected by the entry sensor
    CROSSINGZONE_EXITING = 2  // train detected by the exit sensor, when sensor clears, state= Clear
};

Where RELAY_OFF = HIGH, HIGH is #define HIGH 0x1 which I assume is a C++/Arduino constant? because I didn't define it. And RELAY_ON = LOW, LOW is 0x0

in the following function I get the error that follows.

CrossingZoneState CheckEntrySensor(uint8_t esp) {
    //esp, short for entry sensor pin
    if (digitalRead(esp) == HIGH)
    {
        state = CrossingZoneState::CROSSINGZONE_CLEAR;
        return state;
    }
    else if (digitalRead(esp) == LOW)
    {
        state = CrossingZoneState::CROSSINGZONE_OCCUPIED;
        return state;
    }
    // if the digital read errs, return the current state so it re-runs
    return state;
};

boolean throwRelayAndCheckStatus(uint8_t relayNumber, RelayState relayState)    {

    int testInt = 0;
    if (relayState == RelayState::RELAY_OFF)
    {
        testInt = 1;
    }
    digitalWrite(relayNumber, relayState);
    if (digitalRead(relayNumber) == testInt) {
        return true;
    };
    return false;
};

I tried having RelayState be an enum class as well but was getting similar type errors. Here is the error from VS2015 with the code shown above.

Compiling debug version of 'ModelRRXingStateMachine' for 'Arduino/Genuino Uno' ModelRRXingStateMachine.ino:11:55: error: 'RelayState' has not been declared :boolean throwRelayAndCheckStatus(uint8_t relayNumber, RelayState relayState) ModelRRXingStateMachine.ino:2:1: error: 'CrossingZoneState' does not name a type :CrossingZoneState CheckEntrySensor(byte esp) Error compiling project sources

I'm not a professional programmer and am new to C++, usually writing in C# or VB.Net so I'm not sure what the compiler is looking for here, both enums are declared and one is declared with a type. Also, the VS code editor is showing no errors, the errors shown above show up in the error window when I try to build.

4
  • is this all in the .ino? the sketch preprocessor may be reordering the declarations and mucking things up. Commented Apr 18, 2016 at 17:23
  • I am using Visual Studio Professional 2015 and the Visual Micro add-in for Arduino, not the Arduino IDE
    – dinotom
    Commented Apr 18, 2016 at 17:38
  • and yes, all this code is from the .ino file
    – dinotom
    Commented Apr 18, 2016 at 17:44
  • The IDE automatically puts forward declarations for methods at the top of the file, conveniently before any types you make get defined. The VS add-in might do it too so everything compiles the same. Moving the code to a separate .h file and including that file would stop it from reordering things if that were the problem. Commented Apr 18, 2016 at 22:54

2 Answers 2

2

The solution was to move the enum declarations to a header file, due to the fact this was a VM add-in issue which will be resolved once they've implemented arduino version 1.6.8.

Adding this code to a header file and removing it from the main file resolved the issues and the code builds and runs.

// ModelRRCrossing.h

#ifndef _MODELRRCROSSING_h
#define _MODELRRCROSSING_h

#if defined(ARDUINO) && ARDUINO >= 100
    #include "arduino.h"
#else
    #include "WProgram.h"
#endif
#pragma once
// Arduino Digital I/O pin numbers for MEGA
//note: digital pins 30-45
//MEGA is a MUST for this project
enum {
    Relay1 = 30, Relay2 = 31, Relay3 = 32, Relay4 = 33, Relay5 = 34, Relay6 = 35,
    Relay7 = 36, Relay8 = 37, Relay9 = 38, Relay10 = 39, Relay11 = 40,
    Relay12 = 41, Relay13 = 42, Relay14 = 43, Relay15 = 44, Relay16 = 45
};

enum RelayState { RELAY_OFF = HIGH, RELAY_ON = LOW };
enum class CrossingZoneState : uint8_t {
    CROSSINGZONE_CLEAR = 0, // no train in crossing area, also initialized state
    CROSSINGZONE_OCCUPIED = 1, // train detected by the entry sensor
    CROSSINGZONE_EXITING = 2  // train detected by the exit sensor, when sensor clears, state= Clear
};

#endif
0

For one thing, you are using the variable state without defining it. Moreover, you have not declared the functions CheckEntrySensor() and throwRelayAndCheckStatus() . When you define a function without first declaring it, the arduino preprocessor builds its own declarations, but often does so in a defective way. This is one of the idiosyncracies of the arduino environment versus a plain C++ compiler.

The following compiles:

enum RelayState { RELAY_OFF = HIGH, RELAY_ON = LOW };
typedef enum RelayState RelayState_t ;


enum CrossingZoneState {
    CROSSINGZONE_CLEAR = 0, // no train in crossing area, also initialized state
    CROSSINGZONE_OCCUPIED = 1, // train detected by the entry sensor
    CROSSINGZONE_EXITING = 2  // train detected by the exit sensor, when sensor clears, state= Clear
};
typedef enum CrossingZoneState CrossingZoneState_t ;

CrossingZoneState_t CheckEntrySensor(uint8_t esp) ;
boolean throwRelayAndCheckStatus(uint8_t relayNumber, RelayState_t relayState) ;

CrossingZoneState_t CheckEntrySensor(uint8_t esp)
{
  CrossingZoneState_t state ;
    //esp, short for entry sensor pin
    if (digitalRead(esp) == HIGH)
    {
        state = /*CrossingZoneState_t::*/CROSSINGZONE_CLEAR;
        return state;
    }
    else if (digitalRead(esp) == LOW)
    {
        state = /*CrossingZoneState::*/CROSSINGZONE_OCCUPIED;
        return state;
    }
    // if the digital read errs, return the current state so it re-runs
    return state;
}

boolean throwRelayAndCheckStatus(uint8_t relayNumber, RelayState_t relayState)    {

    int testInt = 0;
    if (relayState == /*RelayState::*/RELAY_OFF)
    {
        testInt = 1;
    }
    digitalWrite(relayNumber, relayState);
    if (digitalRead(relayNumber) == testInt) {
        return true;
    };
    return false;
}

Or, if you want to avoid the use of typedef, you can use the following:

enum RelayState { RELAY_OFF = HIGH, RELAY_ON = LOW };
enum CrossingZoneState: uint8_t {
    CROSSINGZONE_CLEAR = 0, // no train in crossing area, also initialized state
    CROSSINGZONE_OCCUPIED = 1, // train detected by the entry sensor
    CROSSINGZONE_EXITING = 2  // train detected by the exit sensor, when sensor clears, state= Clear
};

enum CrossingZoneState CheckEntrySensor(uint8_t esp) ;
boolean throwRelayAndCheckStatus(uint8_t relayNumber, enum RelayState relayState) ;


enum CrossingZoneState CheckEntrySensor(uint8_t esp) {
    enum CrossingZoneState state ;
    //esp, short for entry sensor pin
    if (digitalRead(esp) == HIGH)
    {
        state = CROSSINGZONE_CLEAR;
        return state;
    }
    else if (digitalRead(esp) == LOW)
    {
        state = CROSSINGZONE_OCCUPIED;
        return state;
    }
    // if the digital read errs, return the current state so it re-runs
    return state;
}

boolean throwRelayAndCheckStatus(uint8_t relayNumber, enum RelayState relayState)    {

    int testInt = 0;
    if (relayState == RELAY_OFF)
    {
        testInt = 1;
    }
    digitalWrite(relayNumber, relayState);
    if (digitalRead(relayNumber) == testInt) {
        return true;
    };
    return false;
}
10
  • It is good that you are able to get the code to compile, but seems this is a Q&A site and a few months/years from now other inexperienced ones my become lazy(Ctrl+c Ctrl+v) and not gain any understanding about the cause or solution to there problems. Could you thus elaborate on why it compiled and also maybe mentions of general use of enums in this way.
    – RSM
    Commented Apr 18, 2016 at 23:05
  • Type def is a C structure and is not standard in C++11 and forward and is not recommended for enums any longer.
    – dinotom
    Commented Apr 19, 2016 at 2:11
  • A lot of code compiles, that doesn't make it right or effective
    – dinotom
    Commented Apr 19, 2016 at 2:13
  • @RSM: You are right. Commented Apr 19, 2016 at 8:35
  • a) In function CheckEntrySensor(), the variable state was used without being defined. Commented Apr 19, 2016 at 8:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.