// https://wokwi.com/projects/448822516009346049
// https://forum.arduino.cc/t/control-system-and-ui-control-rc-servo-according-to-incoming-pulses-from-inductive-sensor/1416579
# include <Servo.h>
Servo theServo;
# define thePulse 2 // input pulses on pin 2
# define ONOFF 3 // do or don't
// as periods in microseconds
const unsigned long minPulse = 34468ul; // ~30 Hz, low end
const unsigned long maxPulse = 2868ul; // ~350 Hz, high end
// corresponding servo degrees
const int minDeflection = 5;
const int maxDeflection = 175;
# define PARK 60 // when off, park here
float minFrequency;
float maxFrequency;
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
Serial.begin(115200);
Serial.println("\nCrude frequency -> servo pos.\n");
theServo.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(ONOFF, INPUT_PULLUP);
pinMode(thePulse, INPUT_PULLUP); // Set interrupt pin as input with internal pull-up resistor
attachInterrupt(digitalPinToInterrupt(thePulse), pulseISR, RISING);
minFrequency = 1.0 / maxPulse;
maxFrequency = 1.0 / minPulse;
}
volatile unsigned long edgeToEdge;
// each rising edge triggers this function
void pulseISR() {
static unsigned long lastEdge;
unsigned long thisEdge;
thisEdge = micros();
edgeToEdge = thisEdge - lastEdge;
lastEdge = thisEdge;
}
// a little Algebra
float fmap(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void loop() {
if (digitalRead(ONOFF) == LOW) {
theServo.write(PARK);
return; // we done!
}
// else... check if there's a plausible measurement and move the servo accordianly
unsigned long now = millis(); // the time for this entire pass
noInterrupts();
unsigned long myE2E = edgeToEdge;
interrupts();
if (maxPulse <= myE2E && myE2E <= minPulse) {
float frequency = 1.0 / myE2E;
int deflection = fmap(frequency, minFrequency, maxFrequency, minDeflection, maxDeflection);
theServo.write(deflection);
}
// periodically print the edgeToEdge value
// as a check
static unsigned long lastCheck;
if (now - lastCheck > 777) {
Serial.println(myE2E);
lastCheck = now;
}
}
// turtles all the way down
// from the wokwi demo for the pulse generator IC
/*
Flow Sensor Counter Meter FS300A G3/4
Flow rate : 1-60L/min
Flow Pulse: 508 pulse / Liter
Description: This code interfaces with the FS300A flow sensor to measure flow rate and frequency. It handles interrupt-driven pulse counting and calculates the corresponding flow rate based on the sensor specifications.
#define FS300A_PULSE 508 // Number of pulses per liter
#define FS300A_FLOW_RATE 60 // Maximum flow rate in liters per minute
const float factor = 60.0F / 508.0F; // Conversion factor from pulses to flow rate (FS300A_FLOW_RATE / FS300A_PULSE)
#define interruptPin 2 // Define interrupt pin for flow sensor
uint16_t pulse; // Variable to store pulse count
uint16_t count; // Variable to store pulse count for calculation
float frequency; // Variable to store frequency
float flowRate; // Variable to store flow rate
bool busy; // Flag to indicate interrupt handling status
void setup() {
Serial.begin(115200); // Initialize serial communication at 115200 baud
pinMode(interruptPin, INPUT_PULLUP); // Set interrupt pin as input with internal pull-up resistor
attachInterrupt(digitalPinToInterrupt(interruptPin), FlowInterrupt, CHANGE); // Attach interrupt handler to the interrupt pin
}
void loop() {
Frequency(); // Call frequency measurement function
}
void FlowInterrupt() {
busy = true; // Set busy flag to indicate interrupt handling
pulse++; // Increment pulse count
busy = false; // Clear busy flag after interrupt handling
}
void Frequency() {
static unsigned long startTime;
if (micros() - startTime < 1000000UL ) return; // Check if 1000 milliseconds interval has passed
startTime = micros();
while (busy) {}; // Wait for interrupt handling to complete
uint8_t sreg = SREG; // Save status register
cli(); // Disable interrupts
count = pulse; // Save pulse count for calculation
pulse = 0; // Reset pulse count
SREG = sreg; // Restore status register
frequency = count / 2.0f; // Calculate frequency
flowRate = frequency * factor; // Calculate flow rate
PlotInfo(); // Display information
}
void PlotInfo() {
Serial.print("Freq.:= " + String(frequency, 2) + " Hz"); // Print frequency with 2 decimal places
Serial.println(", FLow:= " + String(flowRate, 3) + " L/min"); // Print flow rate with 3 decimal places
}
*/
//;
;
//;