// Arduino Mega: read TWO 555 OUT signals on D2 and D3 (INT0/INT1)
// Counts edges on CHANGE for 1-second windows and prints frequency per channel
// Auto unit printing: Hz / kHz / MHz
const byte IN1_PIN = 2; // 555 #1 OUT -> D2 (INT0)
const byte IN2_PIN = 3; // 555 #2 OUT -> D3 (INT1)
volatile unsigned long edges1 = 0;
volatile unsigned long edges2 = 0;
// ---- ISRs: keep them short (increment only) ----
void ISR_edge1() { edges1++; }
void ISR_edge2() { edges2++; }
// ---- Helper: print frequency with automatic units ----
void printAutoHz(float hz) {
if (hz >= 1.0e6f) {
Serial.print(hz / 1.0e6f, 3); Serial.print(F(" MHz"));
} else if (hz >= 1.0e3f) {
Serial.print(hz / 1.0e3f, 3); Serial.print(F(" kHz"));
} else {
Serial.print(hz, 2); Serial.print(F(" Hz"));
}
}
void setup() {
Serial.begin(115200);
pinMode(IN1_PIN, INPUT_PULLUP);
pinMode(IN2_PIN, INPUT_PULLUP);
// Count both edges from the 555 square wave
attachInterrupt(digitalPinToInterrupt(IN1_PIN), ISR_edge1, CHANGE);
attachInterrupt(digitalPinToInterrupt(IN2_PIN), ISR_edge2, CHANGE);
Serial.println(F("Dual 555 frequency monitor (D2 & D3, CHANGE mode)"));
Serial.println(F("CH1=D2, CH2=D3"));
}
void loop() {
static unsigned long tPrev = millis();
const unsigned long now = millis();
const unsigned long elapsed = now - tPrev;
if (elapsed >= 1000UL) {
tPrev += 1000UL; // keeps schedule tight; reduces long-term drift
// ---- Atomic snapshots ----
noInterrupts();
unsigned long e1 = edges1; edges1 = 0;
unsigned long e2 = edges2; edges2 = 0;
interrupts();
// CHANGE counts two edges per cycle; compute using actual elapsed time
const float seconds = (float)elapsed * 0.001f;
const float freq1 = (seconds > 0) ? ( (e1 * 0.5f) / seconds ) : 0.0f;
const float freq2 = (seconds > 0) ? ( (e2 * 0.5f) / seconds ) : 0.0f;
// ---- Print nicely with auto units ----
Serial.print(F("CH1: "));
printAutoHz(freq1);
Serial.print(F(" CH2: "));
printAutoHz(freq2);
Serial.println();
}
}