สารบัญ:
- ขั้นตอนที่ 1: ขึ้นและลง
- ขั้นตอนที่ 2: แล้วซ้ายและขวาล่ะ
- ขั้นตอนที่ 3: จับร่างกาย…ยังไง?
- ขั้นตอนที่ 4: แต่กล่องเหล่านั้นไม่สวยขนาดนั้น…
- ขั้นตอนที่ 5: ของเล่นสลิงกี้?? พุทโธ่
- ขั้นตอนที่ 6: พิมพ์มังกรของคุณ
- ขั้นตอนที่ 7: ถึงเวลาก้าวขึ้นมังกรของคุณด้วย NeoPixels
- ขั้นตอนที่ 8: เวลาการเขียนโปรแกรม
- ขั้นตอนที่ 9: การเขียนโปรแกรมดำเนินต่อไป
- ขั้นตอนที่ 10: สนุกกับมังกรของคุณ
วีดีโอ: Sine-ese Dragon: 10 ขั้นตอน (พร้อมรูปภาพ)
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:07
Sine-ese Dragon เป็นของตกแต่งบ้านโดยรอบที่ใช้การเคลื่อนไหวทางกลและไฟเพื่อบอกพยากรณ์อากาศสำหรับช่วงเวลาสามชั่วโมงถัดไป ตามคำจำกัดความ Ambient อธิบายสภาพแวดล้อมในทันทีของบางสิ่ง ดังนั้นจึงมีความเหมาะสมที่จะรวมข้อมูลสภาพอากาศเข้ากับการแสดงผลโดยรอบ สภาพอากาศเป็นแง่มุมหนึ่งที่เปลี่ยนแปลงวันของผู้คนโดยไม่ได้ตั้งใจ และเป็นข้อมูลชิ้นหนึ่งที่เปลี่ยนแปลงตลอดเวลาทุกนาที หรือแม้แต่วินาที
มังกรจีนเป็น “สัญลักษณ์แห่งพลัง ความแข็งแกร่ง และความโชคดี” และมักถูกมองว่ามีคุณค่าทางวัฒนธรรมและประเพณีสูงทั่วทั้งอนุทวีปเอเชีย นอกจากจะนำโชคลาภมาให้แล้ว มังกรจีนยังกล่าวกันว่ามีพลังอำนาจที่ควบคุม “น้ำ ฝน ไต้ฝุ่น และน้ำท่วม” ในที่สุด มังกรจีนก็ถือว่าเหมาะสมที่จะนำเสนอข้อมูลสภาพอากาศ
การสร้างภาพ
Sine-ese Dragon ได้รับการจัดการที่หกจุดหลักในสามส่วนแยกกันเพื่อเป็นตัวแทนของการพยากรณ์อากาศเป็นเวลา 3 ชั่วโมง สำหรับแต่ละช่วงเวลา 3 ชั่วโมง ข้อมูลต่อไปนี้จะถูกรวมไว้:
- คำอธิบายสภาพอากาศ - กำหนดสีของข้อมูลสภาพอากาศปัจจุบัน
- อุณหภูมิ - ระบุความสูงของร่างกาย
- ความชื้น - ไฟ LED กะพริบ
- ความเร็วลม - ควบคุมความเร็วของร่างกายที่เคลื่อนที่ไปทางซ้ายและขวา
วัสดุที่จำเป็น
- ไม้อัด/กระดาษแข็ง 3 มม.
- เดือยไม้หรือตะเกียบ 5 มม
- 2 อนุภาคโฟตอน
- 3 ของเล่นสลิงกี้
- เซอร์โวมอเตอร์ 6 ตัว
- ไฟ NeoPixel (ทั้งเส้นหรือไฟแต่ละดวงที่เย็บเข้าด้วยกัน)
- ซุปเปอร์กาวมากมาย
- ด้ายนำไฟฟ้า
- ภาพวาดสีอะคิลิก
- ผ้าตกแต่ง
- เครื่องตัดเลเซอร์
- เครื่องพิมพ์ 3 มิติ
ขั้นตอนที่ 1: ขึ้นและลง
ขั้นตอนแรกของคุณในการสร้าง Sine-ese Dragon คือการสร้างส่วนประกอบที่ควบคุมการเคลื่อนไหวขึ้นและลงของร่างกาย น่าตื่นเต้นแค่ไหน!
-
ดาวน์โหลดไฟล์ Adobe Illustrator (.ai) และพิมพ์ออกมาโดยใช้เครื่องตัดเลเซอร์
upDownBoxWithPlatform.ai ควรพิมพ์บนกระดาษแข็ง
-
ดาวน์โหลดไฟล์การพิมพ์ 3 มิติ (.stl) และใช้เครื่องพิมพ์ 3 มิติที่คุณชื่นชอบเพื่อพิมพ์ออกมา
สีไม่สำคัญสำหรับดิสก์หรือตัวหมุนดิสก์ ในภาพที่สอง ตัวหมุนดิสก์ถูกใส่เข้าไปในรูของดิสก์
-
ประกอบสององค์ประกอบแรกและกาวเข้าด้วยกันดังแสดงในภาพที่ 3 ถึง 5
- แพลตฟอร์ม
- ร่องสำหรับแผ่นดิสก์
-
ตอนนี้ ประกอบกล่องตามคำแนะนำด้านล่าง
- สายไฟของเซอร์โวควรผ่านช่องสี่เหลี่ยมที่ด้านข้างของกล่อง
- ปลายที่สั้นที่สุดของตัวหมุนดิสก์จะติดกับหัวเซอร์โว และปลายที่ยาวกว่าจะผ่านรูของอีกด้านหนึ่งของกล่องโดยมีรูเป็นวงกลมอยู่ นี่แสดงให้เห็นในภาพที่ 6
- ตอนนี้ เราต้องการบางสิ่งเพื่อให้แน่ใจว่าแพลตฟอร์มจะอยู่ในระดับเดียวกันเมื่อดิสก์ถูกเปิด ตัดตะเกียบเป็นแท่งยาว 75 มม. (ภาพที่ 7) แล้วทากาวผ่านด้านบนของกล่องไปที่ด้านบนของแท่นโดยใช้กาวร้อน ตรวจสอบให้แน่ใจว่าได้ปรับระดับไม้ลงที่ 90 องศากับแท่น
- ใส่ไม้ยาว 212 มม. เข้าไปในรูตรงกลางด้านบนของกล่องบนแท่น
หวาน! ตอนนี้คุณมีกล่องที่สมบูรณ์ (ภาพที่ 8) สำหรับการเคลื่อนตัวของมังกรขึ้นและลง ตอนนี้ ทำซ้ำขั้นตอนข้างต้นอีกสองครั้ง!
ขั้นตอนที่ 2: แล้วซ้ายและขวาล่ะ
ตอนนี้เราไม่สามารถลืมการเคลื่อนไหวซ้ายและขวาของ Sine-ese Dragon ได้ไหม มากระโดดเข้าสู่ขั้นตอนที่สองกันเถอะ!
-
ดาวน์โหลดไฟล์ Adobe Illustrator (.ai) และพิมพ์ออกมาโดยใช้เครื่องตัดเลเซอร์
- leftRightBoxWithPlatforms.ai ควรพิมพ์บนกระดาษแข็ง
- ไฟล์ armTurner.ai ควรพิมพ์บนวัสดุที่มีความหนา 3 มม.
-
ดาวน์โหลดไฟล์การพิมพ์ 3 มิติ (.stl) และใช้เครื่องพิมพ์ 3 มิติที่คุณชื่นชอบเพื่อพิมพ์ออกมา
อย่าลืมพิมพ์แขนทั้งสองข้าง! สีไม่สำคัญที่นี่
- ประกอบแท่นทั้งสองเข้าด้วยกันดังรูปที่ 3 โดยใช้กาวร้อน
-
ประกอบกล่องครับ แม้ว่าการทำเช่นนี้อาจเป็นเรื่องยาก แต่ก็ทำได้ง่ายกว่าโดย:
- สอดแท่นทั้งสองระหว่างช่องขนาดใหญ่สองช่องที่ด้านใดด้านหนึ่งของกล่อง
- วางแขนแรกไว้บนแท่นด้านบน
- ร้อยเกลียวแขนผ่านแขนแล้วต่อกับแท่นด้านบน
- วางแขนที่สองไว้ที่ด้านบนของแพลตฟอร์มด้านล่าง
- ร้อยเกลียวแขนผ่านแขนที่สองแล้วต่อกับแท่นล่าง
- ติดเครื่องหมุนแขนผ่านช่องสี่เหลี่ยมของเครื่องหมุนแขนที่พิมพ์ 3 มิติ
- ปลายอีกด้านของเทิร์นเนอร์จะไปอยู่ด้านบนของเซอร์โวมอเตอร์
- เพิ่มชิ้นส่วนด้านบน ด้านล่าง และด้านหลังลงในกล่อง
กล่องประกอบขั้นสุดท้ายของคุณควรมีลักษณะเหมือนภาพที่หก ตอนนี้คุณต้องทำซ้ำอีกสองครั้ง!
เมื่อสิ้นสุดขั้นตอนนี้ คุณควรมีกล่องหกกล่องโดยประกอบด้วยระบบการเคลื่อนไหวขึ้น/ลง และระบบการเคลื่อนไหวซ้าย/ขวาอย่างละสามกล่อง
ขั้นตอนที่ 3: จับร่างกาย…ยังไง?
คำถามที่ดี! นั่นคือเมื่อผู้ถือ slinky ที่พิมพ์ 3 มิติเข้ามา ดาวน์โหลดไฟล์.stl ที่รวมไว้ และพิมพ์โดยใช้เครื่องพิมพ์ 3 มิติ อย่าลืมพิมพ์ที่ยึดทั้งหมด 6 กล่องสำหรับกล่องที่แตกต่างกัน 6 กล่อง
หากคุณเคยเห็นภาพเจ้าสลิงกี้โฮลเดอร์ด้านบนมาแล้ว แสดงว่าเซอร์ไพรส์ถูกทำลายไปแล้ว นั่นคือสีของ Sine-ese Dragon ของเรา!
ขั้นตอนที่ 4: แต่กล่องเหล่านั้นไม่สวยขนาดนั้น…
และฉันเห็นด้วย! นี่คือเหตุผลที่เราจะใช้เครื่องตัดเลเซอร์เพื่อตัดกล่องที่สวยงามยิ่งขึ้นเพื่อบรรจุกล่องเหล่านั้นทั้งหมดและปิดบังไว้
ดาวน์โหลดไฟล์ Adobe Illustrator เหล่านั้นและตัดออกโดยใช้เครื่องตัดเลเซอร์ การออกแบบเมฆถูกวาดด้วยมือโดยหนึ่งในผู้ร่วมให้ข้อมูล คุณสามารถแก้ไขได้โดยลบออกในไฟล์ illustrator และเพิ่มการออกแบบของคุณเองตามที่เห็นสมควร! ด้านล่างนี้เป็นขั้นตอนที่แนะนำในการรวมทุกอย่างเข้าด้วยกัน
- ประกอบและกาวทั้งสามชิ้นจากไฟล์แรก (outerBoxFinal_1) เข้าด้วยกัน
- อย่าเพิ่งเพิ่มชิ้นส่วนจากไฟล์ที่สอง (outerBoxFinal_2)
- วางชิ้นส่วนจากไฟล์ที่สาม (outerBoxFinal_3) ไปที่ด้านล่างของกล่องและควรปิดที่ด้านบน กาวที่ด้านล่างของกล่องเท่านั้น
- พิมพ์ innerBoxesPlatform สองครั้ง กาวสองชิ้นที่มีรูสี่เหลี่ยมขนาดใหญ่เข้าด้วยกัน จากนั้นกาวสามชิ้นที่เหลือเข้าด้วยกัน สุดท้ายติดกาวกับชุดกาวอื่น ๆ ที่มีรูอยู่
- วางแท่นที่ด้านล่างของกล่องขนาดใหญ่
- ใส่กล่องเล็กทั้ง 6 กล่องลงในจุดที่เกี่ยวข้องบนแพลตฟอร์ม
- ตอนนี้ วางชิ้นส่วนจากไฟล์ที่สอง (outerBoxFinal_2) ที่ด้านบนของกล่องแล้วทากาวที่ขอบ รูบนชิ้นบนควรอยู่ในแนวเดียวกับรูบนกล่องที่เล็กกว่า ถ้าไม่เช่นนั้น ให้จัดเรียงกล่องขนาดเล็กของคุณใหม่ อย่าใส่กาวลงในกล่องขนาดเล็กเลย
- หากคุณกำลังใช้เขียงหั่นขนมที่มีแผ่นเหนียวที่ด้านล่าง ให้วางไว้ใกล้กับกึ่งกลางของชิ้นด้านล่างในตำแหน่งที่เมื่อคุณปิดกล่อง เขียงหั่นขนมพร้อมกับโฟตอนจะหายไป มีรอยกรีดเล็ก ๆ ที่ส่วนล่างทำให้ง่ายต่อการเชื่อมต่อกับโฟตอนจากภายนอก
ขั้นตอนที่ 5: ของเล่นสลิงกี้?? พุทโธ่
ร่างของมังกร:
1. รวมสาม slinkies เข้าด้วยกันโดยใช้กาวร้อนหรือเทป
2. วัดความยาวและเส้นผ่านศูนย์กลางของสลิงกี้และตัดผ้าตกแต่งชิ้นหนึ่ง
3. นำปลายผ้าทั้งสองข้างมาเย็บเข้าด้วยกัน
4. เมื่อเย็บเสร็จแล้ว ให้สอดสลิงกี้เข้าเหมือนถุงเท้า
5. เย็บปลายสลิงเข้ากับผ้าที่เย็บ
ขั้นตอนที่ 6: พิมพ์มังกรของคุณ
ชิ้นส่วนที่พิมพ์ 3 มิติของมังกร:
1. ส่วนประกอบต่างๆ นำมาจาก
2. เราใช้เฉพาะหัว ขา และตา
3. หลังจากพิมพ์ชิ้นงาน 3 มิติแล้ว ให้ปรับให้เรียบโดยใช้กระดาษทรายและอะซิโตน
4. ทาสีส่วนต่าง ๆ ตามที่คุณต้องการตกแต่ง
ขั้นตอนที่ 7: ถึงเวลาก้าวขึ้นมังกรของคุณด้วย NeoPixels
ส่วนแสง:
1. คุณสามารถใช้เส้นนีโอพิกเซลเพื่อสร้างแสงได้หากต้องการ (แถบนี้หมดแล้ว)
2. เราใช้ไฟนีโอพิกเซล 20 ดวงและเชื่อมต่อโดยใช้สายไฟ ลวดเหล่านี้ถูกบัดกรีเข้ากับพวกมันและเชื่อมต่อกับโฟตอนโดยใช้สายไฟสีแดงเพื่อให้เข้ากับธีมของมังกร
3. คุณยังสามารถเย็บไฟนีโอพิกเซลของคุณบนผ้าผืนยาวได้ แต่เราไม่ได้ใช้มันเพราะเรามีแถบโลหะที่ลื่นไหล
การประกอบชิ้นส่วน: ยึดส่วนแสงภายในร่างของมังกรโดยใช้ด้ายหรือลวด ตรวจสอบให้แน่ใจว่าคุณสามารถเชื่อมต่อไฟกับโฟตอนภายในกล่องฐานได้ ติดหัว ขา และหางเข้ากับลำตัวโดยใช้กาว เมื่อเข้าที่แล้ว ให้ยึดร่างกายไว้ในที่ยึดที่เราพิมพ์ไว้ก่อนหน้านี้ ตอนนี้ร่างกายพร้อมที่จะตั้งโปรแกรมแล้ว
ขั้นตอนที่ 8: เวลาการเขียนโปรแกรม
เนื่องจากเราจะใช้อนุภาคโฟตอนสองตัวเพื่อทำงานกับเซอร์โวมอเตอร์แยกกันหกตัว (โฟตอนหนึ่งตัวสามารถทำงานกับสี่ตัวเท่านั้น) เราจะเขียนโค้ดแยกกันสองตัวแต่คล้ายกันเพื่อแฟลชบนไมโครคอนโทรลเลอร์
สำหรับไมโครคอนโทรลเลอร์ตัวแรก…
ในไฟล์ Arduino (.ino) ให้รวมไลบรารีต่อไปนี้และกำหนด:
#รวม "neopixel.h"
#include "ArduinoJson.h"
#define PIXEL_PIN D4
#define PIXEL_COUNT 18
ถัดไป ประกาศตัวแปรต่อไปนี้:
แถบ Adafruit_NeoPixel = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN);
เซอร์โวเซอร์โวซ้ายขวา_1; เซอร์โว servoUpDown_1; เซอร์โวเซอร์โวซ้ายขวา_2; เซอร์โวเซอร์โวUpDown_2; 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=ขึ้น, 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_OBJ 390; const size_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(3) + 38_JSON_OB(4) (5) + 76*JSON_OBJECT_SIZE(8) + 12490; สตริง weatherArray[3]; อุณหภูมิลอยตัว[3]; ลอยความชื้นอาร์เรย์[3]; ลมลอยSpeedArray[3]; สตริงการประทับเวลาอาร์เรย์[3]; int upDownMaxDegree[3]; int leftRightSpeed[3]; สตริง allData5DaysForecast;
คลิกที่นี่เพื่อเรียนรู้วิธีตั้งค่าเว็บฮุค เมื่อคุณทำเสร็จแล้ว ให้เพิ่มการประกาศและฟังก์ชันต่อไปนี้ และทำการเปลี่ยนแปลงตามความเหมาะสมหากจำเป็น:
เป็นโมฆะ getWeather5DayForecast () { Particle.publish ("get_weather5DayForecast"); allData5DaysForecast = ""; } ตัวจับเวลา ตัวจับเวลา WeatherForecast (60000, getWeather5DayForecast); เป็นโมฆะ getCurrentWeather () { Particle.publish ("get_currentWeather"); } ตัวจับเวลา ตัวจับเวลา สภาพอากาศปัจจุบัน (60000, getCurrentWeather);
ฟังก์ชันต่อไปนี้ควบคุมการเคลื่อนไหวขึ้น/ลง และซ้าย/ขวาของมังกร:
ถือเป็นโมฆะ changeLeftRight1() { if (leftRight_1) { positionLeftRight_1 = positionLeftRight_1 + leftRightSpeed[0]; ถ้า (positionLeftRight_1 > 100) { leftRight_1 = 0; } } อื่น { positionLeftRight_1 = positionLeftRight_1 - leftRightSpeed[0]; ถ้า (positionLeftRight_1 < 0) { leftRight_1 = 1; } } servoLeftRight_1.write (ตำแหน่งซ้ายขวา_1); }
เป็นโมฆะ changeLeftRight2 () {
ถ้า (leftRight_2) { positionLeftRight_2 = positionLeftRight_2 + leftRightSpeed[1]; ถ้า (positionLeftRight_2 > 100) { leftRight_2 = 0; } } อื่น { positionLeftRight_2 = positionLeftRight_2 - leftRightSpeed[1]; ถ้า (positionLeftRight_2 < 0) { leftRight_2 = 1; } } servoLeftRight_2.write (ตำแหน่งซ้ายขวา_2); }
เป็นโมฆะ changeUpDown1 () {
ถ้า (upDown_1) { positionUpDown_1++; ถ้า (positionUpDown_1 > upDownMaxDegree[0]) { upDown_1 = 0; } } อื่น { positionUpDown_1--; ถ้า (positionUpDown_1 < 1) { upDown_1 = 1; } } servoUpDown_1.write(positionUpDown_1); }
เป็นโมฆะ changeUpDown2 () {
ถ้า (upDown_2) { positionUpDown_2++; ถ้า (positionUpDown_2 > upDownMaxDegree [1]) { upDown_2 = 0; } } อื่น ๆ { positionUpDown_2--; ถ้า (positionUpDown_2 < 1) { upDown_2 = 1; } } servoUpDown_2.write(positionUpDown_2); }
เพื่อให้สามารถเปลี่ยนการเคลื่อนไหวในช่วงเวลาหนึ่งได้ ตัวจับเวลาจะถูกสร้างขึ้น
ตัวจับเวลาตัวจับเวลาLeftRight1(100, changeLeftRight1);
ตัวจับเวลาตัวจับเวลาLeftRight2(100, changeLeftRight2); ตัวจับเวลาตัวจับเวลาUpDown1 (10, changeUpDown1); ตัวจับเวลาตัวจับเวลาUpDown2 (10, changeUpDown2);
ในที่สุดฟังก์ชั่นการตั้งค่าก็ถูกเพิ่มเข้ามาต่อไป อย่าลืมทำการเปลี่ยนแปลงบรรทัดโค้ดที่เกี่ยวข้องกับเว็บฮุคอย่างเหมาะสม
การตั้งค่าเป็นโมฆะ () { // เริ่มตัวจับเวลาสภาพอากาศ timerWeatherForecast.start (); timerWeatherCurrent.start(); // Neopixels strip.begin(); // ใส่การเริ่มต้นเช่น pinMode และเริ่มฟังก์ชั่นที่นี่ // ตั้งค่าไมโครเซอร์โว servoLeftRight_1.attach(D1); servoUpDown_1.attach(D0); servoLeftRight_2.attach(D3); servoUpDown_2.attach(D2); servoLeftRight_1.write (ตำแหน่งLeftRight_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(); }
ฟังก์ชันวนซ้ำไม่ได้ใช้สำหรับโปรเจ็กต์นี้ เราไม่สามารถลืมฟังก์ชั่นในการจัดการข้อมูลที่ได้รับจากเว็บฮุคได้!
เป็นโมฆะ gotWeather5DayForecast (const char * เหตุการณ์ const char * data) { allData5DaysForecast += data; // บันทึกข้อมูลทั้งหมดลงในสตริงเดียว int allData5DaysForecastLen = allData5DaysForecast.length(); ถ่านบัฟเฟอร์ [allData5DaysForecastLen + 1]; allData5DaysForecast.toCharArray (บัฟเฟอร์ allData5DaysForecastLen + 1); // สร้างบัฟเฟอร์สำหรับสตริง int bufferLength = sizeof (บัฟเฟอร์); DynamicJsonBuffer jsonBufferWeather (ความยาวบัฟเฟอร์); JsonObject& root = jsonBufferWeather.parseObject (บัฟเฟอร์); // ทดสอบว่าการแยกวิเคราะห์สำเร็จหรือไม่ if (!root.success()) { //Serial.println("กำลังแยกวิเคราะห์พยากรณ์อากาศ 5 วัน…ข้อผิดพลาด!"); กลับ; } int i = 1; JsonArray& list = root["list"]; สำหรับ (JsonObject& currentObject: list){ if (i < 3){ JsonObject& main = currentObject["main"]; อุณหภูมิลอยตัว = หลัก["อุณหภูมิ"]; ความชื้นในอากาศ = หลัก["ความชื้น"]; JsonObject& weather = currentObject["weather"][0]; const char* weatherInfo = สภาพอากาศ["main"]; ลมลอยความเร็ว = currentObject["wind"]["speed"]; const char* timestamp = currentObject["dt_txt"]; int tempFah = แปลงเป็นฟาเรนไฮต์ (อุณหภูมิ); int servoMaxDegree = updateUpDown (tempFah); upDownMaxDegree = servoMaxDegree; int servoIncrement = updateleftRight (ความเร็วลม); leftRightSpeed = servoIncrement; setColor (ข้อมูลสภาพอากาศ, ผม); temperatureArray = tempFah; moistureArray = ความชื้น; weatherArray = weatherInfo; windSpeedArray = ความเร็วลม; timestampArray = การประทับเวลา; ผม++; } อื่น ๆ { แตก; } } }
เป็นโมฆะ gotCurrentWeatherData (const char * เหตุการณ์ const char * data) { DynamicJsonBuffer jsonBufferWeather (bufferSizeCurrent); JsonObject& root = jsonBufferWeather.parseObject (ข้อมูล); // ทดสอบว่าการแยกวิเคราะห์สำเร็จหรือไม่ if (!root.success()) { //Serial.println("กำลังแยกวิเคราะห์สภาพอากาศปัจจุบัน…ข้อผิดพลาด!"); กลับ; } JsonObject& weather = root["weather"][0]; const char* weather_main = สภาพอากาศ["main"]; JsonObject& main = รูท["main"]; float main_temp = หลัก["ชั่วคราว"]; int main_humidity = หลัก["ความชื้น"]; float wind_speed = รูท["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; moistureArray[0]= main_humidity; 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 (ความเร็วลมลอย){
//จับคู่ความเร็วลมกับช่วง [1, 100] float servoIncrement = windSpeed * 99 / 26 + 1; Serial.print ("ค่าการเพิ่มของเซอร์โวใหม่: "); Serial.println (servoIncrement); ส่งคืน servoIncrement; }
int convertToFahrenheit (ลอย tempKel){
int tempFah = tempKel * 9.0 / 5.0 - 459.67; ส่งคืน tempFah; }
เป็นโมฆะ setColor (สตริง weatherDesc ดัชนี int) {
int ledIndex = 0; ถ้า (ดัชนี == 0){ ledIndex = 0; } อื่น ๆ ถ้า (ดัชนี == 1) { ledIndex = 6; } อื่น ๆ ถ้า (ดัชนี == 2) { ledIndex = 12; } อื่น{ กลับ; } if(weatherDesc == "Clear") { //yellow for (int j = ledIndex; j < ledIndex+6; j++){ strip.setPixelColor(j, strip. Color(253, 219, 62));// แถบสีเหลือง.show(); ล่าช้า (20); } } else if(weatherDesc == "Clouds"){ //grey for (int j = ledIndex; j < ledIndex+6; j++){ strip.setPixelColor(j, strip. Color (223, 229, 237)); //แถบสีเทา.show(); ล่าช้า (20); } } else if (weatherDesc == "Snow"){ //white for (int j = ledIndex; j < ledIndex+6; j++){ strip.setPixelColor(j, strip. Color(255, 225, 225)); //แถบขาว.show(); ล่าช้า (20); } } else if (weatherDesc == "Rain"){//blue for (int j = ledIndex; j < ledIndex+6; j++){ strip.setPixelColor(j, strip. Color(119, 191, 246)); //แถบสีน้ำเงิน.show(); ล่าช้า (20); } } อื่น { //red สำหรับ (int j = ledIndex; j < ledIndex+6; j++){ strip.setPixelColor(j, strip. Color(254, 11, 5));//red strip.show(); ล่าช้า (20); } } }
เมื่อคุณเพิ่มทุกอย่างลงในไฟล์ Arduino แล้ว ให้คอมไพล์มัน หากไม่มีข้อผิดพลาด ให้แฟลชโค้ดไปที่โฟตอนแรก ขั้นตอนต่อไปจะให้รหัสที่คล้ายกันแก่คุณเพื่อแฟลชบนโฟตอนที่สอง
ขั้นตอนที่ 9: การเขียนโปรแกรมดำเนินต่อไป
เนื่องจากรหัสสำหรับโฟตอนที่สองเกือบจะเหมือนกับรหัสสำหรับรหัสแรก ดังนั้นรหัสทั้งหมดจึงถูกคัดลอกและวางด้านล่าง:
#include "ArduinoJson.h"
เซอร์โวเซอร์โวซ้ายขวา_3;
เซอร์โวเซอร์โวUpDown_3;
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;(12)
const size_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(3) + 38_JSON_OB(4) (5) + 76*JSON_OBJECT_SIZE(8) + 12490;
สตริง weatherArray[3];
อุณหภูมิลอยตัว[3]; ลอยความชื้นอาร์เรย์[3]; ลมลอยSpeedArray[3]; สตริงการประทับเวลาอาร์เรย์[3]; int upDownMaxDegree[3]; int leftRightSpeed[3];
สตริง allData5DaysForecast;
เป็นโมฆะ getWeather5DayForecast()
{ Particle.publish("get_weather5DayForecast2"); allData5DaysForecast = ""; }
ตัวจับเวลา ตัวจับเวลาพยากรณ์อากาศ (60000, getWeather5DayForecast); ///10, 800,000 ms = 3 วัน
เป็นโมฆะ getCurrentWeather()
{ Particle.publish("get_currentWeather2"); }
ตัวจับเวลา ตัวจับเวลาสภาพอากาศปัจจุบัน (60000, getCurrentWeather);
เป็นโมฆะ changeLeftRight3 () {
ถ้า (leftRight_3) { positionLeftRight_3 = positionLeftRight_3 + leftRightSpeed[2]; ถ้า (positionLeftRight_3 > 100) { leftRight_3 = 0; } } อื่น { positionLeftRight_3 = positionLeftRight_3 - leftRightSpeed[2]; ถ้า (positionLeftRight_3 < 0) { leftRight_3 = 1; } } servoLeftRight_3.write (ตำแหน่งซ้ายขวา_3); }
เป็นโมฆะ changeUpDown3 () {
ถ้า (upDown_3) { positionUpDown_3++; ถ้า (positionUpDown_3 > upDownMaxDegree [2]) { upDown_3 = 0; } } อื่น { positionUpDown_3--; ถ้า (positionUpDown_3 < 1) { upDown_3 = 1; } } servoUpDown_3.write(positionUpDown_3); }
ตัวจับเวลาตัวจับเวลาLeftRight3(100, changeLeftRight3);
ตัวจับเวลา timerUpDown3 (10, changeUpDown3);
การตั้งค่าเป็นโมฆะ () {
// เริ่มตัวจับเวลาสภาพอากาศ timerWeatherForecast.start(); timerWeatherCurrent.start(); // ใส่การเริ่มต้นเช่น pinMode และเริ่มฟังก์ชั่นที่นี่ // ตั้งค่าไมโครเซอร์โว servoLeftRight_3.attach(D1); servoUpDown_3.attach(D0);
servoLeftRight_3.write (ตำแหน่งLeftRight_3); // เริ่มต้นตำแหน่งเซอร์โว
servoUpDown_3.write (ตำแหน่งขึ้นลง_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 (const char * เหตุการณ์ const char * data)
{ allData5DaysForecast += ข้อมูล; // บันทึกข้อมูลทั้งหมดลงในสตริงเดียว int allData5DaysForecastLen = allData5DaysForecast.length(); ถ่านบัฟเฟอร์ [allData5DaysForecastLen + 1]; allData5DaysForecast.toCharArray (บัฟเฟอร์ allData5DaysForecastLen + 1); // สร้างบัฟเฟอร์สำหรับสตริง int bufferLength = sizeof (บัฟเฟอร์); DynamicJsonBuffer jsonBufferWeather (ความยาวบัฟเฟอร์); JsonObject& root = jsonBufferWeather.parseObject (บัฟเฟอร์); // Serial.println (allData5DaysForecast); // ทดสอบว่าการแยกวิเคราะห์สำเร็จหรือไม่ if (!root.success()) { //Serial.println("กำลังแยกวิเคราะห์พยากรณ์อากาศ 5 วัน…ข้อผิดพลาด!"); กลับ; } int i = 1; JsonArray& list = root["list"]; สำหรับ (JsonObject& currentObject: list){ if (i < 3){ JsonObject& main = currentObject["main"]; อุณหภูมิลอยตัว = หลัก["อุณหภูมิ"]; ความชื้นในอากาศ = หลัก["ความชื้น"]; JsonObject& weather = currentObject["weather"][0]; const char* weatherInfo = สภาพอากาศ["main"]; ลมลอยความเร็ว = currentObject["wind"]["speed"]; const char* timestamp = currentObject["dt_txt"]; int tempFah = แปลงเป็นฟาเรนไฮต์ (อุณหภูมิ); int servoMaxDegree = updateUpDown (tempFah); upDownMaxDegree = servoMaxDegree; int servoIncrement = updateleftRight (ความเร็วลม); leftRightSpeed = servoIncrement; temperatureArray = tempFah; moistureArray = ความชื้น; weatherArray = weatherInfo; windSpeedArray = ความเร็วลม; timestampArray = การประทับเวลา; ผม++; } อื่น ๆ { แตก; } } }
เป็นโมฆะ gotCurrentWeatherData (const char * เหตุการณ์ const char * data)
{ DynamicJsonBuffer jsonBufferWeather (บัฟเฟอร์SizeCurrent); JsonObject& root = jsonBufferWeather.parseObject (ข้อมูล); //Serial.println(ข้อมูล); // ทดสอบว่าการแยกวิเคราะห์สำเร็จหรือไม่ if (!root.success()) { //Serial.println("กำลังแยกวิเคราะห์สภาพอากาศปัจจุบัน…ข้อผิดพลาด!"); กลับ; } JsonObject& weather = root["weather"][0]; const char* weather_main = สภาพอากาศ["main"]; JsonObject& main = รูท["main"]; float main_temp = หลัก["ชั่วคราว"]; int main_humidity = หลัก["ความชื้น"]; float wind_speed = รูท["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; moistureArray[0]= main_humidity; windSpeedArray[0] = wind_speed; timestampArray[0] = การประทับเวลา; }
int updateUpDown (อุณหภูมิลอย){
// แมปองศากับช่วง [0, 180] float servoMaxDegree = temp * 45 / 31 + (990 / 31); Serial.print ("ระดับเซอร์โวใหม่: "); Serial.println (servoMaxDegree); ส่งคืน servoMaxDegree; }
int updateleftRight (ความเร็วลมลอย){
//จับคู่ความเร็วลมกับช่วง [1, 100] float servoIncrement = windSpeed * 99 / 26 + 1; Serial.print ("ค่าการเพิ่มของเซอร์โวใหม่: "); Serial.println (servoIncrement); ส่งคืน servoIncrement; }
int convertToFahrenheit (ลอย tempKel){
int tempFah = tempKel * 9.0 / 5.0 - 459.67; ส่งคืน tempFah; }
คุณทำได้! คุณผ่านส่วนการเขียนโปรแกรมของโครงการแล้ว! ตอนนี้ ตรวจสอบให้แน่ใจว่าได้ทำการเดินสายและการเชื่อมต่อทั้งหมดจากเซอร์โวมอเตอร์และนีโอพิกเซลไปยังเขียงหั่นขนมและไมโครคอนโทรลเลอร์หมายเหตุ: เสียบเดือย/ตะเกียบพิเศษผ่านร่องแนวตั้งบนกล่องสำหรับการเคลื่อนไหวซ้ายและขวาของร่างกาย ปลายอีกด้านควรเชื่อมต่อกับร่างของมังกร
ขั้นตอนที่ 10: สนุกกับมังกรของคุณ
ยินดีด้วย! คุณได้สร้าง Sine-ese Dragon ตั้งแต่เริ่มต้น! ตอนนี้สิ่งที่คุณต้องทำคือนั่งเอนหลังและเพลิดเพลินไปกับการแสดงผลรอบข้างของคุณ!
หมายเหตุ: โครงการนี้สร้างขึ้นโดยเป็นส่วนหนึ่งของรายวิชาโดย Joan Bempong และ Soundarya Muthuvel หน้าหลักสูตรสามารถพบได้ที่นี่
แนะนำ:
ของเล่น Switch-Adapt: Water-Breathing Walking Dragon เข้าถึงได้!: 7 ขั้นตอน (พร้อมรูปภาพ)
ของเล่นที่ปรับเปลี่ยนได้: มังกรเดินที่หายใจทางน้ำที่เข้าถึงได้!: การปรับตัวของเล่นเปิดช่องทางใหม่และโซลูชันที่ปรับแต่งได้เอง เพื่อให้เด็กที่มีความสามารถในการเคลื่อนไหวจำกัดหรือมีความบกพร่องทางพัฒนาการสามารถโต้ตอบกับของเล่นได้อย่างอิสระ ในหลายกรณี เด็กๆ ที่ต้องการของเล่นที่ดัดแปลงไม่สามารถ
อินเวอร์เตอร์ Pure Sine Wave: 8 ขั้นตอน
อินเวอร์เตอร์ Pure Sine Wave: งานวิจัยของฉัน
การผลิต Sine Wave Control Board: 5 ขั้นตอน
การผลิตบอร์ดควบคุมคลื่นไซน์: คราวนี้เป็นบอร์ดควบคุมนอกตารางคลื่นไซน์เฟสเดียว ตามด้วยคณะกรรมการควบคุมนอกตารางคลื่นไซน์เฟสเดียว จากนั้นเป็นบอร์ดควบคุมนอกตารางคลื่นไซน์สามเฟส และสุดท้ายเป็นบอร์ดควบคุมแบบ off-grid แบบคลื่นไซน์สามเฟส เราหวังว่าเ
ESP8266/Arduino SmartThings Bearded Dragon Habitat Controller/Monitor: 4 ขั้นตอน
ESP8266/Arduino SmartThings Bearded Dragon Habitat Controller/Monitor: DaVinci มังกรของเรามีกำหนดจะอัปเกรดซอฟต์แวร์เป็นตัวควบคุมของ Vivarium ฉันตัดสินใจที่จะโยกย้ายจากตรรกะ Arduino แบบ 'เต็มรูปแบบ' แบบดั้งเดิมที่ดี ที่เลิกใช้ไปอย่างน่าเชื่อถือในปีที่ผ่านมา ไปเป็น ST_Anything SmartThings int
วิธีใช้ Dragon Rider 500 กับ AVR Dragon: 10 ขั้นตอน
วิธีใช้ Dragon Rider 500 กับ AVR Dragon ของคุณ: คำแนะนำนี้เป็นหลักสูตรเร่งด่วนในการใช้คุณสมบัติบางอย่างของ Dragon Rider 500 จาก Ecos Technologies โปรดทราบว่ามีคู่มือผู้ใช้โดยละเอียดอยู่บนเว็บไซต์ของ Ecos Dragon Rider เป็นบอร์ดอินเตอร์เฟส