สารบัญ:
2025 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2025-01-13 06:58
ไม่กี่วันหลังจากซื้อรถมือสอง ฉันพบว่าไม่สามารถเล่นเพลงจากโทรศัพท์ผ่านเครื่องเสียงติดรถยนต์ได้ สิ่งที่น่าผิดหวังยิ่งกว่านั้นคือรถมีบลูทูธ แต่อนุญาตเฉพาะการโทรด้วยเสียง ไม่สามารถใช้เพลงได้ นอกจากนี้ยังมีพอร์ต USB สำหรับ Windows Phone แต่จะใช้งานกับ iPhone ไม่ได้หากไม่มีดองเกิล 60$
หลังจากเปลี่ยนสเตอริโอในรถคันก่อนโดยไม่ต้องคิดหรือค้นคว้าอะไรมาก ฉันจึงสั่งซื้อสเตอริโอทดแทนราคา 40 ดอลลาร์จากเว็บไซต์ "ราคาถูก" ที่รู้จักกันดี สเตอริโอมาพร้อมกับกล้องถอยหลัง Car Play และคุณสมบัติพิเศษมากมาย ซึ่งดูคุ้มค่ากว่าด็องเกิลที่มีราคาแพงกว่าซึ่งทำสิ่งเดียวเท่านั้น
หลังจากซื้อและทาสีแผ่นปิดหน้าใหม่ การพิมพ์ 3 มิติแท่นยึด และงานพิเศษมากมาย (ซึ่งอาจเป็นคำสั่งได้ด้วยตัวเอง) ฉันก็พบกับการค้นพบที่ไม่น่าพอใจ คำสั่งปุ่มพวงมาลัยถูกส่งผ่าน CAN บัส แต่สเตอริโอมีอินพุต Key1 เท่านั้น ไม่ใช่คนเดียวที่จะยอมแพ้ครึ่งทางฉันสั่งอะแดปเตอร์ 60 ปอนด์ซึ่งกลับกลายเป็นว่าใช้ไม่ได้ ณ จุดนี้ฉันตัดสินใจทำอะแดปเตอร์ด้วยตัวเอง
ฉันไม่ใช่วิศวกรไฟฟ้า ฉันแค่มีความรู้ด้านอิเล็กทรอนิกส์เบื้องต้นเท่านั้น และนี่เป็นโครงการเรียนรู้และสำรวจสำหรับฉัน คำแนะนำของฉันคือให้ตรวจสอบข้อกำหนดรถของคุณก่อนและสั่งซื้อวิทยุที่ใช้งานร่วมกันได้ แต่ถ้าคุณติดขัดอยู่แล้ว (เหมือนที่ฉันเป็นอยู่) ให้ปฏิบัติตามคำแนะนำโดยยอมรับความเสี่ยงของคุณเอง
เสบียง
อะแดปเตอร์ (ประมาณ 15$)
- Arduino Pro Mini 5V (หรือบอร์ดที่เข้ากันได้)
- MCP2515 โมดูลบัส CAN
- แผ่นไม้อัด 60x80mm
- X9C104 โพเทนชิโอมิเตอร์แบบดิจิตอล 100K โอห์ม (ขึ้นอยู่กับสเตอริโอของคุณ)
- DC-DC สเต็ปดาวน์เรกูเลเตอร์ LM2596S 3-40V 3A
- ตัวยึดฟิวส์สายไฟ + ฟิวส์ (100-200 โอห์ม)
- กล่องโปรเจ็กต์หรือเครื่องพิมพ์ 3 มิติเพื่อพิมพ์
- แจ็คสเตอริโอติดรถยนต์ (ชาย+หญิง)
- อุปกรณ์บัดกรี สายไฟ ฯลฯ
ตัวช่วยทดสอบ (ไม่จำเป็นอย่างยิ่ง แต่จะทำให้การทดสอบง่ายขึ้นมาก)
- Arduino (บอร์ด 5V ใด ๆ จะทำ)
- MCP2515 โมดูลบัส CAN
- เขียงหั่นขนม + จัมเปอร์
ขั้นตอนที่ 1: CAN บัสดมกลิ่น
แทนที่จะมีสายไฟพันรอบภายในรถของคุณที่เชื่อมต่อระบบต่างๆ เข้าด้วยกัน ยานพาหนะสมัยใหม่บางคันมีสายไฟคู่หนึ่งวิ่งไปยังแต่ละส่วนประกอบ ข้อมูลจะถูกส่งเป็นแพ็กเก็ตข้อมูลดิจิทัลผ่านสายเหล่านี้ และระบบทั้งหมดสามารถอ่านข้อความทั้งหมดได้ นี่คือเครือข่ายบัส CAN (อาจมีหลายเครือข่ายในรถของคุณ ดังนั้นข้อมูลทั้งหมดอาจไม่ปรากฏให้เห็น)
สิ่งที่เราต้องทำคือเชื่อมต่อกับเครือข่ายบัส CAN และ "สูดอากาศ" การรับส่งข้อมูล วิธีนี้ทำให้เรา "มองเห็น" เมื่อกดปุ่มบนพวงมาลัยได้ แต่ละแพ็กเก็ตมี ID ซึ่งแสดงถึงระบบย่อยของรถที่ส่งแพ็กเก็ต และข้อมูลที่แสดงสถานะของระบบ ในกรณีนี้ เรากำลังพยายามค้นหา ID ของระบบย่อยที่ส่งข้อความเกี่ยวกับกุญแจบนพวงมาลัย และการแสดงข้อมูลของแต่ละคีย์
หากคุณโชคดี คุณอาจพบค่าสำหรับรถของคุณที่ใดที่หนึ่งทางออนไลน์ และสามารถข้ามขั้นตอนนี้ได้
กระบวนการนี้ค่อนข้างเกี่ยวข้องและได้อธิบายไว้ในที่อื่นแล้ว ดังนั้นฉันจะสรุปได้ดังนี้:
- ค้นหาค่าที่ถูกต้องสำหรับการสื่อสาร CAN บัสบนรถของคุณ สำหรับรถของฉัน (แนวคิด Fiat ปี 2009) เป็นอัตราบอด 50KBPS และความเร็วสัญญาณนาฬิกา 8MHz
- เชื่อมต่อกับเครือข่ายบัส CAN โดยใช้โมดูลบัส CAN และ Arduino ในการกำหนดค่า "ดมกลิ่น"
- อ่านค่าบัส CAN บนแล็ปท็อปของคุณโดยใช้เครื่องมือ เช่น https://github.com/alexandreblin/python-can-monito…. หากไม่มีสิ่งนี้จะยากมาก เนื่องจากมีข้อความจำนวนมากถูกส่งถึงแม้รถไม่ได้ทำอะไรเลย
- กดปุ่มบนพวงมาลัยและสังเกตการเปลี่ยนแปลงค่า การดำเนินการนี้อาจยุ่งยากเล็กน้อยเนื่องจากมีการส่งข้อความจำนวนมากและอาจเป็นเรื่องยากที่จะทราบว่าข้อความใดเป็นข้อความใด
ต่อไปนี้คือบทความดีๆ สองบทความที่อธิบายกระบวนการในเชิงลึก:
- https://medium.com/@alexandreblin/can-bus-reverse-…
- https://www.instructables.com/id/CAN-Bus-Sniffing-…
ในตอนท้ายคุณควรมี ID ระบบย่อยที่เราจะใช้เพื่อฟังเฉพาะข้อความ CAN บัสบนพวงมาลัย และรายการค่าเลขฐานสิบหกสำหรับคำสั่งคีย์ ในกรณีของฉันข้อมูลมีลักษณะดังนี้:
ไอดี | ID Hex | ไบต์ 0 | ไบต์ 1 | ปุ่ม
---------------------------------------------------- 964 | 3C4 | 00 | 00 | ไม่มีปุ่ม 964 | 3C4 | 04 | 00 | SRC 964 | 3C4 | 10 | 00 | >> 964 | 3C4 | 08 | 00 | << 964 | 3C4 | 00 | 80 | โทรศัพท์ 964 | 3C4 | 00 | 08 | ESC 964 | 3C4 | 80 | 00 | +964 | 3C4 | 40 | 00 | - 964 | 3C4 | 00 | 40 | ชนะ 964 | 3C4 | 00 | 02 | ขึ้น 964 | 3C4 | 00 | 01 | ลง 964 | 3C4 | 00 | 04 | ตกลง
รหัสระบบย่อยคือ 3C4 (ในกรณีนี้) ซึ่งเป็นเลขฐานสิบหก ดังนั้นเราควรเขียนมันเหมือน 0x3C4 ในแบบร่าง Arduino เราสนใจไบต์ 0 และ 1 ด้วย (ในกรณีของคุณอาจมีไบต์มากกว่านั้น) ค่าเหล่านี้เป็นค่าฐานสิบหกด้วย ดังนั้นควรเขียนด้วย 0x นำหน้าด้วย
หากคุณแปลงค่าเป็นเลขฐานสอง คุณจะสังเกตเห็นว่าบิตไม่ทับซ้อนกัน (เช่น + 0b10000000 และ - 0b01000000) เพื่อให้สามารถกดได้หลายปุ่มพร้อมกัน
ฉันขอแนะนำให้สร้างเครื่องดมกลิ่นด้วยวัสดุที่ระบุไว้ในส่วน "ตัวช่วยทดสอบ" เพื่อให้คุณสามารถนำกลับมาใช้ใหม่ในภายหลังเพื่อจำลองรถของคุณได้ วิธีนี้จะช่วยให้คุณไม่ต้องนั่งอยู่ในรถตลอดเวลาขณะสร้างและทดสอบอะแดปเตอร์ คุณสามารถใช้ภาพร่างที่ให้มาเพื่อทำหน้าที่เป็นตัวจำลอง แก้ไข "subsystemId", "data0" และ "data1" ด้วยค่าที่คุณดมกลิ่น
ขั้นตอนที่ 2: การส่งคำสั่งไปยัง Stereo
ก่อนเริ่มสร้างอแด็ปเตอร์ ทางที่ดีควรทดสอบก่อนว่าสเตอริโอสามารถรับคำสั่งได้หรือไม่
ฉันมีแบตเตอรี่รถยนต์สำรอง ดังนั้นฉันจึงต่อสเตอริโอเข้ากับแบตเตอรี่โดยตรง หากคุณมีแหล่งจ่ายไฟแบบตั้งโต๊ะ 12V ที่ดียิ่งขึ้น น่าเสียดายที่ฉันไม่สามารถหาข้อมูลออนไลน์เกี่ยวกับอินพุต Key1 ในหน่วยของฉันได้มากนัก ดังนั้นฉันจึงใช้วิธีทดลอง ฉันไม่ได้วิตกกังวลมากเกินไปเกี่ยวกับการเผาไหม้ของสเตอริโอ ณ จุดนี้ เพราะมันค่อนข้างถูก และนี่เป็นความพยายามครั้งสุดท้ายของฉันที่จะให้มันใช้งานได้กับรถของฉัน
สเตอริโอมีหน้าจอการเรียนรู้คำสั่ง ซึ่งคุณสามารถเลือกค่าความต้านทานหนึ่งในสองค่า (1K และ 3.3K) และดูค่า "แรงดันไฟฟ้า" (0-255) "แรงดันไฟฟ้า" ถูกยกมาเพราะมันทำให้เข้าใจผิด ฉันใช้เวลามากมายกับการใช้แรงดันไฟฟ้าที่แตกต่างกันกับ Key1 โดยไม่มีโชค ฉันยังลองใช้ตัวต้านทานที่แตกต่างกันเพื่อใช้แรงดันไฟฟ้าโดยไม่มีโชค
ความก้าวหน้าเกิดขึ้นเมื่อฉันพยายามแตะสาย Key1 กับกราวด์ของแบตเตอรี่ ซึ่งส่งผลให้ "แรงดันไฟฟ้า" ลดลงเหลือ 0 ซึ่งเมื่อใช้ร่วมกับตัวต้านทานต่างๆ จะสร้างค่า "แรงดันไฟฟ้า" ที่สอดคล้องกันบนหน้าจอการเรียนรู้
ตอนนี้ฉันรู้วิธีส่งสัญญาณอินพุตไปยังสเตอริโอแล้ว ฉันต้องการวิธีส่งสัญญาณจาก Arduino ณ จุดนี้ ฉันไม่เคยได้ยินเกี่ยวกับมัลติเพล็กเซอร์ ซึ่งร่วมกับตัวต้านทานบางตัว อาจเป็นวิธีแก้ปัญหาที่เร็วกว่าและเชื่อถือได้มากกว่า (ฉันยังไม่แน่ใจว่าวิธีนี้เป็นไปได้หรือไม่) ดังนั้นฉันจึงใช้โพเทนชิออมิเตอร์แบบดิจิตอล ตอนแรกฉันมีปัญหาในการทำให้หม้อดิจิทัลทำงาน จนกระทั่งฉันพบว่าฉันต้องต่อสายมันเป็นลิโน่เพื่อทำหน้าที่เป็นตัวต้านทานปรับค่าได้แทนที่จะเป็นตัวแบ่งแรงดันไฟฟ้า โดยทั่วไปฉันต้องเชื่อมต่อขั้ว RH และ RW
นอกจากการต่อต้านแล้ว เวลาเป็นสิ่งสำคัญ หากแนวต้านสั้นเกินไป คำสั่งจะไม่ถูกลงทะเบียน หากยาวเกินไปอาจได้รับการลงทะเบียนหลายครั้ง ลดลง 240ms ตามด้วยความล่าช้า 240ms จนกว่าคำสั่งถัดไปจะทำงานได้อย่างน่าเชื่อถือสำหรับสเตอริโอของฉัน แม้ว่าจะดูเหมือนเวลาน้อยมาก แต่ก็หมายความว่าเราสามารถส่งคำสั่งได้สูงสุด 2 คำสั่งต่อวินาที ซึ่งจะเห็นได้ชัดเจนหากคุณพยายามเพิ่มหรือลดระดับเสียงอย่างรวดเร็ว ฉันลองเล่นโดยใช้เวลาและรูปแบบต่างๆ กัน ซึ่งเพิ่มความเร็วได้ แต่ก็ไม่น่าเชื่อถือมากนัก หากคุณมีความคิดใด ๆ เกี่ยวกับวิธีการปรับปรุงนี้โปรดทิ้งไว้ในความคิดเห็น
ก่อนดำเนินการต่อ ฉันแนะนำให้สร้างต้นแบบเพื่อตรวจสอบว่าสเตอริโอของคุณยอมรับอินพุตประเภทเดียวกันหรือไม่ แม้ว่าจะยอมรับแรงดันไฟฟ้าที่แตกต่างกัน แต่อะแดปเตอร์ก็ควรทำงานโดยมีการเปลี่ยนแปลงเล็กน้อยในการเดินสายและร่าง Arduino
ขั้นตอนที่ 3: สร้างอะแดปเตอร์
หลังจากทดสอบส่วนประกอบทั้งหมดแยกจากกัน และลองใช้ร่วมกันบนเขียงหั่นขนม ถึงเวลาแล้วที่จะมอบบ้านถาวรให้กับพวกมัน ใช้เวลาสองสามชั่วโมงในการจัดวางส่วนประกอบและการบัดกรี
ที่ด้านบนซ้ายคือตัวควบคุมแบบสเต็ปดาวน์ ซึ่งจะแปลง 12V จากแบตเตอรี่รถยนต์เป็น 5V ซึ่งส่วนประกอบอื่นๆ สามารถใช้งานได้
ที่ด้านล่างซ้ายคือโมดูลบัส CAN ซึ่งอ่านค่าจากเครือข่ายบัส CAN ของรถยนต์และส่งต่อไปยัง Arduino
ที่ด้านบนขวาคือโพเทนชิออมิเตอร์แบบดิจิตอล (ต่อสายเป็นลิโน่) ที่ทำหน้าที่เป็นตัวต้านทานผันแปรระหว่างกราวด์และอินพุต Key1 ของสเตอริโอ
ที่มุมขวาล่างคือ Arduino ซึ่งทำหน้าที่เป็นสมองของอะแดปเตอร์ เปลี่ยนข้อความบัส CAN เป็นความต้านทานที่อ่านโดยสเตอริโอ
ที่อินพุต 12V เป็นฟิวส์ 150mA ซึ่งส่วนใหญ่จะไม่ป้องกันวงจร แต่มีไว้เพื่อป้องกันไม่ให้เกิดไฟไหม้ในกรณีที่ไฟฟ้าลัดวงจร
ขั้นตอนที่ 4: ซอฟต์แวร์
หลังจากดาวน์โหลดแล้ว ให้ใส่ไฟล์.ino ทั้งสามไฟล์ไว้ในโฟลเดอร์เดียว วิธีนั้นจะเป็นส่วนหนึ่งของภาพร่างเดียวกันและนำไปปรับใช้กับ Arudino ด้วยกัน
คุณต้องเพิ่มไลบรารีที่จำเป็นลงใน Arduino IDE ด้วย โดยดาวน์โหลดไฟล์ต่อไปนี้:
github.com/autowp/arduino-mcp2515/archive/…
github.com/philbowles/Arduino-X9C/archive/…
จากนั้นเพิ่มทั้งคู่โดยไปที่ Sketch > รวมไลบรารี > เพิ่ม. Zip Library…
CanBusStereoAdapter.ino
การตั้งค่าพื้นฐานดำเนินการในไฟล์นี้
คำสั่งคีย์ ค่าบัส CAN ถูกกำหนดไว้ที่ด้านบน ถ้าคุณไม่มีรถแบบเดียวกับฉัน คุณมักจะต้องใส่ค่านิยมของคุณเอง คุณสามารถใช้ค่าเลขฐานสิบหกจาก sniffer ได้ ฉันใช้เลขฐานสอง ดังนั้นจึงง่ายที่จะเห็นว่าไม่มีการทับซ้อนโดยไม่ได้ตั้งใจในบิต
รถทุกคันไม่มีคำสั่งพวงมาลัยเหมือนกัน ดังนั้นอย่าลังเลที่จะลบ เพิ่ม หรือแก้ไขค่าที่กำหนดไว้
อย่าลืมแทนที่ id ระบบย่อยของคุณใน "STEERING_ID"
CanBus.ino
ไฟล์นี้ตั้งค่าตัวฟังบัส CAN ตีความแพ็กเก็ต และใส่ค่าความต้านทานลงในบัฟเฟอร์แบบวงกลม
ปรับการกำหนดค่าบัส CAN ในฟังก์ชัน "setupCanBus" เพื่อให้เหมาะกับรถของคุณ
เราใช้บัฟเฟอร์แบบวงกลม เนื่องจากตามที่กล่าวไว้ก่อนหน้านี้ อินพุตคำสั่งบนพวงมาลัยนั้นเร็วกว่าอินพุตสเตอริโอมาก วิธีนี้ทำให้เราไม่พลาดคำสั่งใดๆ ในขณะที่โพเทนชิออมิเตอร์แบบดิจิตอลกำลังทำงานอยู่ หากเราป้อนคำสั่งมากเกินไป คำสั่งที่เก่าที่สุดจะถูกละทิ้งก่อน เนื่องจากคำสั่งเหล่านั้นมีความสำคัญน้อยที่สุด นอกจากนี้ยังช่วยให้เราจัดการกับกรณีนี้เมื่อกดปุ่มหลายปุ่ม เนื่องจากอินพุตสเตอริโอยอมรับเพียงค่าเดียวในแต่ละครั้ง
หากคุณได้เปลี่ยนแปลงคำจำกัดความของคำสั่งใดๆ ใน "CanBusStereoAdapter.ino" คุณจะต้องอัปเดตข้อกำหนดเหล่านี้ในฟังก์ชัน "handleMessageData" ด้วย "handleMessageData" ตรวจสอบว่าเฟรมข้อมูลบัส CAN ที่ให้มามีคำสั่งที่รู้จักโดยใช้การดำเนินการ AND ระดับบิตหรือไม่
ตัวอย่างเช่น หากฉันกด >> และ + พร้อมกันจะทำให้ data frame มีค่าเท่ากับ 0b10010000 >> (สำหรับรถของฉัน) คือ 0b00010000 ในรูปแบบไบนารี และ + คือ 0b10000000
--------------- >> -------------- + ------------- << --- -- data0 | 0b10010000 | 0b10010000 | คำสั่ง 0b10010000 | และ 0b00010000 | และ 0b10000000 | AND 0b00001000 ผลลัพธ์ | = 0b00010000 | = 0b10000000 | = 0b00000000
ที่นี่เราจะเห็นว่าผลลัพธ์ของการดำเนินการ AND จะมากกว่า 0 หากมีคำสั่งอยู่ในกรอบข้อมูล สิ่งที่เราต้องทำคือตรวจสอบ {data frame} & {command value} > 0 สำหรับแต่ละคำสั่งที่เรากำหนด
โปรดทราบว่าแต่ละ data frame มีคำสั่งที่แตกต่างกัน ดังนั้นจึงเป็นเรื่องปกติหากค่าของคำสั่งเหมือนกัน เนื่องจากเรากำลังตรวจสอบกับเฟรมของคำสั่งนั้นๆ ในตัวอย่างของฉันทั้ง << และ ESC ทั้งคู่มีค่าเท่ากัน 0b00001000 (0x08) แต่ << อยู่ใน data0 และ ESC ใน data1
หลังจากที่เราพิจารณาแล้วว่าคำสั่งมีอยู่ในเฟรม เราจะเพิ่มค่า pot ดิจิทัลให้กับบัฟเฟอร์แบบวงกลม ค่ามีตั้งแต่ 0 ถึง 99 แต่ฉันสังเกตเห็นว่า "แรงดันไฟฟ้า" ที่อ่านโดยสเตอริโอไม่เป็นเชิงเส้น ดังนั้นให้ทดสอบค่าด้วยตัวคุณเอง
DigitalPot.ino
ไฟล์นี้ดึงค่าออกจากบัฟเฟอร์แบบวงกลมและส่งไปยังหม้อดิจิทัลเพื่อดำเนินการ ในกรณีของฉัน "pot.setPotMin(false);" จะเพิ่มความต้านทานสูงสุดซึ่งสเตอริโอจะอ่านเป็น "แรงดันไฟฟ้า" สูงสุด สเตอริโอของคุณอาจต้องการให้คุณตั้งค่าหม้อดิจิทัลเป็นขั้นต่ำ ดังนั้น ทดสอบออก
ขั้นตอนที่ 5: สิ่งที่แนบมากับโครงการ
ฉันมีเครื่องพิมพ์ 3 มิติ ดังนั้นฉันจึงตัดสินใจพิมพ์กล่องหุ้มสองส่วนสำหรับอะแดปเตอร์ของฉัน ฉันได้รวมไฟล์ Fusion 360 ที่คุณสามารถแก้ไขได้ และไฟล์ gcode ที่จะพอดีกับ perfboard ขนาด 60x80 มม.
หากคุณไม่มีเครื่องพิมพ์ 3 มิติ คุณสามารถใช้โครงสำเร็จรูปหรือภาชนะที่ทนทานได้
ขั้นตอนที่ 6: ความคิดสุดท้าย
ตอนแรกฉันวางแผนไว้ว่าอะแดปเตอร์จะเชื่อมต่อกับพลังงานคงที่และปลุกด้วยข้อความ CAN บัสบางข้อความ เนื่องจากรถของฉันไม่มีสายไฟในห้องสเตอริโอ ต่อมาฉันตัดสินใจไม่ทำ เพราะฉันไม่ต้องการที่จะเสี่ยงกับการใช้แบตเตอรี่จนหมดและกังวลเกี่ยวกับอะแดปเตอร์ในขณะที่ฉันไม่อยู่ที่รถ ฉันใช้ตัวแยกกล่องฟิวส์ในรถยนต์เพื่อเรียกใช้สายจุดระเบิดและไม่ต้องทำให้อะแดปเตอร์ยุ่งยากอีกต่อไป
จากการทดสอบของฉัน การใช้พลังงานคือ 20-30 mA ฉันลดระดับเสียงลงเหลือ 10 mA ในโหมดสลีป และอาจลดได้อีกด้วยการถอด LED ออกจากส่วนประกอบ แต่ฉันตัดสินใจที่จะไม่ยุ่งกับมัน เพราะมันจะทำงานในขณะที่รถกำลังวิ่งอยู่เท่านั้น
ฉันค่อนข้างพอใจกับผลลัพธ์ที่ได้ เวลาตอบสนองนั้นสมเหตุสมผลและแทบไม่พลาดคำสั่ง
แม้ว่าการลงทุนเวลาของฉันจะมากกว่าค่าใช้จ่ายของอะแดปเตอร์ที่มีจำหน่ายทั่วไป (ซึ่งใช้งานไม่ได้) ความรู้ที่ฉันได้รับนั้นมีค่ามาก