3

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.

  • is this all in the .ino? the sketch preprocessor may be reordering the declarations and mucking things up. – BrettAM Apr 18 '16 at 17:23
  • I am using Visual Studio Professional 2015 and the Visual Micro add-in for Arduino, not the Arduino IDE – dinotom Apr 18 '16 at 17:38
  • and yes, all this code is from the .ino file – dinotom Apr 18 '16 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. – BrettAM Apr 18 '16 at 22:54
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;
}
  • 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 Apr 18 '16 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 Apr 19 '16 at 2:11
  • A lot of code compiles, that doesn't make it right or effective – dinotom Apr 19 '16 at 2:13
  • @RSM: You are right. – Alphonsos_Pangas Apr 19 '16 at 8:35
  • a) In function CheckEntrySensor(), the variable state was used without being defined. – Alphonsos_Pangas Apr 19 '16 at 8:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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