#include // config: const int pinData = 6; const int pinStatus = 7; // fixed values const int timerDelay = 500; void setup(void) { pinMode(pinData, OUTPUT); digitalWrite(pinData, HIGH); Timer1.initialize(timerDelay); Timer1.attachInterrupt(clockCycle); Timer1.stop(); pinMode(pinStatus, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(pinStatus), statusCycle, CHANGE); Serial.begin(9600); } volatile long lastChange = 0; volatile int x = 0; volatile int dataWord = 0; volatile int dataState = 0; volatile int dataDelay = 0; volatile int packetDelay = 0; volatile int packetTail = 0; volatile int clkState = HIGH; volatile bool nextKeyReady = false; volatile byte nextKey = 0; void typeKey(byte key) { noInterrupts(); nextKeyReady = true; nextKey = key; interrupts(); } void sendKey(byte key) { noInterrupts(); dataWord = key; dataState = 8; dataDelay = 0; packetDelay = 0; packetTail = 10; clkState = HIGH; interrupts(); Timer1.initialize(timerDelay); Timer1.start(); } void statusCycle() { long timeNow = millis(); long changeDiff = timeNow - lastChange; lastChange = timeNow; if (changeDiff >= 10 && nextKeyReady) { sendKey(nextKey); nextKeyReady = false; } } void clockCycle(void) { int dataBit = HIGH; if (clkState == LOW) { clkState = HIGH; } else { clkState = LOW; } if (packetDelay > 0) { packetDelay--; } else if (dataDelay > 0) { dataDelay--; dataBit = LOW; } else if (dataState > 0) { int bitToSend = (dataWord >> (dataState - 1)) & 1; dataBit = !bitToSend ? LOW : HIGH; dataState--; } else if (packetTail > 0) { packetTail--; dataBit = LOW; } else { Timer1.stop(); } digitalWrite(pinData, dataBit); } void loop(void) { delay(50); if (Serial.available() > 0) { long key = Serial.parseInt(SKIP_ALL); if (key != 0) { typeKey(key); } } }