Delay klidně zkrať na těch 20-50 ms. Co se ovládání stiskem týká, tak si musíš uložit načtený stav tlačítka jako minulý a v příští smyčce porovnávat nově načtený stav s tím minulým. Pokud nejsou stavy shodné, víš, že nastala změna. A pokud nastala změna, tak podle nového stavu tlačítka změníš (nebo nezměníš) stav LEDky.
Snad jsem to napsal dostatečně srozumitelně.
Těch 300ms musíš držet tlačítko proto, že program tráví 99.999999999% času v delay smyčkách. Provedení zbytku trvá rádově jednotky us. Program nečeká na stisk klávesy. Program během pár us zkontroluje PIND a jde na 300ms makat na čekání a znova. Je tedy pravděpodobnější, že se trefíš do tý čekací smyčky, než do kontroly PIND. Kromě toho, pokud jsi stisknul tlačítko, máš LEDku zhasnutou a program zrovna skočil do čekací smyčky, které následuje po kontrole PIND na rozsvícení, tak může klidně čekat až 600ms na rozsvícení.
Prostě program má vypadat nějak takto :
1) načtení tlačítka
2) je nová hodnota stejná jako stará ?
3a) ano - nic
3b) ne - 4) je tlačítko stisknuto ? - 5a) ano - přepnout LEDku
5b) ne - nic
6) krátký delay
7) jdi na 1