I've set up an ISR to trigger on the RISING
edge of pin #2, but I find that if pin 2 is held high, the ISR triggers repeatedly.
Here's a trace of the voltage measured right at the pin:
Scope trace of voltage at pin 2
I can see a little bit of noise, but it shouldn't be enough to trigger multiple pulses. I've tried both INPUT
and INPUT_PULLUP
modes for the pin; behavior is the same.
constexpr byte kClockPin = 2;
constexpr byte kReadWritePin = 3;
constexpr byte kLedPin = 13;
constexpr int kNumAddressPins = 16;
constexpr byte kAddressPins[] = {/* MSB */52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22};
constexpr int kNumDataPins = 8;
constexpr byte kDataPins[] = {/* MSB */45, 43, 41, 39, 37, 35, 33, 31};
volatile bool dirty = false;
volatile uint8_t data = 0;
volatile uint16_t address = 0;
volatile bool read = false;
void setup() {
// put your setup code here, to run once:
pinMode(kClockPin, INPUT_PULLUP);
pinMode(kReadWritePin, INPUT);
for (byte pin : kAddressPins) {
pinMode(pin, INPUT);
}
for (byte pin : kDataPins) {
pinMode(pin, INPUT);
}
pinMode(kLedPin, OUTPUT);
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(kClockPin), OnClock, RISING);
}
void loop() {
// digitalWrite(kLedPin, digitalRead(kClockPin));
if (!dirty) return;
char output[15];
sprintf(output, "%04x %c %02x", address, read ? 'r' : 'w', data);
Serial.println(output);
dirty = false;
// digitalWrite(kLedPin, digitalRead(kClockPin));
}
void OnClock() {
read = digitalRead(kReadWritePin);
data = 0;
for (byte pin : kDataPins) {
data = (data << 1) + (digitalRead(pin) ? 1 : 0);
}
address = 0;
for (byte pin : kAddressPins) {
address = (address << 1) + (digitalRead(pin) ? 1 : 0);
}
dirty = true;
}
1 Answer 1
Turns out the short answer is that I'm still not great at using an oscilloscope.
Longer version is that the noise was very visible at smaller time scales. A filter capacitor had come disconnected from the breadboard in a way that was hard to see, and that was causing a whole bunch of noise. Replacing it fixed the problem.