Advertisement
dougs

Arduino flusher code

Mar 15th, 2022 (edited)
358
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.34 KB | None | 0 0
  1.  
  2. using Time = unsigned long;
  3. using Pin = int8_t;
  4.  
  5. constexpr Time kSecond = 1000;
  6. constexpr Time kMinute = 60 * kSecond;
  7.  
  8. class Stepper28BYJ_48
  9. {
  10. public:
  11.     static constexpr int8_t kPinCount = 4;
  12.     static constexpr float kMinimumDelay = 2.0;
  13.     static constexpr float kMotorStepsPerRevolution = 2048.0;
  14.  
  15.     Stepper28BYJ_48(const Pin a, const Pin b, const Pin c, const Pin d)
  16.     :mPins{a,b,c,d}
  17.     {
  18.         for (size_t idx = 0; idx < kPinCount; ++idx) {
  19.             pinMode(mPins[idx], OUTPUT);
  20.         }
  21.         powerOff();
  22.     }
  23.  
  24.     // Performs a blocking rotation
  25.     // -1.0 <= speed < 0 or 0 < speed <= 1.0
  26.     // revolutions >= 0.0
  27.     void rotate(const float speed, const float revolutions) const
  28.     {
  29.         if (speed == 0.0 || speed < -1.0 || speed > 1.0 || revolutions <= 0.0) {
  30.             return;
  31.         }
  32.         // Possible improvement - we don't keep track of or know whether where we're starting meshes
  33.         // with where we left off.
  34.         const int32_t totalSteps = static_cast<int32_t>(revolutions * kMotorStepsPerRevolution);
  35.         int currentStep = 0;
  36.        
  37.         for (int stepCount = 0; stepCount < totalSteps; ++stepCount) {
  38.             outputStep(currentStep);
  39.             delay(static_cast<Time>(kMinimumDelay / fabs(speed)));
  40.             currentStep = nextStep(speed < 0.0, currentStep);
  41.         }
  42.  
  43.         powerOff();
  44.     }
  45.  
  46.     inline void powerOff() const
  47.     {
  48.         // Turns off all pins to avoid overheating while idling.
  49.         outputStep(kPinCount);
  50.     }
  51.  
  52.     void rotateDegrees(const float speed, const float degrees) const
  53.     {
  54.        rotate(speed, degrees / 360.0);
  55.     }
  56. private:
  57.     const Pin mPins[kPinCount];
  58.  
  59.     Pin nextStep(const bool direction, const Pin lastStep) const
  60.     {
  61.         return (lastStep + kPinCount + (direction ? 1 : -1)) % kPinCount;
  62.     }
  63.  
  64.     void outputStep(const int step) const
  65.     {
  66.         for (int pinIndex = 0; pinIndex < kPinCount; ++pinIndex) {
  67.             digitalWrite(mPins[pinIndex], step == pinIndex ? HIGH : LOW);
  68.         }
  69.     }
  70. };
  71.  
  72. class Button
  73. {
  74. public:
  75.     Button(const Pin pin)
  76.     :mPin(pin)
  77.     {
  78.         // Use pullup and connect the other end of the button to ground.  Input is high
  79.         // all the time and only low when button is pressed.
  80.         pinMode(mPin, INPUT_PULLUP);
  81.     }
  82.  
  83.     bool pressed() const
  84.     {
  85.         return digitalRead(mPin) != HIGH;
  86.     }
  87. private:
  88.     const Pin mPin;
  89. };
  90.  
  91. class MotionDetector
  92. {
  93. public:
  94.     MotionDetector(const Pin pin)
  95.     :mPin(pin)
  96.     {
  97.         pinMode(mPin, INPUT);
  98.         // Wait for the motion detector to initialize
  99.         delay(1 * kMinute);
  100.     }
  101.  
  102.     bool motionDetected() const
  103.     {
  104.         return digitalRead(mPin) != LOW;
  105.     }
  106. private:    
  107.     const Pin mPin;
  108. };
  109.  
  110. class LED
  111. {
  112. public:
  113.     LED(const Pin pin)
  114.     :mPin(pin)
  115.     {
  116.         pinMode(mPin, OUTPUT);
  117.     }
  118.  
  119.     void onIf(const bool on) const
  120.     {
  121.         digitalWrite(mPin, on ? HIGH : LOW);
  122.     }
  123. private:    
  124.     const Pin mPin;
  125. };
  126.  
  127. const Stepper28BYJ_48& flushStepper()
  128. {
  129.     static const Stepper28BYJ_48 theStepper(6, 7, 8, 9);
  130.     return theStepper;
  131. }
  132.  
  133. const MotionDetector& motionDetector()
  134. {
  135.     static const MotionDetector detector(10);
  136.     return detector;
  137. }
  138.  
  139. const LED& flushScheduledLed()
  140. {
  141.     static const LED flushPending(14);
  142.     return flushPending;
  143. }
  144.  
  145. const LED& detectionPausedLed()
  146. {
  147.     static const LED detectionPaused(15);
  148.     return detectionPaused;
  149. }
  150.  
  151. const Button& cancelButton()
  152. {
  153.     static const Button cancelBtn(2);
  154.     return cancelBtn;
  155. }
  156.  
  157. void flush()
  158. {
  159.     //static uint32_t flushCount = 0;
  160.     //++flushCount;
  161.     constexpr float speed = 0.25;
  162.     flushStepper().rotate(speed, 1.0);
  163. }
  164.  
  165. void setup()
  166. {
  167.     // initialize statics
  168.     flushStepper();
  169.     motionDetector();
  170.     detectionPausedLed();
  171.     flushScheduledLed();
  172.     cancelButton();
  173. }
  174.  
  175. void loop()
  176. {
  177. #if 0
  178.     // testing settings.
  179.     constexpr Time kDelayBetweenDetectAndFlush = 5 * kSecond;
  180.     constexpr Time kDelayBetweenFlushAndResumeDetection = 5 * kSecond;
  181. #else
  182.     constexpr Time kDelayBetweenDetectAndFlush = 10 * kMinute;
  183.     constexpr Time kDelayBetweenFlushAndResumeDetection = 10 * kMinute;
  184. #endif
  185.     constexpr Time kNoFlushScheduled = 0;
  186.     static Time nextScheduledFlushTime = kNoFlushScheduled;
  187.     static Time detectionResumeTime = 0;
  188.  
  189.     flushScheduledLed().onIf(nextScheduledFlushTime != kNoFlushScheduled);
  190.     detectionPausedLed().onIf(millis() < detectionResumeTime);
  191.  
  192.     if (millis() > detectionResumeTime && motionDetector().motionDetected()) {
  193.         // We detected motion.  Schedule a flush.  Keep watching and pushing back flush time
  194.         // as long as we detect movement.
  195.         nextScheduledFlushTime = millis() + kDelayBetweenDetectAndFlush;
  196.     }
  197.  
  198.     if (nextScheduledFlushTime != kNoFlushScheduled && millis() > nextScheduledFlushTime) {
  199.         // Unschedule the flush.
  200.         nextScheduledFlushTime = kNoFlushScheduled;
  201.         flushScheduledLed().onIf(false);
  202.         flush();
  203.         // After a flush, ignore detections for a little while.
  204.         detectionResumeTime = millis() + kDelayBetweenFlushAndResumeDetection;
  205.     }
  206.  
  207.     if (cancelButton().pressed()) {
  208.         nextScheduledFlushTime = kNoFlushScheduled;
  209.         detectionResumeTime = millis() + 10 * kSecond;
  210.     }
  211. }
  212.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement