// -------------------------------------------------------------------------------------//// A simple class that represents a complete AHOB with all its leds and two servos// for moving the arms//// TBD, the sound of the bells//class AHOB{ private: SingleRedLed *redLight; SingleWhiteLed *whiteLight; ArmServo *arm1; ArmServo *arm2; AkiStaat state = uit; public: // // Create an instance of the AHOB, using the specified Led and ArmServo objects // AHOB(SingleWhiteLed *aWhiteLed, SingleRedLed *aRedLed, ArmServo *aServo1, ArmServo *aServo2) { redLight = aRedLed; whiteLight = aWhiteLed; arm1 = aServo1; arm2 = aServo2; state = uit; // // AHOB is veilig, dus armen omhoog, roodlicht uit, wit licht aan // arm1->hoog(); arm2->hoog(); redLight->setOn(false); whiteLight->setOn(true); } // // Activate the connected leds and arm servos. TBD: the sound // void heartBeat() { if (arm1->isHoog() && arm2->isHoog()) { redLight->setOn(false); // Als de armen omhoog staan mag het rode licht niet branden whiteLight->setOn(true); // armen omhoog = wit licht aan } redLight->heartBeat(); whiteLight->heartBeat(); arm1->stepServo(); arm2->stepServo(); } void set(AkiStaat aState) {#if (DEBUG) if (state != aState) { Serial.print("[AKI::set]"); if (aState == uit) Serial.println(" uit"); else Serial.println(" aan"); }#endif state = aState; if (state == uit) { // // AHOB is open, dus roodlicht uit, witlicht aan en armen omhoog // arm1->hoog(); arm2->hoog(); whiteLight->setOn(true); } else { // // AHOB is dicht, dus witlicht uit, roodlicht aan en armen omlaag // whiteLight->setOn(false); redLight->setOn(true); arm1->laag(); arm2->laag(); } }};//// ------------------------------------------------------------------------------------------------------//// Some sensors use a digital signal and keep it high when not active and drop the signal// when the sensor trips, use in that case the "laag" setting. // Others use a digital signal and are low when not active and make the signal high when the sensor trips, // use the "hoog" setting in that case.// // If the sensor does not generate a digital signal, you have to use a pullup resistor // (or INPUT_PULLUP) and in that case specify "hoog".//// The Flying Fish proximity detectors, when used in reflective mode, need the "laag" setting, // when their sensors are removed and positioned opposit each other, they need the "hoog" setting//// -----------------------------------------------------------------// A simple class which represents the state of a single sensor//class Sensor{ private: int sensorPin; SensorTrigger type = hoog; // of laag, zie boven bool state = false; // true = on, false = off unsigned long lastTime = 0; // Timer to ignore short interrupts const int JITTER_TIME = 1000; // wait a second before the sensor goes off public: // // Create a new instance // Sensor(int aPin) { sensorPin = aPin; pinMode(sensorPin, INPUT_PULLUP); } // // Create a new instance // Sensor(int aPin, SensorTrigger aType) { sensorPin = aPin; type = aType; pinMode(sensorPin, INPUT_PULLUP); } // // Return the current logical state of the sensor // bool getState() { return state; } // // Monitor the physical sensor and update the state accordingly // void heartBeat() { if (digitalRead(sensorPin) == HIGH) { if (type == laag) // For sensors type laag an high signal means they are in the off state { if (state != false) // Process this signal only when the current state is ON { if (lastTime == 0) { lastTime = millis(); // start Interval } else { unsigned long currTime = millis(); if ((currTime - lastTime) >= JITTER_TIME) {#if (DEBUG) Serial.println("[Sensor::heartBeat] sensor(laag) goes off");#endif state = false; // sensor goes OFF lastTime = 0; // Reset interval timer } } } } else {#if (DEBUG) if (state != true) { Serial.println("[Sensor::heartBeat] sensor(hoog) goes on"); }#endif state = true; // Sensor goes ON lastTime = 0; // Reset interval timer } } else // sensorPin = LOW { if (type == laag) {#if (DEBUG) if (state != true) { Serial.println("[Sensor::heartBeat] sensor(laag) goes on"); }#endif state = true; // Sensor goes ON lastTime = 0; // Reset interval timer; } else { if (state != false) // Process this signal only when the current state is ON { if (lastTime == 0) { lastTime = millis(); // start Interval } else { unsigned long currTime = millis(); if ((currTime - lastTime) >= JITTER_TIME) {#if (DEBUG) Serial.println("[Sensor::heartBeat] sensor(hoog) goes off");#endif state = false; // sensor goes OFF lastTime = 0; // Reset interval timer } } } } } }};// --------------------------------------------------------------------------------------//// A finite state machine that guards a occupance of a single track//class SpoorControl{ private: Sensor *sensor1; Sensor *sensor2; SpoorState state = leeg; // // Based on the state of sensor 1 and the current state of the FSM, a new state // is calculated. // void handleSensor1(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 (DEBUG) Serial.println("[SpoorControl::handleSensor1] state is sensor1komend");#endif state = sensor1komend; // so set it to state komend } else if (state == sensor2komend) // if the other sensor tripped first {#if (DEBUG) Serial.println("[SpoorControl::handleSensor1] state is sensor1gaand");#endif state = sensor1gaand; // The train is starting to leave the section } } else { // Sensor went OFF if (state == sensor1gaand) // If the train started to leave via sensor 1 {#if (DEBUG) Serial.println("[SpoorControl::handleSensor1] state is leeg");#endif state = leeg; // the section is "leeg" } } } // // Based on the state of sensor 2 and the current state of the FSM, a new state // is calculated. // void handleSensor2(bool trigger) { if (trigger) // Sensor 2 is ON { if (state == leeg) // Is the section "leeg"? {#if (DEBUG) Serial.println("[SpoorControl::handleSensor2] state is sensor2komend");#endif state = sensor2komend; // A Train entered the section via sensor 2 } else if (state == sensor1komend) // No a train entered the section via the other sensor {#if (DEBUG) Serial.println("[SpoorControl::handleSensor2] state is sensor2gaand");#endif state = sensor2gaand; // Start the leaving process } } else { if (state == sensor2gaand) // A train is in the process of leaving {#if (DEBUG) Serial.println("[SpoorControl::handleSensor2] state is leeg");#endif state = leeg; // Section is empty again } } } public: // // Create an instance with two sensors // SpoorControl(Sensor *aSensor1, Sensor *aSensor2) { sensor1 = aSensor1; sensor2 = aSensor2; } // // Get give the sensors a kick and check their state so we can update our own // state. // void heartBeat() { sensor1->heartBeat(); sensor2->heartBeat(); handleSensor1(sensor1->getState()); handleSensor2(sensor2->getState()); } // // Return the current state of the section // SpoorState getState() { return state; }};// ------------------------------------------------------------------------------------//// Create 2 FSM controling two track sections//SpoorControl spoor1(new Sensor(SENSOR1_PIN, laag), new Sensor(SENSOR2_PIN, laag)); // Sensor works reflectiveSpoorControl spoor2(new Sensor(SENSOR3_PIN, laag), new Sensor(SENSOR4_PIN, laag));SingleRedLed roodlicht(LED_RED_PIN, false);SingleWhiteLed witlicht(LED_WHITE_PIN, false);ArmServo arm_een (SERVO1_PIN, SERVO1_WACHTTIJD, SERVO1_LAAGPOSITIE, SERVO1_HOOGPOSITIE);ArmServo arm_twee(SERVO2_PIN, SERVO2_WACHTTIJD, SERVO2_LAAGPOSITIE, SERVO2_HOOGPOSITIE);//// Create an instance of the AHOB//AHOB ahob(&witlicht, &roodlicht, &arm_een, &arm_twee);//// --------------------------------------------------------------------void setup(){#if (DEBUG) //Serial.begin(9600); Serial.begin(115200); while (!Serial); Serial.println("Starting"); Serial.flush();#endif //DEBUG}// ----------------------------------------------void loop(){ spoor1.heartBeat(); // These object must monitor their sensors spoor2.heartBeat(); // so they can update their states if ((spoor1.getState() == leeg) && (spoor2.getState() == leeg)) { ahob.set(uit); // Stop sound and flashing red lights // Start flashing white lights } else { ahob.set(aan); // Start flashing red lights and sound // Stop flashing white lights } ahob.heartBeat(); // Let the AKI update its connected bells and leds}// =======================================================================
Bovendien heeft een AHOB geen witte lampen.
... die controller die ik aangeschaft heb, door de winkel was mij geadviseerd ...
Ik begrijp dat ik de laatste sketch van Martin moet gebruiken vanavond?
... De slagboompjes draaien een halve van een kwartslag
#define SERVO1_LAAGPOSITIE 45 // Positie arm in laag stand#define SERVO1_HOOGPOSITIE 100 // Positie arm in hoog stand