2015-05-07 3 views
1

Это мой код:Raspberry Pi, зацикливание функции задержки

#include <wiringPi.h> 
#include <stdio.h> 

#define LED 18 
#define IN 24 

int main(void) 
{ 
     wiringPiSetupGpio(); 
     pinMode (LED, OUTPUT); 
     pinMode (IN, INPUT); 
     for (;;) 

     { 
         digitalWrite (LED, 1); 
         delay (2000); 
         digitalWrite (LED, 0); 
         delay (2000); 
     } 
     if (digitalRead (IN) == 1) 
     { 
     for (;;) 

     { 
         digitalWrite (LED, 1); 
         delay(500); 
         digitalWrite (LED, 0); 
         delay(500); 
     } 
     } 

     return 0; 
} 

Я использую переключатель, чтобы перейти от 2000 задержки до 500 задержки. Проблема в том, что когда я нажимаю переключатель, он ждет, пока цикл не закончится, пока он не станет быстрее. То же самое относится и к наоборот. Мне нужно написать функцию или петлю где-нибудь в моем коде, что позволяет мне нажимать переключатель и сразу же без ожидания перейти на более медленную/более быструю скорость. Я кодирую это в C, на малине pi, используя библиотеки pi для проводки, и нумерацию букв gpio.

ответ

1

Перво-наперво, что код, как вы показали, что это будет никогда отклоняться от задержки 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. У вас есть отдельный счетчик, который решает, когда светодиод должен быть перевернут, а начальное значение для этого счетчика зависит от текущего времени цикла.

Когда переключатель перевернут, этот счетчик обнуляется, чтобы он (почти) сразу же изменился на следующий цикл.