สารบัญ:
2025 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2025-01-23 15:12
ฉันมีรีโมทของ Logitech Harmony และเรียกใช้ Home Assistant บน Raspberry Pi
ฉันต้องการหยุด Chromecast ชั่วคราวจากรีโมตของฉัน แต่ฉันมีทีวีเครื่องเก่าที่ไม่รองรับสิ่งนี้ผ่าน hdmi ไอเดียของฉันคือใช้ NodeMcu เพื่อจับสัญญาณ ir และหยุดชั่วคราว
หากคุณใช้งานไม่ได้หรือมีคำถามโปรดแสดงความคิดเห็นด้านล่าง
ขั้นตอนที่ 1: อุปกรณ์
อุปกรณ์ที่จำเป็น:
โนเดมคู (https://www.ebay.com/sch/i.html?_from=R40&_trksid=…
Ir reciver (เช่นอดีตนี้:
สายดูปองท์
สายไมโครยูเอสบี (power nodemcu)
ฉันใช้ Logitech Harmony -hub
สำหรับแนวทางของฉัน คุณต้องการ Raspberry pi ที่ติดตั้ง hass.io และ Nodered ฉันจะไม่เข้าไปตั้งค่าผู้ช่วยที่บ้านที่นี่ หากคุณใช้อย่างอื่นที่ไม่ใช่ผู้ช่วยที่บ้าน คุณต้องปรับเปลี่ยนสิ่งต่างๆ ด้วยตัวเอง
คุณต้องสามารถใช้ Nodemcu บน Arduino IDE ได้ เพราะฉันจะไม่เข้าไปที่นี่
ขั้นตอนที่ 2: สัญญาณระยะไกล
วิธีที่ฉันทำคือคัดลอกสัญญาณจากรีโมตที่ฉันไม่ได้ใช้เป็นรีโมตฮาร์โมนี่
ฉันใช้รีโมตสำหรับทีวี panasonic รุ่น TXL32C3E เนื่องจากไม่รบกวนอุปกรณ์ของฉันที่ชั้น 1 นั่นคือทีวีที่ฉันอยู่ชั้นบน
หากคุณไม่ได้ใช้ความสามัคคีคุณสามารถข้ามไปได้
ดังนั้นในการค้นหาสัญญาณ ฉันจึงใช้ scetch นี้:
/* * IRremoteESP8266: IRrecvDumpV2 - การถ่ายโอนข้อมูลรายละเอียดของรหัส IR ด้วย IRrecv * ตัวตรวจจับ/ตัวถอดรหัส IR ต้องเชื่อมต่อกับอินพุต RECV_PIN * * ลิขสิทธิ์ 2009 Ken Shirriff, https://arcfn.com * ลิขสิทธิ์ 2017 David Conran * * ตัวอย่างแผนภาพวงจร: * https://arcfn.com * * การเปลี่ยนแปลง: * เวอร์ชัน 0.3 พฤศจิกายน 2017 * - รองรับ A/C การถอดรหัสสำหรับโปรโตคอลบางตัว * เวอร์ชัน 0.2 เมษายน 2017 * - ถอดรหัสจากสำเนาของข้อมูลเพื่อให้เราเริ่มจับภาพได้เร็วขึ้น ดังนั้น * ลดโอกาสในการจับผิด * อ้างอิงจาก IrsendDemo ของ Ken Shirriff เวอร์ชัน 0.1 กรกฎาคม 2009 */
#ifndef UNIT_TEST
#include #endif #include #include #include #if DECODE_AC #include #include #include #include #include #endif // DECODE_AC
// ==================== จุดเริ่มต้นของพารามิเตอร์ที่ปรับแต่งได้ =====================
// ตัวตรวจจับ/ตัวจำลอง IR เชื่อมต่อกับ GPIO pin 14 // เช่น D5 บนบอร์ด NodeMCU #define RECV_PIN 14
// อัตราบอดของการเชื่อมต่อแบบอนุกรม
// เช่น ข้อความสถานะจะถูกส่งไปยังพีซีในอัตราบอดนี้ // พยายามหลีกเลี่ยงความเร็วที่ช้า เช่น 9600 เนื่องจากคุณจะพลาดข้อความและ // ทำให้เกิดปัญหาอื่นๆ ขอแนะนำให้ใช้ 115200 (หรือเร็วกว่า) // หมายเหตุ: ตรวจสอบให้แน่ใจว่าคุณตั้งค่า Serial Monitor เป็นความเร็วเท่ากัน #define BAUD_RATE 115200
// เนื่องจากโปรแกรมนี้เป็นโปรแกรมดักจับ/ถอดรหัสวัตถุประสงค์พิเศษ ให้เราใช้โปรแกรมที่ใหญ่กว่า
// กว่าบัฟเฟอร์ปกติเพื่อให้เราสามารถจัดการกับรหัสรีโมทของเครื่องปรับอากาศได้ #define CAPTURE_BUFFER_SIZE 1024
// TIMEOUT คือ Nr ของมิลลิวินาทีที่ไม่มีข้อมูล ก่อนที่เราจะพิจารณา a
//ข้อความสิ้นสุด // พารามิเตอร์นี้เป็นการแลกเปลี่ยนที่น่าสนใจ ยิ่งหมดเวลานานเท่าไร // ก็ยิ่งทำให้ข้อความซับซ้อนมากขึ้นเท่านั้น เช่น. โปรโตคอลของอุปกรณ์บางอย่างจะส่ง // แพ็กเก็ตข้อความหลายชุดติดต่อกันอย่างรวดเร็ว เช่น รีโมทของเครื่องปรับอากาศ // โปรโตคอล Air Coniditioner มักจะมีช่องว่างมาก (20-40+ms) ระหว่าง // แพ็กเก็ต // ข้อเสียของค่าหมดเวลามากคือโปรโตคอลที่ซับซ้อนน้อยกว่ามาก // ส่งข้อความหลายข้อความเมื่อกดปุ่มของรีโมทค้างไว้ ช่องว่างระหว่าง // มักอยู่ที่ประมาณ 20+ms ซึ่งอาจส่งผลให้ข้อมูลดิบเป็น 2-3+ // มากกว่าที่จำเป็น เนื่องจากได้บันทึกข้อความ 2-3+ ในการจับภาพ // ครั้งเดียว การตั้งค่าระยะหมดเวลาต่ำสามารถแก้ไขปัญหานี้ได้ // ดังนั้น การเลือกค่า TIMEOUT ที่ดีที่สุดสำหรับกรณีการใช้งานของคุณโดยเฉพาะคือ // ค่อนข้างเหมาะสมยิ่ง ขอให้โชคดีและการล่าสัตว์อย่างมีความสุข // หมายเหตุ: ไม่เกิน MAX_TIMEOUT_MS โดยปกติ 130ms #if DECODE_AC #define TIMEOUT 50U // A/C บางยูนิตมีช่องว่างในโปรโตคอลประมาณ 40ms // เช่น. Kelvinator // ค่าขนาดใหญ่นี้อาจกลืนการทำซ้ำของโปรโตคอลบางตัว #else // DECODE_AC #define TIMEOUT 15U // เหมาะกับข้อความส่วนใหญ่ โดยไม่กลืนซ้ำหลายๆ ครั้ง #endif // DECODE_AC // ทางเลือก: // #define TIMEOUT 90U // เหมาะกับข้อความที่มีช่องว่างขนาดใหญ่ เช่น XMP-1 และเครื่องปรับอากาศบางส่วน // หน่วย แต่สามารถกลืนข้อความซ้ำโดยไม่ได้ตั้งใจ // ในเอาต์พุต rawData // #define TIMEOUT MAX_TIMEOUT_MS // สิ่งนี้จะตั้งค่าเป็นค่าสูงสุดที่เราอนุญาตในปัจจุบัน // สูงสุด ค่าที่สูงนี้เป็นปัญหา // เนื่องจากเป็นขอบเขตทั่วไป // ที่ข้อความส่วนใหญ่เกิดซ้ำ // เช่น. จะหยุดถอดรหัสข้อความและ // เริ่มส่งไปยังซีเรียลอย่างแม่นยำ // เวลาที่ข้อความถัดไปมีแนวโน้มว่าจะ // จะถูกส่งและอาจพลาด
// ตั้งค่าแพ็กเก็ตข้อความ "UNKNOWN" ที่มีขนาดเล็กที่สุดที่เราสนใจจริงๆ
// ค่านี้ช่วยลดอัตราการตรวจจับเท็จบวกของพื้นหลัง IR // สัญญาณรบกวนเป็นข้อความจริง โอกาสของการตรวจจับสัญญาณรบกวน IR พื้นหลัง // เมื่อข้อความเพิ่มขึ้นตามความยาวของค่า TIMEOUT (ดูด้านบน) // ข้อเสียของการตั้งค่าข้อความนี้ให้ใหญ่เกินไปคือ คุณอาจพลาดบางข้อความที่ถูกต้อง // ข้อความสั้นสำหรับโปรโตคอลที่ไลบรารีนี้ยังไม่ได้ถอดรหัส // // ตั้งค่าให้สูงขึ้นหากคุณได้รับข้อความ UNKNOWN สั้นๆ แบบสุ่มจำนวนมากโดยที่ไม่มีอะไร // ควรจะส่งข้อความ // ตั้งค่าให้ต่ำลงหากคุณแน่ใจว่าการตั้งค่าของคุณใช้งานได้ แต่ไม่เห็นข้อความ // จากอุปกรณ์ของคุณ (เช่น รีโมท IR อื่นๆ ใช้งานได้) // หมายเหตุ: ตั้งค่านี้ให้สูงมากเพื่อปิดการตรวจจับ UNKNOWN อย่างมีประสิทธิภาพ #define MIN_UNKNOWN_SIZE 12 // ==================== สิ้นสุดพารามิเตอร์ที่ปรับแต่งได้ =====================
// ใช้เปิดฟีเจอร์บันทึกบัฟเฟอร์เพื่อให้ครอบคลุมการดักจับที่สมบูรณ์ยิ่งขึ้น
IRrecv irrecv(RECV_PIN, CAPTURE_BUFFER_SIZE, TIMEOUT, จริง);
ผลลัพธ์ decode_results; // ที่ไหนสักแห่งที่จะเก็บผลลัพธ์
// แสดงสถานะที่มนุษย์สามารถอ่านได้ของข้อความ A/C หากเราทำได้
เป็นโมฆะ dumpACInfo (decode_results * ผลลัพธ์) { คำอธิบายสตริง = ""; #if DECODE_DAIKIN ถ้า (ผลลัพธ์ -> decode_type == DAIKIN) { IRDaikinESP ac (0); ac.setRaw(ผลลัพธ์->สถานะ); คำอธิบาย = ac.toString(); } #endif // DECODE_DAIKIN #if DECODE_FUJITSU_AC ถ้า (ผลลัพธ์->decode_type == FUJITSU_AC) { IRFujitsuAC ac (0); ac.setRaw(results->state, results->bits / 8); คำอธิบาย = ac.toString(); } #endif // DECODE_FUJITSU_AC #if DECODE_KELVINATOR ถ้า (ผลลัพธ์ -> decode_type == KELVINATOR) { IRKelvinatorAC ac (0); ac.setRaw(ผลลัพธ์->สถานะ); คำอธิบาย = ac.toString(); } #endif // DECODE_KELVINATOR #if DECODE_TOSHIBA_AC ถ้า (ผลลัพธ์ -> decode_type == TOSHIBA_AC) { IRtohibaAC ac (0); ac.setRaw(ผลลัพธ์->สถานะ); คำอธิบาย = ac.toString(); } #endif // DECODE_TOSHIBA_AC #if DECODE_MIDEA ถ้า (ผลลัพธ์ -> decode_type == MIDEA) { IRMideaAC ac (0); ac.setRaw(ผลลัพธ์->ค่า); // Midea ใช้ค่าแทนสถานะ คำอธิบาย = ac.toString(); } #endif // DECODE_MIDEA // หากเราได้รับคำอธิบายข้อความที่มนุษย์สามารถอ่านได้ ให้แสดงข้อความนั้น if (description != "") Serial.println("Mesg Desc.: " + คำอธิบาย); }
// ส่วนของรหัสทำงานเพียงครั้งเดียวเมื่อเริ่มต้น
การตั้งค่าเป็นโมฆะ () { Serial.begin (BAUD_RATE, SERIAL_8N1, SERIAL_TX_ONLY); ล่าช้า (500); // รอสักครู่เพื่อให้การเชื่อมต่อแบบอนุกรมถูกสร้างขึ้น
#ถ้า DECODE_HASH
// ละเว้นข้อความที่มีพัลส์เปิดหรือปิดน้อยกว่าขั้นต่ำ irrecv.setUnknownThreshold(MIN_UNKNOWN_SIZE); #endif // DECODE_HASH irrecv.enableIRIn(); // เริ่มเครื่องรับ }
// ส่วนซ้ำของรหัส
// void loop() { // ตรวจสอบว่าได้รับรหัส IR หรือไม่ if (irrecv.decode (&results)) { // แสดงการประทับเวลาคร่าวๆ uint32_t ตอนนี้ = millis(); Serial.printf("Timestamp: %06u.%03u\n", ตอนนี้ / 1000, ตอนนี้ % 1000); if (results.overflow) Serial.printf("คำเตือน: รหัส IR ใหญ่เกินไปสำหรับบัฟเฟอร์ (>= %d) " "ไม่ควรเชื่อถือผลลัพธ์นี้จนกว่าจะได้รับการแก้ไข " "แก้ไขและเพิ่ม CAPTURE_BUFFER_SIZE.\n ", CAPTURE_BUFFER_SIZE); // แสดงผลลัพธ์พื้นฐานของสิ่งที่เราพบ Serial.print(resultToHumanReadableBasic(&ผล)); dumpACInfo(&ผลลัพธ์); // แสดงข้อมูล A/C เพิ่มเติมหากเรามี ผลผลิต(); // ป้อน WDT เนื่องจากข้อความที่ส่งออกอาจใช้เวลาสักครู่ในการพิมพ์
// แสดงเวอร์ชันไลบรารีที่ข้อความถูกจับด้วย
Serial.print("ห้องสมุด: v"); Serial.println(_IRREMOTEESP8266_VERSION_); Serial.println();
// ส่งออกข้อมูลเวลา RAW ของผลลัพธ์
Serial.println(resultToTimingInfo(&ผล)); ผลผลิต(); // ป้อน WDT (อีกครั้ง)
// ส่งออกผลลัพธ์เป็นซอร์สโค้ด
Serial.println(resultToSourceCode(&ผล)); Serial.println(""); // บรรทัดว่างระหว่างรายการให้ผลตอบแทน (); // ป้อน WDT (อีกครั้ง) } }
เมื่อ scetch นี้ถูกอัปโหลดและทำงานโดยเปิดมอนิเตอร์แบบอนุกรม มันจะส่งออกรหัสสำหรับการกดปุ่ม (ดูรูป)
จดรหัสที่คุณต้องการใช้ในภายหลัง ฉันใช้ excel เพื่อจดบันทึกสิ่งที่ฉันได้สำหรับปุ่มที่ฉันต้องการใช้ (ดูรูป)
ฉันแก้ไขปุ่มในกิจกรรม Netflix ของฉันเพื่อส่งสัญญาณหยุดชั่วคราวจากรีโมท panasonic.. (ดูรูป)
ขั้นตอนที่ 3: การเขียนโค้ดสำหรับส่งไปยัง Nodered
#ifndef UNIT_TEST#include #endif #include
#รวม
#รวม
#รวม
#รวม
#รวม
const ถ่าน* ssid = ""; // ป้อน SSID ที่นี่const char* password = ""; //ป้อนรหัสผ่านที่นี่ const char *host = ""; //ที่อยู่ IP #define USE_SERIAL Serial ESP8266WiFiMulti WiFiMulti; uint16_t RECV_PIN = 14; IRrecv irrecv(RECV_PIN); ผลลัพธ์ decode_results; การตั้งค่าเป็นโมฆะ () { irrecv.enableIRIn (); // เริ่มตัวรับ USE_SERIAL.begin(115200); // USE_SERIAL.setDebugOutput(จริง); USE_SERIAL.println(); USE_SERIAL.println(); USE_SERIAL.println();
สำหรับ (uint8_t เสื้อ = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] รอ %d…\n", t); USE_SERIAL.flush(); ล่าช้า (1000); } WiFi.mode (WIFI_STA); WiFiMulti.addAP(ssid, รหัสผ่าน); } วงเป็นโมฆะ () { ถ้า (irrecv.decode (&ผลลัพธ์)) {
// เปลี่ยนค่าสัญญาณนี้สำหรับค่าที่คุณได้รับ
ถ้า (results.value == 0x40040D00606D) { USE_SERIAL.println ("หยุดรับสัญญาณชั่วคราว"); wifisend(หยุดชั่วคราว); ล่าช้า (1000);
} if (results.value == 0x400401007273){
USE_SERIAL.println("ก่อนหน้า");
wifisend("ก่อนหน้า"); ล่าช้า (1000); } if (results.value == 0x40040100F2F3) { USE_SERIAL.println("next"); wifisend("ต่อไป"); ล่าช้า (1000); }
irrecv.resume(); // รับค่าถัดไป } ล่าช้า (100); } โมฆะ wifisend (ข้อมูลสตริง) { if ((WiFiMulti.run () == WL_CONNECTED)) { HTTPClient http; USE_SERIAL.print("[HTTP] เริ่ม…\n"); // กำหนดค่าเซิร์ฟเวอร์ traged และ url http.begin("https://[user]:[pass]@[ip]:[port]/chromecastpause?data=" + data); USE_SERIAL.print("[HTTP] รับ…\n"); // เริ่มการเชื่อมต่อและส่งส่วนหัว HTTP int httpCode = http. GET(); // httpCode จะเป็นค่าลบจากข้อผิดพลาดหาก (httpCode > 0) { // ส่วนหัว HTTP ถูกส่งและส่วนหัวการตอบกลับของเซิร์ฟเวอร์ได้รับการจัดการแล้ว USE_SERIAL.printf ("[HTTP] รับ… รหัส: %d\n", // พบไฟล์ที่เซิร์ฟเวอร์
ถ้า (httpCode == HTTP_CODE_OK) { ส่วนของข้อมูลสตริง = http.getString (); USE_SERIAL.println (เพย์โหลด); } } อื่น ๆ { USE_SERIAL.printf("[HTTP] GET… ล้มเหลว ข้อผิดพลาด: %s\n", http.errorToString(httpCode).c_str()); } http.end(); ล่าช้า (100); } }
นี่คือรหัสที่ฉันใช้กับ nodemcu ของฉัน คุณจะต้องติดตั้งไลบรารีเหล่านั้น
คุณสามารถทดสอบโดยใช้จอภาพแบบอนุกรมและกดปุ่มรีโมทที่คุณเพิ่มในรหัสเพื่อดูการตอบสนอง..
ในบรรทัด:
http.begin("https://[ผู้ใช้]:[pass]@[ip]:[port]/chromecastpause?data=" + data);
คุณต้องเปลี่ยน [ผู้ใช้] เป็นผู้ใช้ของคุณเป็นต้น ไม่มีวงเล็บ มีวงเล็บเพื่อแสดงทุ่งแม่มดที่จะเปลี่ยน
บรรทัดนั้นจะไม่ทำงานจนกว่าเราจะตั้งค่าโฟลว์ของเราเป็นโหนด
ขั้นตอนที่ 4: การสร้างโฟลว์ใน Nodered
ดังที่กล่าวไว้ในตอนต้นฉันใช้ hass.io กับ nodered หากคุณใช้การตั้งค่าอื่น คุณจะต้องทำให้การตั้งค่านี้แตกต่างออกไป! คุณสามารถเห็นในภาพว่าเมื่อกดปุ่มจะแสดงในหน้าต่างดีบั๊ก…
การเปลี่ยนแปลง payload node อาจจะถูกข้ามไป ถ้าฉันเลือกบางอย่างที่ต่างไปจาก data= ในขั้นตอนก่อนหน้า โหนดสวิตช์ที่ฉันใช้นั้นใหญ่กว่าเพียงแค่หยุดชั่วคราว แต่นั่นเป็นเพียงเพื่อให้ฉันสามารถเพิ่มสัญญาณ ir เพิ่มเติมเพื่อใช้ Chromecast สำหรับสถานีวิทยุ ฯลฯ
สำหรับการหยุดเล่นชั่วคราวคุณสามารถใช้โฟลว์ในรูปภาพอื่นได้
[{"id":"e6440c30.4a35a", "type":"http in", "z":"869ceb74.0275c8", "name":"", "url":"chromecastpause", "method": "get", "upload":false, "swaggerDoc":"", "x":133, "y":98, "wires":
ฉันลบชื่อผู้ใช้และ url ออกจากสิ่งนี้ ดังนั้นคุณอาจต้องแก้ไข
เพิ่มโหนดสวิตช์หากคุณต้องการตอบสนองมากกว่าแค่หยุดชั่วคราว (ดูรูปตัวอย่าง)
ในโหนดผู้ช่วยภายในบ้านสำหรับการหยุดชั่วคราว:
ชื่อ: play หยุดชั่วคราว chromecastdomain: media_playerService: media_play_pausedata: { "entity_id": "media_player.[your chromecast here]" }
สำหรับแทร็กถัดไปเพียงคัดลอกโหนดนั้นและแก้ไขบริการไปที่: media_next_track และตั้งชื่อไปที่: chromecast ถัดไป
ขั้นตอนที่ 5: ตัวเลือก Alexa หยุดชั่วคราว Chromecast
คำสั่งเพิ่ม alexa ทางเลือกสำหรับการหยุด Chromecast ชั่วคราว:
มีตัวเลือกอยู่ที่นี่.. คุณสามารถสร้าง alexa nnode หนึ่งตัวที่เรียกว่า chromecast ที่หยุดชั่วคราว chromecast
หรือคุณสามารถสร้างรายการที่เรียกว่าหยุดชั่วคราวทีวีซึ่งจะตรวจสอบกิจกรรมความสามัคคีในปัจจุบันและหยุดชั่วคราวขึ้นอยู่กับว่า
ฉันจะเพิ่มที่นี่ในภายหลัง..
แนะนำ:
การออกแบบเกมในการสะบัดใน 5 ขั้นตอน: 5 ขั้นตอน
การออกแบบเกมในการสะบัดใน 5 ขั้นตอน: การตวัดเป็นวิธีง่ายๆ ในการสร้างเกม โดยเฉพาะอย่างยิ่งเกมปริศนา นิยายภาพ หรือเกมผจญภัย
การตรวจจับใบหน้าบน Raspberry Pi 4B ใน 3 ขั้นตอน: 3 ขั้นตอน
การตรวจจับใบหน้าบน Raspberry Pi 4B ใน 3 ขั้นตอน: ในคำแนะนำนี้ เราจะทำการตรวจจับใบหน้าบน Raspberry Pi 4 ด้วย Shunya O/S โดยใช้ Shunyaface Library Shunyaface เป็นห้องสมุดจดจำใบหน้า/ตรวจจับใบหน้า โปรเจ็กต์นี้มีจุดมุ่งหมายเพื่อให้เกิดความเร็วในการตรวจจับและจดจำได้เร็วที่สุดด้วย
วิธีการติดตั้งปลั๊กอินใน WordPress ใน 3 ขั้นตอน: 3 ขั้นตอน
วิธีการติดตั้งปลั๊กอินใน WordPress ใน 3 ขั้นตอน: ในบทช่วยสอนนี้ ฉันจะแสดงขั้นตอนสำคัญในการติดตั้งปลั๊กอิน WordPress ให้กับเว็บไซต์ของคุณ โดยทั่วไป คุณสามารถติดตั้งปลั๊กอินได้สองวิธี วิธีแรกคือผ่าน ftp หรือผ่าน cpanel แต่ฉันจะไม่แสดงมันเพราะมันสอดคล้องกับ
การลอยแบบอะคูสติกด้วย Arduino Uno ทีละขั้นตอน (8 ขั้นตอน): 8 ขั้นตอน
การลอยแบบอะคูสติกด้วย Arduino Uno ทีละขั้นตอน (8 ขั้นตอน): ตัวแปลงสัญญาณเสียงล้ำเสียง L298N Dc ตัวเมียอะแดปเตอร์จ่ายไฟพร้อมขา DC ตัวผู้ Arduino UNOBreadboardวิธีการทำงาน: ก่อนอื่น คุณอัปโหลดรหัสไปยัง Arduino Uno (เป็นไมโครคอนโทรลเลอร์ที่ติดตั้งดิจิตอล และพอร์ตแอนะล็อกเพื่อแปลงรหัส (C++)
เครื่อง Rube Goldberg 11 ขั้นตอน: 8 ขั้นตอน
เครื่อง 11 Step Rube Goldberg: โครงการนี้เป็นเครื่อง 11 Step Rube Goldberg ซึ่งออกแบบมาเพื่อสร้างงานง่ายๆ ในรูปแบบที่ซับซ้อน งานของโครงการนี้คือการจับสบู่ก้อนหนึ่ง