Maar hoe een zg H brug werkt? geen idee.
Maar hoe een zg H brug werkt? geen idee. [...] in combinatie met standaard interface kaartjes.
Verlicht mij eventjes wat is halve golf aan sturing precies? Ik moet nu opeens aan zo'n racebaan denken waarbij een positieve spanning werd gebruikt voor 1 auto en de negatieve spanning voor de andere...maar nu heb ik het over iets anders dan jullie denk ik
//// A class that encapsulated sensors and detectors used for controlling// a rail section. This specific sensor receives it's state updates through// Canbus messages//class Sensor{private: int sensorAddress; // The address/number of this sensor, derived from // position on a S88 bank. volatile bool state;public: Sensor(int aSensorAddress); void attach(); int getSensorAddress(); void heartBeat(); void setState(bool aState); bool getState();};//// A finite state machine that guards a occupance of a single track//class SectionControl{public: enum SectionState { leeg, sensor1komend, sensor2komend, sensor1gaand, sensor2gaand }; // // Create an instance with two sensors // SectionControl(Sensor *anEntrySensor, Sensor *anExitSensor); // // Attach pins // void attach(); // // Get give the sensors a kick and check their state so we can update our own // state. // void heartBeat(); // // Is the section occupied by a train? // bool isOccupied(); void setEntrySensor(Sensor *aSensor); Sensor *getEntrySensor(); void setExitSensor(Sensor *aSensor); Sensor *getExitSensor();private: SectionState state = leeg; Sensor *entrySensor = nullptr; Sensor *exitSensor = nullptr; SectionControl::SectionState getState(); // // Based on the state of sensor 1 and the current state of the FSM, a new state // is calculated. // void handleEntrySensor(bool trigger); // // Based on the state of sensor 2 and the current state of the FSM, a new state // is calculated. // void handleExitSensor(bool trigger);};
Sensor::Sensor(int aSensorAddress){ sensorAddress = aSensorAddress; state = false;}void Sensor::attach(){}int Sensor::getSensorAddress(){ return sensorAddress;}void Sensor::heartBeat(){}void Sensor::setState(bool aState){ state = aState;}bool Sensor::getState(){ return state;}//// Based on the state of entry sensor and the current state of the FSM, a new state// is calculated.//void SectionControl::handleEntrySensor(bool trigger){ if (trigger) // Sensor 1 is ON { if (state == leeg) // If the state is "leeg" it means that a train enters the section {#if (RRX_DEBUG) Serial.print("[SectionControl::handleEntrySensor] ON, nr: "); Serial.print(sectionNr); Serial.println(" state is sensor1komend"); Serial.flush();#endif state = sensor1komend; // so set it to state komend } } else // Sensor is OFF {#if (RRX_DEBUG) Serial.print("[SectionControl::handleEntrySensor] OFF, nr: "); Serial.print(sectionNr); Serial.println(" ignored"); Serial.flush();#endif }}//// Based on the state of the exit sensor and the current state of the FSM, a new state// is calculated.//void SectionControl::handleExitSensor(bool trigger){ if (trigger) // Sensor 2 is ON { if (state == sensor1komend) // A train has entered the section {#if (RRX_DEBUG) Serial.print("[SectionControl::handleExitSensor] ON, nr: "); Serial.print(sectionNr); Serial.println(" state is sensor2gaand"); Serial.flush();#endif state = sensor2gaand; // Start the leaving process } } else { if (state == sensor2gaand) // A train is in the process of leaving {#if (RRX_DEBUG) Serial.print("[SectionControl::handleExitSensor] OFF, nr: "); Serial.print(sectionNr); Serial.println("state is leeg"); Serial.flush();#endif state = leeg; // Section is empty again }#if (RRX_DEBUG) else { Serial.print("[SectionControl::handleExitSensor] OFF, nr: "); Serial.print(sectionNr); Serial.println(" ignored"); Serial.flush(); }#endif }}//// Create an instance with two sensors//SectionControl::SectionControl(Sensor *anEntrySensor, Sensor *anExitSensor){ entrySensor = anEntrySensor; exitSensor = anExitSensor; state = leeg; // initial state}//// Initialise and setup//void SectionControl::attach(){}//// Get give the sensors a kick and check their state so we can update our own// state.//void SectionControl::heartBeat(){ if ((entrySensor == nullptr) || (exitSensor == nullptr)) { state = leeg; } else { entrySensor->heartBeat(); exitSensor->heartBeat();#if (RRX_DEBUG) Serial.print("[SectionControl::heartBeat] entry sensor address: "); Serial.print(entrySensor->getSensorAddress()); Serial.print(", state: "); Serial.println(entrySensor->getState());#endif handleEntrySensor(entrySensor->getState());#if (RRX_DEBUG) Serial.print("[SectionControl::heartBeat] exit sensor address: "); Serial.print(exitSensor->getSensorAddress()); Serial.print(", state: "); Serial.println(exitSensor->getState()); Serial.flush();#endif handleExitSensor(exitSensor->getState()); }}//// Ask if the section is occupied by a train. only if it's state equals// 'leeg' we may deny it, all other states tells us that a train is active// in the section.//bool SectionControl::isOccupied(){ if (state == leeg) { return false; } else { return true; }}//// Return the current state of the section//SectionControl::SectionState SectionControl::getState(){ return state;}void SectionControl::setEntrySensor(Sensor *aSensor){ entrySensor = aSensor;}Sensor *SectionControl::getEntrySensor(){ return entrySensor;}void SectionControl::setExitSensor(Sensor *aSensor){ exitSensor = aSensor;}Sensor *SectionControl::getExitSensor(){ return exitSensor;}
const int nrOfSensors = 4;Sensor sensors[nrOfSensors] = { Sensor(12), // 1.13 SectionControl 2 exit Sensor( 9), // 1,10 SectionControl 1 entry Sensor(16), // 2.01 SectionControl 2 entry Sensor(22) // 2.07 SectionControl 1 exit};SectionControl section1(&sensors[1], &sensors[3]);SectionControl section2(&sensors[2], &sensors[0]);
// // Initialize the sensors // for (int i=0; i<nrOfSensors; i++) { sensors[i].attach(); } section1.attach(); section2.attach();
// // Keep the sections running, so they will update their states // section1.heartBeat(); section2.heartBeat();
Je hebt qua detecties ongeveer hetzelfde gedaan als ik voor de AHOB. Ik had alleen mijn sporen bi-directioneel gemaakt. En zodoende had ik 5 states.
Dit allemaal gezegd hebbende. Volgens mij is wat jij doe, wat ik doe en het grootbedrijf doet allemaal onnodig moeilijk doen. Ik denk als je gewoon 1 enkele bezetmelder gebruikt voor de gehele lengte dus van je huidige entrySensor t/m je huidige exitSensor dat je dan al een perfect werkend en feilloos systeem heb.
//// A simple class that represents a complete AKI (Automatische Knipperlicht Installatie)// with all its leds and the sound of a bell//class AKI{public: enum CrossingState { OPEN, CLOSED }; // // Create an instance of the AKI, using the specified Led's // AKI(BlinkingLed *aRedLed, BlinkingLed *aGreenLight, int aBellPin); // // Attach pins // void attach(); // // Activate the connected leds. TBD: the sound // void heartBeat(); // // Close the crossing // void close(); // // Open the crossing // void open();private: BlinkingLed *redLight; BlinkingLed *greenLight; int bellPin; CrossingState state; void setCrossingState(CrossingState aState); CrossingState getCrossingState();};
//// Create an instance of the AKI, using the specified Led's //AKI::AKI(BlinkingLed *aRedLight, BlinkingLed *aGreenLight, int aBellPin){ redLight = aRedLight; greenLight = aGreenLight; bellPin = aBellPin;}//// Attach pins//void AKI::attach(){ redLight->attachPin(); greenLight->attachPin(); pinMode(bellPin, OUTPUT); digitalWrite(bellPin, LOW); setCrossingState(OPEN);}//// Activate the connected leds. //void AKI::heartBeat(){ // // The leds have a flicker, so we have to keep them running // redLight->heartBeat(); greenLight->heartBeat();}void AKI::setCrossingState(AKI::CrossingState aState){ state = aState; if (state == OPEN) { redLight->setLedOn(false); greenLight->setLedOn(true); digitalWrite(bellPin, LOW); // Bell is off } else { redLight->setLedOn(true); greenLight->setLedOn(false); digitalWrite(bellPin, HIGH); // Bell is on }}AKI::CrossingState AKI::getCrossingState(){ return state;}void AKI::open(){ setCrossingState(AKI::OPEN);}void AKI::close(){ setCrossingState(AKI::CLOSED);}
class BlinkingLed{private: int blPin; short blinkInterval; bool blinking; bool ledOn; long lastTime; public: BlinkingLed(int, int); void setBlinkInterval(int); int getBlinkInterval(); void setLedOn(bool); bool getLedOn(); void attachPin(); void heartBeat();};
BlinkingLed::BlinkingLed(int aPin, int aBlinkInterval){ blPin = aPin; blinking = false; ledOn = false; blinkInterval = aBlinkInterval;}void BlinkingLed::setBlinkInterval(int aBlinkInterval){ blinkInterval = aBlinkInterval;}int BlinkingLed::getBlinkInterval(){ return blinkInterval;} void BlinkingLed::setLedOn(bool aLedOn){ if (ledOn != aLedOn) { ledOn = aLedOn; if (!ledOn) { digitalWrite(blPin, LOW); } }} bool BlinkingLed::getLedOn(){ return ledOn; } void BlinkingLed::attachPin(){ pinMode(blPin, OUTPUT); delay(100); lastTime = millis();} void BlinkingLed::heartBeat(){ if (ledOn) { unsigned long currTime = millis(); if ((currTime - lastTime) >= blinkInterval) { lastTime = currTime; if (blinking) { digitalWrite(blPin, HIGH); blinking = false; } else { digitalWrite(blPin, LOW); blinking = true; } } }}
AKI aki(new BlinkingLed(23,333), new BlinkingLed(22,667), 24); // Red blinks 90/minute, green 45/minute
aki.attach();
// // Update the state of the AKI based on the stateS of the sections // if ((section1.isOccupied()) || (section2.isOccupied())) { aki.close(); } else { aki.open(); } // // Keep the AKI running // aki.heartBeat();
private: int blPin; short blinkInterval; bool blinking; bool ledOn; long lastTime;
void BlinkingLed::heartBeat(){ if (ledOn) { unsigned long currTime = millis(); if ((currTime - lastTime) >= blinkInterval)
struct { unsigned int blinking: 1; unsigned int ledOn: 1;} status;
bool's [..] ruzie mee toen ik [..] het getal 2 er in wilde stoppen
Mooie toepassing. Maar het duurt wel erg lang voordat de overweg weer 'vrij' is.
[Kritiek mode]Ik weet dat deze SW past in je OO stijl manier van programmeren maar....Je doet wel erg veel moeite en werk om een led te laten knipperen zeg en dan nog het geheugen wat je er aan toewijdt. Een hele classe om een led te laten knipperen...........Ik vind bool's persoonlijk ondingen. Ik had er een keer ruzie mee toen ik een state wilde toevoegen en het getal 2 er in wilde stoppen. Een bool neemt ook 8 bits in gebruik terwijl je er maar 1 van nodig heb. Je hebt 2 bits nodig en je gebruikt er 16.
Deze OO manier maakt alleen het gebruik van constantes niet mogelijk. Ze verschillen per object en dat maakt het lastig. Daarom zou ik voor de leds zelf niet kiezen voor een classe. Maar zoals ik altijd zeg, what ever grinds your gears (doe wat jou goeddunkt) . Hij doet het iig.
Je hebt natuurlijk ook nog de standaard 'getters' (de get functies) die je eigenlijk niet gebruikt. Ik weet nog van Java les dat je die eerder tikt uit gewoonte dan uit noodzaak. Ik weet niet of de functies daadwerkelijk worden meegecompileerd op dat ze door de compiler worden weggeoptimaliseerd (schitterend woord)
Wat ik standaard ook graag als advies geef, is om ten alle tijden de intX_t en de uintX_t notaties te gebruiken vanwege de duidelijkheid er van. Ik moest nu bijvoorbeeld opzoeken wat een short ook alweer was en een 'int' kan per platform verschillen. En iedereen kan in het eerste oog opslag zien, hoeveel bits er gebruikt worden en of de waarde signed of unsigned is als je dus de uintX_t en de intX_t gebruikt.