جدول المحتويات:

التنين الجيبي: 10 خطوات (مع صور)
التنين الجيبي: 10 خطوات (مع صور)

فيديو: التنين الجيبي: 10 خطوات (مع صور)

فيديو: التنين الجيبي: 10 خطوات (مع صور)
فيديو: قوة التنين تتصدى لهجوم الفضائيين 2024, شهر نوفمبر
Anonim
التنين الجيبي
التنين الجيبي

Sine-ese Dragon هي قطعة ديكور منزلي محيطة تستخدم حركات ميكانيكية وأضواء لتخبرك بتوقعات الطقس لفترات الثلاث ساعات القادمة. بالتعريف ، يصف المحيط المحيط المباشر لشيء ما ؛ ومن ثم فقد تقرر أنه من المناسب دمج بيانات الطقس في العرض المحيط. الطقس هو أحد الجوانب التي تغير يوم الناس عن غير قصد وهي جزء من المعلومات التي تتغير باستمرار كل دقيقة ، أو حتى في الثانية.

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

التصور

يتم التلاعب بـ Sine-ese Dragon في ست نقاط رئيسية في ثلاثة أقسام منفصلة تمثل توقعات الطقس لمدة ثلاث ساعات. لكل فاصل زمني مدته 3 ساعات ، سيتم تضمين المعلومات التالية:

  • وصف الطقس - يحدد لون معلومات الطقس الحالية.
  • درجة الحرارة - تحدد ارتفاع الجسم
  • الرطوبة - وميض مقاطع LED
  • سرعة الرياح - يتحكم في سرعة تحرك الجسم لليسار واليمين.

المواد المطلوبة

  1. 3 مم الخشب الرقائقي / الكرتون
  2. 5 مم من المسامير الخشبية أو عيدان تناول الطعام
  3. 2 فوتونات جسيمية
  4. 3 ألعاب سلينكي
  5. 6 محركات مؤازرة
  6. مصابيح NeoPixel (إما حبلا أو أضواء فردية مخيطة معًا)
  7. الكثير من الغراء الفائق
  8. خيط موصل
  9. طلاء أكريليك
  10. نسيج زخرفي
  11. قاطع ليزري
  12. طابعة 3D

الخطوة 1: صعودا وهبوطا

اعلى واسفل!
اعلى واسفل!
اعلى واسفل!
اعلى واسفل!
اعلى واسفل!
اعلى واسفل!

خطوتك الأولى لبناء التنين الجيبي هي بناء المكون الذي يتحكم في حركة الجسم لأعلى ولأسفل. كم هو مثير!

  1. قم بتنزيل ملفات Adobe Illustrator (.ai) واطبعها باستخدام آلة القطع بالليزر.

    يجب طباعة upDownBoxWithPlatform.ai على ورق مقوى

  2. قم بتنزيل ملفات الطباعة ثلاثية الأبعاد (.stl) واستخدم الطابعة ثلاثية الأبعاد المفضلة لديك لطباعتها.

    لا يهم اللون بالنسبة للقرص أو محرك الأقراص. في الصورة الثانية ، تم إدخال قرص التقليب داخل فتحة القرص

  3. قم بتجميع أول مكونين ولصقهما معًا كما هو موضح في الصور من 3 إلى 5.

    1. المنصة
    2. الأخاديد للقرص
  4. الآن ، قم بتجميع المربع باتباع النصائح أدناه.

    1. يجب أن تمر أسلاك المؤازرة عبر الفتحة المستطيلة الموجودة على جانب الصندوق.
    2. يتم توصيل أقصر نهاية لمحرك القرص برأس المؤازرة ويمر الطرف الأطول عبر الفتحة الموجودة في الجانب الآخر من الصندوق مع وجود ثقب دائري عليه. هذا موضح في الصورة 6.
  5. الآن ، نحتاج إلى شيء ما لضمان بقاء النظام الأساسي مستويًا عند تشغيل القرص. اقطع عود الطعام إلى عيدان بطول 75 مم (الصورة 7) وألصقها من خلال الجزء العلوي من الصندوق في الجزء العلوي من المنصة باستخدام الغراء الساخن. تأكد من أن العصي مستوية بزاوية 90 درجة على المنصة.
  6. أدخل عصا بطول 212 مم في الفتحة الوسطى أعلى الصندوق بالمنصة.

حلو! الآن لديك صندوق كامل (الصورة 8) لحركة التنين لأعلى ولأسفل. الآن ، كرر الخطوات المذكورة أعلاه مرتين أخريين!

الخطوة الثانية: ماذا عن اليسار واليمين ؟

وماذا عن اليسار واليمين ؟!
وماذا عن اليسار واليمين ؟!
ماذا عن اليسار واليمين ؟!
ماذا عن اليسار واليمين ؟!
ماذا عن اليسار واليمين ؟!
ماذا عن اليسار واليمين ؟!
ماذا عن اليسار واليمين ؟!
ماذا عن اليسار واليمين ؟!

الآن ، لا يمكننا أن ننسى الحركة اليمنى واليسرى لـ Sine-ese Dragon ، هل يمكننا ذلك؟ دعنا ننتقل إلى الخطوة الثانية!

  1. قم بتنزيل ملفات Adobe Illustrator (.ai) واطبعها باستخدام آلة القطع بالليزر.

    1. يجب طباعة leftRightBoxWithPlatforms.ai على ورق مقوى.
    2. يجب طباعة ملف armTurner.ai على مادة بسمك 3 مم.
  2. قم بتنزيل ملفات الطباعة ثلاثية الأبعاد (.stl) واستخدم الطابعة ثلاثية الأبعاد المفضلة لديك لطباعتها.

    تأكد من طباعة اثنين من الذراعين! اللون لا يهم هنا

  3. قم بتجميع المنصتين معًا كما هو موضح في الصورة 3 باستخدام الغراء الساخن.
  4. ضع الصندوق معًا. في حين أنه قد يكون من الصعب القيام بذلك ، إلا أنه من الأسهل تحقيقه من خلال:

    1. إدخال المنصتين بين الشقين الكبيرين على جانبي الصندوق.
    2. وضع الذراع الأول أعلى المنصة العلوية.
    3. قم بتدوير ذراع التدوير من خلال الذراع ثم المنصة العلوية.
    4. وضع الذراع الثانية أعلى المنصة السفلية.
    5. قم بتدوير ذراع التدوير من خلال الذراع الثانية ثم المنصة السفلية.
    6. لصق ذراع التدوير من خلال الفتحة المستطيلة لقلب الذراع المطبوع ثلاثي الأبعاد.
    7. يذهب الطرف الآخر من الخلاط أعلى محرك سيرفو.
    8. أضف القطع العلوية والسفلية والخلفية إلى الصندوق.

يجب أن يبدو صندوقك المجمع النهائي مثل الصورة السادسة. الآن ، عليك أن تكرر ذلك مرتين أخريين!

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

الخطوة الثالثة: رفع الجسد … كيف؟

رفع الجسد … كيف؟
رفع الجسد … كيف؟

سؤال جيد! هذا هو الوقت الذي يأتي فيه هؤلاء حاملو الطباعة ثلاثية الأبعاد. قم بتنزيل ملف.stl المضمن وطباعته باستخدام طابعة ثلاثية الأبعاد. تأكد من طباعة 6 حوامل إجمالاً للمربعات الستة المختلفة.

إذا كنت قد رأيت صورة الحامل الخشن أعلاه ، فقد تم تدمير المفاجأة - وهذا هو لون التنين الجيبي الخاص بنا!

الخطوة 4: لكن هذه الصناديق ليست بهذا الجمال …

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

قم بتنزيل ملفات Adobe Illustrator وقصها باستخدام قاطع الليزر. تم رسم تصميم الغيوم من قبل أحد المساهمين. لا تتردد في تعديلها عن طريق إزالتها داخل ملف الرسام وإضافة التصميم الخاص بك كما تراه مناسبًا! فيما يلي الخطوات المقترحة لتجميع كل شيء معًا.

  1. قم بتجميع كل القطع الثلاث من الملف الأول (OuterBoxFinal_1) ولصقها معًا.
  2. لا تقم بإضافة القطعة من الملف الثاني (OuterBoxFinal_2) بعد.
  3. ضع القطعة من الملف الثالث (OuterBoxFinal_3) إلى أسفل الصندوق ويجب أن تغلق في الأعلى. صمغ فقط في الجزء السفلي من الصندوق.
  4. اطبع innerBoxesPlatform مرتين. ألصق القطعتين اللتين تحتويان على فتحات مستطيلة كبيرة معًا. ثم قم بغراء ثلاث قطع متبقية معًا. أخيرًا ، قم بلصقه بالمجموعة اللاصقة الأخرى التي بها ثقوب.
  5. ضع المنصة في أسفل الصندوق الكبير.
  6. أدخل جميع الصناديق الست الأصغر في مواضعها المقابلة على المنصة.
  7. الآن ، ضع القطعة من الملف الثاني (OuterBoxFinal_2) أعلى الصندوق والصقها حول الحافة. يجب أن تتماشى الثقوب الموجودة على القطعة العلوية مع الفتحات الموجودة في الصناديق الأصغر. إذا لم يكن كذلك ، أعد ترتيب الصناديق الصغيرة. لا تقم بإضافة الغراء إلى الصناديق الصغيرة على الإطلاق.
  8. إذا كنت تستخدم لوح تجارب يحتوي على قطعة لزجة في الأسفل ، فضعها بالقرب من منتصف القطعة السفلية في مكان عند إغلاق الصندوق ، يجب أن تختفي اللوح مع الفوتونات. توجد شقوق صغيرة في القطعة السفلية تسهل عليك الاتصال بالفوتونات من الخارج.

الخطوة 5: ألعاب Slinky ؟؟ أوه يا

سلينكي تويز ؟؟ أوه يا!
سلينكي تويز ؟؟ أوه يا!
سلينكي تويز ؟؟ أوه يا!
سلينكي تويز ؟؟ أوه يا!

جسد التنين:

1. اجمع بين ثلاث قطع سلينكيس معًا باستخدام الغراء الساخن أو الشريط اللاصق.

2. قم بقياس طول وقطر السلينكيس وقطع قطعة من القماش الزخرفي.

3. اجمع طرفي القماش وخياطتهما معًا.

4. بمجرد الانتهاء من الخياطة ، حرك السلينكي مثل الجورب.

5. خيط نهايات الخيط الخشن على القماش المخيط.

الخطوة 6: اطبع تنينك

أجزاء التنين المطبوعة ثلاثية الأبعاد:

1. تم أخذ الأجزاء من

2. استخدمنا الرأس والساقين والعينين فقط.

3. بعد الطباعة ثلاثية الأبعاد للجزء ، قم بتنعيمه باستخدام ورق الصنفرة والأسيتون.

4. قم بطلاء الأجزاء بالطريقة التي ترغب في تزيينها بها.

الخطوة 7: حان الوقت لتصعيد تنينك باستخدام NeoPixels

حان الوقت لتصعيد تنينك باستخدام NeoPixels!
حان الوقت لتصعيد تنينك باستخدام NeoPixels!
حان الوقت لتصعيد تنينك باستخدام NeoPixels!
حان الوقت لتصعيد تنينك باستخدام NeoPixels!

قطعة خفيفة:

1. يمكنك ببساطة استخدام حبلا neopixel لإنشاء الأضواء إذا كنت ترغب في ذلك (نفدنا من الخيوط).

2. استخدمنا 20 مصباح نيوبيكسل وقمنا بتوصيلها باستخدام الأسلاك. تم لحام هذه الأسلاك عليها وتوصيلها بالفوتون باستخدام أسلاك حمراء بحيث تتطابق مع موضوع التنين.

3. يمكنك أيضًا خياطة مصابيح neopixel الخاصة بك على قطعة طويلة من القماش ، لكننا لم نستخدمها لأن لدينا قطعة قماش مصنوعة من المعدن.

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

الخطوة 8: وقت البرمجة

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

الآن ، لأول متحكم …

في ملف Arduino (.ino) ، قم بتضمين المكتبات التالية وتعريفات:

# تضمين "neopixel.h"

# تضمين "ArduinoJson.h"

#define PIXEL_PIN D4

#define PIXEL_COUNT 18

بعد ذلك ، أعلن عن المتغيرات التالية:

شريط Adafruit_NeoPixel = Adafruit_NeoPixel (PIXEL_COUNT ، PIXEL_PIN) ؛

المؤازرة المؤازرةLeftRight_1 ؛ أجهزة مؤازرة أجهزة مؤازرة أجهزة مؤازرة int positionLeftRight_1 = 0 ؛ int positionUpDown_1 = 0 ؛ int leftRight_1 = 1 ؛ int upDown_1 = 1 ؛ int positionLeftRight_2 = 100 ؛ // يجب أن يكون بين 0 و 180 (بالدرجات) int positionUpDown_2 = 180 ؛ // يجب أن يكون بين 0 و 180 (بالدرجات) int leftRight_2 = 1 ؛ // 0 = يسار ، 1 = يمين int upDown_2 = 1 ؛ // 0 = up، 1 = down const size_t bufferSizeCurrent = JSON_ARRAY_SIZE (1) + JSON_OBJECT_SIZE (1) + 2 * JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (4) + JSON_OBJECT_SIZE (5) + JSON_OBJECT_SIZE (5) + JSON_OBJECT_SIZE (5) + JSON_OBJECT_SIZE (5) + JSON_OBJECT_SIZE (5) + JSON_OB 390 ؛ حجم const_t bufferSizeForecast = 38 * JSON_ARRAY_SIZE (1) + JSON_ARRAY_SIZE (38) + 2 * JSON_OBJECT_SIZE (0) + 112 * JSON_OBJECT_SIZE (1) + 39 * JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (2) + 4 * JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (2) + (5) + 76 * JSON_OBJECT_SIZE (8) + 12490 ؛ String weatherArray [3] ؛ درجة حرارة تعويم الصفيف [3] ؛ رطوبة عائمة صفيف [3] ؛ صفيف سرعة الرياح [3] ؛ صفيف الطابع الزمني للسلسلة [3] ؛ int upDownMaxDegree [3] ، int leftRightSpeed [3] ، سلسلة allData5DaysForecast ؛

انقر هنا لمعرفة كيفية إعداد webhooks. عند الانتهاء ، أضف الإعلانات والوظائف التالية وقم بإجراء التغييرات المناسبة إذا لزم الأمر:

void getWeather5DayForecast () {Particle.publish ("get_weather5DayForecast") ؛ allData5DaysForecast = "" ؛ } Timer timerWeatherForecast (60000، getWeather5DayForecast)؛ void getCurrentWeather () {Particle.publish ("get_currentWeather") ؛ } Timer timerWeatherCurrent (60000، getCurrentWeather) ؛

تتحكم الوظائف التالية في حركات التنين لأعلى / لأسفل ولليسار / لليمين:

تغيير باطل LeftRight1 () {if (leftRight_1) {positionLeftRight_1 = positionLeftRight_1 + leftRightSpeed [0] ؛ إذا (positionLeftRight_1> 100) {leftRight_1 = 0 ؛ }} else {positionLeftRight_1 = positionLeftRight_1 - leftRightSpeed [0] ؛ إذا (positionLeftRight_1 <0) {leftRight_1 = 1 ؛ }} servoLeftRight_1.write (positionLeftRight_1) ، }

changeLeftRight2 باطلة {

إذا (leftRight_2) {positionLeftRight_2 = positionLeftRight_2 + leftRightSpeed [1] ؛ إذا (positionLeftRight_2> 100) {leftRight_2 = 0 ؛ }} else {positionLeftRight_2 = positionLeftRight_2 - leftRightSpeed [1] ؛ إذا (positionLeftRight_2 <0) {leftRight_2 = 1 ؛ }} servoLeftRight_2.write (positionLeftRight_2) ، }

تغيير باطلUpDown1 () {

إذا (upDown_1) {positionUpDown_1 ++ ؛ إذا (positionUpDown_1> upDownMaxDegree [0]) {upDown_1 = 0 ؛ }} else {positionUpDown_1-- ؛ إذا (positionUpDown_1 <1) {upDown_1 = 1 ؛ }} servoUpDown_1.write (positionUpDown_1) ، }

تغيير باطلUpDown2 () {

إذا (upDown_2) {positionUpDown_2 ++ ؛ إذا (positionUpDown_2> upDownMaxDegree [1]) {upDown_2 = 0 ؛ }} else {positionUpDown_2-- ؛ إذا (positionUpDown_2 <1) {upDown_2 = 1 ؛ }} servoUpDown_2.write (positionUpDown_2) ، }

لتكون قادرًا على تغيير الحركات في فترة زمنية ، يتم إنشاء مؤقتات.

Timer timerLeftRight1 (100 ، changeLeftRight1) ؛

Timer timerLeftRight2 (100 ، changeLeftRight2) ؛ Timer timerUpDown1 (10 ، changeUpDown1) ؛ Timer timerUpDown2 (10 ، changeUpDown2) ؛

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

إعداد باطل () {// start the weather timer timerWeatherForecast.start ()؛ timerWeatherCurrent.start () ، // Neopixels strip.begin () ؛ // ضع التهيئة مثل pinMode وابدأ الوظائف هنا. // إعداد Micro Servo servoLeftRight_1.attach (D1) ؛ servoUpDown_1.attach (D0) ، servoLeftRight_2.attach (D3) ؛ servoUpDown_2.attach (D2) ، servoLeftRight_1.write (positionLeftRight_1) ، // تهيئة وضع المؤازرة servoUpDown_1.write (positionUpDown_1) ؛ // تهيئة وضع المؤازرة servoLeftRight_2.write (positionLeftRight_2) ؛ // تهيئة وضع المؤازرة servoUpDown_2.write (positionUpDown_2) ؛ // تهيئة جهاز ضبط الوقت timerLeftRight1.start () ؛ timerLeftRight2.start () ، timerUpDown1.start () ، timerUpDown2.start () ، // فتح وحدة تحكم Serial.begin (9600) ؛ تأخير (2000) ؛ Serial.println ("مرحبًا!") ؛ // اشترك في get_weather5DayForecast و get_currentWeather webhooks Particle.subscribe ("hook-response / get_weather5DayForecast"، gotWeather5DayForecast، MY_DEVICES) ؛ Particle.subscribe ("hook-response / get_currentWeather / 0"، gotCurrentWeatherData، MY_DEVICES)؛ getCurrentWeather () ، getWeather5DayForecast () ، }

لا يتم استخدام وظيفة الحلقة لهذا المشروع. لا يمكننا أن ننسى وظائف التعامل مع البيانات الواردة من خطافات الويب!

void gotWeather5DayForecast (const char * event، const char * data) {allData5DaysForecast + = data؛ // يحفظ جميع البيانات في سلسلة واحدة. int allData5DaysForecastLen = allData5DaysForecast.length () ، المخزن المؤقت char [allData5DaysForecastLen + 1] ؛ allData5DaysForecast.toCharArray (المخزن المؤقت ، allData5DaysForecastLen + 1) ؛ // إنشاء مخزن مؤقت للسلسلة int bufferLength = sizeof (buffer) ؛ DynamicJsonBuffer jsonBufferWeather (bufferLength) ؛ JsonObject & root = jsonBufferWeather.parseObject (المخزن المؤقت) ؛ // اختبار نجاح التحليل. if (! root.success ()) {//Serial.println(" التحليل لتوقعات الطقس لمدة 5 أيام … ERROR! ")؛ إرجاع؛ } int i = 1 ؛ JsonArray & list = root ["list"]؛ لـ (JsonObject & currentObject: list) {if (i <3) {JsonObject & main = currentObject ["main"] ؛ درجة حرارة الطفو = الرئيسية ["درجة الحرارة"] ؛ الرطوبة النسبية = الرئيسية ["الرطوبة"] ؛ JsonObject & weather = currentObject ["الطقس"] [0] ؛ const char * weatherInfo = الطقس ["main"] ؛ float windSpeed = currentObject ["wind"] ["speed"] ؛ const char * timestamp = currentObject ["dt_txt"] ؛ int tempFah = convertToFahrenheit (درجة الحرارة) ؛ int servoMaxDegree = updateUpDown (tempFah) ، upDownMaxDegree = servoMaxDegree ، int servoIncrement = updateleftRight (windSpeed) ؛ leftRightSpeed = servoIncrement ، setColor (weatherInfo ، ط) ؛ temperatureArray = tempFah ؛ الرطوبة ؛ Array = الرطوبة ؛ weatherArray = weatherInfo ؛ windSpeedArray = windSpeed ؛ timestampArray = طابع زمني ؛ أنا ++ ؛ } آخر {استراحة؛ }}}

void gotCurrentWeatherData (const char * event ، const char * data) {DynamicJsonBuffer jsonBufferWeather (bufferSizeCurrent) ؛ JsonObject & root = jsonBufferWeather.parseObject (بيانات) ؛ // اختبار نجاح التحليل. if (! root.success ()) {//Serial.println(" التحليل للطقس الحالي … ERROR! ")؛ إرجاع؛ } JsonObject & weather = root ["weather"] [0] ؛ const char * weather_main = weather ["main"] ؛ JsonObject & main = root ["main"] ؛ float main_temp = main ["temp"] ؛ int main_humidity = الرطوبة الرئيسية ["الرطوبة"] ؛ تعويم wind_speed = الجذر ["الرياح"] ["السرعة"] ؛ const char * timestamp = root ["dt_txt"] ؛ int tempFah = convertToFahrenheit (main_temp) ؛ int servoMaxDegree = updateUpDown (tempFah) ، upDownMaxDegree [0] = servoMaxDegree ، int servoIncrement = updateleftRight (wind_speed) ؛ leftRightSpeed [0] = servoIncrement ، setColor (weather_main ، 0) ؛ weatherArray [0] = weather_main ؛ temperatureArray [0] = tempFah ؛ معدل الرطوبة [0] = الرطوبة الرئيسية ؛ windSpeedArray [0] = wind_speed ، timestampArray [0] = طابع زمني ؛ }

أدناه ، يمكنك العثور على وظائف إضافية تتحكم في تحديث أوضاع محركات المؤازرة ، وتحويل درجة الحرارة من كلفن إلى فهرنهايت وتعيين ألوان مصابيح LED.

int updateUpDown (float temp) {// عيِّن الدرجة إلى نطاق [0 ، 180] float servoMaxDegree = temp * 45/31 + (990/31) ؛ Serial.print ("درجة مؤازرة جديدة:") ؛ Serial.println (servoMaxDegree) ؛ عودة servoMaxDegree ؛ }

int updateleftRight (تعويم windSpeed) {

// عيّن سرعة الرياح إلى نطاق [1 ، 100] مضاعفات تعويم = سرعة الرياح * 99/26 + 1 ؛ Serial.print ("قيمة الزيادة المؤازرة الجديدة:") ؛ Serial.println (مضاعفات مؤازرة) ؛ مضاعفات العودة }

int convertToFahrenheit (float tempKel) {

int tempFah = tempKel * 9.0 / 5.0 - 459.67 ؛ عودة tempFah. }

void setColor (String weatherDesc، int index) {

int ledIndex = 0 ؛ إذا (الفهرس == 0) {ledIndex = 0 ؛ } else if (index == 1) {ledIndex = 6 ؛ } else if (index == 2) {ledIndex = 12 ؛ } else {return؛ } if (weatherDesc == "Clear") {// yellow for (int j = ledIndex؛ j <ledIndex + 6؛ j ++) {strip.setPixelColor (j، strip. Color (253، 219، 62))؛ // عرض الشريط الأصفر () ؛ تأخير (20) ؛ }} else if (weatherDesc == "Clouds") {// gray لـ (int j = ledIndex؛ j <ledIndex + 6؛ j ++) {strip.setPixelColor (j، strip. Color (223، 229، 237))؛ // شريط رمادي. تأخير (20) ؛ }} else if (weatherDesc == "Snow") {// white for (int j = ledIndex؛ j <ledIndex + 6؛ j ++) {strip.setPixelColor (j، strip. Color (255، 225، 225))؛ // شريط أبيض. تأخير (20) ؛ }} else if (weatherDesc == "Rain") {// blue لـ (int j = ledIndex؛ j <ledIndex + 6؛ j ++) {strip.setPixelColor (j، strip. Color (119، 191، 246))؛ // الشريط الأزرق. تأخير (20) ؛ }} else {// red for (int j = ledIndex؛ j <ledIndex + 6؛ j ++) {strip.setPixelColor (j، strip. Color (254، 11، 5))؛ // red strip.show ()؛ تأخير (20) ؛ }}}

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

الخطوة 9: البرمجة مستمرة

نظرًا لأن رمز الفوتون الثاني متطابق تقريبًا مع الرمز الخاص بالفوتون الأول ، يتم نسخ الكود بالكامل ولصقه أدناه:

# تضمين "ArduinoJson.h"

أجهزة مؤازرة

أجهزة مؤازرة

int positionLeftRight_3 = 45 ؛

int positionUpDown_3 = 0 ؛ int leftRight_3 = 1 ، int upDown_3 = 1 ؛

const size_t bufferSizeCurrent = JSON_ARRAY_SIZE (1) + JSON_OBJECT_SIZE (1) + 2 * JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (4) + JSON_OBJECT_SIZE (5) + JSON_OBJECT_SIZE (6) + JSON_OBJECT_SIZE (6) + JSON_OBJECT_SIZE (6)

حجم const_t bufferSizeForecast = 38 * JSON_ARRAY_SIZE (1) + JSON_ARRAY_SIZE (38) + 2 * JSON_OBJECT_SIZE (0) + 112 * JSON_OBJECT_SIZE (1) + 39 * JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (2) + 4 * JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (2) + JSON_OBJECT_SIZE (2) + (5) + 76 * JSON_OBJECT_SIZE (8) + 12490 ؛

String weatherArray [3] ؛

درجة حرارة تعويم الصفيف [3] ؛ رطوبة عائمة صفيف [3] ؛ صفيف سرعة الرياح [3] ؛ صفيف الطابع الزمني للسلسلة [3] ؛ int upDownMaxDegree [3] ، int leftRightSpeed [3] ،

سلسلة allData5DaysForecast ؛

باطل getWeather5DayForecast ()

{Particle.publish ("get_weather5DayForecast2") ؛ allData5DaysForecast = "" ؛ }

Timer timerWeatherForecast (60000 ، getWeather5DayForecast) ؛ // 10 ، 800 ، 000 مللي ثانية = 3 أيام

getCurrentWeather باطل ()

{Particle.publish ("get_currentWeather2") ؛ }

Timer timerWeatherCurrent (60000 ، getCurrentWeather) ؛

changeLeftRight3 باطلة {

إذا (leftRight_3) {positionLeftRight_3 = positionLeftRight_3 + leftRightSpeed [2] ؛ إذا (positionLeftRight_3> 100) {leftRight_3 = 0 ؛ }} else {positionLeftRight_3 = positionLeftRight_3 - leftRightSpeed [2] ؛ إذا (positionLeftRight_3 <0) {leftRight_3 = 1 ؛ }} servoLeftRight_3.write (positionLeftRight_3) ، }

تغيير باطلUpDown3 () {

إذا (upDown_3) {positionUpDown_3 ++ ؛ إذا (positionUpDown_3> upDownMaxDegree [2]) {upDown_3 = 0 ؛ }} else {positionUpDown_3-- ؛ إذا (positionUpDown_3 <1) {upDown_3 = 1 ؛ }} servoUpDown_3.write (positionUpDown_3) ، }

Timer timerLeftRight3 (100 ، changeLeftRight3) ؛

Timer timerUpDown3 (10 ، changeUpDown3) ؛

الإعداد باطل() {

// بدء عداد توقيت الطقس WeatherForecast.start () ؛ timerWeatherCurrent.start () ، // ضع التهيئة مثل pinMode وابدأ الوظائف هنا. // إعداد Micro Servo servoLeftRight_3.attach (D1) ؛ servoUpDown_3.attach (D0) ،

servoLeftRight_3.write (positionLeftRight_3) ، // تهيئة وضع المؤازرة

servoUpDown_3.write (positionUpDown_3) ، // تهيئة وضع المؤازرة

timerLeftRight3.start () ،

timerUpDown3.start () ، // فتح وحدة تحكم Serial.begin (9600) ؛ تأخير (2000) ؛ Serial.println ("مرحبًا!") ؛ // اشترك في get_weather5DayForecast و get_currentWeather webhooks Particle.subscribe ("hook-response / get_weather5DayForecast2"، gotWeather5DayForecast، MY_DEVICES) ؛ Particle.subscribe ("hook-response / get_currentWeather2 / 0"، gotCurrentWeatherData، MY_DEVICES) ؛ getCurrentWeather () ، getWeather5DayForecast () ، }

gotWeather5DayForecast باطل (حدث حرف * ، حرف * بيانات)

{allData5DaysForecast + = بيانات ؛ // يحفظ جميع البيانات في سلسلة واحدة. int allData5DaysForecastLen = allData5DaysForecast.length () ، المخزن المؤقت char [allData5DaysForecastLen + 1] ؛ allData5DaysForecast.toCharArray (المخزن المؤقت ، allData5DaysForecastLen + 1) ؛ // إنشاء مخزن مؤقت للسلسلة int bufferLength = sizeof (buffer) ؛ DynamicJsonBuffer jsonBufferWeather (bufferLength) ؛ JsonObject & root = jsonBufferWeather.parseObject (المخزن المؤقت) ؛ //Serial.println(allData5DaysForecast) ؛ // اختبار نجاح التحليل. if (! root.success ()) {//Serial.println(" التحليل لتوقعات الطقس لمدة 5 أيام … ERROR! ")؛ إرجاع؛ } int i = 1 ؛ JsonArray & list = root ["list"]؛ لـ (JsonObject & currentObject: list) {if (i <3) {JsonObject & main = currentObject ["main"] ؛ درجة حرارة الطفو = الرئيسية ["درجة الحرارة"] ؛ الرطوبة النسبية = الرئيسية ["الرطوبة"] ؛ JsonObject & weather = currentObject ["الطقس"] [0] ؛ const char * weatherInfo = الطقس ["main"] ؛ float windSpeed = currentObject ["wind"] ["speed"] ؛ const char * timestamp = currentObject ["dt_txt"] ؛ int tempFah = convertToFahrenheit (درجة الحرارة) ؛ int servoMaxDegree = updateUpDown (tempFah) ، upDownMaxDegree = servoMaxDegree ، int servoIncrement = updateleftRight (windSpeed) ؛ leftRightSpeed = servoIncrement ، temperatureArray = tempFah ؛ الرطوبة ؛ Array = الرطوبة ؛ weatherArray = weatherInfo ؛ windSpeedArray = windSpeed ؛ timestampArray = طابع زمني ؛ أنا ++ ؛ } آخر {استراحة؛ }}}

gotCurrentWeatherData باطل (حدث حرف * ، بيانات حرف * ثابت)

{DynamicJsonBuffer jsonBufferWeather (bufferSizeCurrent) ؛ JsonObject & root = jsonBufferWeather.parseObject (بيانات) ؛ //Serial.println(data) ؛ // اختبار نجاح التحليل. if (! root.success ()) {//Serial.println(" التحليل للطقس الحالي … ERROR! ")؛ إرجاع؛ } JsonObject & weather = root ["weather"] [0] ؛ const char * weather_main = weather ["main"] ؛ JsonObject & main = root ["main"] ؛ float main_temp = main ["temp"] ؛ int main_humidity = الرطوبة الرئيسية ["الرطوبة"] ؛ تعويم wind_speed = الجذر ["الرياح"] ["السرعة"] ؛ const char * timestamp = root ["dt_txt"] ؛ int tempFah = convertToFahrenheit (main_temp) ؛ int servoMaxDegree = updateUpDown (tempFah) ، upDownMaxDegree [0] = servoMaxDegree ، int servoIncrement = updateleftRight (wind_speed) ؛ leftRightSpeed [0] = servoIncrement ، weatherArray [0] = weather_main ؛ temperatureArray [0] = tempFah ؛ معدل الرطوبة [0] = الرطوبة الرئيسية ؛ windSpeedArray [0] = wind_speed ، timestampArray [0] = طابع زمني ؛ }

int updateUpDown (float temp) {

// عيّن الدرجة إلى نطاق [0 ، 180] مؤازر تعويم MaxDegree = temp * 45/31 + (990/31) ؛ Serial.print ("درجة مؤازرة جديدة:") ؛ Serial.println (servoMaxDegree) ؛ عودة servoMaxDegree ؛ }

int updateleftRight (تعويم windSpeed) {

// عيّن سرعة الرياح إلى نطاق [1 ، 100] مضاعفات تعويم = سرعة الرياح * 99/26 + 1 ؛ Serial.print ("قيمة الزيادة المؤازرة الجديدة:") ؛ Serial.println (مضاعفات مؤازرة) ؛ مضاعفات العودة }

int convertToFahrenheit (float tempKel) {

int tempFah = tempKel * 9.0 / 5.0 - 459.67 ؛ عودة tempFah. }

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

الخطوة 10: استمتع بالتنين الخاص بك

تهانينا! لقد بنيت تنينًا جيبيًا من الصفر! الآن كل ما عليك فعله هو الجلوس والاستمتاع بعرضك المحيط!

ملاحظة: تم بناء هذا المشروع كجزء من الدورات الدراسية بواسطة Joan Bempong و Soundarya Muthuvel. يمكن العثور على صفحة الدورة التدريبية هنا.

موصى به: