مشاهدة LED Shadowplay على منصة Arduino Uno

بدلاً من الانضمام




لذلك ، كان على فريقنا المكون من ثلاثة أشخاص المهمة: تجميع مشروع صغير للأجهزة في وقت قصير جدًا ، ويفضل أن يكون ذلك على منصة Arduino. ومن الجدير بالذكر أنه حتى تلك اللحظة كنا على دراية بالدوائر ، من الناحية النظرية. وهذا يعني - لا تجربة مع لحام الحديد (عمليا) ، ولا سيما تجربة Arduino.

فجأة تعثرنا على مقالمخصصة لمشروع Shadowplay Clock. هذه ساعة حائط صممها فريق من مصممي فيينا ، وهو الوقت الذي يمكنك رؤيته من خلال لمس إصبعك في مركزهم. تضيء مصابيح LED بطريقة تُظهر ظل الإصبع في المنتصف الوقت. تقرر إنشاء نفس (أو متشابه جدًا) ، ولكن في المنزل. المقالة أعلاه ، كما ترون ، لا تحتوي على وصف تفصيلي للمشروع. من كل هذا ، تبع ذلك أننا اضطررنا إلى معرفة كيفية عمل هذا الجهاز وإعادته إلى الحياة. ما فعلناه ، في الواقع.

المواد


لإنشاء ساعة ، تحتاج إلى:

  • الفراغات اللوح الليفي
  • 60 شريط الصمام الثنائي
  • اردوينو أونو
  • RTC DS1307 وحدة ساعة الوقت الحقيقي
  • زر
  • اللوح
  • سجل المناوبة 74HC595 (x2)
  • مزلاج تسجيل 8 بت 74HC573N (x8)
  • وحدة فك الترميز 4-16 K155ID3
  • فتح العاكس الصرف IN74HC05AN (x10)
  • وحدة الطاقة

دعنا نبدأ


إذن ، خوارزمية الجهاز:

  1. عند تطبيق الطاقة ، يتم تشغيل مصابيح LED في المجموعة المحددة. في لعبة Shadowplay الأصلية ، أضاءت جميع مصابيح LED ، ولكن بدا لنا أنه سيكون أكثر إثارة للاهتمام إطلاق بعض التركيبة كشاشة توقف.
  2. عند الضغط على الزر (نعم ، انتقلنا أيضًا بعيدًا عن الأصلي وأدخلنا زرًا صغيرًا في المنتصف) ، تتم قراءة الوقت من وحدة RTC.
  3. يتم تحويل وقت القراءة إلى رمز ثنائي (قناع) وإدخاله في السجلات.
  4. اعتمادا على القناع ، يتم إشعال الصمام الثنائي المطلوب.

الأجهزة


عندما قررنا أخيرًا فكرة المشروع ، كان أول شيء جربناه هو رسم النماذج التقريبية للمخططات لتنفيذه. كان السؤال الرئيسي هو كيفية معالجة 60 LEDs. في الواقع ، حددت الإجابة على هذا السؤال طريقة بناء المخطط بأكمله تقريبًا.

كان الخيار الأول الذي يتبادر إلى الذهن هو استخدام أجهزة فك التشفير. كانت الدائرة المترجمة عبارة عن سلسلة من أربعة أجهزة فك تشفير 4-16 وفك تشفير واحد 2-4 ، كلاهما مع مدخلات تمكين فك التشفير. سمحت هذه السلسلة المتتالية بمعالجة 64 ناتجًا ، وهو ما كان أكثر من كافٍ لتوصيل 60 مصباح LED.

ومع ذلك ، ثار السؤال حول كيفية جعل أكثر من عمل LED (العنوان) واحد في نفس الوقت (بعد كل شيء ، كنا بحاجة إلى تزويد الساعة بالدقيقة وعقارب الساعة على الأقل). هنا يتجلى العيب الرئيسي لهذا المخطط - لا يمكن لمفكك التشفير ، بحكم تعريفه ، معالجة أكثر من ناتج واحد في كل مرة.

أجبرنا هذا الخلل على التخلي عن الفكرة مع سلسلة من أجهزة فك التشفير. بالإضافة إلى ذلك ، لدينا الآن متطلبات أخرى للدائرة المستقبلية - دعم التشغيل المتزامن لعدد مختلف من مصابيح LED.

لتلبية هذا المطلب ، اعتقدنا أنه من الممكن تمكين كل LED لتخزين حالته. تعتبر السجلات مناسبة تمامًا لهذا الغرض ، حيث يتوافق كل تفريغ فردي مع حالة أحد مصابيح LED. قررنا استخدام سجلات 8 بت ، لأنها أكثر شيوعًا وأكثر عملية. وفقًا لذلك ، في دائرتنا ، سنحتاج إلى 8 تسجيلات من هذا القبيل لتقديم الدعم لـ 60 LED.

بعد ذلك ، فكرنا في كيفية التحكم في حالة LED مع Arduino من خلال السجلات. يجب أن يتلقى كل سجل للتشغيل العادي جميع البتات الثمانية بأكملها. يوفر Arduino Uno ، بالطبع ، مخرجات كافية لإرسال عدة بتات في المرة الواحدة ، لكن هذا النهج لن يكون عقلانيًا. بالإضافة إلى ذلك ، يحتوي المخطط على 8 سجلات فقط ، مما يعني أنك بحاجة إلى معالجتها بطريقة أو بأخرى. لهذا الغرض ، أضفنا مفكك تشفير وسجلي إزاحة 8-بت متصلين بالتتابع إلى الدائرة. يخزن سجل النوبة الواحدة قناع حالة 8 بت ، والذي سيتم تحميله في واحد من 8 سجلات عادية ، يتم تخزين عددها في سجل النوبة الثانية. وبناءً على ذلك ، يتم توصيل مفكك التشفير بسجل المناوبة الثاني. لهذه الأغراض ، يكفي وجود مفكك تشفير 3 × 8.

لإزالة الانعكاس من العدد المطلوب من المخرجات ، استخدمنا دائرتي عاكس KR1533LN1. هذا ، بالطبع ، تعقيد المخطط إلى حد ما.

كانت المهمة الأخرى هي جهد العمل لمصابيح LED تساوي 12 فولت مقارنة بـ 5 فولت من الدوائر المنطقية. كان الحل المقترح هو استخدام عاكس استنزاف مفتوح. تلعب هذه الدائرة المصغرة دور المفتاح الذي يغلق (مع المنطقي 1) أو يفتح (مع المنطقي 0) أحد جهات اتصال LED مع الأرض ، وبالتالي تشغيل أو إيقاف تشغيل LED. تفترض الدائرة التشغيل من 12 فولت ، وفقًا لجهد التشغيل لمصابيح LED ، لذلك من أجل الحصول على 5 فولت للدوائر المنطقية ، تمت إضافة مثبت KR142EN5A مع مكثفتين إلى الدائرة.

تشير بعض مدخلات بعض الدوائر المصغرة إلى قيمة ثابتة عند المدخلات ، لذلك تم توصيلها بالأرض أو بمصدر طاقة. في هذه الحالة ، هذه هي المدخلات التالية:

  • يتم توصيل إدخال إعادة تعيين MR المعكوس في كل من سجلات التحول من خلال سجل الحمل إلى خرج المثبت عند 5 فولت.
  • يتم توصيل خرج OE المعكوس الذي يمكّن الإدخال في كل من سجلات التحول مباشرة بالأرض.
  • يتيح مفكك الشفرة العكسي إدخال E0 المتصل بالأرض




يتم التحكم في الدائرة بأربعة مدخلات (E1 ، SH ، ST ، DS). تتم مناقشة الغرض والغرض من مستويات كل منهما بمزيد من التفصيل أدناه:

تم تصميم الإدخال E1 لتمكين وحدة فك الترميز. في حالتنا ، في البداية على مفكك التشفير ، يوجد إدخالان للتحكم E1 و E0 وكلاهما معكوس. سيكون هناك ما يكفي من مخرج واحد ، بحيث يمكن إخراج الثاني (E0) على الأرض. حالة مفكك التشفير "الافتراضية" تعمل حتى يتم تطبيق مستوى إشارة مرتفع على E1. من أجل القيام بالعكس ، قمنا بتوصيل هذا الإدخال بالعاكس. بدون هذا ، يمكن لمفكك التشفير أن يعطي إشارات تحكم غير صحيحة للسجلات ، على سبيل المثال ، في وقت تحديث البيانات في سجل النوبات. كما ذكرنا من قبل ، يمكن استخدام وحدة فك الترميز 3 في 8 في الدائرة ، والتي يمكن أن تحتوي على إدخال تحكم غير معكوس ، مما يجعل من السهل حل جميع المشاكل الموضحة أعلاه بدون أسلاك إضافية ومكواة لحام.

عند تطبيق مستوى إشارة واحدة على E1 ، يقوم مفكك التشفير بفك تشفير عنوان التسجيل الموجود في سجل المناوبة المقابل ، ويرسل إشارة إلى الخرج المطلوب. بعد ذلك ، يتوقف مفكك التشفير مرة أخرى عن طريق تطبيق مستوى إشارة منخفضة على E1. مثل هذا المفتاح من مفكك الشفرة يولد إشارة عند المخرج المطلوب ، حيث تعمل الحافة والانحلال بمثابة نبض ساعة تسجيل لالتقاط البيانات المخزنة في الناقل في حد ذاته.

والمدخلات الثلاثة التالية مخصصة بالفعل للتحكم في سجلات التحول. يجدر البدء بالأبسط - إدخال بيانات DS. هذا الإدخال ، كما يوحي الاسم ، مخصص لنقل البيانات. بما أن سجلات التحول في الدائرة متصلة في سلسلة ، فإن DS يمثل الناتج المقابل لأحدها. يتم توصيل إدخال سجل النوبة الثانية بإخراج الجزء الأخير من السجل الأول. والنتيجة هي تسجيل نوبة واحدة لـ 16 بت ، منها 12 بت فقط تُستخدم.

إدخال SH هو إدخال ساعة. يتم تغذية الموجة المربعة إلى هذا الإدخال ، وهو المسؤول عن تحميل ونقل البيانات في كل من السجلات ، على التوالي ، هذا الاتصال للدائرة متصل بدبابيس SHCP لكلا التسجيلين.

يعمل دبوس ST الأخير كمزلاج بيانات عن مخرجات السجل. يتم إعطاء دفعة لهذا الإدخال ، ومع ذلك ، فإنه يتم توفيره فقط عندما يتم تحميل البيانات في سجل النوبات أخيرًا ويتطلب إصلاحها عند إخراج السجلات. فقط بعد إعطاء هذه الإشارة ، البيانات التي تم تنزيلها داخل السجل في الصف الأول من المشغلات تحصل على الصف الثاني من المشغلات وتصبح متاحة في الحافلة. ST هو دبوس متصل بدبابيس STcp لكلا التسجيلين.

يبقى لشرح الأسلاك من دبابيس التحول يسجل MR و OE. الإدخال الأول (MR) مسؤول عن تفريغ البيانات داخل السجل. في هذه الدائرة ، هذه الفرصة ليست مطلوبة ، وبالتالي يتم توفير مستوى إشارة عالية لهذا الإخراج من خلال الحمل.

يعد إدخال السجل الثاني (OE) مسؤولًا عن فصل الصف الثاني من المشغلات داخل سجل النقل من الناقل ، أي إدخال التمكين. هذه الوظيفة غير مطلوبة أيضًا ، لذلك ، يتم إخراج الإخراج على الأرض.

تم تصميم جهة اتصال أخرى غير موصوفة أعلاه لإزالة مستوى الإشارة من الزر الموجود في وسط الساعة ، مخطط الزر نموذجي ويمثل حملاً ومفتاحًا ، اعتمادًا على موضع إرسال مستوى إشارة منخفض أو مرتفع إلى Arduino. وفقًا لحالة الزر ، تعمل الساعة إما في وضع شاشة التوقف أو في وضع عرض الوقت.
لا يحتوي الاتصال بـ Arduino على ميزات خاصة ، باستثناء أن دبوس SH متصل بشكل مثالي بدبوس SCK الرقمي. يمكن توصيل باقي مخرجات الدائرة بأي من المدخلات الرقمية المتاحة للأغراض العامة. في حالتنا ، يكون الاتصال على الشكل التالي:

  • Arduino pin13 (SCK) – SH
  • Arduino pin 11 – ST Arduino pin 8 – DS Arduino pin 5 – E1 Arduino pin 3 – Arduino pin GND – ( )
    , .

    : 36 — ; 36 ( ) \ 26 ( ) — . Shadowplay 72 , 36. , 60 ( + ). . , , , .



    , . , . , . , «» 50 — 60, . , 60 . : — .



    , , , . — . , , . , — .

    .


    -, .

    Shadowplay. , , . , , . , .. . , , 100% . , . . , . , .

    , ( ), , — . , , ! . , - - . , , . , , . , , , . ., - . , , , , , .



    , . . .. , , ( , , ), .


    , (). Arduino. , RTC, — . DS1307, — I2C. 2100 . . RTC Arduino, . RTC.



    , RTC, .

    #include <Time.h>
    #include <DS1307RTC.h>
    
    char REG [8];
    tmElements_t te;
    int c,reset=1;
    
    void setup() {
      pinMode(13, OUTPUT); 
      pinMode(11, OUTPUT); 
      pinMode(8, OUTPUT);  
      pinMode(5, OUTPUT);  
      pinMode(3, INPUT);   
      Serial.begin(57600);
      
      //      RTC  
      //te.Hour = 18;
      //te.Minute = 50;
      //te.Second = 0;
      //te.Day = 20; //
      //te.Month = 4; // 
      //te.Year = CalendarYrToTm(2016); 
      //RTC.write(te);
    }
    
    void loop()
    { 
    if(digitalRead(3))                    // ,     
      {RTC.read(te);
       SetShadowTime(te.Hour,te.Minute,te.Second,2);        //         
       delay(900);
       reset=1;
      }
    
    else                                   //    ,  
      {wait1();
       reset=1;
      }
                                             //  
      for(int j = 0; j<8 ; j++) SetUpLightByMask(j,0); 
       
     
    }
    
    
    //======================================================================= 
    
    void SetUpLightByMask(int RegNum, char LightMask) //         
    {
      
      digitalWrite(5, LOW);
      digitalWrite(11, LOW);
      shiftOut(8, 13, MSBFIRST, LightMask);
      shiftOut(8, 13, LSBFIRST, RegNum);
      digitalWrite(11, HIGH);
      digitalWrite(5, HIGH);
    }
    
    void digitalClockDisplay() {  //    RTC  ,    RTC  
      RTC.read(te);
      Serial.print(te.Hour);
      Serial.print(" : ");
      Serial.print(te.Minute);
      Serial.print(" :");
      Serial.print(te.Second);
      Serial.print(" ");
      Serial.print(te.Day);
      Serial.print(" ");
      Serial.print(te.Month);
      Serial.print(" ");
      Serial.print(tmYearToCalendar(te.Year));
      Serial.println();
    }
    
    //     ,     , ,        :
    //0 -  ,1 -   , 2 -    
    
    void SetShadowTime(int Hours, int Minutes, int Seconds, int param){   
      int h,hshift,m,s;
      for(int j = 0; j<8 ; j++) REG[j] = 0;
    
      if(Hours >= 12) Hours -= 12;
      h = Hours + 6;
      if(h >= 12) h -= 12;
        
      hshift = (int) Minutes / 12;
      
      REG[(int)(((h*5)+hshift)/8)] = REG[(int)(((h*5)+hshift)/8)] | 1<<(((h*5)+hshift)%8);
                 
       
      if(param == 1)
      {m = Minutes + 30;
       if(m >= 60) m -= 60;
       REG[(int)(m/8)] = REG[(int)(m/8)] | 1<<(m%8);
       }
    
      if(param == 2)
      {m = Minutes + 30;
       if(m >= 60) m -= 60;
       REG[(int)(m/8)] = REG[(int)(m/8)] | 1<<(m%8);
         
       s = Seconds + 30;
       if(s >= 60) s -= 60;
       REG[(int)(s/8)] = REG[(int)(s/8)] | 1<<(s%8);
      }
    
      for(int j = 0; j<8 ; j++) SetUpLightByMask(j,REG[j]);
      }
      
    void wait1() //    
    {for(int a = 0; a < 8; a++)
        {c=0;
         for(int b = 0; b < 8; b++)
          {c = c << 1;
           c = c | 1;
           SetUpLightByMask(a, c);  
           delay(10);   
          }
       }
      for(int a = 0; a < 8; a++)
        {c=255;
          for(int b = 0; b < 8; b++)
          {c = c << 1;
           SetUpLightByMask(a, c);
           delay(10);     
          }
        }  
    }
    



    . . (Arduino, RTC) . , . , «- ». — . :

    .



    , «»:



    , , :



    , , , .

    , , . , ? . : ( , , ..). , , , . . , .


    ?

    • , , .
    • .
    • القدرة على تغيير تسلسل مصابيح LED الوامضة بسهولة ، مما يعطي مجموعة متنوعة لا حصر لها من المجموعات.

    نحن لا ندعي الصحة المطلقة لحلول الدوائر والبرامج. كما سبق ذكره ، فإن التجربة السلبية هي أيضًا تجربة. ربما ستساعد هذه المقالة شخصًا على تجنب أخطائنا.

    شكرا لكم على اهتمامكم!

Source: https://habr.com/ru/post/ar394107/


All Articles