const uint8_t MONITOR_MASK = 0b11111111; // Überwache D0–D7 volatile uint16_t ringBuffer[8] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; volatile uint8_t sum[8] = {16, 16, 16, 16, 16, 16, 16, 16}; volatile bool portDLow = 0b00000000; volatile bool portDHigh = 0b11111111; ISR(TIMER1_COMPA_vect) { uint8_t portValue = PIND & MONITOR_MASK; // z. B. D2–D7 for (uint8_t i = 0; i < 8; i++) { if (!(MONITOR_MASK & (1 << i))) continue; uint8_t newBit = (portValue >> i) & 1; uint8_t oldBit = (ringBuffer[i] & 0x8000) ? 1 : 0; // Ältestes Bit extrahieren (MSB) ringBuffer[i] = (ringBuffer[i] << 1) | newBit; // Shift + neues Bit sum[i] += newBit - oldBit; // Summe anpassen if (sum[i] == 4 && newBit == 0) { // Schwellenwert prüfen portDLow |= (1 << i); // Setze Bit i in portDLow } if (sum[i] == 12 && newBit == 1) { // Schwellenwert prüfen portDHigh |= (1 << i); } } } void setup() { cli(); // Interrupts deaktivieren // --------- Timer1 Setup: CTC Mode, 3.2kHz ---------- TCCR1A = 0; TCCR1B = (1 << WGM12) | (1 << CS10); // CTC mode, Prescaler = 1 // CCR1B = (1 << WGM12) | (1 << CS11);// Prescaler 8 // TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // Prescaler 64 OCR1A = 999; // 1auf 16.000 kHz mit 999 TIMSK1 = (1 << OCIE1A); // Compare Match Interrupt aktivieren sei(); // Interrupts aktivieren Serial.begin(115200); DDRD=0b00000000; // set all pins as input; PORTD=0b11111111; DDRB=0b00111111; // set pins 0..5 as output } void loop() { noInterrupts(); uint8_t pending = portDLow; portDLow = 0; interrupts(); PORTB=pending&0b00111111; /* while (pending) { uint8_t i = __builtin_ctz(pending); // Index des niedrigsten gesetzten Bits pending &= pending - 1; // Dieses Bit löschen Serial.print("Pin D"); Serial.print(i); Serial.print(" unter Schwellwert! "); } */ delayMicroseconds(500); }