次の列挙型を指定
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 };
RELAY_OFF = HIGHの場合、 HIGHは#defineHIGH 0x1で、C ++ / Arduino定数だと思いますか?定義しなかったためです。RELAY_ON= LOW、LOWは0x0です
次の関数では、次のエラーが発生します。
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; };
RelayStateも列挙型クラスにしようとしましたが、同様の型エラーが発生していました。これは、上記のコードを使用したVS2015のエラーです。
「Arduino / GenuinoUno」の「ModelRRXingStateMachine」のデバッグバージョンのコンパイルModelRRXingStateMachine.ino:11:55:エラー:「RelayState」は宣言されていません:boolean throwRelayAndCheckStatus(uint8_t RelayNumber、RelayState RelayState)ModelRRXingStateMachine.ino:2:1:エラー:「CrossingZoneState」はタイプに名前を付けていません:CrossingZoneState CheckEntrySensor(byte esp)プロジェクトソースのコンパイル中にエラーが発生しました
私はプロのプログラマーではなく、新しいですC ++に、通常はC#またはVB.Netで記述しているため、コンパイラがここで何を探しているのかわかりません。両方の列挙型が宣言され、一方が型で宣言されています。また、VSコードエディタはnを表示していますoエラー、ビルドしようとすると、上記のエラーがエラーウィンドウに表示されます。
コメント
- これはすべて.inoにありますか?スケッチプリプロセッサが宣言を並べ替えて、物事を台無しにしている可能性があります。
- ArduinoIDEではなくVisualStudio Professional2015とArduino用のVisualMicroアドインを使用しています
- はい、このコードはすべて.inoファイルからのものです
- IDEは、作成するタイプが定義される前に、メソッドの宣言をファイルの先頭に自動的に配置します。 VSアドインもそれを行う可能性があるため、すべてが同じようにコンパイルされます。コードを別の.hファイルに移動し、そのファイルをインクルードすると、問題が発生した場合にファイルを並べ替えることができなくなります。
回答
解決策は、列挙型宣言をヘッダーファイルに移動することでした。これは、これがVMアドインの問題であり、arduinoバージョン1.6.8を実装すると解決されるためです。
このコードをヘッダーファイルに追加し、メインファイルから削除すると、問題が解決し、コードがビルドおよび実行されます。
// 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
回答
1つには、変数の状態を定義せずに使用しています。さらに、関数CheckEntrySensor()およびthrowRelayAndCheckStatus()を宣言していません。 arduinoプリプロセッサは最初に宣言せずに機能し、独自の宣言を作成しますが、多くの場合、欠陥のある方法で作成します。これは、単純なC ++コンパイラと比較したarduino環境の特異性の1つです。
次のコンパイルs:
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; }
または、typedefの使用を避けたい場合は、次を使用できます:
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; }
コメント
- コードをコンパイルできるのは良いことですが、これはQ サイトと今から数か月/年後の他の経験の浅いサイトは怠惰になり(Ctrl + c Ctrl + v)、問題の原因や解決策について理解できなくなります。したがって、コンパイルされた理由について詳しく説明していただけますか。また、この方法での
enums
の一般的な使用法についても説明してください。 - タイプdefはC構造体であり、C ++ 11以降では標準ではなく、列挙型には推奨されなくなりました。
- 多くのコードがコンパイルされますが、’ t正しくまたは効果的にする
- @RSM:その通りです。
- a)関数CheckEntrySensor()で、変数の状態が定義されずに使用されました。