73 lines
1.7 KiB
C++
73 lines
1.7 KiB
C++
#include <Servo.h>
|
||
|
||
Servo myServo; // Create a Servo object
|
||
const int servoPin = 10; // D10 is OC1B on Pro Mini
|
||
const int ledPin = 13;
|
||
const int analogPin = A0;
|
||
const int SensorPin = 2;
|
||
|
||
volatile uint16_t pulses = 0,ppm = 0; //pulse per minute
|
||
|
||
|
||
// Interrupt Service Routine (ISR)
|
||
void INT0_ISR() {
|
||
pulses++;
|
||
}
|
||
|
||
void setup_timer() {
|
||
|
||
// Stop Timer2
|
||
TCCR2A = 0;
|
||
TCCR2B = 0;
|
||
TCNT2 = 0;
|
||
// Set compare match value for 100ms
|
||
// Clock = 16 MHz, Prescaler = 1024
|
||
// Tick = 16,000,000 / 1024 = 15,625 ticks/sec
|
||
// 100ms = 0.1s → 0.1 * 15625 = 1562.5 ticks
|
||
// Since Timer2 is 8-bit, we can't reach 1562 in one cycle.
|
||
// So we will count multiple compare matches.
|
||
OCR2A = 50; // Compare match every ~16ms (250 counts at 1024 prescaler)
|
||
// CTC mode
|
||
TCCR2A |= (1 << WGM21);
|
||
// Prescaler = 1024
|
||
TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
|
||
// Enable compare match interrupt
|
||
TIMSK2 |= (1 << OCIE2A);
|
||
// Enable global interrupts
|
||
sei();
|
||
}
|
||
|
||
void setup() {
|
||
pinMode(ledPin, OUTPUT);
|
||
Serial.begin(115200); // Initialize Serial
|
||
myServo.attach(servoPin); // Attach servo to pin 10
|
||
|
||
attachInterrupt(digitalPinToInterrupt(SensorPin), INT0_ISR, FALLING);
|
||
setup_timer();
|
||
}
|
||
|
||
void loop() {
|
||
int analogValue = analogRead(analogPin); // Read from A0 (0–1023)
|
||
int angle = map(analogValue, 0, 1023, 0, 180); // Map to 0–180 degrees
|
||
Serial.print("pulses: ");
|
||
Serial.println(pulses);
|
||
|
||
myServo.write(angle); // Set servo angle
|
||
|
||
delay(1000);
|
||
}
|
||
|
||
|
||
ISR(TIMER2_COMPA_vect) {
|
||
static uint16_t ticks = 0;
|
||
static bool ledState = false;
|
||
ticks++;
|
||
if (ticks >= 150) { // 150 => 1s
|
||
ticks = 0;
|
||
ledState = !ledState;
|
||
ppm = pulses;
|
||
pulses = 0;
|
||
digitalWrite(ledPin, ledState);
|
||
}
|
||
}
|