Перво-наперво, что код, как вы показали, что это будет никогда отклоняться от задержки 2000
просто потому, что нет никакого способа, чтобы выйти из начального for(;;)
цикла. Это, вероятно, первый вещь, которую вы должны проверить и исправить.
С точки зрения того, чтобы быть в состоянии закончить задержку рано, вы можете сделать что-то вроде изменения:
delay (2000);
в:
for (i = 0; i < 2000; i += 10) {
delay (10);
if (digitalRead (IN) == 1)
break;
}
Это в основном выходит из задержки в начале, если переключатель изменения, так что вы никогда не будете ждать более 10 единиц времени (а не до 2000).
Просто имейте в виду, что может потребоваться накладные расходы для многократного вызова задержки. Другими словами, в то время как delay(2000)
может принимать очень близко к 2000 единицам времени, двести вызовов до delay(10)
могут занять немного больше из-за времени установки для каждого вызова и так далее.
Фактически, вы, вероятно, можете значительно упростить свой код, не используя жестко закодированные значения вообще. Вместо этого вы можете иметь один цикл с минимальной задержкой, с некоторыми внутренними элементами управления, которые работают, когда и как менять светодиод (т. Е. Не каждые время через цикл).
Например, что-то подобное сделало бы это. Я не проверял, так как мой Pi2 все еще сидит в коробке ждет какое-то время для меня, чтобы играть с ним, но он должен быть очень близко:
#include <wiringPi.h>
#include <stdio.h>
#define LED 18
#define IN 24
#define RES 10
int main (void) {
int cycleTime, ledState, lastSwitch, currSwitch, timeLeft;
wiringPiSetupGpio();
pinMode (LED, OUTPUT);
pinMode (IN, INPUT);
cycleTime = 2000; // Initial cycle time
ledState = 0; // and LED state.
lastSwitch = 0; // Previous switch state,
// Start infinite loop with first cycle time.
timeLeft = cycleTime;
for (;;) {
// Delay for minimal time and adjust time left.
delay (RES);
timeLeft = timeLeft - RES;
// Detect switch change.
currSwith = digitalRead (IN);
if (currSwitch != lastSwitch) {
// If so, store new state, change cycle time
// and force IMMEDIATE end of current cycle.
lastSwitch = currSwitch;
cycleTime = 2500 - cycleTime; // switch 500 <-> 2000
timeLeft = 0;
}
// Detect end of cycle.
if (timeLeft <= 0) {
// Toggle LED and start new cycle.
ledState = 1 - ledState;
digitalWrite (LED, ledState);
timeLeft = cycleTime;
}
}
}
В принципе, у вас есть один цикл, кроме одного, который петли каждые десять раз, а не каждые 500 или 2000. У вас есть отдельный счетчик, который решает, когда светодиод должен быть перевернут, а начальное значение для этого счетчика зависит от текущего времени цикла.
Когда переключатель перевернут, этот счетчик обнуляется, чтобы он (почти) сразу же изменился на следующий цикл.