สารบัญ:
- ขั้นตอนที่ 1: สร้างวงจร
- ขั้นตอนที่ 2: การตั้งค่าออสซิลโลสโคป
- ขั้นตอนที่ 3: ดาวน์โหลดและเรียกใช้ซอฟต์แวร์
- ขั้นตอนที่ 4: สร้างภาพวาดของคุณเอง
- ขั้นตอนที่ 5: วางพิกัดจากไฟล์ SVG ลงใน Arduino IDE
- ขั้นตอนที่ 6: ทำความเข้าใจว่าทำไม PWM ถึงช้ามาก
- ขั้นตอนที่ 7: รับจาก a ถึง B เร็วขึ้นเล็กน้อย
- ขั้นตอนที่ 8: รับจาก a ถึง B ด้วยเทอร์โบชาร์จเจอร์
- ขั้นตอนที่ 9: ทำความเข้าใจรหัส
- ขั้นตอนที่ 10: ด้วยความเร็วอันยอดเยี่ยม มาพร้อมความรับผิดชอบอันยอดเยี่ยม
2025 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2025-01-13 06:58
คำแนะนำนี้แสดงวิธีการสร้างการเปลี่ยนแปลงแรงดันไฟฟ้าแบบอะนาล็อกที่เร็วมากจาก Arduino และคู่ตัวต้านทานและตัวเก็บประจุอย่างง่าย แอปพลิเคชั่นหนึ่งที่มีประโยชน์คือการสร้างกราฟิกบนออสซิลโลสโคป มีอีกหลายโครงการที่ทำสิ่งนี้ Johngineer แสดงต้นคริสต์มาสอย่างง่ายโดยใช้การปรับความกว้างพัลส์ (PWM) คนอื่น ๆ ได้ปรับปรุงโครงการดังกล่าวโดยใช้บันไดตัวต้านทานหรือใช้ชิปแปลงสัญญาณดิจิทัลเป็นแอนะล็อกโดยเฉพาะ
การใช้ PWM ทำให้เกิดการสั่นไหวมาก ในขณะที่การใช้ตัวต้านทานแลดเดอร์หรือตัวแปลงดิจิทัลเป็นแอนะล็อกต้องการพินเอาต์พุตและส่วนประกอบที่อาจไม่พร้อมใช้งานมากขึ้น วงจรที่ฉันใช้คือตัวต้านทานแบบธรรมดาและคู่ตัวเก็บประจุแบบตายตัวแบบเดียวกับที่ใช้ในการสาธิตต้นคริสต์มาส แต่ทำงานด้วยการสั่นไหวน้อยลงอย่างเห็นได้ชัด
อันดับแรก ฉันจะแนะนำคุณตลอดขั้นตอนการสร้างวงจร แล้วผมจะสอนวิธีเพิ่มภาพของคุณเอง สุดท้ายนี้ ผมจะแนะนำทฤษฎีเกี่ยวกับสิ่งที่ทำให้เร็วขึ้น
หากคุณชอบคำแนะนำนี้ โปรดพิจารณาลงคะแนนให้!:)
ขั้นตอนที่ 1: สร้างวงจร
ในการสร้างวงจรคุณจะต้องมีสิ่งต่อไปนี้:
a) Arduino ที่ใช้ Atmel 16MHz ATmega328P เช่น Arduino Uno หรือ Arduino Nano
b) ตัวต้านทานสองตัวที่มีค่า R อย่างน้อย 150Ω
c) ตัวเก็บประจุสองตัวที่มีค่า C โดยที่ C = 0.0015 / R ตัวอย่าง:
- R = 150Ω และ C = 10µ
- R = 1.5kΩ และ C = 1µ
- R = 15kΩ และ C = 100nF
- R = 150kΩ และ C = 10nF
เหตุผลในการเลือกค่าเหล่านี้เป็นสองเท่า ในขั้นต้น เราต้องการให้กระแสบนพินของ Arduino อยู่ต่ำกว่ากระแสพิกัดสูงสุดที่ 40mA การใช้ค่า 150Ω จะจำกัดกระแสไว้ที่ 30mA เมื่อใช้กับแรงดันไฟฟ้าของ Arduino ที่ 5V ค่า R ที่มากขึ้นจะลดกระแสลงและเป็นที่ยอมรับได้
ข้อจำกัดที่สองคือ เราต้องการให้เวลาคงที่ ซึ่งเป็นผลคูณของ R และ C เท่ากับประมาณ 1.5 มิลลิวินาที ซอฟต์แวร์นี้ได้รับการปรับแต่งเป็นพิเศษสำหรับค่าคงที่เวลานี้ แม้ว่าจะสามารถปรับค่าของ R และ C ในซอฟต์แวร์ได้ แต่ก็มีช่วงที่แคบซึ่งใช้งานได้ ดังนั้นควรเลือกส่วนประกอบที่ใกล้เคียงกับอัตราส่วนที่แนะนำมากที่สุด
คำอธิบายโดยละเอียดเพิ่มเติมเกี่ยวกับสาเหตุที่ค่าคงที่ RC มีความสำคัญจะได้รับในส่วนทฤษฎี หลังจากที่ฉันได้แสดงให้คุณเห็นถึงวิธีการประกอบวงจรสาธิตแล้ว
ขั้นตอนที่ 2: การตั้งค่าออสซิลโลสโคป
การสาธิตต้องตั้งค่าออสซิลโลสโคปเป็นโหมด X/Y ต้องต่อสายวัดทดสอบตามที่แสดงในแผนผัง ออสซิลโลสโคปของคุณจะแตกต่างจากของฉัน แต่ฉันจะอธิบายขั้นตอนที่จำเป็นในการตั้งค่าโหมด X/Y บนยูนิตของฉัน:
a) ตั้งค่าการกวาดแนวนอนที่จะควบคุมโดย Channel B (แกน X)
b) ตั้งค่าออสซิลโลสโคปเป็นโหมดช่องสัญญาณคู่
c) ตั้งค่าโวลต์/div บนทั้งสองช่องสัญญาณเพื่อให้สามารถแสดงแรงดันไฟฟ้าได้ตั้งแต่ 0V ถึง 5V ฉันตั้งค่าของฉันเป็น 0.5V/div
d) ตั้งค่าโหมด coupling เป็น DC ทั้งสองช่อง
e) ปรับตำแหน่งของ X และ Y เพื่อให้จุดอยู่ที่มุมล่างซ้ายของหน้าจอเมื่อปิด Arduino
ขั้นตอนที่ 3: ดาวน์โหลดและเรียกใช้ซอฟต์แวร์
ดาวน์โหลดซอฟต์แวร์จากที่เก็บ Fast Vector Display For Arduino ซอฟต์แวร์ได้รับอนุญาตภายใต้ GNU Affero Public License v3 และสามารถใช้และแก้ไขได้อย่างอิสระภายใต้เงื่อนไขของใบอนุญาตนั้น
เปิดไฟล์ "fast-vector-display-arduino.ino" ใน Arduino IDE แล้วอัปโหลดไปยัง Arduino ของคุณ คุณจะเห็นแอนิเมชั่น "สวัสดีปีใหม่" บนหน้าจอออสซิลโลสโคปของคุณ
ฉันพัฒนาโปรเจ็กต์นี้เป็นแฮ็กกาตันส่วนตัวในช่วงสัปดาห์ก่อนถึงคริสต์มาส ดังนั้นจึงมีข้อความธีมคริสต์มาสและปีใหม่ที่คุณสามารถดูได้โดยการแก้ไขตัวแปร PATTERN ในโค้ด
ขั้นตอนที่ 4: สร้างภาพวาดของคุณเอง
หากคุณต้องการสร้างภาพวาดของคุณเอง คุณสามารถวางพิกัดจุดลงในร่าง Arduino บนบรรทัดที่กำหนด USER_PATTERN
ฉันพบว่า Inkscape เป็นเครื่องมือที่ดีในการสร้างภาพวาดแบบกำหนดเอง:
- สร้างข้อความโดยใช้ฟอนต์ตัวหนาขนาดใหญ่ เช่น Impact
- เลือกวัตถุข้อความและเลือก "วัตถุไปยังเส้นทาง" จากเมนู "เส้นทาง"
- เลือกตัวอักษรแต่ละตัวและทับซ้อนกันเพื่อสร้างรูปร่างที่เชื่อมต่อกัน
- เลือก "Union" จากเมนู "Path" เพื่อรวมเป็นเส้นโค้งเดียว
- หากมีรูในตัวอักษรใดๆ ให้ตัดรอยบากเล็กๆ โดยการวาดรูปสี่เหลี่ยมผืนผ้าด้วยเครื่องมือสี่เหลี่ยมผืนผ้า แล้วลบออกจากเส้นขอบโดยใช้เครื่องมือ "Difference"
- คลิกสองครั้งที่เส้นทางเพื่อแสดงโหนด
- สี่เหลี่ยมผืนผ้าเลือกโหนดทั้งหมดแล้วคลิกเครื่องมือ "สร้างมุมโหนดที่เลือก"
- บันทึกไฟล์ SVG
สิ่งสำคัญคือภาพวาดของคุณควรมีเส้นทางปิดเดียวและไม่มีรู ตรวจสอบให้แน่ใจว่าการออกแบบของคุณมีคะแนนน้อยกว่า 130 คะแนน
ขั้นตอนที่ 5: วางพิกัดจากไฟล์ SVG ลงใน Arduino IDE
- เปิดไฟล์ SVG และคัดลอกพิกัด สิ่งเหล่านี้จะถูกฝังในองค์ประกอบ "เส้นทาง" พิกัดคู่แรกสามารถละเว้นได้ แทนที่ด้วย 0, 0
- วางพิกัดลงในร่าง Arduino ภายในวงเล็บทันทีหลัง "#define USER_PATTERN"
- แทนที่ช่องว่างทั้งหมดด้วยเครื่องหมายจุลภาค มิฉะนั้น คุณจะได้รับข้อผิดพลาดในการคอมไพล์ เครื่องมือ "แทนที่และค้นหา" อาจมีประโยชน์
- รวบรวมและเรียกใช้!
- หากคุณมีปัญหา โปรดดูข้อผิดพลาดในคอนโซลซีเรียล โดยเฉพาะอย่างยิ่ง คุณจะเห็นข้อความหากรูปแบบของคุณมีจุดมากเกินไปสำหรับบัฟเฟอร์ภายใน ในกรณีดังกล่าว ภาพจะแสดงการสั่นไหวมากเกินไป
ขั้นตอนที่ 6: ทำความเข้าใจว่าทำไม PWM ถึงช้ามาก
ในการเริ่มต้น เรามาทบทวนพฤติกรรมของตัวเก็บประจุในขณะที่กำลังชาร์จ
ตัวเก็บประจุที่เชื่อมต่อกับแหล่งจ่ายแรงดัน Vcc จะเพิ่มแรงดันไฟฟ้าตามเส้นโค้งเลขชี้กำลัง เส้นโค้งนี้เป็นแบบไม่แสดง ซึ่งหมายความว่าจะช้าลงเมื่อเข้าใกล้แรงดันไฟฟ้าเป้าหมาย สำหรับวัตถุประสงค์ในทางปฏิบัติทั้งหมด แรงดันไฟฟ้า "ใกล้เพียงพอ" หลังจาก 5 RC วินาที RC เรียกว่า "ค่าคงที่เวลา" ดังที่เราเห็นก่อนหน้านี้ เป็นผลคูณของค่าของตัวต้านทานและตัวเก็บประจุในวงจรของคุณ ปัญหาคือว่า 5 RC นั้นค่อนข้างนานในการอัปเดตแต่ละจุดในการแสดงผลกราฟิก นี้นำไปสู่การสั่นไหวมาก!
เมื่อเราใช้การปรับความกว้างพัลส์ (PWM) เพื่อชาร์จตัวเก็บประจุ เราก็ไม่มีอะไรดีไปกว่านี้แล้ว ด้วย PWM แรงดันไฟฟ้าจะสลับอย่างรวดเร็วระหว่าง 0V ถึง 5V ในทางปฏิบัติ นี่หมายความว่าเราสลับกันอย่างรวดเร็วระหว่างการผลักประจุเข้าไปในตัวเก็บประจุและดึงออกมาเล็กน้อยอีกครั้ง – การผลักและดึงนี้เหมือนกับการพยายามวิ่งมาราธอนด้วยการก้าวไปข้างหน้าครั้งใหญ่แล้วถอยหลังเล็กน้อย ครั้งแล้วครั้งเล่า.
เมื่อคุณหาค่าเฉลี่ยทั้งหมด พฤติกรรมของการชาร์จตัวเก็บประจุโดยใช้ PWM จะเหมือนกับที่คุณใช้แรงดันไฟคงที่ของ Vpwm เพื่อชาร์จตัวเก็บประจุ ยังคงใช้เวลาประมาณ 5 RC วินาทีเพื่อให้เราได้รับ "ใกล้เพียงพอ" กับแรงดันไฟฟ้าที่ต้องการ
ขั้นตอนที่ 7: รับจาก a ถึง B เร็วขึ้นเล็กน้อย
สมมติว่าเรามีตัวเก็บประจุที่มีประจุถึง Va แล้ว สมมติว่าเราใช้ analogWrite() เพื่อเขียนค่าใหม่ของ b ระยะเวลาขั้นต่ำที่คุณต้องรอให้ถึงแรงดัน Vb คืออะไร?
หากคุณเดา 5 RC วินาทีนั่นเยี่ยมมาก! โดยการรอ 5 RC วินาที ตัวเก็บประจุจะถูกชาร์จจนเกือบ Vb แต่ถ้าเราต้องการจริง ๆ เราสามารถรอน้อยลงเล็กน้อย
ดูเส้นโค้งประจุ คุณเห็นไหมว่าตัวเก็บประจุอยู่ที่ Va เมื่อเราเริ่ม ซึ่งหมายความว่าเราไม่ต้องรอเวลา t_a เราจะต้องทำก็ต่อเมื่อเราชาร์จตัวเก็บประจุจากศูนย์เท่านั้น
ดังนั้นโดยไม่รอเวลานั้น เราจึงเห็นการปรับปรุง เวลา t_ab นั้นสั้นกว่า 5 RC เล็กน้อย
แต่เดี๋ยวก่อน เราทำได้ดีกว่านี้มาก! ดูช่องว่างด้านบน v_b ทั้งหมด นั่นคือความแตกต่างระหว่าง Vcc แรงดันไฟฟ้าสูงสุดที่เรามี และ Vb ที่เราตั้งใจจะเข้าถึง คุณเห็นไหมว่าแรงดันไฟฟ้าที่เพิ่มขึ้นนั้นสามารถช่วยให้เราไปถึงที่ที่เราต้องการได้เร็วขึ้นมากได้อย่างไร
ขั้นตอนที่ 8: รับจาก a ถึง B ด้วยเทอร์โบชาร์จเจอร์
ถูกตัอง. แทนที่จะใช้ PWM ที่แรงดันไฟเป้าหมาย V_b เราถือไว้ที่ Vcc ที่คงที่ในระยะเวลาที่สั้นกว่ามาก ฉันเรียกวิธีนี้ว่าวิธีเทอร์โบชาร์จเจอร์ และทำให้เราไปถึงจุดหมายอย่างรวดเร็วจริงๆ! หลังจากหน่วงเวลา (ซึ่งเราต้องคำนวณ) เราก็เบรกโดยสลับไปที่ PWM ที่ V_b วิธีนี้จะช่วยไม่ให้แรงดันไฟเกินเป้าหมาย
ด้วยวิธีนี้ คุณสามารถเปลี่ยนแรงดันไฟฟ้าในตัวเก็บประจุจาก V_a เป็น V_b ได้ในเวลาเพียงเสี้ยววินาที มากกว่าการใช้แค่ PWM นี่คือวิธีที่คุณจะได้สถานที่ ที่รัก!
ขั้นตอนที่ 9: ทำความเข้าใจรหัส
รูปภาพมีค่าหนึ่งพันคำ ดังนั้นไดอะแกรมจึงแสดงข้อมูลและการดำเนินการที่ทำในโค้ด จากซ้ายไปขวา:
- ข้อมูลกราฟิกถูกเก็บไว้ใน PROGMEM (นั่นคือหน่วยความจำแฟลช) เป็นรายการจุด
- การรวมกันของการแปล การปรับมาตราส่วน และการหมุนจะรวมกันเป็นเมทริกซ์การแปลงแบบสัมพัทธ์ ทำได้ครั้งเดียวเมื่อเริ่มต้นเฟรมภาพเคลื่อนไหวแต่ละเฟรม
- คะแนนจะถูกอ่านทีละจุดจากข้อมูลกราฟิกและคูณด้วยเมทริกซ์การแปลงที่เก็บไว้
- จุดที่เปลี่ยนรูปจะถูกป้อนผ่านอัลกอริธึมแบบกรรไกรซึ่งจะครอบตัดจุดใดๆ นอกพื้นที่ที่มองเห็นได้
- การใช้ตารางค้นหาการหน่วงเวลา RC จุดต่างๆ จะถูกแปลงเป็นแรงดันไฟและความล่าช้าของเวลา ตารางการค้นหาการหน่วงเวลา RC ถูกเก็บไว้ใน EEPROM และสามารถนำมาใช้ซ้ำได้สำหรับการรันโค้ดหลายครั้ง เมื่อเริ่มต้น ตารางการค้นหา RC จะถูกตรวจสอบความถูกต้อง และค่าที่ไม่ถูกต้องจะได้รับการอัปเดต การใช้ EEPROM ช่วยประหยัดหน่วยความจำ RAM อันมีค่า
- แรงดันไฟฟ้าและความล่าช้าในการขับขี่จะถูกเขียนไปยังเฟรมที่ไม่ได้ใช้งานในบัฟเฟอร์เฟรม บัฟเฟอร์เฟรมมีพื้นที่สำหรับเฟรมที่ใช้งานอยู่และเฟรมที่ไม่ใช้งาน เมื่อเขียนเฟรมที่สมบูรณ์แล้ว เฟรมที่ไม่ได้ใช้งานจะถูกเปิดใช้งาน
- รูทีนบริการขัดจังหวะจะวาดภาพใหม่อย่างต่อเนื่องโดยการอ่านค่าแรงดันไฟฟ้าและความล่าช้าจากบัฟเฟอร์เฟรมที่ใช้งานอยู่ ตามค่าเหล่านั้น มันจะปรับรอบการทำงานของพินเอาต์พุต ตัวจับเวลา 1 ใช้สำหรับวัดการหน่วงเวลาที่มีความแม่นยำไม่กี่นาโนวินาที ในขณะที่ตัวจับเวลา 2 ใช้สำหรับควบคุมรอบการทำงานของพิน
- พินที่มีการเปลี่ยนแปลงแรงดันไฟฟ้ามากที่สุดมักจะ "ชาร์จด้วยเทอร์โบ" โดยมีรอบการทำงานเป็นศูนย์หรือ 100% ซึ่งให้เวลาในการชาร์จหรือคายประจุที่เร็วที่สุด พินที่มีการเปลี่ยนแปลงของแรงดันไฟฟ้าน้อยกว่าจะถูกขับเคลื่อนด้วยรอบการทำงานที่เลือกเพื่อให้ตรงกับเวลาการเปลี่ยนแปลงของพินแรก การจับคู่ครั้งนี้เป็นสิ่งสำคัญเพื่อให้แน่ใจว่าเส้นจะถูกลากตรงบนออสซิลโลสโคป
ขั้นตอนที่ 10: ด้วยความเร็วอันยอดเยี่ยม มาพร้อมความรับผิดชอบอันยอดเยี่ยม
เนื่องจากวิธีนี้เร็วกว่า PWM มาก เหตุใดจึงไม่ใช้ analogWrite () เพราะการใช้แค่ PWM นั้นดีพอสำหรับโปรแกรมส่วนใหญ่และให้อภัยได้มากกว่า อย่างไรก็ตาม วิธี "เทอร์โบชาร์จเจอร์" ต้องใช้การเข้ารหัสอย่างระมัดระวังและเหมาะสำหรับบางกรณีเท่านั้น:
- มีความไวต่อเวลามาก เมื่อเราไปถึงระดับแรงดันไฟฟ้าเป้าหมายแล้ว หมุดขับเคลื่อนจะต้องเปลี่ยนเป็นโหมด PWM ปกติทันที เพื่อหลีกเลี่ยงไม่ให้แรงดันเกินเป้าหมาย
- ต้องใช้ความรู้เกี่ยวกับค่าคงที่ RC ดังนั้นต้องป้อนค่าเหล่านี้ล่วงหน้า ด้วยค่าที่ไม่ถูกต้อง เวลาจะผิดและแรงดันไฟฟ้าจะไม่ถูกต้อง ด้วย PWM ปกติ มีการรับประกันว่าคุณจะจ่ายแรงดันไฟฟ้าที่ถูกต้องหลังจากผ่านไประยะหนึ่ง แม้ว่าจะไม่ทราบค่าคงที่ RC ก็ตาม
- การคำนวณช่วงเวลาที่แม่นยำสำหรับการชาร์จตัวเก็บประจุต้องใช้สมการลอการิทึมซึ่งช้าเกินไปสำหรับการคำนวณแบบเรียลไทม์บน Arduino ต้องคำนวณล่วงหน้าก่อนเฟรมภาพเคลื่อนไหวแต่ละเฟรมและแคชในหน่วยความจำที่ใดที่หนึ่ง
- โปรแกรมที่เกี่ยวข้องกับวิธีนี้ต้องต่อสู้กับความจริงที่ว่าความล่าช้านั้นไม่เชิงเส้นมาก (อันที่จริงแล้วเป็นการชี้แจง) แรงดันไฟฟ้าเป้าหมายใกล้ Vcc หรือ GND จะใช้เวลาหลายคำสั่งของขนาดที่ยาวกว่าจะไปถึงมากกว่าแรงดันไฟฟ้าใกล้จุดกึ่งกลาง
เพื่อเอาชนะข้อจำกัดเหล่านี้ โค้ดกราฟิกแบบเวกเตอร์ของฉันทำสิ่งต่อไปนี้:
- ใช้ตัวจับเวลา 1 ที่ 16kHz และรูทีนบริการขัดจังหวะเพื่อการจัดการและกำหนดเวลาเอาต์พุตที่แม่นยำ
- ต้องใช้ค่าคงที่เวลา RC เฉพาะ เพื่อจำกัดตัวเลือกของค่าตัวเก็บประจุและค่าตัวต้านทาน
- มันเก็บการหน่วงเวลาสำหรับจุดทั้งหมดในเฟรมภาพเคลื่อนไหวในบัฟเฟอร์หน่วยความจำ ซึ่งหมายความว่ารูทีนที่คำนวณการหน่วงเวลาทำงานในอัตราที่ช้ากว่ารูทีนบริการขัดจังหวะที่อัพเดตพินเอาต์พุต กรอบใดก็ตามอาจถูกทาสีหลายสิบครั้งก่อนที่ชุดการหน่วงเวลาใหม่สำหรับเฟรมถัดไปจะพร้อมใช้งาน
- การใช้บัฟเฟอร์หน่วยความจำทำให้มีข้อจำกัดเกี่ยวกับจำนวนจุดที่สามารถวาดได้ต่อเฟรม ฉันใช้การเข้ารหัสแบบประหยัดพื้นที่เพื่อใช้ประโยชน์สูงสุดจาก RAM ที่มีอยู่ แต่ก็ยังจำกัดอยู่ที่ประมาณ 150 คะแนน เกินกว่าร้อยจุดหรือมากกว่านั้น จอภาพจะเริ่มสั่นไหวอยู่แล้ว ดังนั้นมันจึงเป็นจุดที่สงสัย!