เปิดและปิด LED ด้วยสวิตช์


10

ฉันพยายามเขียนรหัสเพื่อให้ LED เปิดเมื่อปิดและปิดเมื่อเปิดสวิตช์ปุ่มกดแบบสัมผัส ฉันเขียนสิ่งที่ฉันเชื่อว่าเป็นรหัสที่ถูกต้องกับห้องสมุด wiringPi แต่ฉันสามารถเปิดใช้งานได้เมื่อปิดเท่านั้นและไม่สามารถปิดใช้งานได้หลังจากนั้น ในกรณีที่หายากมากและหลังจากกดซ้ำหลายครั้งไฟ LED จะดับเมื่อเปิดใช้งานและฉันกดปุ่ม แต่ฉันแน่ใจว่านั่นไม่ใช่วิธีการทำงาน

#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;
}

ฉันได้แนบภาพว่าวงจรมีสายอย่างไรLEDciruit

c 

2
ห้องสมุดของคุณมี debounce สำหรับสวิตช์หรือไม่ หากไม่ใช่คุณอาจปิด LED เรียบร้อยแล้วจึงเปิดใหม่ทันที เมื่อคุณตรวจพบการเปลี่ยนแปลงสถานะจะไม่สนใจการตรวจจับใด ๆ เพิ่มเติมในช่วงเวลาสั้น ๆ

1
@ MikeW ฉันไม่เชื่อเช่นนั้น ฉันจะลองแทรกการหน่วงเวลาหลังจากประมวลผลคำสั่ง if

6
@duskwuff คำถามนี้แน่นอนเกี่ยวกับการเขียนโปรแกรม

1
เก็บตัวแปรโลคัลที่มีสถานะปัจจุบันของ led (เปิด / ปิด) (อาจผ่าน enum) อย่าพยายามอ่านสถานะของเอาต์พุตขา แทนที่จะตรวจจับขอบของสถานะอินพุตเปลี่ยนจากสูงไปต่ำของพินอินพุต จากนั้นอัพเดตสถานะปัจจุบันของตัวแปรโลคัล: outputimagevar = (outputimagevar == HIGH)? สูงต่ำ; จากนั้น digitalWrite (0, outputimagevar); จากนั้นเมื่ออินพุตเปลี่ยนจาก LOW เป็น HIGH ให้รีเซ็ตตรรกะการตรวจจับ HIGH เป็น LOW นอกจากนี้ตรวจสอบให้แน่ใจว่าได้ 'debounce' สถานะอินพุตบางทีโดยให้ความมั่นใจ (พูด) 3 อ่านติดต่อกันแสดงทั้งหมดแสดงสถานะเดียวกัน

สิ่งที่ฉันเพิ่งทำคือการแทรกการหน่วงเวลาครึ่งวินาทีภายในรังของคำสั่ง if และดูเหมือนว่าจะทำงานได้ในเวลานี้ มีบางอย่างบอกฉันว่านี่เป็นวิธีการ bruteforce ที่ไม่ได้ผลเสมอไปถ้าฉันกดปุ่มเร็วกว่าครึ่งวินาทีและมันอาจจะไม่ทำงานอย่างนั้นในโครงการหลักของฉันดังนั้นฉันจะดู ส่วนที่เหลือของคำตอบ ฉันซาบซึ้งในความคิดเห็นของทุกคน

คำตอบ:


4

การเดินสายมีลักษณะที่ถูกต้องสำหรับรหัส

ปัญหาคือรหัสอยู่ในวงที่แน่นมาก ในทางทฤษฎีเมื่อกดปุ่มตัวลูปจะเปิดและปิด LED ซ้ำ ๆ ในทางทฤษฎีจะมีโอกาส 50/50 ที่ LED จะเปิด (หรือปิด) เมื่อปล่อยปุ่ม คุณสังเกตเห็นการเปลี่ยนแปลงของความสว่างเมื่อกดปุ่ม อาจสังเกตไม่พอ

ในทางปฏิบัติเหตุผลสำหรับแนวโน้มที่จะเปิดไฟ LED เป็นวิธีที่คุณทดสอบเพื่อดูว่าเปิดอยู่แล้ว การเขียนพิน 0 HIGH ใช้ 3.3 V กับเอาต์พุต แต่สายนั้นเชื่อมต่อกับ LED และพินที่กำหนดค่าให้เป็นเอาท์พุท LED อาจลดแรงดันไฟต่ำพอที่จะไม่ลงทะเบียนเป็น HIGH เมื่ออ่าน แต่บางครั้งก็เป็นเพราะใกล้กับทางลัด

ในทางปฏิบัติรหัสที่จะปิดและเปิดไฟ LED ด้วยการกดปุ่มแต่ละปุ่มจะใช้สัญญาณขัดจังหวะ ตามที่ระบุไว้ในความคิดเห็นที่คุณต้องการ debounce การขัดจังหวะในกรณีนั้น คุณสามารถทำสิ่งเดียวกันโดยไม่ขัดจังหวะด้วยการบันทึกสถานะก่อนหน้าของปุ่มและเปลี่ยน LED เฉพาะเมื่อสถานะปุ่มเปลี่ยนไป การเปิดใช้งานการถอดรหัสในขณะนี้ไม่สมเหตุสมผล

#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

มันอาจจะง่ายกว่าในการรักษา "สถานะ" ในตัวแปรปกติแทนที่จะพยายามอนุมานจากสถานะ GPIO ปัจจุบัน

นอกจากนี้ "busy-loop" จะใช้ CPU รอบ ๆ ทุกระบบจะอนุญาตให้กระบวนการ สำหรับกระบวนการง่ายๆคุณจะเห็นว่าโหลด CPU ของคุณจะเพิ่มขึ้นถึง 100%! คุณควรอนุญาตให้กระบวนการปล่อยซีพียูไปยังงานอื่นด้วยการusleep()โทร ความล่าช้าจะทำหน้าที่ในการยกเลิกการตีกลับสวิตช์

#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;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.