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.

dinotom
  • 360
  • 2
  • 6
  • 18

2 Answers2

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
dinotom
  • 360
  • 2
  • 6
  • 18
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;
}