بيت / دائم / كيفية تجميع الساعة الإلكترونية بيديك. ساعة يد محلية الصنع

كيفية تجميع الساعة الإلكترونية بيديك. ساعة يد محلية الصنع

تمت مراجعة هذه الساعة بالفعل عدة مرات، ولكن آمل أن تكون مراجعتي مثيرة للاهتمام لك أيضًا. تمت إضافة الوصف الوظيفي والتعليمات.

تم شراء المصمم على موقع ebay.com مقابل 1.38 جنيه إسترليني (0.99+0.39 شحن)، أي ما يعادل 2.16 دولار. في وقت الشراء، هذا هو أقل سعر معروض.

استغرق التسليم حوالي 3 أسابيع، وجاءت المجموعة في كيس بلاستيكي عادي، والذي بدوره كان معبأة في كيس فقاعي صغير. كانت هناك قطعة صغيرة من الرغوة على أطراف المؤشر، وكانت بقية الأجزاء بدون أي حماية.

من الوثائق لا يوجد سوى ورقة صغيرة بحجم A5 تحتوي على قائمة بمكونات الراديو على جانب واحد ومخطط دائرة على الجانب الآخر.

1. مخطط الدائرة الكهربائية والأجزاء المستخدمة ومبدأ التشغيل



أساس أو "قلب" الساعة هو متحكم CMOS 8 بت AT89C2051-24PU مزود بذاكرة ROM قابلة للبرمجة والمسح بسعة 2 كيلو بايت.
عقدة مولد الساعةيتم تجميعها وفقًا للدائرة (الشكل 1) وتتكون من مرنان الكوارتز Y1 ومكثفين C2 وC3، اللذين يشكلان معًا دائرة تذبذبية متوازية.


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

عقدة إعادة الضبط الأوليةيعمل على ضبط السجلات الداخلية للمتحكم الدقيق على الحالة الأولية. إنه يعمل على تزويد دبوس واحد من MK، بعد توصيل الطاقة، بنبضة واحدة بمدة لا تقل عن 1 ميكروثانية (12 فترة ساعة).
يتكون من دائرة RC مكونة من المقاوم R1 والمكثف C1.

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

وحدة العرضتم تجميعها على مؤشر مكون من أربعة أرقام مكون من سبعة أجزاء مع كاثود مشترك DS1 ومجموعة مقاومة PR1.
التجميع المقاوم عبارة عن مجموعة من المقاومات في غلاف واحد:


جزء الصوتالدائرة عبارة عن دائرة تم تجميعها باستخدام المقاوم R2 بقدرة 10 كيلو أوم وترانزستور pnp Q1 SS8550 (يعمل كمضخم) وعنصر كهرضغطية LS1.

تَغذِيَةيتم توفيره من خلال الموصل J1 مع مكثف التنعيم C4 المتصل بالتوازي. يتراوح جهد الإمداد من 3 إلى 6 فولت.

2. تجميع المنشئ

لم يسبب التجميع أي صعوبات، فقد كتب على السبورة مكان لحام الأجزاء.

الكثير من الصور - مجموعة المصمم مخفية تحت المفسد

لقد بدأت بالمقبس، لأنه الوحيد الذي ليس مكونًا راديويًا:

وكانت الخطوة التالية هي لحام المقاومات. من المستحيل الخلط بينهما، فكلاهما 10 كيلو أوم:


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

والخطوة التالية هي لحام الأزرار ومكثف مرشح الطاقة:

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

وأخيرًا، قمت بلحام المؤشر وموصل الطاقة:

أقوم بتوصيله بمصدر 5V. كل شيء يعمل!!!


3. ضبط الوقت الحالي، وأجهزة الإنذار وإشارة كل ساعة.

بعد تشغيل الطاقة، تصبح الشاشة في وضع "الساعات: الدقائق" وتعرض الوقت الافتراضي وهو 12:59. يتم تشغيل الصافرة كل ساعة. كلا المنبهين قيد التشغيل. ومن المقرر أن يعمل الأول عند الساعة 13:01، والثاني عند الساعة 13:02.


في كل مرة تضغط فيها لفترة وجيزة على الزر S2، ستقوم الشاشة بالتبديل بين الوضعين ("الساعات: الدقائق") و("الدقائق: الثواني").
عند الضغط على الزر S1 لفترة طويلة، تدخل إلى قائمة الإعدادات، والتي تتكون من 9 قوائم فرعية، تم تحديدها بواسطة الحروف A، B، C، D، E، F، G، H، I. يتم تبديل القوائم الفرعية بواسطة الزر زر S1، يتم تغيير القيم عن طريق زر S2. القائمة الفرعية I يتبعها الخروج من قائمة الإعدادات.

ج: ضبط الساعة الزمنية الحالية
عند الضغط على الزر S2، تتغير قيمة الساعة من 0 إلى 23. بعد ضبط الساعة، يجب عليك الضغط على S1 للانتقال إلى القائمة الفرعية B.

ب: ضبط دقائق الوقت الحالي


ج: قم بتشغيل الصافرة كل ساعة
الإعداد الافتراضي هو تشغيل - تصدر إشارة صوتية كل ساعة من الساعة 8:00 إلى الساعة 20:00. يؤدي الضغط على الزر S2 إلى تغيير القيمة بين ON وOFF. بعد تحديد القيمة، يجب الضغط على S1 للانتقال إلى القائمة الفرعية D.

د: تشغيل/إيقاف التنبيه الأول
افتراضيًا، يكون المنبه قيد التشغيل. يؤدي الضغط على الزر S2 إلى تغيير القيمة بين ON وOFF. بعد تعيين القيمة، يجب عليك الضغط على S1 للانتقال إلى القائمة الفرعية التالية. إذا تم إيقاف تشغيل المنبه، فسيتم تخطي القائمتين الفرعيتين E وF.

هـ: ضبط المنبه الأول
عند الضغط على الزر S2، تتغير قيمة الساعة من 0 إلى 23. بعد ضبط الساعة، يجب عليك الضغط على S1 للانتقال إلى القائمة الفرعية F.

F: ضبط دقائق المنبه الأول
عند الضغط على الزر S2، تتغير قيمة الدقائق من 0 إلى 59. بعد ضبط الدقائق، يجب الضغط على S1 للانتقال إلى القائمة الفرعية C.

G: تشغيل/إيقاف المنبه الثاني
افتراضيًا، يكون المنبه قيد التشغيل. يؤدي الضغط على الزر S2 إلى تغيير القيمة بين ON وOFF. بعد تعيين القيمة، يجب عليك الضغط على S1 للانتقال إلى القائمة الفرعية التالية. إذا تم إيقاف تشغيل المنبه، فسيتم تخطي القائمة الفرعية H وI ويتم الخروج من قائمة الإعدادات.

ح: ضبط المنبه الثاني
عند الضغط على الزر S2، تتغير قيمة الساعة من 0 إلى 23. بعد ضبط الساعة، يجب عليك الضغط على S1 للانتقال إلى القائمة الفرعية I.

الأول: ضبط دقائق المنبه الثاني
عند الضغط على الزر S2، تتغير قيمة الدقائق من 0 إلى 59. بعد ضبط الدقائق، يجب الضغط على S1 للخروج من قائمة الإعدادات.

تصحيح الثواني
في الوضع ("الدقائق: الثواني")، يجب عليك الضغط باستمرار على الزر S2 لإعادة ضبط الثواني. بعد ذلك، اضغط لفترة وجيزة على الزر S2 لبدء حساب الثواني.

4. الانطباعات العامة عن الساعة.

الايجابيات:
+ سعر منخفض
+ سهولة التجميع، الحد الأدنى من الأجزاء
+ متعة التجمع الذاتي
+ خطأ منخفض إلى حد ما (كنت متأخرًا ببضع ثوانٍ خلال اليوم)

السلبيات:
- لا يحتفظ بالوقت بعد انقطاع التيار الكهربائي
- عدم وجود أي وثائق بخلاف الرسم التخطيطي (هذه المقالة تحل هذا العيب جزئيًا)
- البرامج الثابتة في وحدة التحكم الدقيقة محمية من القراءة

5. بالإضافة إلى ذلك:

1) في مساحات الإنترنت التي لا نهاية لها، وجدت تعليمات لهذه الساعة باللغة الإنجليزية وترجمتها إلى اللغة الروسية. يمكنك تنزيله

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

رسم تخطيطي كهربائي لساعة محلية الصنع مع مقياس حرارة

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

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

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

تبدأ الإلكترونيات نفسها من 5 فولت، ولكن لكي تتوهج مصابيح LED بشكل ساطع، من الضروري استخدام 12 فولت. من الشبكة، يتم توفير الطاقة من خلال محول محول تنحي إلى المثبت 7805 ، والتي تنتج جهدًا بدقة 5 فولت. انتبه إلى البطارية الأسطوانية الخضراء الصغيرة - فهي تعمل كمصدر طاقة احتياطي في حالة فقدان شبكة 220 فولت. ليس من الضروري تناولها عند 5 فولت - ليثيوم أيون أو بطارية Ni-MH بقوة 3.6 فولت كافية.

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

هنا يمكنك العثور على جميع التفاصيل الضرورية لتصميم الساعة الرقمية المقترح محلي الصنع، بما في ذلك مخطط الدائرة وتخطيط PCB والبرامج الثابتة PIC و

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

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

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

الخطوة 1. قائمة المكونات

لتجميع ساعة بسيطة على مصفوفات LED، لن تحتاج سوى إلى عدد قليل من المكونات الرخيصة:

  • منصة اردوينو. أبسط النماذج سوف تفعل - أو مايكرو؛
  • الاتصال اللوح.
  • توصيل الأسلاك للوح؛
  • Adafruit DS3231 وحدة الساعة في الوقت الحقيقي؛
  • وحدة مصفوفة LED 32x8 MAX7219؛
  • زرين.

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


الخطوة 2. تجميع الدائرة الإلكترونية

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

وحدة اردوينو → 32x8 MAX7219 مصفوفة LED

وحدة اردوينو → Adafruit DS3231 ساعة الوقت الحقيقي

وحدة اردوينو → الأزرار

د2 - الزر 1

D3 - الزر 2

يتم توصيل الدبوس الثاني من الأزرار بـ GND.

كل ما عليك فعله هو الانتباه وتذكر كيفية اتصال فتحات التلامس الموجودة على اللوحة ببعضها البعض. يوضح الرسم البياني التالي طريقة التوصيل الداخلي لفتحات التلامس:


يتم توصيل صفين (1 و 4) على كلا الجانبين أفقيًا - وعادةً ما يتم استخدامهما كخط طاقة +5 فولت وأرضي GND. جميع جهات الاتصال الداخلية (2 و 3) مغلقة عموديًا. في هذه الحالة، يتم تقسيم لوحة الدائرة عموديًا وأفقيًا إلى جزأين متماثلين مستقلين عن بعضهما البعض. وهذا يسمح، على سبيل المثال، بتجميع جهازين مختلفين على لوحة واحدة.

يظهر الرسم التخطيطي للساعة الإلكترونية المزودة بمؤشر LED، بالإضافة إلى ترتيب العناصر على لوحة الدائرة، في الرسم التوضيحي:

تحقق بعناية من أن جميع التوصيلات متوافقة مع الرسم التخطيطي الموضح. تأكد أيضًا من أن الموصلات مثبتة جيدًا في فتحات التلامس بلوحة الدائرة.


الخطوة 3. البرامج الثابتة لاردوينو

بمجرد الانتهاء من تجميع واختبار الدائرة، يمكنك البدء في تحميل برنامج التحكم (أو "البرنامج الثابت") في ذاكرة Arduino.


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

// تضمين المكتبات: #include "LedControl.h" #include // مكتبة الخطوط #include // ساعة DS1307 #تتضمن "RTClib.h" // ساعة DS1307 #تتضمن // مكتبة الأزرار بواسطة Alexander Brevig // مصفوفة LED للإعداد // السن 12 متصل بـ DataIn على الشاشة // السن 11 متصل بـ CLK على الشاشة // السن 10 متصل بـ LOAD على الشاشة LedControl lc = LedControl(6, 5, 4, 4); // يضبط الأطراف الثلاثة على 12 و11 و10 ثم يضبط 4 شاشات (الحد الأقصى هو 8 شاشات) // المتغيرات العالمية كثافة البايت = 7؛ // الكثافة/السطوع الافتراضي (0-15) بايت Clock_mode = 0; // وضع الساعة الافتراضي. الافتراضي = 0 (الوضع الأساسي) bool Random_mode = 0؛ // تعريف الوضع العشوائي - يغير نوع العرض كل بضع ساعات. الافتراضي = 0 (إيقاف) بايت old_mode = Clock_mode؛ // يخزن وضع الساعة السابق، لذلك إذا ذهبنا إلى التاريخ أو أي شيء آخر، فإننا نعرف الوضع الذي يجب الرجوع إليه بعد ذلك. منطقي أمبير = 0؛ // حدد الوقت بـ 12 أو 24 ساعة. 0 = 24 ساعة. 1 = 12 ساعة بايت Change_mode_time = 0؛ // يحمل الساعة عندما يتغير وضع الساعة بعد ذلك إذا كان في الوضع العشوائي. وقت تأخير طويل غير موقع = 500؛ // نحن دائمًا ننتظر قليلاً بين تحديثات الشاشة int rtc; // يحمل إخراج الساعة في الوقت الحقيقي char day = ( "Sun"، "Mon"، "Tue"، "Wed"، "Thu"، "Fri"، "Sat" ); // مصفوفة اليوم - تُستخدم في أوضاع الشرائح والوضع الأساسي والخليط (يخرج DS1307 قيمًا من 1 إلى 7 أيام في الأسبوع) char daysfull = ( "Sunday"، "Monday"، "Tuesday"، "Wed"، "Thursday" "، "الجمعة"، "السبت")؛ لاحقة الحرف = ("st"، "nd"، "rd"، "th" ); // مصفوفة لاحقة التاريخ، تُستخدم في أوضاع الشريحة والوضع الأساسي والخلط. e,g, الأول الثاني ... // تحديد الثوابت #define NUM_DISPLAY_MODES 3 // أوضاع عرض الأرقام (مع احتساب الصفر كوضع أول) #define NUM_SETTINGS_MODES 4 // أوضاع إعدادات الأرقام = 6 (مع احتواء الصفر كوضع أول) # تعريف SLIDE_DELAY 20 // الوقت بالمللي ثانية لتأثير الشريحة لكل حرف في وضع الشريحة. اجعل هذا أعلى للحصول على تأثير أبطأ #define cls Clear_display // Clear Display RTC_DS1307 ds1307; // إنشاء كائن RTC Button ButtonA = Button(2, BUTTON_PULLUP); // زر الإعداد A (باستخدام مكتبة الأزرار) Button ButtonB = Button(3, BUTTON_PULLUP); // زر الإعداد B (باستخدام مكتبة الأزرار) الإعداد الفارغ () (digitalWrite (2، HIGH)؛ // تشغيل مقاوم السحب للزر الموجود على الدبوس 2 digitalWrite (3، HIGH)؛ // تشغيل مقاوم السحب للزر الموجود على الدبوس 3 الكتابة الرقمية (4، عالية)؛ // تشغيل مقاومة السحب للزر الموجود على الدبوس 4 Serial.begin (9600)؛ // بدء التسلسل // تهيئة لوحات المصفوفة الأربعة // لقد قمنا بالفعل بتعيين عدد الأجهزة عندما أنشأنا أجهزة LedControl int = lc.getDeviceCount ()؛ // يتعين علينا تشغيل جميع الأجهزة في حلقة لـ (عنوان int = 0؛ العنوان< devices; address++) { /*The MAX72XX is in power-saving mode on startup*/ lc.shutdown(3-address, false); /* Set the brightness to a medium values */ lc.setIntensity(3-address, intensity); /* and clear the display */ lc.clearDisplay(3-address); } //Setup DS1307 RTC #ifdef AVR Wire.begin(); #else Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino #endif ds1307.begin(); //start RTC Clock if (! ds1307.isrunning()) { Serial.println("RTC is NOT running!"); ds1307.adjust(DateTime(__DATE__, __TIME__)); // sets the RTC to the date & time this sketch was compiled } //Show software version & hello message printver(); //enable red led digitalWrite(13, HIGH); } void loop() { //run the clock with whatever mode is set by clock_mode - the default is set at top of code. switch (clock_mode){ case 0: basic_mode(); break; case 1: small_mode(); break; case 2: slide(); break; case 3: word_clock(); break; case 4: setup_menu(); break; } } //plot a point on the display void plot (byte x, byte y, byte val) { //select which matrix depending on the x coord byte address; if (x >= 0 && س<= 7) { address = 3; } if (x >= 8 && س<= 15) { address = 2; x = x - 8; } if (x >= 16 && س<= 23) { address = 1; x = x - 16; } if (x >= 24 && س<= 31) { address = 0; x = x - 24; } if (val == 1) { lc.setLed(address, y, x, true); } else { lc.setLed(address, y, x, false); } } //clear screen void clear_display() { for (byte address = 0; address < 4; address++) { lc.clearDisplay(address); } } //fade screen down void fade_down() { //fade from global intensity to 1 for (byte i = intensity; i >0; i--) (لـ (عنوان البايت = 0؛ العنوان< 4; address++) { lc.setIntensity(address, i); } delay(30); //change this to change fade down speed } clear_display(); //clear display completely (off) //reset intentsity to global val for (byte address = 0; address < 4; address++) { lc.setIntensity(address, intensity); } } //power up led test & display software version number void printver() { byte i = 0; char ver_a = "MADE"; char ver_b = "IN"; char ver_c = "RUSSIA"; //test all leds. for (byte x = 0; x <= 32; x++) { for (byte y = 0; y <= 7; y++) { plot(x, y, 1); } } delay(300); fade_down(); while (ver_a[i]) { puttinychar((i * 4), 1, ver_a[i]); delay(35); i++; } delay(500); fade_down(); i = 0; while (ver_b[i]) { puttinychar((i * 4), 1, ver_b[i]); delay(35); i++; } delay(500); fade_down(); i = 0; while (ver_c[i]) { puttinychar((i * 4), 1, ver_c[i]); delay(35); i++; } delay(500); fade_down(); } // puttinychar // Copy a 3x5 character glyph from the myfont data structure to display memory, with its upper left at the given coordinate // This is unoptimized and simply uses plot() to draw each dot. void puttinychar(byte x, byte y, char c) { byte dots; if (c >= "أ" && ج<= "Z" || (c >= "أ" && ج<= "z")) { c &= 0x1F; // A-Z maps to 1-26 } else if (c >= "0" && ج<= "9") { c = (c - "0") + 32; } else if (c == " ") { c = 0; // space } else if (c == ".") { c = 27; // full stop } else if (c == ":") { c = 28; // colon } else if (c == "\"") { c = 29; // single quote mark } else if (c == "!") { c = 30; // single quote mark } else if (c == "?") { c = 31; // single quote mark } for (byte col = 0; col < 3; col++) { dots = pgm_read_byte_near(&mytinyfont[c]); for (char row = 0; row < 5; row++) { if (dots & (16 >> صف)) مؤامرة (س + عمود، ص + صف، 1)؛ مؤامرة أخرى (س + عمود، ص + صف، 0)؛ ) ) ) باطلة putnormalchar(byte x, byte y, char c) (نقاط البايت; // if (c >= "A" && c<= "Z" || (c >= "أ" && ج<= "z")) { // c &= 0x1F; // A-Z maps to 1-26 // } if (c >= "أ" && ج<= "Z") { c &= 0x1F; // A-Z maps to 1-26 } else if (c >= "أ" && ج<= "z") { c = (c - "a") + 41; // A-Z maps to 41-67 } else if (c >= "0" && ج<= "9") { c = (c - "0") + 31; } else if (c == " ") { c = 0; // space } else if (c == ".") { c = 27; // full stop } else if (c == "\"") { c = 28; // single quote mark } else if (c == ":") { c = 29; // clock_mode selector arrow } else if (c == ">") ( c = 30؛ // سهم محدد وضع الساعة ) else if (c >= -80 && c<= -67) { c *= -1; } for (char col = 0; col < 5; col++) { dots = pgm_read_byte_near(&myfont[c]); for (char row = 0; row < 7; row++) { //check coords are on screen before trying to plot //if ((x >= 0) && (س<= 31) && (y >= 0) && (ص<= 7)){ if (dots & (64 >> صف)) ( // 7 صفوف فقط.plot(x + col, y + Row, 1); ) else (plot(x + col, y + Row, 0); ) //) ) ) //small_mode // إظهار الوقت بأحرف صغيرة 3 × 5 مع عرض الثواني void Small_mode () ( char textchar؛ // الأحرف الـ 16 الموجودة على الشاشة بايت دقيقة = 100؛ // دقيقة بايت secs = rtc؛ // ثانية بايت old_secs = secs؛ / / يحمل قيمة الثواني القديمة - من آخر مرة تم فيها تحديث الثواني o العرض - يستخدم للتحقق مما إذا كانت الثواني قد تغيرت cls ()؛ // تشغيل الحلقة الرئيسية للساعة طالما أن وضع التشغيل يعود صحيحًا while (run_mode ()) ( get_time ()؛ / / تحقق من الضغط على الزر إذا (buttonA.uniquePress()) ( Switch_mode(); return; ) if (buttonB.uniquePress()) (display_date(); return;) // إذا تغيرت الثواني ثم قم بتحديثها على الشاشة secs = rtc; if (secs != old_secs) ( //secs char buffer; itoa(secs, buffer, 10); //fix - بخلاف ذلك إذا كان الرقم يحتوي على صفر بادئ، على سبيل المثال "03" ثانية، فإن itoa يغطي هذا إلى الأحرف ذات المسافة "3".إذا (ثواني< 10) { buffer = buffer; buffer = "0"; } puttinychar(20, 1, ":"); //seconds colon puttinychar(24, 1, buffer); //seconds puttinychar(28, 1, buffer); //seconds old_secs = secs; } //if minute changes change time if (mins != rtc) { //reset these for comparison next time mins = rtc; byte hours = rtc; if (hours > < 1) { hours = hours + ampm * 12; } //byte dow = rtc; // the DS1307 outputs 0 - 6 where 0 = Sunday0 - 6 where 0 = Sunday. //byte date = rtc; //set characters char buffer; itoa(hours, buffer, 10); //fix - as otherwise if num has leading zero, e.g. "03" hours, itoa coverts this to chars with space "3 ". if (hours < 10) { buffer = buffer; //if we are in 12 hour mode blank the leading zero. if (ampm) { buffer = " "; } else { buffer = "0"; } } //set hours chars textchar = buffer; textchar = buffer; textchar = ":"; itoa (mins, buffer, 10); if (mins < 10) { buffer = buffer; buffer = "0"; } //set mins characters textchar = buffer; textchar = buffer; //do seconds textchar = ":"; buffer; secs = rtc; itoa(secs, buffer, 10); //fix - as otherwise if num has leading zero, e.g. "03" secs, itoa coverts this to chars with space "3 ". if (secs < 10) { buffer = buffer; buffer = "0"; } //set seconds textchar = buffer; textchar = buffer; byte x = 0; byte y = 0; //print each char for (byte x = 0; x < 6 ; x++) { puttinychar(x * 4, 1, textchar[x]); } } delay(50); } fade_down(); } // basic_mode() // show the time in 5x7 characters void basic_mode() { cls(); char buffer; //for int to char conversion to turn rtc values into chars we can print on screen byte offset = 0; //used to offset the x postition of the digits and centre the display when we are in 12 hour mode and the clock shows only 3 digits. e.g. 3:21 byte x, y; //used to draw a clear box over the left hand "1" of the display when we roll from 12:59 ->1:00 صباحًا في وضع 12 ساعة. // قم بتحويل 12/24 ساعة إذا تم ضبط ampm على 1 بايتhours = rtc; إذا (ساعات > 12) (ساعات = ساعات - أمبير * 12؛) إذا (ساعات< 1) { hours = hours + ampm * 12; } //do offset conversion if (ampm && hours < 10) { offset = 2; } //set the next minute we show the date at //set_next_date(); // initially set mins to value 100 - so it wll never equal rtc on the first loop of the clock, meaning we draw the clock display when we enter the function byte secs = 100; byte mins = 100; int count = 0; //run clock main loop as long as run_mode returns true while (run_mode()) { //get the time from the clock chip get_time(); //check for button press if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); return; } //check whether it"s time to automatically display the date //check_show_date(); //draw the flashing: as on if the secs have changed. if (secs != rtc) { //update secs with new value secs = rtc; //draw: plot (15 - offset, 2, 1); //top point plot (15 - offset, 5, 1); //bottom point count = 400; } //if count has run out, turn off the: if (count == 0) { plot (15 - offset, 2, 0); //top point plot (15 - offset, 5, 0); //bottom point } else { count--; } //re draw the display if button pressed or if mins != rtc i.e. if the time has changed from what we had stored in mins, (also trigggered on first entering function when mins is 100) if (mins != rtc) { //update mins and hours with the new values mins = rtc; hours = rtc; //adjust hours of ampm set to 12 hour mode if (hours >12) ( ساعات = ساعات - أمبير * 12؛ ) إذا (ساعات< 1) { hours = hours + ampm * 12; } itoa(hours, buffer, 10); //if hours < 10 the num e.g. "3" hours, itoa coverts this to chars with space "3 " which we dont want if (hours < 10) { buffer = buffer; buffer = "0"; } //print hours //if we in 12 hour mode and hours < 10, then don"t print the leading zero, and set the offset so we centre the display with 3 digits. if (ampm && hours < 10) { offset = 2; //if the time is 1:00am clear the entire display as the offset changes at this time and we need to blank out the old 12:59 if ((hours == 1 && mins == 0)) { cls(); } } else { //else no offset and print hours tens digit offset = 0; //if the time is 10:00am clear the entire display as the offset changes at this time and we need to blank out the old 9:59 if (hours == 10 && mins == 0) { cls(); } putnormalchar(1, 0, buffer); } //print hours ones digit putnormalchar(7 - offset, 0, buffer); //print mins //add leading zero if mins < 10 itoa (mins, buffer, 10); if (mins < 10) { buffer = buffer; buffer = "0"; } //print mins tens and ones digits putnormalchar(19 - offset, 0, buffer); putnormalchar(25 - offset, 0, buffer); } } fade_down(); } //like basic_mode but with slide effect void slide() { byte digits_old = {99, 99, 99, 99}; //old values we store time in. Set to somthing that will never match the time initially so all digits get drawn wnen the mode starts byte digits_new; //new digits time will slide to reveal byte digits_x_pos = {25, 19, 7, 1}; //x pos for which to draw each digit at char old_char; //used when we use itoa to transpose the current digit (type byte) into a char to pass to the animation function char new_char; //used when we use itoa to transpose the new digit (type byte) into a char to pass to the animation function //old_chars - stores the 5 day and date suffix chars on the display. e.g. "mon" and "st". We feed these into the slide animation as the current char when these chars are updated. //We sent them as A initially, which are used when the clocl enters the mode and no last chars are stored. //char old_chars = "AAAAA"; //plot the clock colon on the display cls(); putnormalchar(13, 0, ":"); byte old_secs = rtc; //store seconds in old_secs. We compare secs and old secs. WHen they are different we redraw the display //run clock main loop as long as run_mode returns true while (run_mode()) { get_time(); //check for button press if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); return; } //if secs have changed then update the display if (rtc != old_secs) { old_secs = rtc; //do 12/24 hour conversion if ampm set to 1 byte hours = rtc; if (hours >12) ( ساعات = ساعات - أمبير * 12؛ ) إذا (ساعات< 1) { hours = hours + ampm * 12; } //split all date and time into individual digits - stick in digits_new array //rtc = secs //array pos and digit stored //digits_new = (rtc%10); //0 - secs ones //digits_new = ((rtc/10)%10); //1 - secs tens //rtc = mins digits_new = (rtc % 10); //2 - mins ones digits_new = ((rtc / 10) % 10); //3 - mins tens //rtc = hours digits_new = (hours % 10); //4 - hour ones digits_new = ((hours / 10) % 10); //5 - hour tens //rtc = date //digits_new = (rtc%10); //6 - date ones //digits_new = ((rtc/10)%10); //7 - date tens //draw initial screen of all chars. After this we just draw the changes. //compare digits 0 to 3 (mins and hours) for (byte i = 0; i <= 3; i++) { //see if digit has changed... if (digits_old[i] != digits_new[i]) { //run 9 step animation sequence for each in turn for (byte seq = 0; seq <= 8 ; seq++) { //convert digit to string itoa(digits_old[i], old_char, 10); itoa(digits_new[i], new_char, 10); //if set to 12 hour mode and we"re on digit 2 (hours tens mode) then check to see if this is a zero. If it is, blank it instead so we get 2.00pm not 02.00pm if (ampm && i == 3) { if (digits_new == 0) { new_char = " "; } if (digits_old == 0) { old_char = " "; } } //draw the animation frame for each digit slideanim(digits_x_pos[i], 0, seq, old_char, new_char); delay(SLIDE_DELAY); } } } /* //compare date digit 6 (ones) and (7) tens - if either of these change we need to update the date line. We compare date tens as say from Jan 31 ->01 فبراير، ثم لا يتغير رقم الآحاد إذا ((digits_old != digits_new) || (digits_old != digits_new)) ( // تغيير اليوم الموضح. تمر الحلقة أدناه عبر كل حرف من الأحرف الثلاثة على التوالي، على سبيل المثال "MON" لـ (بايت day_char = 0؛ day_char<=2 ; day_char++){ //run the anim sequence for each char for (byte seq = 0; seq <=8 ; seq++){ //the day (0 - 6) Read this number into the days char array. the seconds number in the array 0-2 gets the 3 chars of the day name, e.g. m o n slideanim(6*day_char,8,seq,old_chars,days); //6 x day_char gives us the x pos for the char delay(SLIDE_DELAY); } //save the old day chars into the old_chars array at array pos 0-2. We use this next time we change the day and feed it to the animation as the current char. The updated char is fed in as the new char. old_chars = days; } //change the date tens digit (if needed) and ones digit. (the date ones digit wil alwaus change, but putting this in the "if" loop makes it a bit neater code wise.) for (byte i = 7; i >= 6؛ i--)( إذا (digits_old[i] != digits_new[i]) ( for (byte seq = 0; seq<=8 ; seq++){ itoa(digits_old[i],old_char,10); itoa(digits_new[i],new_char,10); slideanim(digits_x_pos[i],8,seq,old_char,new_char); delay(SLIDE_DELAY); } } } //print the day suffix "nd" "rd" "th" etc. First work out date 2 letter suffix - eg st, nd, rd, th byte s = 3; //the pos to read our suffix array from. byte date = rtc; if(date == 1 || date == 21 || date == 31) { s = 0; } else if (date == 2 || date == 22) { s = 1; } else if (date == 3 || date == 23) { s = 2; } for (byte suffix_char = 0; suffix_char <=1 ; suffix_char++){ for (byte seq = 0; seq <=8 ; seq++){ slideanim((suffix_char*6)+36,8,seq,old_chars,suffix[s]); // we pass in the old_char array char as the current char and the suffix array as the new char delay(SLIDE_DELAY); } //save the suffic char in the old chars array at array pos 3 and 5. We use these chars next time we change the suffix and feed it to the animation as the current char. The updated char is fed in as the new char. old_chars = suffix[s]; } }//end do date line */ //save digita array tol old for comparison next loop for (byte i = 0; i <= 3; i++) { digits_old[i] = digits_new[i]; } }//secs/oldsecs }//while loop fade_down(); } //called by slide //this draws the animation of one char sliding on and the other sliding off. There are 8 steps in the animation, we call the function to draw one of the steps from 0-7 //inputs are are char x and y, animation frame sequence (0-7) and the current and new chars being drawn. void slideanim(byte x, byte y, byte sequence, char current_c, char new_c) { // To slide one char off and another on we need 9 steps or frames in sequence... // seq# 0123456 <-rows of the display // | ||||||| // seq0 0123456 START - all rows of the display 0-6 show the current characters rows 0-6 // seq1 012345 current char moves down one row on the display. We only see it"s rows 0-5. There are at display positions 1-6 There is a blank row inserted at the top // seq2 6 01234 current char moves down 2 rows. we now only see rows 0-4 at display rows 2-6 on the display. Row 1 of the display is blank. Row 0 shows row 6 of the new char // seq3 56 0123 // seq4 456 012 half old / half new char // seq5 3456 01 // seq6 23456 0 // seq7 123456 // seq8 0123456 END - all rows show the new char //from above we can see... //currentchar runs 0-6 then 0-5 then 0-4 all the way to 0. starting Y position increases by 1 row each time. //new char runs 6 then 5-6 then 4-6 then 3-6. starting Y position increases by 1 row each time. //if sequence number is below 7, we need to draw the current char if (sequence < 7) { byte dots; // if (current_c >= "أ" && || (current_c >= "a" &¤t_c<= "z")) { // current_c &= 0x1F; // A-Z maps to 1-26 // } if (current_c >= "أ" && current_c<= "Z") { current_c &= 0x1F; // A-Z maps to 1-26 } else if (current_c >= "أ" && current_c<= "z") { current_c = (current_c - "a") + 41; // A-Z maps to 41-67 } else if (current_c >= "0" && current_c<= "9") { current_c = (current_c - "0") + 31; } else if (current_c == " ") { current_c = 0; // space } else if (current_c == ".") { current_c = 27; // full stop } else if (current_c == "\"") { current_c = 28; // single quote mark } else if (current_c == ":") { current_c = 29; //colon } else if (current_c == ">") (current_c = 30؛ // سهم محدد وضع الساعة) بايت curr_char_row_max = 7 - تسلسل؛ // الحد الأقصى لعدد الصفوف المراد رسمها هو 6 - رقم التسلسل بايت start_y = تسلسل؛ // موضع y للبدء عند - هو نفسه رقم التسلسل، نقوم بإضافة كل حلقة // رسم كل صف حتى الحد الأقصى للصف (محسوبًا من رقم التسلسل) لـ (البايت curr_char_row = 0؛ curr_char_row<= curr_char_row_max; curr_char_row++) { for (byte col = 0; col < 5; col++) { dots = pgm_read_byte_near(&myfont); if (dots & (64 >> curr_char_row)) مؤامرة(x + col, y + start_y, 1); // مؤامرة LED على آخر مؤامرة (x + col، y + start_y، 0)؛ //مؤامرة أخرى متوقفة) start_y++;//أضف واحدًا إلى y حتى نرسم الصف التالي واحدًا لأسفل)) //ارسم خطًا فارغًا بين الأحرف إذا كان التسلسل بين 1 و7. إذا لم نفعل ذلك، فسنحصل على بقايا الموضع الأخير للأحرف الحالية المتبقية على الشاشة إذا (التسلسل >= 1 && التسلسل<= 8) { for (byte col = 0; col < 5; col++) { plot(x + col, y + (sequence - 1), 0); //the y position to draw the line is equivalent to the sequence number - 1 } } //if sequence is above 2, we also need to start drawing the new char if (sequence >= 2) ( // احسب نقاط بايت char؛ //if (new_c >= "A" && new_c<= "Z" || (new_c >= "أ" && new_c<= "z")) { // new_c &= 0x1F; // A-Z maps to 1-26 //} if (new_c >= "أ" && new_c<= "Z") { new_c &= 0x1F; // A-Z maps to 1-26 } else if (new_c >= "أ" && new_c<= "z") { new_c = (new_c - "a") + 41; // A-Z maps to 41-67 } else if (new_c >= "0" && new_c<= "9") { new_c = (new_c - "0") + 31; } else if (new_c == " ") { new_c = 0; // space } else if (new_c == ".") { new_c = 27; // full stop } else if (new_c == "\"") { new_c = 28; // single quote mark } else if (new_c == ":") { new_c = 29; // clock_mode selector arrow } else if (new_c == ">") ( new_c = 30؛ // سهم محدد وضع الساعة ) بايت newcharrowmin = 6 - (التسلسل - 2)؛ // الحد الأدنى لعدد الصف المراد رسمه لحرف جديد - يؤدي هذا إلى إنشاء مخرجات من 6 إلى 0 عند تغذية أرقام التسلسل 2-8 هذا هو الحد الأدنى للصف الذي سيتم رسمه لـ char byte الجديد start_y = 0؛ // موضع البدء عند - هو نفس رقم التسلسل. نقوم بإدخاله في كل صف // رسم كل صف لأعلى من الحد الأدنى للصف (يتم حسابه بواسطة رقم التسلسل ) ما يصل إلى 6 لـ (بايت newcharrow = newcharrowmin؛ newcharrow<= 6; newcharrow++) { for (byte col = 0; col < 5; col++) { dots = pgm_read_byte_near(&myfont); if (dots & (64 >> newcharrow)) مؤامرة(x + col, y + start_y, 1); // مؤامرة LED على آخر مؤامرة (x + col، y + start_y، 0)؛ // تم إيقاف تشغيل مؤامرة أخرى ) start_y++;// أضف واحدًا إلى y حتى نرسم الصف التالي واحدًا لأسفل ) ) // اطبع ساعة باستخدام الكلمات بدلاً من الأرقام void word_clock() ( cls(); char أرقام = ( "one "، "اثنان"، "ثلاثة"، "أربعة"، "خمسة"، "ستة"، "سبعة"، "ثمانية"، "تسعة"، "عشرة"، "أحد عشر"، "اثنا عشر"، "ثلاثة عشر"، "أربعة عشر"، "خمسة عشر"، "ستة عشر"، "سبعة عشر"، "ثمانية عشر"، "تسعة عشر")؛ حرف الأرقام = ("عشرة"، "عشرون"، "ثلاثون"، "أربعون"، "خمسون")؛ // من المحتمل أن يتم عرض 3 أسطر char str_a؛ char str_b؛ char str_c؛ // بايت ساعات_y، mins_y؛ // الساعات والدقائق والمواضع للساعات وخطوط الدقائق بايت ساعات = rtc؛ إذا (ساعات> 12) (ساعات = ساعات - أمبير * 12؛ ) إذا (ساعات< 1) { hours = hours + ampm * 12; } get_time(); //get the time from the clock chip byte old_mins = 100; //store mins in old_mins. We compare mins and old mins & when they are different we redraw the display. Set this to 100 initially so display is drawn when mode starts. byte mins; //run clock main loop as long as run_mode returns true while (run_mode()) { //check for button press if (buttonA.uniquePress()) { switch_mode(); return; } if (buttonB.uniquePress()) { display_date(); } get_time(); //get the time from the clock chip mins = rtc; //get mins //if mins is different from old_mins - redraw display if (mins != old_mins) { //update old_mins with current mins value old_mins = mins; //reset these for comparison next time mins = rtc; hours = rtc; //make hours into 12 hour format if (hours >12) ( ساعات = ساعات - 12؛ ) إذا (ساعات == 0) ( ساعات = 12؛) // تقسيم قيمة الدقائق إلى رقمين منفصلين int minsdigit = rtc % 10; بايت دقيقة رقمية = (rtc / 10) % 10؛ //إذا دقيقة<= 10 , then top line has to read "minsdigti past" and bottom line reads hours if (mins < 10) { strcpy (str_a, numbers); strcpy (str_b, "PAST"); strcpy (str_c, numbers); } //if mins = 10, cant use minsdigit as above, so soecial case to print 10 past /n hour. if (mins == 10) { strcpy (str_a, numbers); strcpy (str_b, " PAST"); strcpy (str_c, numbers); } //if time is not on the hour - i.e. both mins digits are not zero, //then make first line read "hours" and 2 & 3rd lines read "minstens" "mins" e.g. "three /n twenty /n one" else if (minsdigitten != 0 && minsdigit != 0) { strcpy (str_a, numbers); //if mins is in the teens, use teens from the numbers array for the 2nd line, e.g. "fifteen" //if (mins >= 11 && دقيقة<= 19) { if (mins <= 19) { strcpy (str_b, numbers); } else { strcpy (str_b, numberstens); strcpy (str_c, numbers); } } // if mins digit is zero, don"t print it. read read "hours" "minstens" e.g. "three /n twenty" else if (minsdigitten != 0 && minsdigit == 0) { strcpy (str_a, numbers); strcpy (str_b, numberstens); strcpy (str_c, ""); } //if both mins are zero, i.e. it is on the hour, the top line reads "hours" and bottom line reads "o"clock" else if (minsdigitten == 0 && minsdigit == 0) { strcpy (str_a, numbers); strcpy (str_b, "O"CLOCK"); strcpy (str_c, ""); } }//end worknig out time //run in a loop //print line a "twelve" byte len = 0; while (str_a) { len++; }; //get length of message byte offset_top = (31 - ((len - 1) * 4)) / 2; // //plot hours line byte i = 0; while (str_a[i]) { puttinychar((i * 4) + offset_top, 1, str_a[i]); i++; } //hold display but check for button presses int counter = 1000; while (counter >0)( // التحقق من الضغط على الزر إذا (buttonA.uniquePress()) ( Switch_mode(); return; ) إذا (buttonB.uniquePress()) (display_date(); ) تأخير(1); counter--; ) Fade_down ()؛ // خط الطباعة ب لين = 0؛ بينما (str_b) ( len++; ); // الحصول على طول الرسالة offset_top = (31 - ((len - 1) * 4)) / 2; أنا = 0؛ while (str_b[i]) ( puttinychar((i * 4) + offset_top, 1, str_b[i]); i++; ) // استمر في العرض ولكن تحقق من الضغط على الزر counter = 1000; بينما (counter > 0)( if (buttonA.uniquePress()) ( Switch_mode(); return; ) if (buttonB.uniquePress()) (display_date(); ) تأخير(1); counter--; ) Fade_down() ; //اطبع السطر ج إذا كان هناك. لين = 0; بينما (str_c) ( len++; ); // الحصول على طول الرسالة offset_top = (31 - ((len - 1) * 4)) / 2; أنا = 0؛ while (str_c[i]) ( puttinychar((i * 4) + offset_top, 1, str_c[i]); i++; ) counter = 1000; بينما (counter > 0)(//تحقق من الضغط على الزر إذا (buttonA.uniquePress()) (switch_mode(); return;) if (buttonB.uniquePress()) (display_date();) تأخير(1); counter- -; ) Fade_down(); // استمر في الضغط على شاشة العرض فارغة ولكن تحقق من الضغط على الزر قبل البدء مرة أخرى. العداد = 1000؛ بينما (counter > 0)(//تحقق من الضغط على الزر إذا (buttonA.uniquePress()) (switch_mode(); return;) if (buttonB.uniquePress()) (display_date();) تأخير(1); counter- -; ) ) Fade_down(); ) /// تمرير الرسالة - غير مستخدم حاليًا - بطيء جدًا. التمرير الفراغي () (رسالة char = ("مرحبًا بك")؛ cls ()؛ بايت p = 6؛ // نقطة البيع الحالية في السلسلة بايت شارا = (0، 1، 2، 3، 4، 5)؛ // أحرف من السلسلة int x = (0, 6, 12, 18, 24, 30); //xpos لكل بايت شار y = 0; //y pos // Clear_buffer(); while (message[p] != "\ 0") ( // ارسم جميع الأحرف الستة لـ (byte c = 0; c< 6; c++) { putnormalchar(x[c],y,message[ chara[c] ]); //draw a line of pixels turned off after each char,otherwise the gaps between the chars have pixels left in them from the previous char for (byte yy = 0 ; yy < 8; yy ++) { plot(x[c] + 5, yy, 0); } //take one off each chars position x[c] = x[c] - 1; } //reset a char if it"s gone off screen for (byte i = 0; i <= 5; i++) { if (x[i] < -5) { x[i] = 31; chara[i] = p; p++; } } } } //display_date - print the day of week, date and month with a flashing cursor effect void display_date() { cls(); //read the date from the DS1307 byte dow = rtc; // day of week 0 = Sunday byte date = rtc; byte month = rtc - 1; //array of month names to print on the display. Some are shortened as we only have 8 characters across to play with char monthnames = { "January", "February", "March", "April", "May", "June", "July", "August", "Sept", "October", "November", "December" }; //print the day name //get length of text in pixels, that way we can centre it on the display by divindin the remaining pixels b2 and using that as an offset byte len = 0; while(daysfull) { len++; }; byte offset = (31 - ((len-1)*4)) / 2; //our offset to centre up the text //print the name int i = 0; while(daysfull[i]) { puttinychar((i*4) + offset , 1, daysfull[i]); i++; } delay(1000); fade_down(); cls(); // print date numerals char buffer; itoa(date,buffer,10); offset = 10; //offset to centre text if 3 chars - e.g. 3rd // first work out date 2 letter suffix - eg st, nd, rd, th etc // char suffix={"st", "nd", "rd", "th" }; is defined at top of code byte s = 3; if(date == 1 || date == 21 || date == 31) { s = 0; } else if (date == 2 || date == 22) { s = 1; } else if (date == 3 || date == 23) { s = 2; } //print the 1st date number puttinychar(0+offset, 1, buffer); //if date is under 10 - then we only have 1 digit so set positions of sufix etc one character nearer byte suffixposx = 4; //if date over 9 then print second number and set xpos of suffix to be 1 char further away if (date >9)( suffixposx = 8; puttinychar(4+offset, 1, buffer); Offset = 8; // إزاحة إلى النص المركزي إذا كان هناك 4 أحرف) // اطبع الحرفين اللاحقين puttinychar(suffixposx+offset, 1, suffix[s ]); puttinychar(suffixposx+4+offset, 1, suffix[s]); تأخير (1000)؛ Fade_down(); // اطبع اسم الشهر // احصل على طول النص بالبكسل، وبهذه الطريقة يمكننا توسيطه على الشاشة عن طريق تقسيم البكسلات المتبقية b2 واستخدام ذلك كإزاحة len = 0; بينما (أسماء الشهر) (لين ++؛ )؛ إزاحة = (31 - ((لين-1)*4)) / 2; // إزاحتنا لتوسيط النص i = 0; while(monthnames[i]) ( puttinychar((i*4) +offset, 1,monthnames[i]); i++; ) تأخير(1000); Fade_down(); ) // قائمة dislpay لتغيير وضع الساعة void Switch_mode() ( // تذكر الوضع الذي نحن فيه. نستخدم هذه القيمة إذا ذهبنا إلى وضع الإعدادات، حتى نتمكن من العودة من وضع الإعدادات (6) إلى أي وضع كنا فيه in.old_mode = Clock_mode؛ char* mode = ( "Basic"، "Small"، "Slide"، "Words"، "Setup" )؛ byte next_clock_mode؛ byte firstrun = 1؛ // حلقة انتظار الزر (المهلة بعد 35) حلقات للعودة إلى الوضع X) لـ (int count = 0; count< 35 ; count++) { //if user hits button, change the clock_mode if (buttonA.uniquePress() || firstrun == 1) { count = 0; cls(); if (firstrun == 0) { clock_mode++; } if (clock_mode >NUM_DISPLAY_MODES + 1) (clock_mode = 0;) // طباعة السهم واسم وضع الساعة الحالي على السطر الأول وطباعة اسم وضع الساعة التالي على السطر الثاني char str_top; //strcpy (str_top، "-")؛ strcpy(str_top, modes); next_clock_mode = Clock_mode + 1؛ إذا (next_clock_mode > NUM_DISPLAY_MODES + 1) ( next_clock_mode = 0؛ ) بايت i = 0؛ while (str_top[i]) ( putnormalchar(i * 6, 0, str_top[i]); i++; ) firstrun = 0; ) تأخير(50); ) ) // تشغيل الحلقة الرئيسية على مدار الساعة طالما أن run_mode يُرجع البايت الحقيقي run_mode() ( // إذا كان الوضع العشوائي قيد التشغيل... تحقق من الساعة عندما نغير الوضع. if (random_mode) ( // إذا كانت قيمة الساعة في وضع التغيير الوقت = الساعات، ثم إعادة الخطأ = أي الخروج من الوضع if (change_mode_time == rtc) ( // اضبط وضع الساعة العشوائية التالي ووقت تغييره set_next_random(); // الخروج من الوضع الحالي. return 0; ) ) / /else return 1 - استمر في التشغيل في هذا الوضع return 1;) // اضبط الساعة التالية ستغير الساعة الوضع عندما يكون الوضع العشوائي في وضع التشغيل void set_next_random() (// اضبط الساعة التالية سيتغير وضع الساعة - الوقت الحالي بالإضافة إلى 1 - 4 ساعات get_time(); Change_mode_time = rtc + عشوائي (1, 5)؛ // إذا تجاوز وقت التغيير 23 الآن، فاضبطه على ما بين 1 و3 صباحًا إذا (change_mode_time > 23) (change_mode_time = عشوائي (1) ، 4)؛) // ضبط وضع الساعة الجديد Clock_mode = عشوائي (0، NUM_DISPLAY_MODES + 1)؛ // اختر وضع الساعة العشوائي الجديد) // قائمة dislpay لتغيير إعدادات الساعة void setup_menu() ( char* set_modes = ( "Rndom"، "24 ساعة"، "Set"، "Brght"، "خروج")؛ إذا (ampm == 0) (set_modes = ("12 Hr")؛) byte settings_mode = 0; البايت next_setting_mode؛ بايت أول تشغيل = 1؛ // حلقة انتظار الزر (المهلة بعد 35 حلقة للعودة إلى الوضع X) for(int count=0; count< 35 ; count++) { //if user hits button, change the clock_mode if(buttonA.uniquePress() || firstrun == 1){ count = 0; cls(); if (firstrun == 0) { setting_mode++; } if (setting_mode >NUM_SETTINGS_MODES) (setting_mode = 0;) // طباعة السهم واسم وضع الساعة الحالي على السطر الأول وطباعة اسم وضع الساعة التالي على السطر الثاني char str_top; strcpy(str_top, set_modes); next_setting_mode = settings_mode + 1; إذا (next_setting_mode > NUM_SETTINGS_MODES) (next_setting_mode = 0;) بايت i = 0; while(str_top[i]) ( putnormalchar(i*6, 0, str_top[i]); i++; ) firstrun = 0; ) تأخير(50); ) // اختر مفتاح الوضع (setting_mode) (الحالة 0: set_random ()؛ استراحة؛ الحالة 1: set_ampm ()؛ استراحة؛ الحالة 2: set_time ()؛ استراحة؛ الحالة 3: set_intensity ()؛ استراحة؛ الحالة 4: // فاصل قائمة الخروج؛ ) // قم بتغيير الساعة من الوضع 6 (الإعدادات) إلى الوضع الذي كانت عليه قبل Clock_mode=old_mode; ) // تبديل الوضع العشوائي - اختر وضع ساعة مختلفًا كل بضع ساعات void set_random())( cls(); char text_a = "Off"; char text_b = "On"; byte i = 0; // إذا كان الوضع العشوائي تشغيل، قم بإيقاف تشغيله إذا (random_mode)( // إيقاف تشغيل الوضع العشوائي Random_mode = 0؛ // اطبع رسالة على الشاشة while(text_a[i]) ( putnormalchar((i*6), 0, text_a[i] ) ; i++; ) ) else ( // تشغيل الوضع العشوائي. Random_mode = 1; // وضع الساعة المحدد سيتغير set_next_random(); // اطبع رسالة على الشاشة while(text_b[i]) ( putnormalchar((i * 6), 0, text_b[i]); i++; ) ) تأخير(1500); //اترك الرسالة لمدة ثانية أو نحو ذلك) //ضبط الساعة بنظام 12 أو 24 ساعة void set_ampm() ( // AM/ وضع الساعة PM أو 24 ساعة - اقلب البت (يجعل 0 إلى 1، أو 1 إلى 0 لوضع ampm) ampm = (ampm ^ 1); cls(); ) // تغيير شدة الشاشة باطلة set_intensity() ( cls() ; بايت i = 0; char text = "Bright"; while(text[i]) ( puttinychar((i*4)+4, 0, text[i]); i++; ) // انتظر إدخال الزر while ( ! ButtonA.uniquePress()) (levelbar (0.6,(intensity*2)+2.2); // عرض مستوى الشدة كشريط while (buttonB.isPressed()) ( if(intensity == 15) (كثافة = 0; cls (); ) else (كثافة++;) // اطبع القيمة الجديدة i = 0; while(text[i]) ( puttinychar((i*4)+4, 0, text[i]); i++; ) // عرض مستوى الشدة كشريط مستوى (0,6,(intensity*2)+ 2،2)؛ // تغيير إعداد السطوع على شاشات العرض لـ (عنوان البايت = 0؛ العنوان< 4; address++) { lc.setIntensity(address, intensity); } delay(150); } } } // display a horizontal bar on the screen at offset xposr by ypos with height and width of xbar, ybar void levelbar (byte xpos, byte ypos, byte xbar, byte ybar) { for (byte x = 0; x < xbar; x++) { for (byte y = 0; y <= ybar; y++) { plot(x+xpos, y+ypos, 1); } } } //set time and date routine void set_time() { cls(); //fill settings with current clock values read from clock get_time(); byte set_min = rtc; byte set_hr = rtc; byte set_date = rtc; byte set_mnth = rtc; int set_yr = rtc; //Set function - we pass in: which "set" message to show at top, current value, reset value, and rollover limit. set_date = set_value(2, set_date, 1, 31); set_mnth = set_value(3, set_mnth, 1, 12); set_yr = set_value(4, set_yr, 2013, 2099); set_hr = set_value(1, set_hr, 0, 23); set_min = set_value(0, set_min, 0, 59); ds1307.adjust(DateTime(set_yr, set_mnth, set_date, set_hr, set_min)); cls(); } //used to set min, hr, date, month, year values. pass //message = which "set" message to print, //current value = current value of property we are setting //reset_value = what to reset value to if to rolls over. E.g. mins roll from 60 to 0, months from 12 to 1 //rollover limit = when value rolls over int set_value(byte message, int current_value, int reset_value, int rollover_limit){ cls(); char messages = { "Set Mins", "Set Hour", "Set Day", "Set Mnth", "Set Year"}; //Print "set xyz" top line byte i = 0; while(messages[i]) { puttinychar(i*4 , 1, messages[i]); i++; } delay(2000); cls(); //print digits bottom line char buffer = " "; itoa(current_value,buffer,10); puttinychar(0 , 1, buffer); puttinychar(4 , 1, buffer); puttinychar(8 , 1, buffer); puttinychar(12, 1, buffer); delay(300); //wait for button input while (!buttonA.uniquePress()) { while (buttonB.isPressed()){ if(current_value < rollover_limit) { current_value++; } else { current_value = reset_value; } //print the new value itoa(current_value, buffer ,10); puttinychar(0 , 1, buffer); puttinychar(4 , 1, buffer); puttinychar(8 , 1, buffer); puttinychar(12, 1, buffer); delay(150); } } return current_value; } void get_time() { //get time DateTime now = ds1307.now(); //save time to array rtc = now.year(); rtc = now.month(); rtc = now.day(); rtc = now.dayOfWeek(); //returns 0-6 where 0 = Sunday rtc = now.hour(); rtc = now.minute(); rtc = now.second(); //flash arduino led on pin 13 every second //if ((rtc % 2) == 0) { // digitalWrite(13, HIGH); //} //else { // digitalWrite(13, LOW); //} //print the time to the serial port - useful for debuging RTC issues /* Serial.print(rtc); Serial.print(":"); Serial.print(rtc); Serial.print(":"); Serial.println(rtc); */ }

الآن، لإكمال العمل على الجهاز، ما عليك سوى إجراء عدد من العمليات البسيطة:


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

ساعة جاهزة على اردوينو

يتم ضبط الساعة باستخدام زرين. يدعم الجهاز تنسيقات الوقت 12 و 24 ساعة، ويعرض التاريخ واليوم من الأسبوع، ويعرض الوقت بالثواني أو بدونها. من الممكن أيضًا تغيير سطوع مصابيح LED.


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

ساعة بمؤشر LED من سبعة أجزاء على شريحة K145IK1911

يختلف تاريخ ظهور هذه الساعات على الموقع قليلاً عن الرسوم البيانية الأخرى الموجودة على الموقع.

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

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

مخطط الساعة:


لتكبير الصورة، ما عليك سوى النقر عليها لتكبيرها وحفظها على جهاز الكمبيوتر.

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

لم يكن موجودًا في المتجر في ذلك الوقت، ولكن كان هناك نظير في حزمة مكونة من 40 سنًا - K145IK1911. لا يختلف اسم دبابيس هذه الدائرة الدقيقة عن سابقتها، والفرق هو في الترقيم.



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

كمحركات سلسلة – J1-J7 يمكن استخدام الترانزستورات KT3107 مع فهرس الحروف I، A، B. للسائقين لاختيار القطاعات D1-D4، KT3102I، أو KT3117A، KT660A، بالإضافة إلى أي أجهزة أخرى ذات جهد باعث جامع أقصى لا يقل عن 35 فولت وتيار مجمع يبلغ سيتم استخدام 100 مللي أمبير على الأقل. يتم تنظيم تيار قطاعات المؤشر بواسطة مقاومات في دوائر المجمع الخاصة بمحركات الصف.



يتم استخدام نقطة تومض بتردد 1 هرتز للفصل بين أرقام الساعة والدقائق.

هذا التردد موجود عند الطرف Y4 بعد بدء التوقيت. يوفر هذا المخطط أيضًا القدرة على العرض على الشاشة بدلاً من الساعات والدقائق - الدقائق والثواني على التوالي. يتم الانتقال إلى هذا الوضع بالضغط على الزر "Sec". تتم العودة إلى عرض الوقت بالساعة والدقيقة بعد الضغط على زر "الرجوع". توفر هذه الشريحة القدرة على ضبط منبهين في وقت واحد، ولكن في هذا المخطط لا يتم استخدام المنبه الثاني باعتباره غير ضروري. يتم استخدام مكبر صوت بيزو مزود بمولد مدمج بجهد إمداد يبلغ 12 فولت كباعث صوت. تتم إزالة إشارة المنبه من الدبوس Y5 للدائرة الدقيقة. لتوفير صوت متقطع، يتم تعديل الإشارة بتردد 1 هرتز، يستخدم للإشارة إلى الإيقاع الثاني (النقطة). للحصول على دراسة أكثر تفصيلاً لوظيفة الدائرة الدقيقة K145IK1901(11)، يمكنك الرجوع إلى الوثائق التي يمكن العثور عليها بسهولة مؤخرًا على الإنترنت. يجب أن يتم تشغيل الدائرة الدقيقة بجهد سالب يبلغ -27 فولت ± 10%. وفقًا للتجارب التي تم إجراؤها، تظل الدائرة الدقيقة قيد التشغيل حتى عند جهد -19 فولت، ولا تتأثر دقة الساعة على الإطلاق.

يظهر مخطط الساعة في الشكل أعلاه. تم استخدام مقاومات الرقائق ذات الحجم القياسي 1206 في الدائرة، مما يجعل من الممكن تقليل أبعاد الجهاز بشكل كبير. أي مؤشرات مكونة من سبعة أجزاء ذات أنود مشترك مناسبة.

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

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

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

الخطوة 1: المكونات المطلوبة



إليك ما ستحتاج إليه:

  • وحدة الفولتميتر التناظرية 5 فولت تيار مستمر ؛
  • متحكم Arduino UNO أو أي جهاز Arduino مناسب آخر؛
  • لوحة دوائر اردوينو (لوحة بروتو) ؛
  • وحدة DS1307 لساعة الوقت الحقيقي (RTC)؛
  • وحدة مع وحدة تحكم PWM TLC5940؛
  • المصابيح الخلفية LED البتلة - 12 قطعة؛
  • مكونات لتجميع دائرة التحكم التلقائي في السطوع (LDR).

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

الخطوة 2: اطلب




يتكون القرص من ثلاثة أجزاء (طبقات) مقطوعة على آلة القطع بالليزر من لوح MDF مقاس 3 مم، ويتم تثبيتها معًا بمسامير. يتم وضع لوحة بدون فتحات (أسفل اليمين في الصورة) أسفل لوحة أخرى لوضع مصابيح LED (أسفل اليسار). بعد ذلك، يتم وضع مصابيح LED الفردية في الفتحات المناسبة، ويتم وضع اللوحة الأمامية في الأعلى (في الشكل العلوي). يتم حفر أربعة ثقوب على طول حافة القرص، حيث يتم من خلالها ربط الأجزاء الثلاثة معًا.

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

الرسم الفني لأجزاء الاتصال متاح على:

الخطوة 3: تصميم الدائرة



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

الخطوة 4: توصيل لوحة دائرة اردوينو





  1. الخطوة الأولى هي فك جميع وصلات الإبرة الموجودة على لوحات الدوائر واللوحات المقطعية؛
  2. علاوة على ذلك، نظرًا لحقيقة أن العديد من اللوحات والأجهزة الطرفية تستخدم طاقة 5V وGND، فمن أجل الموثوقية، تم لحام سلكين لـ 5V وGND على لوحة الدائرة؛
  3. بعد ذلك، تم تثبيت وحدة تحكم TLC5940 PWM بجوار جهات الاتصال المستخدمة؛
  4. ثم يتم توصيل وحدة التحكم TLC5940 وفقًا لمخطط الاتصال؛
  5. لكي تتمكن من استخدام البطارية، تم تركيب وحدة RTC على حافة لوحة الدائرة. إذا قمت بلحامها في منتصف اللوحة، فلن تكون علامات الدبوس مرئية؛
  6. تم توصيل وحدة RTC وفقًا لمخطط الاتصال؛
  7. تم تجميع دائرة التحكم التلقائي في السطوع (LDR)، يمكنك مشاهدتها على الرابط
  8. يتم توصيل أسلاك الفولتميتر عن طريق توصيل الأسلاك بالدبوس 6 و GND.
  9. في النهاية، تم لحام 13 سلكًا لمصابيح LED (في الممارسة العملية، اتضح أنه كان من الأفضل القيام بذلك قبل الانتقال إلى الخطوة 3).

الخطوة 5: الكود

تم تجميع الكود أدناه من أجزاء مختلفة من مكونات الساعة الموجودة على الإنترنت. لقد تم تصحيحه بالكامل وهو الآن يعمل بكامل طاقته، وتمت إضافة بعض التعليقات التفصيلية. ولكن قبل التحميل إلى المتحكم الدقيق، ضع في اعتبارك النقاط التالية:

  • قبل تحديث البرنامج الثابت لـ Arduino، يجب عليك إلغاء التعليق على السطر الذي يحدد الوقت:
    rtc.adjust(DateTime(__DATE__, __TIME__))
    بعد وميض وحدة التحكم بهذا الخط (تم ضبط الوقت)، تحتاج إلى التعليق عليه مرة أخرى وميض وحدة التحكم مرة أخرى. يتيح ذلك لوحدة RTC استخدام البطارية لتذكر الوقت في حالة فقدان الطاقة الرئيسية.
  • في كل مرة تستخدم فيها "Tlc.set()" تحتاج إلى استخدام "Tlc.update"

الخطوة 6: الحلقة الخارجية

تمت طباعة حلقة الساعة الخارجية بتقنية ثلاثية الأبعاد باستخدام طابعة Replicator Z18. يتم تثبيته على الساعة باستخدام البراغي الموجودة على وجه الساعة. يوجد أدناه ملف يحتوي على نموذج ثلاثي الأبعاد للحلقة للطباعة على طابعة ثلاثية الأبعاد.

الخطوة 7: تجميع الساعة


تم تثبيت متحكم Arduino مع جميع الأجهزة الإلكترونية الأخرى في الجزء الخلفي من الساعة باستخدام البراغي والصواميل كفواصل. ثم قمت بتوصيل جميع مصابيح LED والفولتميتر التناظري و LDR بالأسلاك التي كانت ملحومة مسبقًا بلوحة الدائرة. جميع مصابيح LED مترابطة بواسطة ساق واحدة ومتصلة بمنفذ VCC الموجود على وحدة التحكم TLC5940 (قطعة من السلك ملحومة ببساطة في دائرة).

حتى الآن، كل هذا ليس معزولًا جيدًا عن الدوائر القصيرة، لكن العمل على ذلك سيستمر في الإصدارات المستقبلية.