Bật và tắt đèn LED bằng công tắc


10

Tôi đang cố gắng viết mã để bật đèn LED khi tắt và tắt khi bật bằng công tắc nút nhấn xúc giác. Tôi đã viết những gì tôi tin là mã đúng với thư viện WiredPi, nhưng tôi chỉ có thể bật nó khi nó tắt và không thể tắt nó sau đó. Trong những trường hợp rất hiếm và sau nhiều lần nhấn, đèn LED sẽ tắt khi bật và tôi nhấn nút, nhưng tôi chắc chắn đó không phải là cách nó hoạt động.

#include <wiringPi.h>
int main (void)
{
    wiringPiSetup ();
    pinMode (0, OUTPUT);
    pinMode (1, INPUT);
    digitalWrite (0, LOW);
    for(;;)
    {
        if(digitalRead (1) == LOW)
        {
            if(digitalRead (0) == HIGH)
                digitalWrite (0, LOW);
            else if(digitalRead (0) == LOW)
                digitalWrite (0, HIGH);
         }
     }
     return 0;
}

Tôi đã đính kèm một hình ảnh về cách mạch có dây.Đèn led

c 

2
Có thư viện của bạn bao gồm bất kỳ gỡ lỗi cho chuyển đổi? Nếu không, có lẽ bạn đang tắt đèn LED thành công và ngay lập tức bật lại. Khi bạn đã phát hiện thay đổi trạng thái, hãy bỏ qua mọi phát hiện tiếp theo trong một thời gian ngắn.

1
@MikeW Tôi không tin như vậy. Tôi sẽ thử chèn một độ trễ sau khi câu lệnh if được xử lý.

6
@duskwuff Câu hỏi này chắc chắn là về lập trình.

1
giữ một biến cục bộ có chứa trạng thái hiện tại của led (ON / OFF) (có thể thông qua enum) không cố đọc trạng thái của pin đầu ra. Thay vào đó, hãy phát hiện cạnh của thay đổi trạng thái đầu vào từ cao xuống thấp của chân đầu vào. sau đó cập nhật trạng thái hiện tại của biến cục bộ: outputimagevar = (outputimagevar == CAO)? CAO THẤP; sau đó là DigitalWrite (0, outputimagevar); sau đó, khi đầu vào thay đổi từ THẤP sang CAO, hãy đặt lại logic phát hiện CAO thành THẤP. Ngoài ra, hãy chắc chắn 'gỡ bỏ' trạng thái đầu vào, có lẽ bằng cách đảm bảo (giả sử) 3 lần đọc liên tiếp đều hiển thị cùng một trạng thái.

Những gì tôi vừa làm là chèn một nửa giây trễ bên trong tổ của mỗi câu lệnh if và nó dường như hoạt động ngay lúc này. Một cái gì đó cho tôi biết đây là một phương pháp bruteforce sẽ không luôn hoạt động như tôi có thể dự đoán nếu nút được nhấn nhanh hơn nửa giây và có lẽ nó sẽ không hoạt động như vậy trong dự án chính của tôi, vì vậy tôi sẽ xem xét phần còn lại của câu trả lời. Tôi đánh giá cao đầu vào của mọi người.

Câu trả lời:


4

Hệ thống dây có vẻ đúng cho mã.

Vấn đề là mã nằm trong một vòng lặp rất chặt chẽ. Về lý thuyết, khi nhấn nút, thân vòng lặp liên tục bật và tắt đèn LED. Về lý thuyết, sẽ có 50/50 khả năng đèn LED được bật (hoặc tắt) khi nút được nhả. Bạn có nhận thấy sự thay đổi độ sáng khi nhấn nút. Có thể không đủ để được chú ý.

Trong thực tế, lý do cho xu hướng bật đèn LED là cách bạn kiểm tra xem nó đã được bật chưa. Viết pin 0 CAO áp dụng 3,3 V cho đầu ra. Nhưng dây đó được kết nối với đèn LED và chân được cấu hình là đầu ra. Đèn LED có thể giảm điện áp đủ thấp để không đăng ký là CAO khi được đọc, nhưng đôi khi nó xảy ra vì nó ở gần ngưỡng.

Trong thực tế, mã để tắt và bật đèn LED với mỗi lần nhấn nút sẽ sử dụng ngắt kích hoạt cạnh rơi. Như đã chỉ ra trong các ý kiến, bạn sẽ muốn gỡ lỗi ngắt trong trường hợp đó. Bạn cũng có thể làm điều tương tự mà không bị gián đoạn bằng cách ghi lại trạng thái trước đó của nút và chỉ thay đổi đèn LED khi trạng thái nút đã thay đổi. Tranh luận như mã được viết bây giờ không có ý nghĩa.

#include <wiringPi.h>
int main (void)
{
    wiringPiSetup ();
    pinMode (0, OUTPUT);
    pinMode (1, INPUT);
    digitalWrite (0, LOW);

    int prevButton = HIGH, LED = 0;

    for(;;)
    {
        if(prevButton == HIGH && digitalRead(1) == LOW)  // a falling edge
        {
            prevButton = LOW;

            if(LED)
            {
                LED = 0;
                digitalWrite(0, LOW);
            }
            else
            {
                LED = 1;
                digitalWrite(0, HIGH);
            }
        }
        else if(prevButton == LOW && digitalRead(1) == HIGH)  // a rising edge, do nothing
        {
            prevButton = HIGH;
        )

        // Add a delay here to debounce the button 

    }
    return 0;
}

0

Có lẽ đơn giản hơn để duy trì "trạng thái" trong các biến thông thường thay vì cố gắng suy ra nó từ trạng thái GPIO hiện tại.

Ngoài ra, "vòng lặp bận" sẽ tiêu tốn mọi chu kỳ CPU mà HĐH sẽ cho phép xử lý; với quy trình đơn giản như vậy, bạn sẽ thấy tải CPU của mình sẽ tăng lên 100%! Bạn nên cho phép quá trình từ bỏ CPU sang các tác vụ khác bằng một usleep()cuộc gọi chẳng hạn. Sự chậm trễ cũng sẽ phục vụ cho việc bật lại công tắc.

#include <wiringPi.h>
#include <unistd.h>

int main (void)
{
  wiringPiSetup ();
  pinMode (0, OUTPUT);
  pinMode (1, INPUT);
  digitalWrite (0, LOW);

  // Initial state
  int led = LOW ;
  bool button_down = (digitalRead(1) == LOW) ;

  for(;;)
  {
    // If button-down event (Hi-lo transition)...
    if( !button_down && digitalRead(1) == LOW )
    { 
      // Keep button state
      button_down = true ;

      // Toggle LED state
      led = (led == LOW) ? HIGH : LOW ;
      digitalWrite( 0, led ) ;
    }
    // Button up event...
    else if( button_down && digitalRead(1) == HIGH ) 
    {
      // Keep button state
      button_down = false ;
    }

    usleep( 10000 ) ;
  }

  return 0;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.