Implement interruptable_delay
authorLukáš Jiřiště <jiriste@icpf.cas.cz>
Mon, 18 Nov 2024 14:36:16 +0000 (15:36 +0100)
committerLukáš Jiřiště <jiriste@icpf.cas.cz>
Mon, 18 Nov 2024 14:36:16 +0000 (15:36 +0100)
This enables a fast interruption of the sequence (mainly the
wait_for_equilibrium method).

Measurement.h
Measurement.ino
Servomatic.h [new file with mode: 0644]
Servomatic.ino

index 4b5c596a57495bc2731f7c2a2d5a3b24e81139bb..a0813e6c1505bb95fd7c4683a9bafcbfb1cda5e2 100644 (file)
@@ -34,7 +34,7 @@ class Measurement
                void    get_measurement();
                void    thin_out();
                void    clear();
-               void    wait_for_equilibrium(float threshold = 0.01);
+               int             wait_for_equilibrium(float threshold = 0.01);
 };
 
 #endif // MEASUREMENT_H
index 6eadc2d6f42486482767bb29c8cd2714a632396b..3107f4bad8a8f9e796da73e2a4e19c8a2de7c173 100644 (file)
@@ -1,4 +1,5 @@
 #include "Measurement.h"
+#include "Servomatic.h"
 
 Measurement::Measurement(const PressureSensor &sensor)
        : m_size{0}
@@ -70,14 +71,16 @@ void        Measurement::clear()
 //
 // Using this we can then numerically optimize a. Interval halving is used
 // because it is foolproof and the evaluation is not computationally demanding.
-void   Measurement::wait_for_equilibrium(float threshold = 0.01)
+int    Measurement::wait_for_equilibrium(float threshold = 0.01)
 {
        clear();
        while (m_size < 20 || threshold < calc_equilibrium_dist())
        {
                get_measurement();
-               delay(m_interval_ms);
+               if (interuptable_delay(m_interval_ms))
+                       return (1);
        }
+       return (0);
 }
 
 float  Measurement::calc_equilibrium_dist() const
diff --git a/Servomatic.h b/Servomatic.h
new file mode 100644 (file)
index 0000000..763cd4c
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef SERVOMATIC_H
+# define SERVOMATIC_H
+
+int    interuptable_delay(unsigned long ms);
+
+#endif // SERVOMATIC_H
index 368bc603a36264c048b59bfcd2a9274d794655d9..a1d97da19066047a6857b2330d2a575dbe6c0dbf 100644 (file)
@@ -1,36 +1,91 @@
 #include "PressureSensor.h"
 #include "Valve.h"
+#include "CellValve.h"
 #include "Measurement.h"
+#include <avr/sleep.h>
 
 static const int       PRESSURE_SENSOR1_PIN = A1;
 static const int       PRESSURE_SENSOR2_PIN = A2;
 static const int       PRESSURE_SENSOR3_PIN = A3;
 
-static const int       SWITCH_PIN = 8;
+static const int       SWITCH_PIN = 2; // Only pins 2; 3 have external interrupts
 
-static const int       VALVE_THREEWAY_PIN = 9;
-static const int       VALVE_CELL_PIN = 10;
-static const int       VALVE_PRESSURE_SENSOR_PIN = 11;
+static const int       THREEWAY_VALVE_PIN = 9;
+static const int       CELL_VALVE_PIN = 10;
+static const int       PRESSURE_SENSOR_VALVE_PIN = 11;
+static const int       VACUUM_VALVE_PIN = 12;
 
-int    main()
+static volatile int    interrupt_happened{0};
+
+void   interrupt_routine()
 {
-       init();
-       Serial.begin(9600);
+       interrupt_happened = 1;
+}
 
-       main_loop();
+int    interruptable_delay(unsigned long ms)
+{
+       const unsigned int      start_time{millis()};
+
+       while (ms > millis() - start_time)
+               if (interrupt_happened == 1)
+                       return (1);
        return (0);
 }
 
+void   signal_going_to_sleep()
+{
+       delay(300);
+       digitalWrite(SWITCH_PIN, HIGH);
+       pinMode(SWITCH_PIN, OUTPUT);
+       delay(100);
+       pinMode(SWITCH_PIN, INPUT);
+}
+
+void   sleep()
+{
+       noInterrupts();
+       if (digitalRead(SWITCH_PIN) == LOW)
+       {
+               set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+               sleep_enable();
+               interrupts();
+               sleep_cpu();
+               sleep_disable();
+       }
+       else
+               interrupts();
+}
+
 void   main_loop()
 {
        PressureSensor  sensor_1{PRESSURE_SENSOR1_PIN, 10};
-       Valve                   test_valve{6, 760, 1600, 2400};
-       int                             usec;
        Measurement             measurement{sensor_1};
+       Valve                   vacuum_valve{VACUUM_VALVE_PIN, 760, 2400};
+       CellValve               cell_valve{CELL_VALVE_PIN, 760, 1600,  2400};
+       Valve                   gas_threeway_valve{THREEWAY_VALVE_PIN, 760, 2400};
 
        while (1)
        {
-               measurement.wait_for_equilibrium();
-               delay(10000);
+               while (!interrupt_happened && digitalRead(SWITCH_PIN) == HIGH)
+               {
+                       if (measurement.wait_for_equilibrium())
+                               break ;
+                       // Operate valves to prepare for next jump.
+               }
+               signal_going_to_sleep();
+               sleep();
+               interrupt_happened = 0;
        }
 }
+
+int    main()
+{
+       init();
+       Serial.begin(9600);
+       attachInterrupt(digitalPinToInterrupt(SWITCH_PIN), interrupt_routine,
+               CHANGE);
+       pinMode(SWITCH_PIN, INPUT);
+
+       main_loop();
+       return (0);
+}